-
Notifications
You must be signed in to change notification settings - Fork 38.7k
validation: fix coins disappearing mid-package evaluation #28251
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
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. 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. |
|
cc @instagibbs |
|
@sipa you might want to weigh in as well |
instagibbs
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.
ariard
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.
Note the code path affected by the bug is under the submitpackage RPC, which is clearly indicated as an experimental RPC with an unstable interface.
More test coverage sounds good.
fjahr
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.
Concept ACK, will do a full review once the test has been added.
|
Pushed a test - it should fail on master with the assertion. Generally, the conditions to hit the case are:
Timeline of what happens:
|
c4ac016 to
3729ee4
Compare
|
the above test description sounds right. The eldest ancestor gets trimmed due to size limitations, then things go wonky without this change |
instagibbs
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.
ACK 3729ee4
The newly added test, while slightly obscure to trigger it, makes sense and triggers the crash bug when the fix is not applied.
3729ee4 to
a5a029c
Compare
|
Updated the approach + added a test for replacement case. There are now 2 fixes: Technically (1) is sufficient, but I think (2) is also beneficial as it avoids changing the mempool minimum feerate (which affects how we group transactions) mid-package evaluation. It would be sad if a CPFP package contains a parent that's just barely above mempool minimum feerate, so we submit it, then evict it (due to later parent), then can't submit the child... when we could have just submitted all of them and evicted something else. |
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.
Ifirst pass on most recent fix to a5a029c
approach ack on fixes, would be flakey to trim things within packages prematurely.
a5a029c to
24b9cea
Compare
24b9cea to
22fe13e
Compare
instagibbs
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.
ACK 22fe13e
ariard
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.
Thanks for the in-depth explanation of the conditions to hit the case. Will review more the code and test coverage as high-prio.
test/functional/mempool_limit.py
Outdated
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.
As I understand one of the condition to hit the case is a full mempool and when we call LimitMempool(), one interesting variation of the test case could be to limit the mempool size to the subpackage only. It might be a tricky one, though boundary conditions are always nice to exercise.
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.
Yes, full mempool is one of the conditions (i.e. the one tested in test_mid_package_eviction). It's not strictly necessary though, the coin can also disappear due to replacement.
one interesting variation of the test case could be to limit the mempool size to the subpackage only
Do you mean setting the mempool's maximum memory to something very tiny?
Useful to ensure that the topologies of packages/transactions are as expected, preventing bugs caused by having unexpected mempool ancestors.
We want to be able to re-use fill_mempool so that none of the tests affect each other. Change the logs from info to debug because they are otherwise repeated many times in the test output.
Test for scenario(s) outlined in PR 28251. Test what happens when a package transaction spends a mempool coin which is fetched and then disappears mid-package evaluation due to eviction or replacement.
40d0db8 to
32c1dd1
Compare
|
I'm reviewing this PR more carefully, after seeing @instagibbs' comment here: #31122 (comment) As I understand it, I think there are two key behaviors introduced in this PR:
However, the specific issue that @glozow described above (#28251 (comment)), where we need to ensure that package validation fails if an input is evicted mid-validation, seems to be completely mitigated by behavior (1). And this behavior is tested in the As far as I can tell from reviewing
So by preventing mempool limiting from taking place mid-package, the choice of what to evict from the mempool is deferred until after However, I don't think this PR introduced any test for this second behavior, of ensuring success is possible even if an earlier parent might be trimmed mid-validation. Does this summary sound right to others? Have I overlooked other behavior changes/bugfixes that were introduced here? |
This looks accurate to me. I've looked a little at the tests (it's been a while 😅) and can't really point to one for deferring evictions. Will review #31152. |

While we are evaluating a package, we split it into "subpackages" for evaluation (currently subpackages all have size 1 except the last one). If a subpackage has size 1, we may add a tx to mempool and call
LimitMempoolSize(), which evicts transactions if the mempool gets full. We handle the case where the just-submitted transaction is evicted immediately, but we don't handle the case in which a transaction from a previous subpackage (either just submitted or already in mempool) is evicted. Mainly, since the coins created by the evicted transaction are cached inm_view, we don't realize the UTXO has disappeared untilCheckInputsFromMempoolAndCacheasserts that they exist. Also, the returnedPackageMempoolAcceptResultreports that the transaction is in mempool even though it isn't anymore.Fix this by not calling
LimitMempoolSize()until the very end, and editing the results map with "mempool full" if things fall out.Pointed out by instagibbs in faeed68 on top of the v3 PR.