-
Notifications
You must be signed in to change notification settings - Fork 38.7k
test: use MiniWallet for mempool_updatefromblock.py #24183
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
Conversation
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.
There is a whitespace here, you have to remove it to pass the linter.
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.
Thanks. Fixed. Don't know why the linter now complains about the spelling errors in unchanged files.
^---- failure generated from test/lint/lint-python.sh
src/random.h:92: occuring ==> occurring
src/rpc/blockchain.cpp:794: nWe ==> new
src/util/syscall_sandbox.cpp:128: creat ==> create
test/functional/data/rpc_decodescript.json:81: ba ==> by, be
test/functional/data/rpc_decodescript.json:84: ba ==> by, be
^ Warning: codespell identified likely spelling errors. Any false positives? Add them to the list of ignored words in test/lint/lint-spelling.ignore-words.txt
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.
Cool, now you should squash the commits. See: https://github.com/bitcoin/bitcoin/blob/master/CONTRIBUTING.md#squashing-commits
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.
Thanks. Done.
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.
The problem of the linter now is "test/functional/mempool_updatefromblock.py:12:1: F401 'decimal.Decimal' imported but unused" - this PR removes all uses.
47e8d66 to
934d09e
Compare
|
Are you still working on this? |
Yes. Read mzumsande's comment too quickly and didn't realize it was a request to change. Will fix soon. |
934d09e to
4b8eb3c
Compare
|
The linter problem is fixed. |
aureleoules
left a comment
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 203a3e065ecd0ec8a9fb84f4deb512ef2b66cdf7.
Tested on NixOS 22.05 64 bits with --disable-wallet.
I verified that the migration to MiniWallet does not alter what is being tested.
It takes 3s to run on my machine 🚀
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.
Why is this changed?
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.
Changed back to getmempoolentry.
I chose getrawmempool over getmempoolentry to follow some existing functional test files. After a closer look at those two RPCs, I agree the existing getmempoolentry here is better as it indicates the "query using a transaction id" intention.
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.
Why does this need SEQUENCE_FINAL?
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.
Without SEQUENCE_FINAL, the test broke at assert_equal(len(node.getrawmempool()), size) after the first block is invalidated, as the mempool has 26 transactions instead of the expected 100.
In a simpler example with fewer transactions without SEQUENCE_FINAL, I can see after the block is invalidated, transactions are removed from the mempool because of this place:
bitcoin/src/consensus/tx_verify.cpp
Line 53 in f05cf59
| bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2 |
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.
Why is this changed? (from getmempoolentry to getrawmempool)?
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.
Changed back to getmempoolentry.
4b8eb3c to
7be943f
Compare
|
You'll need to do the changes from yesterday in the first commit, not in the second. |
7be943f to
72ad8ad
Compare
|
Fixed. Thank you @MarcoFalke. |
|
Can you explain why it is ok to "flatten" the tournament into a linked list? |
mjdietzx
left a comment
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 this PR introduces an unwanted behavior change. It looks like now you have a simple straight line of spends tx0->tx1->...->txN.
Before this test created a huge, complicated "cyclic tournament" graph of transactions where:
- Transaction tx[K] is a child of each of previous transactions tx[0]..tx[K-1] at their output K-1
- Transaction tx[K] is an ancestor of each of subsequent transactions tx[K+1]..tx[N-1].
That's kind of hard to visualize. But the first transaction tx0 has 99 outputs, and tx1, ... tx100 all spend one of tx0's outputs. And tx100 has 99 inputs, an input from tx1, ... tx99. Looking at L51-L80 (before this PRs changes) you can try to imagine what tx4 looks like and that's kinda hard!
It's easy to see by the runtime of this test. Before this PR running this test in our CI took ~5 minutes. Now this test runs in ~1s.
I've found this test to be extremely valuable bc it highlights a possible denial of service attack vector. Imagine someone creates a graph of transactions like this and gets them all mined into a single block (let's just say they mine the block or collude w/ a miner). Even though the mempool has DEFAULT_ANCESTOR_LIMIT and DEFAULT_DESCENDANT_LIMIT of 25, this test just shows how large and complicated a web of dependent transactions you can make within those limits.
Now imagine that huge graph takes up a single block that's mined. And then somehow (maybe on purpose) that block gets reorged. All of a sudden this entire block of transactions enters the mempool again. And all the nodes need to validate every single transaction in this graph before adding them back to their mempool. Imagine if we did something stupid (or a lot of extra looping work) in the mempool validation logic. When that block gets reorged it could potentially crash or stall a bunch of nodes.
So I think this test is a really good stress test as-is. If you do any looping or weird stuff in the mempool validation logic this test can very easily timeout. I learned this the hard way when trying out some RBF changes, where I saw this test timing out. And I started to really appreciate the value of this specific test at that point
| If all of the N created transactions tx[0]..tx[N-1] reside in the mempool, | ||
| the following holds: | ||
| the tx[K] transaction: | ||
| - has N-K descendants (including this one), and | ||
| - has K+1 ancestors (including this one) |
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 don't think these conditions hold true after this PR
|
Concept ACK - I think this is a valuable test and it'll be good to update it so that it's not skipped when the wallet isn't compiled. My suggestion would be to minimize changes as much as possible to make it work w/ MiniWallet - and implementing this test as-is w/ MiniWallet will probably be difficult! But I think it'll be a good exercise, and I think MiniWallet can probably support what this test needs without any internal code changes to it (although I'm not totally sure bc I haven't looked at that code in a while) |
|
Thank you so much @mjdietzx for the review with the context and insights. I am changing this to draft status, to explore how to keep the graph structure. |
|
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. |
This PR enables a non-wallet functional test
mempool_updatefromblock.pyto be run without wallet compiled, by using the MiniWallet proposed in #20078. This picks up from where #21999 left off.Commit 1 of 2: MiniWallet changes only to minimize diffs for easier reviewing
Commit 2 of 2: Refactor (renaming a function and variables)
The test run time decreases from 16.5s to 4.3s.