-
Notifications
You must be signed in to change notification settings - Fork 37.7k
test: add MiniWallet tagging support to avoid UTXO mixing, use in fill_mempool
#29939
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
test: add MiniWallet tagging support to avoid UTXO mixing, use in fill_mempool
#29939
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. 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. |
Nice, 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, having a separate util for mempool is nice, all mempool helpers will live there.
I'm still not sure if a generic word like "tag" is the right term for what this tries to achieve, happy to pick up better suggestions. Also, maybe passing a tag name is overkill and a boolean flag like "random_output_script" is sufficient?
I don't feel strongly on this but I like the second idea of just boolean flag.
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.
This solution seems really elegant! I don't think the tag is overkill and I can imagine wanting more than 2 wallets so don't think a bool is better.
5bb2cb9
to
45bf7db
Compare
🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the Possibly this is due to a silent merge conflict (the changes in this pull request being Leave a comment here, if you need help tracking down a confusing failure. |
45bf7db
to
176c8cc
Compare
This is needed to avoid circular dependencies in later commits. Can be reviewed via `--color-moved=dimmed-zebra`.
Note that this commit doesn't change behaviour yet, as tagging isn't used in any MiniWallet instance.
176c8cc
to
dd8fa86
Compare
Rebased on master (necessary since #28970 introduced new tests with |
ACK dd8fa86 |
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.
tACK dd8fa86
Make successful, all functional tests pass.
Thanks for splitting the PR into multiple commits, made reviewing easy. I've asked couple questions for my understanding.
To avoid unintentional tx dependencies, it is recommended to use separate miniwallets for | ||
mempool filling vs transactions in tests. | ||
To avoid unintentional tx dependencies, the mempool filling txs are created with a | ||
tagged ephemeral miniwallet instance. |
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 moves the responsibility of avoiding unintentional tx dependencies from the caller to this function instead. Nice, moving this more towards being a pure function!
ephemeral_miniwallet = MiniWallet(node, tag_name="fill_mempool_ephemeral_wallet") | ||
test_framework.generate(ephemeral_miniwallet, 1 + num_of_batches * tx_batch_size) |
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.
For my understanding: I get that having an ephemeral wallet created and destroyed inside this function gets rid of any data sharing related to MiniWallet
between the calls of fill_mempool()
. Since the same tag name is being passed and subsequently the same internal_key
is generated, how does adding the tag name really help here?
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 wouldn't say it disambiguates between separate fill_mempool
calls, just between fill_mempool
and the other MiniWallet
s. I suppose we can add a parameter to modify the tag name further, but we don't have any functional tests where we do this multiple times.
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.
where we do this multiple times
Do what exactly?
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.
fill_mempool
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.
Oh I see.
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 dd8fa86
Code lgtm and I do not see any problem with the "tag", and seems good for determinism.
…rsion) This commit fixes a dormant bug in MiniWallet that exists since support for P2TR was initially added in bitcoin#23371 (see commit 041abfe). In the course of spending the output, the leaf version byte of the control block in the witness stack doesn't set the parity bit, i.e. we were so far just lucky that the used combinations of relevant data (internal pubkey, leaf script / version) didn't result in a tweaked pubkey with odd y-parity. If that was the case, we'd get the following validation error: `mandatory-script-verify-flag-failed (Witness program hash mismatch) (-26)` Since MiniWallets can now optionally be tagged (bitcoin#29939), resulting in different internal pubkeys, the issue is more prevalent now. Fix it by passing the parity bit, as specified in BIP341.
ACK dd8fa86 |
…rsion) This commit fixes a dormant bug in MiniWallet that exists since support for P2TR was initially added in bitcoin#23371 (see commit 041abfe). In the course of spending the output, the leaf version byte of the control block in the witness stack doesn't set the parity bit, i.e. we were so far just lucky that the used combinations of relevant data (internal pubkey, leaf script / version) didn't result in a tweaked pubkey with odd y-parity. If that was the case, we'd get the following validation error: `mandatory-script-verify-flag-failed (Witness program hash mismatch) (-26)` Since MiniWallets can now optionally be tagged (bitcoin#29939), resulting in different internal pubkeys, the issue is more prevalent now. Fix it by passing the parity bit, as specified in BIP341.
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.
Post merge Tested ACK dd8fa86
…rsion) This commit fixes a dormant bug in MiniWallet that exists since support for P2TR was initially added in bitcoin#23371 (see commit 041abfe). In the course of spending the output, the leaf version byte of the control block in the witness stack doesn't set the parity bit, i.e. we were so far just lucky that the used combinations of relevant data (internal pubkey, leaf script / version) didn't result in a tweaked pubkey with odd y-parity. If that was the case, we'd get the following validation error: `mandatory-script-verify-flag-failed (Witness program hash mismatch) (-26)` Since MiniWallets can now optionally be tagged (bitcoin#29939), resulting in different internal pubkeys, the issue is more prevalent now. Fix it by passing the parity bit, as specified in BIP341.
…rsion) This commit fixes a dormant bug in MiniWallet that exists since support for P2TR was initially added in bitcoin#23371 (see commit 041abfe). In the course of spending the output, the leaf version byte of the control block in the witness stack doesn't set the parity bit, i.e. we were so far just lucky that the used combinations of relevant data (internal pubkey, leaf script / version) didn't result in a tweaked pubkey with odd y-parity. If that was the case, we'd get the following validation error: `mandatory-script-verify-flag-failed (Witness program hash mismatch) (-26)` Since MiniWallets can now optionally be tagged (bitcoin#29939), resulting in different internal pubkeys, the issue is more prevalent now. Fix it by passing the parity bit, as specified in BIP341.
…bit in leaf version) e4b0dab test: add functional test for tagged MiniWallet instances (Sebastian Falbesoner) 3162c91 test: fix MiniWallet internal key derivation for tagged instances (Sebastian Falbesoner) c9f7364 test: fix MiniWallet script-path spend (missing parity bit in leaf version) (Sebastian Falbesoner) 7774c31 test: refactor: return TaprootInfo from P2TR address creation routine (Sebastian Falbesoner) Pull request description: This PR fixes a dormant bug in MiniWallet that exists since support for P2TR was initially added in #23371 (see commit 041abfe). In the course of spending the output, the leaf version byte of the control block in the witness stack doesn't set the parity bit, i.e. we were so far just lucky that the used combinations of relevant data (internal pubkey, leaf script / version) didn't result in a tweaked pubkey with odd y-parity. If that was the case, we'd get the following validation error: `mandatory-script-verify-flag-failed (Witness program hash mismatch) (-26)` Since MiniWallets can now optionally be tagged (#29939), resulting in different internal pubkeys, the issue is more prevalent now. Fix it by passing the parity bit, as specified in BIP341. Can be tested with the following patch (fails on master, succeeds on PR): ```diff diff --git a/test/functional/test_framework/mempool_util.py b/test/functional/test_framework/mempool_util.py index 148cc93..7ebe858681 100644 --- a/test/functional/test_framework/mempool_util.py +++ b/test/functional/test_framework/mempool_util.py @@ -42,7 +42,7 @@ def fill_mempool(test_framework, node): # Generate UTXOs to flood the mempool # 1 to create a tx initially that will be evicted from the mempool later # 75 transactions each with a fee rate higher than the previous one - ephemeral_miniwallet = MiniWallet(node, tag_name="fill_mempool_ephemeral_wallet") + ephemeral_miniwallet = MiniWallet(node, tag_name="fill_mempool_ephemeral_wallet3") test_framework.generate(ephemeral_miniwallet, 1 + num_of_batches * tx_batch_size) # Mine enough blocks so that the UTXOs are allowed to be spent ``` In addition to that, another bug is fixed where the internal key derivation failed, as not every pseudorandom hash results in a valid x-only pubkey. Fix this by treating the hash result as private key and calculate the x-only public key out of that, to be used then as internal key. Fixes #30528. ACKs for top commit: glozow: ACK e4b0dab rkrux: reACK [e4b0dab](e4b0dab) hodlinator: ACK e4b0dab Tree-SHA512: a16f33f76bcb1012857cc3129438a9f6badf28aa2b1d25696da0d385ba5866b46de0f1f93ba777ed9263fe6952f98d7d9c44ea0c0170a2bcc86cbef90bf6ac58
…rsion) This commit fixes a dormant bug in MiniWallet that exists since support for P2TR was initially added in bitcoin#23371 (see commit 041abfe). In the course of spending the output, the leaf version byte of the control block in the witness stack doesn't set the parity bit, i.e. we were so far just lucky that the used combinations of relevant data (internal pubkey, leaf script / version) didn't result in a tweaked pubkey with odd y-parity. If that was the case, we'd get the following validation error: `mandatory-script-verify-flag-failed (Witness program hash mismatch) (-26)` Since MiniWallets can now optionally be tagged (bitcoin#29939), resulting in different internal pubkeys, the issue is more prevalent now. Fix it by passing the parity bit, as specified in BIP341.
Different MiniWallet instances using the same mode (either ADDRESS_OP_TRUE, RAW_OP_TRUE or RAW_P2PK) currently always create and spend UTXOs with identical output scripts, which can cause unintentional tx dependencies (see e.g. the discussion in #29827 (comment)). In order to avoid mixing of UTXOs between instances, this PR introduces the possibility to provide a MiniWallet tag name, that is used to derive a different internal key for the taproot construction, leading to a different P2TR output script. Note that since we use script-path spending and only the key-path is changed here, no changes in the MiniWallet spending logic are needed.
The new tagging option is then used in the
fill_mempool
helper to create an ephemeral wallet for the filling txs, as suggested in #29827 (comment). To avoid circular dependencies,fill_mempool
is moved to a new modulemempool_util.py
first.I'm still not sure if a generic word like "tag" is the right term for what this tries to achieve, happy to pick up better suggestions. Also, maybe passing a tag name is overkill and a boolean flag like "random_output_script" is sufficient?