-
Notifications
You must be signed in to change notification settings - Fork 37.7k
[rpc] don't automatically append inputs in walletcreatefundedpsbt #16377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[rpc] don't automatically append inputs in walletcreatefundedpsbt #16377
Conversation
a74855c
to
e87e089
Compare
e87e089
to
4bf5d6a
Compare
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
concept ACK |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK.
Instead of |
4bf5d6a
to
d8e51a2
Compare
This effects |
@achow101 I didn't change this behavior in |
Yes, but |
d8e51a2
to
6769883
Compare
I changed |
6769883
to
f82a770
Compare
src/wallet/rpcwallet.cpp
Outdated
@@ -3107,6 +3111,7 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) | |||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"}, | |||
{"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}", | |||
{ | |||
{"add_inputs", RPCArg::Type::BOOL, /* default */ "false", "For a transaction with existing inputs, automatically include more if they are not enough."}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is backward-incompatible, and it makes no sense for this RPC which does exactly only that? Confused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See @achow101's comment above: #16377 (comment)
I tend to agree that walletcreatefundedpspbt
is different from fundrawtransaction
in this aspect, because walletcreatefundedpspbt
also sets the destination.
Would like to hear some more opinions, otherwise I'll drop the last commit (where this is added). Or I can change the default for fundrawtransaction
but keep the option, in case it's useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think both walletcreatefundedpsbt
and fundrawtransaction
are both most commonly used with no inputs. As I understand it, with add_inputs
defaulting to false, this behavior doesn't change. Even so, the option is useful in fundrawtransaction
as sometimes you just want it to set the change output and fee for a transaction after you've already selected the inputs.
I have built an app on top of bitcoin-cli and definitely would prefer no inputs to be added at all by default when using It makes fee optimization a lot easier in this scenario where a user wants to specify inputs as one can not take advantage of the |
@FontaineDenton does your application use |
I just updated my original comment so it hopefully makes more sense. |
f82a770
to
21af29a
Compare
21af29a
to
914009d
Compare
@@ -3030,6 +3030,10 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f | |||
}, | |||
true, true); | |||
|
|||
if (options.exists("add_inputs") ) { | |||
coinControl.m_add_inputs = options["add_inputs"].get_bool(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to allow add_inputs = false
when no input is manually selected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'll just fail with insufficient funds. I don't think it's necessary to special-case that.
Rebased, slightly tweaked one test and added a new one. |
5fc79ef
to
9d0ef2a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just some small suggestions.
doc/release-notes-16377.md
Outdated
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also add something like
The `fundrawtransaction` RPC now supports `add_inputs` option that when `false` prevents adding more inputs if necessary and consequently the RPC fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
FundTransaction(pwallet, tx, fee, change_position, request.params[1]); | ||
CCoinControl coin_control; | ||
// Automatically select (additional) coins. Can be overriden by options.add_inputs. | ||
coin_control.m_add_inputs = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is already the default value in coin_control
so maybe remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it adds clarity that this (default) value matters for this caller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
// By default new inputs are added automatically. Can be overriden by options.add_inputs.
CHECK_NONFATAL(coin_control.m_add_inputs);
src/wallet/rpcwallet.cpp
Outdated
"Implements the Creator and Updater roles.\n", | ||
{ | ||
{"inputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The inputs", | ||
{"inputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The inputs. Leave empty to add inputs automatically.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, maybe add See add_inputs option
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
When the user doesn't specificy inputs, it makes sense to automatically select them. But when the user does specify inputs, we now fail if the amount is insufficient, unless addInputs is set to true.
9d0ef2a
to
e5327f9
Compare
With |
@sipa the difference is when when you don't specify inputs. If you do specificy inputs, then by default (as of this PR) neither command will add them. But they're still different, because I didn't even realise |
ACK e5327f9 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review ACK but left some comments. This looks great and gives more control to the caller.
The RPC bumpfee
also adds inputs (or reduces change output) so maybe we could add this option there too in a follow-up.
FundTransaction(pwallet, tx, fee, change_position, request.params[1]); | ||
CCoinControl coin_control; | ||
// Automatically select (additional) coins. Can be overriden by options.add_inputs. | ||
coin_control.m_add_inputs = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
// By default new inputs are added automatically. Can be overriden by options.add_inputs.
CHECK_NONFATAL(coin_control.m_add_inputs);
@@ -3148,8 +3148,8 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request) | |||
} | |||
|
|||
RPCHelpMan{"fundrawtransaction", | |||
"\nAdd 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" | |||
"\nIf the transaction has no inputs, they will be automatically selected to meet its out value.\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous text was fine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the previous text suggests that it always adds inputs. I reworded that to make it clear we only do automatic coin selection if there is no manual coin selection.
@@ -10,6 +10,7 @@ void CCoinControl::SetNull() | |||
{ | |||
destChange = CNoDestination(); | |||
m_change_type.reset(); | |||
m_add_inputs = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't tested and looks like nobody asked, but can't we use fAllowOtherInputs
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That won't work. I think fAllowOtherInputs
was designed with RBF in mind. It permits adding coins, as long as all the currently selected coins are included. But this PR tries to prevent adding coins.
@@ -3016,13 +3016,12 @@ static UniValue listunspent(const JSONRPCRequest& request) | |||
return results; | |||
} | |||
|
|||
void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& fee_out, int& change_position, UniValue options) | |||
void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& fee_out, int& change_position, UniValue options, CCoinControl& coinControl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, unrelated, could receive options by reference.
I'll leave the |
@@ -2149,6 +2149,11 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector< | |||
} | |||
|
|||
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) { | |||
// Only consider selected coins if add_inputs is false | |||
if (coinControl && !coinControl->m_add_inputs && !coinControl->IsSelected(COutPoint(entry.first, i))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ultra nit, cache IsSelected()
by adding above:
const bool is_selected = coinControl && coinControl->IsSelected(COutPoint(entry.first, i));
then use this in L2160 below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK e5327f9
…tcreatefundedpsbt e5327f9 [rpc] fundrawtransaction: add_inputs option to control automatic input adding (Sjors Provoost) 79804fe [rpc] walletcreatefundedpsbt: don't automatically append inputs (Sjors Provoost) Pull request description: When the user doesn't specificy inputs, it makes sense to automatically select them. But when the user does specify inputs, `walletcreatefundedpsbt` now fails if the amount is insufficient, unless `addInputs` is set to `true`. Similarly for `fundrawtransaction` if the original transaction already specified inputs, we only add more if `addInputs` is set to `true`. This protects against fat finger mistakes in the amount or fee rate (see also bitcoin#16257). The behavior is also more similar to GUI coin selection. ACKs for top commit: achow101: ACK e5327f9 meshcollider: utACK e5327f9 Tree-SHA512: d8653b820914396c7c25b0d0a2b7e92de214aa023bc1aa085feb37d3b20fab361ebea90416a7db989f19bdc37e26cf0adfbcb712c80985c87afa67a9bd44fecb
Which version of Bitcoin Core will this get released on? |
Current master branch will become 0.21. |
92326d8 [rpc] add send method (Sjors Provoost) 2c2a144 [rpc] add snake case aliases for transaction methods (Sjors Provoost) 1bc8d0f [rpc] walletcreatefundedpsbt: allow inputs to be null (Sjors Provoost) Pull request description: `walletcreatefundedpsbt` has some interesting features that `sendtoaddress` and `sendmany` don't have: * manual coin selection * outputting a PSBT (it was controversial to add this, see #18201) * create a transaction without adding to wallet (which leads to broadcasting, unless `-walletbroadcast=0`) At the same time `walletcreatefundedpsbt` can't broadcast a transaction, which is inconvenient for simple use cases. This PR introduces a new `send` RPC method which creates a PSBT, signs it if possible and adds it to the wallet by default. If it can't sign all inputs, it outputs a PSBT. If `add_to_wallet` is set to `false` it will return the transaction in both PSBT and hex format. Because it uses a PSBT internally, it will much easier to add hardware wallet support to this method (see #16546). For `bitcoin-cli` users, it tries to keep the simplest use case easy to use: ```sh bitcoin-cli -regtest send '{"ADDRESS": 0.1}' 1 sat/b ``` This paves the way for deprecating `sendtoaddress` and `sendmany` though there's no rush. The only missing feature compared to these older methods is adding labels to a destination address. Depends on: - [x] #16377 (`[rpc] don't automatically append inputs in walletcreatefundedpsbt`) - [x] #11413 (`[wallet] [rpc] sendtoaddress/sendmany: Add explicit feerate option`) - [x] #18244 (`[rpc] have lockUnspents also lock manually selected coins`) ACKs for top commit: meshcollider: Light re-utACK 92326d8 achow101: ACK 92326d8 Reviewed code and test, ran tests. kallewoof: utACK 92326d8 Tree-SHA512: 7552ef1b193d4c06e381c44932fdb0d54f64383e4c7d6b988f49d059c7d4bba45ce6aa7813e03df86360ad9dad6f3010eb76ee7da480551742d5fd98c2251c0f
92326d8 [rpc] add send method (Sjors Provoost) 2c2a144 [rpc] add snake case aliases for transaction methods (Sjors Provoost) 1bc8d0f [rpc] walletcreatefundedpsbt: allow inputs to be null (Sjors Provoost) Pull request description: `walletcreatefundedpsbt` has some interesting features that `sendtoaddress` and `sendmany` don't have: * manual coin selection * outputting a PSBT (it was controversial to add this, see bitcoin#18201) * create a transaction without adding to wallet (which leads to broadcasting, unless `-walletbroadcast=0`) At the same time `walletcreatefundedpsbt` can't broadcast a transaction, which is inconvenient for simple use cases. This PR introduces a new `send` RPC method which creates a PSBT, signs it if possible and adds it to the wallet by default. If it can't sign all inputs, it outputs a PSBT. If `add_to_wallet` is set to `false` it will return the transaction in both PSBT and hex format. Because it uses a PSBT internally, it will much easier to add hardware wallet support to this method (see bitcoin#16546). For `bitcoin-cli` users, it tries to keep the simplest use case easy to use: ```sh bitcoin-cli -regtest send '{"ADDRESS": 0.1}' 1 sat/b ``` This paves the way for deprecating `sendtoaddress` and `sendmany` though there's no rush. The only missing feature compared to these older methods is adding labels to a destination address. Depends on: - [x] bitcoin#16377 (`[rpc] don't automatically append inputs in walletcreatefundedpsbt`) - [x] bitcoin#11413 (`[wallet] [rpc] sendtoaddress/sendmany: Add explicit feerate option`) - [x] bitcoin#18244 (`[rpc] have lockUnspents also lock manually selected coins`) ACKs for top commit: meshcollider: Light re-utACK 92326d8 achow101: ACK 92326d8 Reviewed code and test, ran tests. kallewoof: utACK 92326d8 Tree-SHA512: 7552ef1b193d4c06e381c44932fdb0d54f64383e4c7d6b988f49d059c7d4bba45ce6aa7813e03df86360ad9dad6f3010eb76ee7da480551742d5fd98c2251c0f
… append inputs Summary: When the user doesn't specificy inputs, it makes sense to automatically select them. But when the user does specify inputs, we now fail if the amount is insufficient, unless addInputs is set to true. --- Backport of Core [[bitcoin/bitcoin#16377 | PR16377]] [1/2] Test Plan: ninja all check check-functional Reviewers: #bitcoin_abc, PiRK Reviewed By: #bitcoin_abc, PiRK Differential Revision: https://reviews.bitcoinabc.org/D8659
…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
When the user doesn't specificy inputs, it makes sense to automatically select them. But when the user does specify inputs,
walletcreatefundedpsbt
now fails if the amount is insufficient, unlessaddInputs
is set totrue
.Similarly for
fundrawtransaction
if the original transaction already specified inputs, we only add more ifaddInputs
is set totrue
.This protects against fat finger mistakes in the amount or fee rate (see also #16257). The behavior is also more similar to GUI coin selection.