Skip to content

Commit e5327f9

Browse files
committed
[rpc] fundrawtransaction: add_inputs option to control automatic input adding
1 parent 79804fe commit e5327f9

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

doc/release-notes-16377.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ RPC changes
44
`Insufficient funds` when inputs are manually selected but are not enough to cover
55
the outputs and fee. Additional inputs can automatically be added through the
66
new `add_inputs` option.
7+
8+
- The `fundrawtransaction` RPC now supports `add_inputs` option that when `false`
9+
prevents adding more inputs if necessary and consequently the RPC fails.

src/wallet/rpcwallet.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,8 +3148,8 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request)
31483148
}
31493149

31503150
RPCHelpMan{"fundrawtransaction",
3151-
"\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
3152-
"This will not modify existing inputs, and will add at most one change output to the outputs.\n"
3151+
"\nIf the transaction has no inputs, they will be automatically selected to meet its out value.\n"
3152+
"It will add at most one change output to the outputs.\n"
31533153
"No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
31543154
"Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
31553155
"The inputs added will not be signed, use signrawtransactionwithkey\n"
@@ -3163,6 +3163,7 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request)
31633163
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
31643164
{"options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED_NAMED_ARG, "for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}",
31653165
{
3166+
{"add_inputs", RPCArg::Type::BOOL, /* default */ "true", "For a transaction with existing inputs, automatically include more if they are not enough."},
31663167
{"changeAddress", RPCArg::Type::STR, /* default */ "pool address", "The bitcoin address to receive the change"},
31673168
{"changePosition", RPCArg::Type::NUM, /* default */ "random", "The index of the change output"},
31683169
{"change_type", RPCArg::Type::STR, /* default */ "set by -changetype", "The output type to use. Only valid if changeAddress is not specified. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
@@ -3229,6 +3230,8 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request)
32293230
CAmount fee;
32303231
int change_position;
32313232
CCoinControl coin_control;
3233+
// Automatically select (additional) coins. Can be overriden by options.add_inputs.
3234+
coin_control.m_add_inputs = true;
32323235
FundTransaction(pwallet, tx, fee, change_position, request.params[1], coin_control);
32333236

32343237
UniValue result(UniValue::VOBJ);

test/functional/rpc_fundrawtransaction.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,11 @@ def test_coin_selection(self):
271271
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
272272
assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex'])
273273

274+
# Should fail without add_inputs:
275+
assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
276+
# add_inputs is enabled by default
274277
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
278+
275279
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
276280
totalOut = 0
277281
matchingOuts = 0
@@ -299,7 +303,10 @@ def test_two_vin(self):
299303
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
300304
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
301305

302-
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
306+
# Should fail without add_inputs:
307+
assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
308+
rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {"add_inputs": True})
309+
303310
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
304311
totalOut = 0
305312
matchingOuts = 0
@@ -330,7 +337,10 @@ def test_two_vin_two_vout(self):
330337
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
331338
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
332339

333-
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
340+
# Should fail without add_inputs:
341+
assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx, {"add_inputs": False})
342+
rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {"add_inputs": True})
343+
334344
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
335345
totalOut = 0
336346
matchingOuts = 0

0 commit comments

Comments
 (0)