Skip to content

Conversation

furszy
Copy link
Member

@furszy furszy commented Dec 20, 2022

Depends on #27601.

Adding test coverage and the needed checks for two scenarios
where the wallet create invalid transactions.

First Scenario, Do Not Use Outputs From the Tx Being Replaced

When the wallet creates/fund a replacement transaction, it should
not fund the new transaction with outputs belonging to the tx
being replaced.

Reason:
Once replaced, those outputs are no longer going to exist, there
by the created/funded transaction will be invalid.

Second Scenario, Do Not Create BIP125 Rule 2 Invalid Txes

Prevent adding new unconfirmed outputs to the transaction being
created/funded If any preset input was already spent by a mempool
transaction.

Note:
Both scenarios can can be verified cherry-picking the tests commits
on master. They will fail.

@DrahtBot
Copy link
Contributor

DrahtBot commented Dec 20, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept ACK glozow, murchandamus

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #bitcoin-core/gui/807 (refactor: interfaces, make 'createTransaction' less error-prone by furszy)
  • #27865 (wallet: Track no-longer-spendable TXOs separately by achow101)
  • #27286 (wallet: Keep track of the wallet's own transaction outputs in memory by achow101)
  • #25269 (wallet: re-activate "AmountWithFeeExceedsBalance" error by furszy)
  • #21283 (Implement BIP 370 PSBTv2 by achow101)

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.

@achow101
Copy link
Member

To be clear, this is if you make a replacement manually, not with bumpfee. bumpfee avoids this problem by setting a minimum confirmations in the coin control object. IIRC BIP 125 disallows adding new unconfirmed inputs too.

@furszy
Copy link
Member Author

furszy commented Dec 21, 2022

To be clear, this is if you make a replacement manually, not with bumpfee. bumpfee avoids this problem by setting a minimum confirmations in the coin control object.

Yes, could happen if you manually pre-select an input from an unconfirmed transaction and provides it to any RPC command that creates or fund a transaction (e.g. send()). Not an issue for bumpfee as it skips unconfirmed UTXOs.

IIRC BIP 125 disallows adding new unconfirmed inputs too.

You mean, grouping inputs from different unconfirmed transactions into a single replacement tx?
(in other words, a single tx that replaces many unconfirmed txes).

So far, what the test proves is that the wallet, during the transaction creation process, can automatically select outputs from the unconfirmed transaction that is being replaced to use them as inputs. Which shouldn't happen as those coins will no longer exist once the tx gets replaced.

@achow101
Copy link
Member

You mean, grouping inputs from different unconfirmed transactions into a single replacement tx?
(in other words, a single tx that replaces many unconfirmed txes).

Unconfirmed inputs that were in the original transactions being replaced are fine. It's adding new unconfirmed inputs that is not allowed.

@furszy furszy force-pushed the 2022_wallet_do_not_select_utxo_from_the_tx_being_replaced branch from ca9bacd to c288c04 Compare December 21, 2022 22:42
@furszy furszy force-pushed the 2022_wallet_do_not_select_utxo_from_the_tx_being_replaced branch from c288c04 to 431387b Compare December 22, 2022 13:58
@furszy
Copy link
Member Author

furszy commented Dec 22, 2022

You mean, grouping inputs from different unconfirmed transactions into a single replacement tx?
(in other words, a single tx that replaces many unconfirmed txes).

Unconfirmed inputs that were in the original transactions being replaced are fine. It's adding new unconfirmed inputs that is not allowed.

Good to know. Thanks, it's BIP125 rule 2.

The wallet can create invalid transactions due not be contemplating that neither.
Same as with the other case, could happen on any of the "send*" and "fund*" RPC commands, when the user preselects an output that is being used as input for another unconfirmed transaction.

So, added test coverage and internal checks for it as well.

Summary:
Now this PR adds support and test coverage for two different scenarios where the wallet creates invalid transactions.

  1. If is creating a replacement tx; in the available coins fetching process, the wallet need to skip the outputs that corresponds to the transaction being replaced (those coins are no longer going to exist once it's replaced, there by they are not "available").

  2. Prevent adding new unconfirmed outputs to the transaction being created/funded If any preset input was already spent by a mempool transaction. (BIP125 rule 2).

@furszy furszy force-pushed the 2022_wallet_do_not_select_utxo_from_the_tx_being_replaced branch 2 times, most recently from f82e7ba to d7e41b6 Compare December 22, 2022 19:54
Copy link
Member

@glozow glozow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far, what the test proves is that the wallet, during the transaction creation process, can automatically select outputs from the unconfirmed transaction that is being replaced to use them as inputs. Which shouldn't happen as those coins will no longer exist once the tx gets replaced.

Indeed this sounds like a bug that should be fixed.
Would it be better to stop + warn the user that they have selected an input that is already spent by something in this mempool, and, if this is intentional, they should use bumpfee RPC instead? Otherwise you end up implementing RBF checks in 2 places?

}
}

// If this tx is a replacement, disallow unconfirmed UTXO selection by rising the
// coin control min depth param. Ensuring that we don't add any new unconfirmed UTXOs
// to replacement transactions (satisfying BIP125 rule 2).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do not add new mentions of BIP125 that aren't signaling-related, see #25775

@furszy
Copy link
Member Author

furszy commented Dec 26, 2022

So far, what the test proves is that the wallet, during the transaction creation process, can automatically select outputs from the unconfirmed transaction that is being replaced to use them as inputs. Which shouldn't happen as those coins will no longer exist once the tx gets replaced.

Indeed this sounds like a bug that should be fixed. Would it be better to stop + warn the user that they have selected an input that is already spent by something in this mempool, and, if this is intentional, they should use bumpfee RPC instead? Otherwise you end up implementing RBF checks in 2 places?

That is a good point and topic.

Another point of view would be to understand bumpfee as the sendtoaddress of the replacement transaction creation commands: the simplest and most straightforward way to create a replacement transaction, where regular users provide few inputs and the command just work. Without almost any possible customization etc.

Then, under this rationale, instead of blocking replacement txes from happening in lower level commands like fundrawtransaction, walletcreatefundedpsbt etc, it might be good to unify code (not duplicate the checks, which would be ugly for sure) and enable the same RBF validations on other processes too.
Only performing RBF checks if the crafted/funded transaction has at least one already spent input somewhere else (which only could happens if the user manually preset the input/s).

Which, based on a brief walk-through the bumpfee process, might not be that bad as we are duplicating some code that is already inside the general fundtransaction function.

Then, for advanced users, this view might be more adequate as otherwise we would need to add more customization options inside bumpfee so it provides almost the same functionality as the other lower level commands (e.g. be able to bump a tx that have at least one input that does not belong to the wallet, be able to add new confirmed inputs manually, modify an output value, provide an input weight manually, among other "not standard for bump txes" flows that advanced users might want to do).


Still.. have to say that this comes from an out loud thinking.. atm, I don't have a strong preference over any approach:
The blocking approach is reasonable as it would make our life easier for the time being but then, if users start requesting tx customizations, we will end up adding lot of stuff into bumpfee that is already somewhere else. Which will force us to unify code anyway.

Copy link
Member

@glozow glozow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK, apologies for the late re-review

Just to recap the whiteboarding session we had offline, I think what we want is to add a SanitizeCoinControl function that can be used early on across both bumpfee and fundraw RPCs:

  1. If any of the selected inputs is already spent in mempool, is_replacement=true and keep track of which inputs are being spent again.
  2. If the selected inputs includes UTXOs spent and created by the same transaction (i.e. selected output from a tx that is being replaced), return error "invalid input selection"
  3. If is_replacement=true, automatically set min_depth=1
  4. If is_replacement and any of the selected inputs is <min_depth but not part of the replaced tx, return error "invalid input selection" (i.e. selected an additional unconfirmed output in an RBF)

The transactions should fail regardless, but this gives the user a helpful "invalid input selection" to let them know that they have manually selected some inputs that don't make sense.

Copy link
Contributor

@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

Copy link
Member Author

@furszy furszy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There hasn't been much activity lately and the patch still needs rebase. What is the status here?

  • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.

It is still relevant. I'm waiting for #27601 outcome to rebase it. This work depends on it.

@maflcko
Copy link
Member

maflcko commented Dec 11, 2023

There hasn't been much activity lately and the patch still needs rebase. What is the status here?

  • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.

It is still relevant. I'm waiting for #27601 outcome to rebase it. This work depends on it.

Is there an outcome? Seems like nothing has happened on the pull since, other than it needing rebase.

@furszy
Copy link
Member Author

furszy commented Dec 12, 2023

Is there an outcome? Seems like nothing has happened on the pull since, other than it needing rebase.

Not yet. Still need to rework #27601 first. Other wallet works have gotten more priority than this working path. This two PRs are still bugs within the wallet but they could wait a bit in favor of other PRs.
I don't have a fixed time to get back to this work, but will try to do it after new year. We should be able to merge few of the ongoing big PRs by then.

furszy added 2 commits March 30, 2024 20:40
When the wallet creates/fund a replacement transaction (spending
one or more inputs of one or many existent transactions), it should
not fund the new transaction with outputs belonging to the txes
being replaced.

Reason:
Once replaced, those outputs are no longer going to exist, there
by the created/funded transaction will be invalid.
The wallet tx creation process should not select any output
belonging to the transaction that is being replaced.
furszy added 3 commits March 30, 2024 20:40
Ensuring that we don't add any new unconfirmed UTXOs to the replacement
transaction (satisfying BIP125 rule 2).

note:
needed to slightly adapt the 'test_add_inputs_default_value' functional
test case because it was creating a replacement tx and adding new
unconfirmed inputs without noticing it (we are testing a totally
different things there).
the wallet should skip unconfirmed outputs when it is
creating/funding a replacement tx

Per BIP125 rule 2, the replacement tx must only have unconfirmed
inputs from the original transaction that is being replaced.
Cannot contain new unconfirmed inputs.
@furszy furszy force-pushed the 2022_wallet_do_not_select_utxo_from_the_tx_being_replaced branch from d7e41b6 to 34df3c7 Compare March 30, 2024 23:41
@furszy furszy changed the title wallet: tx creation, don't select outputs from txes that are being replaced [WIP] wallet: tx creation, don't select outputs from txes that are being replaced Mar 30, 2024
@DrahtBot
Copy link
Contributor

DrahtBot commented Dec 3, 2024

🤔 There hasn't been much activity lately and the CI seems to be failing.

If no one reviewed the current pull request by commit hash, a rebase can be considered. While the CI failure may be a false positive, the CI hasn't been running for some time, so there may be a real issue hiding as well. A rebase triggers the latest CI and makes sure that no silent merge conflicts have snuck in.

@furszy
Copy link
Member Author

furszy commented Dec 30, 2024

Closing for now. Might revive it in the future, post #27286.

@furszy furszy closed this Dec 30, 2024
@bitcoin bitcoin deleted a comment from Hameedoooooo Jul 2, 2025
@murchandamus
Copy link
Contributor

@furszy: #27286 was merged, in case this is still relevant.

@furszy
Copy link
Member Author

furszy commented Jul 7, 2025

@furszy: #27286 was merged, in case this is still relevant.

Thx. It is still relevant but I don't have enough time to tackle it. Up for grabs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants