Skip to content

Commit

Permalink
[backport#16377 2/2][rpc] fundrawtransaction: add_inputs option to co…
Browse files Browse the repository at this point in the history
…ntrol automatic input adding

Summary:
---

Backport of Core [[bitcoin/bitcoin#16377 | PR16377]]

Depends on D8659

Note: replaced a couple unused `i` for-loop variables in functional tests that the linter complained about with `_`'s

Test Plan:
  ninja all check check-functional

Reviewers: #bitcoin_abc, PiRK

Reviewed By: #bitcoin_abc, PiRK

Differential Revision: https://reviews.bitcoinabc.org/D8660
  • Loading branch information
Sjors authored and majcosta committed Dec 11, 2020
1 parent a3c6da5 commit 1b8a6cb
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
5 changes: 4 additions & 1 deletion doc/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ that `-salvagewallet` did.
The `walletcreatefundedpsbt` RPC call will now fail with `Insufficient funds`
when inputs are manually selected but are not enough to cover the outputs and
fee. Additional inputs can automatically be added through the new `add_inputs`
option.
option.

The `fundrawtransaction` RPC now supports `add_inputs` option that when `false`
prevents adding more inputs if necessary and consequently the RPC fails.
13 changes: 9 additions & 4 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3829,10 +3829,9 @@ static UniValue fundrawtransaction(const Config &config,

RPCHelpMan{
"fundrawtransaction",
"Add inputs to a transaction until it has enough in value to meet "
"its out value.\n"
"This will not modify existing inputs, and will add at most one change "
"output to the outputs.\n"
"If the transaction has no inputs, they will be automatically selected "
"to meet its out value.\n"
"It will add at most one change output to the outputs.\n"
"No existing outputs will be modified unless "
"\"subtractFeeFromOutputs\" is specified.\n"
"Note that inputs which were signed may need to be resigned after "
Expand All @@ -3858,6 +3857,9 @@ static UniValue fundrawtransaction(const Config &config,
"for backward compatibility: passing in a true instead of an "
"object will result in {\"includeWatching\":true}",
{
{"add_inputs", RPCArg::Type::BOOL, /* default */ "true",
"For a transaction with existing inputs, automatically "
"include more if they are not enough."},
{"changeAddress", RPCArg::Type::STR,
/* default */ "pool address",
"The bitcoin address to receive the change"},
Expand Down Expand Up @@ -3935,6 +3937,9 @@ static UniValue fundrawtransaction(const Config &config,
Amount fee;
int change_position;
CCoinControl coin_control;
// Automatically select (additional) coins. Can be overridden by
// options.add_inputs.
coin_control.m_add_inputs = true;
FundTransaction(pwallet, tx, fee, change_position, request.params[1],
coin_control);

Expand Down
32 changes: 28 additions & 4 deletions test/functional/rpc_fundrawtransaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,15 @@ def test_coin_selection(self):
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex'])

# Should fail without add_inputs:
assert_raises_rpc_error(-4,
"Insufficient funds",
self.nodes[2].fundrawtransaction,
rawTx,
{"add_inputs": False})
# add_inputs is enabled by default
rawtxfund = self.nodes[2].fundrawtransaction(rawTx)

dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
totalOut = 0
matchingOuts = 0
Expand Down Expand Up @@ -312,7 +320,15 @@ def test_two_vin(self):
dec_tx = self.nodes[2].decoderawtransaction(rawTx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])

rawtxfund = self.nodes[2].fundrawtransaction(rawTx)
# Should fail without add_inputs:
assert_raises_rpc_error(-4,
"Insufficient funds",
self.nodes[2].fundrawtransaction,
rawTx,
{"add_inputs": False})
rawtxfund = self.nodes[2].fundrawtransaction(
rawTx, {"add_inputs": True})

dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
totalOut = 0
matchingOuts = 0
Expand Down Expand Up @@ -346,7 +362,15 @@ def test_two_vin_two_vout(self):
dec_tx = self.nodes[2].decoderawtransaction(rawTx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])

rawtxfund = self.nodes[2].fundrawtransaction(rawTx)
# Should fail without add_inputs:
assert_raises_rpc_error(-4,
"Insufficient funds",
self.nodes[2].fundrawtransaction,
rawTx,
{"add_inputs": False})
rawtxfund = self.nodes[2].fundrawtransaction(
rawTx, {"add_inputs": True})

dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
totalOut = 0
matchingOuts = 0
Expand Down Expand Up @@ -565,7 +589,7 @@ def test_many_inputs_fee(self):
self.nodes[1].generate(1)
self.sync_all()

for i in range(0, 20):
for _ in range(0, 20):
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
self.nodes[0].generate(1)
self.sync_all()
Expand Down Expand Up @@ -596,7 +620,7 @@ def test_many_inputs_send(self):
self.nodes[1].generate(1)
self.sync_all()

for i in range(0, 20):
for _ in range(0, 20):
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
self.nodes[0].generate(1)
self.sync_all()
Expand Down

0 comments on commit 1b8a6cb

Please sign in to comment.