Skip to content

Commit b00fc44

Browse files
committed
test: add coverage for 'add_inputs' dynamic default value
Covered cases for send() and walletcreatefundedpsbt() RPC commands: 1. Default add_inputs value with no preset inputs (add_inputs=true): Expect: automatically add coins from the wallet to the tx. 2. Default add_inputs value with preset inputs (add_inputs=false): Expect: disallow automatic coin selection. 3. Explicit add_inputs=true and preset inputs (with preset inputs not-covering the target amount). Expect: include inputs from the wallet. 4. Explicit add_inputs=true and preset inputs (with preset inputs covering the target amount). Expect: only preset inputs are used. 5. Explicit add_inputs=true, no preset inputs (same as (1) but with an explicit set): Expect: include inputs from the wallet.
1 parent ddbcfdf commit b00fc44

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

test/functional/rpc_fundrawtransaction.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ def run_test(self):
106106
self.generate(self.nodes[2], 1)
107107
self.generate(self.nodes[0], 121)
108108

109+
self.test_add_inputs_default_value()
109110
self.test_weight_calculation()
110111
self.test_change_position()
111112
self.test_simple()
@@ -1073,6 +1074,121 @@ def test_external_inputs(self):
10731074

10741075
self.nodes[2].unloadwallet("extfund")
10751076

1077+
def test_add_inputs_default_value(self):
1078+
self.log.info("Test 'add_inputs' default value")
1079+
1080+
# Create and fund the wallet with 5 BTC
1081+
self.nodes[2].createwallet("test_preset_inputs")
1082+
wallet = self.nodes[2].get_wallet_rpc("test_preset_inputs")
1083+
addr1 = wallet.getnewaddress(address_type="bech32")
1084+
self.nodes[0].sendtoaddress(addr1, 5)
1085+
self.generate(self.nodes[0], 1)
1086+
1087+
# Covered cases:
1088+
# 1. Default add_inputs value with no preset inputs (add_inputs=true):
1089+
# Expect: automatically add coins from the wallet to the tx.
1090+
# 2. Default add_inputs value with preset inputs (add_inputs=false):
1091+
# Expect: disallow automatic coin selection.
1092+
# 3. Explicit add_inputs=true and preset inputs (with preset inputs not-covering the target amount).
1093+
# Expect: include inputs from the wallet.
1094+
# 4. Explicit add_inputs=true and preset inputs (with preset inputs covering the target amount).
1095+
# Expect: only preset inputs are used.
1096+
# 5. Explicit add_inputs=true, no preset inputs (same as (1) but with an explicit set):
1097+
# Expect: include inputs from the wallet.
1098+
1099+
# Case (1), 'send' command
1100+
# 'add_inputs' value is true unless "inputs" are specified, in such case, add_inputs=false.
1101+
# So, the wallet will automatically select coins and create the transaction if only the outputs are provided.
1102+
tx = wallet.send(outputs=[{addr1: 3}])
1103+
assert tx["complete"]
1104+
1105+
# Case (2), 'send' command
1106+
# Select an input manually, which doesn't cover the entire output amount and
1107+
# verify that the dynamically set 'add_inputs=false' value works.
1108+
1109+
# Fund wallet with 2 outputs, 5 BTC each.
1110+
addr2 = wallet.getnewaddress(address_type="bech32")
1111+
source_tx = self.nodes[0].send(outputs=[{addr1: 5}, {addr2: 5}], options={"change_position": 0})
1112+
self.generate(self.nodes[0], 1)
1113+
1114+
# Select only one input.
1115+
options = {
1116+
"inputs": [
1117+
{
1118+
"txid": source_tx["txid"],
1119+
"vout": 1 # change position was hardcoded to index 0
1120+
}
1121+
]
1122+
}
1123+
assert_raises_rpc_error(-4, "Insufficient funds", wallet.send, outputs=[{addr1: 8}], options=options)
1124+
1125+
# Case (3), Explicit add_inputs=true and preset inputs (with preset inputs not-covering the target amount)
1126+
options["add_inputs"] = True
1127+
options["add_to_wallet"] = False
1128+
tx = wallet.send(outputs=[{addr1: 8}], options=options)
1129+
assert tx["complete"]
1130+
1131+
# Case (4), Explicit add_inputs=true and preset inputs (with preset inputs covering the target amount)
1132+
options["inputs"].append({
1133+
"txid": source_tx["txid"],
1134+
"vout": 2 # change position was hardcoded to index 0
1135+
})
1136+
tx = wallet.send(outputs=[{addr1: 8}], options=options)
1137+
assert tx["complete"]
1138+
# Check that only the preset inputs were added to the tx
1139+
decoded_psbt_inputs = self.nodes[0].decodepsbt(tx["psbt"])['tx']['vin']
1140+
assert_equal(len(decoded_psbt_inputs), 2)
1141+
for input in decoded_psbt_inputs:
1142+
assert_equal(input["txid"], source_tx["txid"])
1143+
1144+
# Case (5), assert that inputs are added to the tx by explicitly setting add_inputs=true
1145+
options = {"add_inputs": True, "add_to_wallet": True}
1146+
tx = wallet.send(outputs=[{addr1: 8}], options=options)
1147+
assert tx["complete"]
1148+
1149+
################################################
1150+
1151+
# Case (1), 'walletcreatefundedpsbt' command
1152+
# Default add_inputs value with no preset inputs (add_inputs=true)
1153+
inputs = []
1154+
outputs = {self.nodes[1].getnewaddress(): 8}
1155+
assert "psbt" in wallet.walletcreatefundedpsbt(inputs=inputs, outputs=outputs)
1156+
1157+
# Case (2), 'walletcreatefundedpsbt' command
1158+
# Default add_inputs value with preset inputs (add_inputs=false).
1159+
inputs = [{
1160+
"txid": source_tx["txid"],
1161+
"vout": 1 # change position was hardcoded to index 0
1162+
}]
1163+
outputs = {self.nodes[1].getnewaddress(): 8}
1164+
assert_raises_rpc_error(-4, "Insufficient funds", wallet.walletcreatefundedpsbt, inputs=inputs, outputs=outputs)
1165+
1166+
# Case (3), Explicit add_inputs=true and preset inputs (with preset inputs not-covering the target amount)
1167+
options["add_inputs"] = True
1168+
options["add_to_wallet"] = False
1169+
assert "psbt" in wallet.walletcreatefundedpsbt(outputs=[{addr1: 8}], inputs=inputs, options=options)
1170+
1171+
# Case (4), Explicit add_inputs=true and preset inputs (with preset inputs covering the target amount)
1172+
inputs.append({
1173+
"txid": source_tx["txid"],
1174+
"vout": 2 # change position was hardcoded to index 0
1175+
})
1176+
psbt_tx = wallet.walletcreatefundedpsbt(outputs=[{addr1: 8}], inputs=inputs, options=options)
1177+
# Check that only the preset inputs were added to the tx
1178+
decoded_psbt_inputs = self.nodes[0].decodepsbt(psbt_tx["psbt"])['tx']['vin']
1179+
assert_equal(len(decoded_psbt_inputs), 2)
1180+
for input in decoded_psbt_inputs:
1181+
assert_equal(input["txid"], source_tx["txid"])
1182+
1183+
# Case (5), 'walletcreatefundedpsbt' command
1184+
# Explicit add_inputs=true, no preset inputs
1185+
options = {
1186+
"add_inputs": True
1187+
}
1188+
assert "psbt" in wallet.walletcreatefundedpsbt(inputs=[], outputs=outputs, options=options)
1189+
1190+
self.nodes[2].unloadwallet("test_preset_inputs")
1191+
10761192
def test_weight_calculation(self):
10771193
self.log.info("Test weight calculation with external inputs")
10781194

0 commit comments

Comments
 (0)