-
Notifications
You must be signed in to change notification settings - Fork 690
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
fix: update miner mempool iterator query to consider both nonces and fee rates #5541
base: develop
Are you sure you want to change the base?
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.
Thanks for taking this on @rafaelcr!
This is something that I think is going to need somewhat extensive real-world testing before we make it the default behavior. Do you think you could add this new mempool walk logic as an opt-in alternative, which the node operator can opt to use? This would give miners a chance to compare/contrast the new behavior with the old behavior in an easy-to-rollback manner. A subsequent PR could make the new behavior the default.
What do you think?
Great idea @jcnelson and thanks for the feedback! I'll get on it. |
your new commits look great @obycode ! thanks for pushing this to the finish line 🙌 |
This allows them to be used in tests in stackslib/ or testnet/.
01e183a
to
db4dc8c
Compare
11650 is the maximum number of transactions possible in one block.
This new mempool iteration algorithm sacrifices optimal fee-based transaction selection in order to guarantee high performance. Since transaction ordering is not consensus critical (other than nonce-ordering per account), this is allowed. There are a couple of downsides I can think of. First is the potential for lower total fees for miners. In practice, this is not likely to be the case, because when the mempool is not very full, the order will be less optimal, but all ready transactions are likely to be included in the block anyway. When the mempool is more full, the current algorithm would stall or only generate tiny blocks, so even though the order is not perfect, miners will end up with more total fees, thanks to the selection speedup. Next is disturbance to the fee market. With this algorithm, chained nonce transactions (where one account has multiple outstanding transactions in the mempool) can end up prioritized behind lower fee-rate transactions. The query used selects all "ready" transactions based on their nonces. If account A has transaction A1 with nonce 0 and A2 with nonce 1, both paying fees of 10 STX, and account B has transaction B0 with nonce 0 paying 0.001 STX, the selection algorithm will choose A0, then B0, then B1. This is due to the fact that on the first query, A1 is not "ready", so it is not included in the results and thus not considered. After A0 has been mined, then A1 will be "ready". |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #5541 +/- ##
============================================
+ Coverage 68.14% 83.61% +15.46%
============================================
Files 521 524 +3
Lines 382814 384636 +1822
Branches 323 323
============================================
+ Hits 260884 321604 +60720
+ Misses 121922 63024 -58898
Partials 8 8
... and 294 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
The remaining issue is due to the fact that the nonce cache is not getting reset after a block is rejected. I will fix this next. |
I think the only remaining task here is to ensure that we don't get stuck if there are 11,650 problematic and ready transactions in the mempool. |
There is room for further improvement by not resetting the nonce DB after a block is successfully mined. I think I will leave that for a future PR though, because it is a bit troublesome. |
Problem
The current query used by Stacks miners to iterate over pending mempool transactions sorts them only by
fee_rate
in descending order. This approach creates the following problems:Solution
This PR adds a new mempool walk strategy (
NextNonceWithHighestFeeRate
) which prioritizes transactions that can be confirmed as fast as possible (next expected nonces for both origin and sponsor) with the highest fee rates as possible. This means that even if it doesn't select the transactions with the highest global fees first, it will select those that can be mined immediately therefore optimizing block building time and allowing the miner to fit in more transactions in total within the allotted time. This strategy also mixes in transactions with null fee rates in results by simulating a fee rate for the purposes of ordering only.For easier testing, a mempool walk strategy enum value was added to the
MinerConfig
, which includes:GlobalFeeRate
: Current global fee rate sorting behavior. Enabled by default.NextNonceWithHighestFeeRate
: The new strategy added by this PR