-
Notifications
You must be signed in to change notification settings - Fork 969
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
Unify fee-based transaction comparisions #3508
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.
Overall looks good - only thing I flagged is wrt canFitWithEviction
that makes too many assumptions
releaseAssert(iter != mTxStackSet.end()); | ||
auto const& evictTxStack = *iter; | ||
auto const& evictTx = *evictTxStack->getTopTx(); | ||
auto evictOps = evictTxStack->getNumOperations(); |
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 method (canFitWithEviction
) should not be in this class, or should be written differently:
what that code does is use the top tx evictTx
to decide on evicting the entire stack (and the code in , which does not make sense in the general case, and only in the context of TxQueueLimiter
that right now uses SingleTxStack
.
If we want to keep it in here, the challenge (I think) is that you can't really iterate over txs in stacks without popping.
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.
what that code does is use the top tx evictTx to decide on evicting the entire stack
Well, that's the invariant of this method and it happens to work for TxQueueLimiter
. I can't say it's incorrect for seq num based stack implementations, as the same invariant would be maintained (whether it's useful or not is up to the caller; currently I guess we know we don't need to reuse it).
I cannot say I'm 100% happy with this class, however I think it's a decent option. The set of supported operations is indeed bespoke and isn't too abstract. This is due to the fact that we have quite specific use cases and there is only so much in common between them. In order to support the upcoming functionality I wanted to encapsulate as much logic as possible in these methods and let as little internals to be exposed as possible. The implementation with lanes is more involved in terms of using the internal structures.
I guess we could make the queue to be 'low-level' data structure that exposes the internals and then a wrapper data structure to be used in TxQueueLimiter
with SingleTxStack
only. However, I'm not sure how much value does that provide, given that the complexity still lies in the iteration methods. I'd also still rather keep the logic in SurgePricingUtils
so that there is a single source for all surge-pricing related stuff.
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.
We talked offline about potentially getting rid of the "transaction chains" per account in the future, so I think it's fine to keep the code as is. As right now we have no use cases for this method outside of the SingleTxStack
, and to avoid surprises if we were to use it in a different context, I think we should just add an assert that there is only one tx in the stack:
auto const& evictTx = *evictTxStack->getTopTx();
auto evictOps = evictTxStack->getNumOperations();
releaseAssert(evictOps == evictTx.getNumOperations());
what do you think?
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.
SG, added the assertion.
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.
Left one suggestion in the only open comment left. We can rebase & squash it as it's pretty much ready to merge
…ons. The priority queue allows ranking transactions/transaction stacks (seq num ordered) by fee rate and limit the amount of operations. This replaces 3 existing implementations of surge-pricing-based comparisons and has special operations to support their use cases: - Building the `TxSetFrame` from transactions via selecting highest fee rate transactions - Limiting the transactions in `TxQueueLimiter` via evicting lowest fee rate transactions - Broadcasting the transactions in 'TransactionQueue` via selecting highest fee rate transactions The respective user changes are in the followup commits.
de46078
to
54f2f93
Compare
Noticed this while checking the refactored code.
…QueueLimiter`. Instead of explicitly looking at the limiter size, verify how many operations were evicted (this also generally improves coverage). Instead of explicitly looking at the minimum fee stored in limiter, make sure that we can (or can not) add transaction at the fee threshold.
…aching the `TxQueueLimiter` limit.
54f2f93
to
9d3ce58
Compare
I've rebased & squashed, just need to wait for the checks to pass. |
r+ 9d3ce58 |
Description
This introduces a common data structure (
SurgePricingPriorityQueue
) that orders the transactions by the fee rate and is aware of operation limits. This data structure is then used in the 3 places that do fee-based transaction comparisons:TransactionQueue
,TxQueueLimiter
andTxSetFrame
.The refactoring is functionally a no-op and serves as a preparation for introducing more complex transaction comparison logic.
Checklist
clang-format
v8.0.0 (viamake format
or the Visual Studio extension)