Skip to content
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

wip: feat(txpool): new txpool design #22

Merged
merged 67 commits into from
Oct 11, 2022
Merged

wip: feat(txpool): new txpool design #22

merged 67 commits into from
Oct 11, 2022

Conversation

mattsse
Copy link
Collaborator

@mattsse mattsse commented Oct 8, 2022

WIP

This is another txpool iteration that replaces the previous graph based pool with a tier-pool design described here https://github.com/ledgerwatch/erigon/wiki/Transaction-Pool-Design#design-proposal

The previous pool design, essentially was only able to handle the nonce gap condition. Introducing additional state-related conditions turned out to be tricky.

Instead of two (pending, queued) sub-pools, this has three subpools (pending, basefee, queued) and can also handle: dynamic fee + balance related restrictions.

The state of a tx is maintained in a bitfield from which the subpool the tx should be moved to is derived.

There's only one BTreeMap((Sender,Nonce), Tx) that tracks all transactions in the pool. The subpools then contain a reference (or rather an Arc clone) to the transaction.

By storing all transactions in one place, state changes can be derived more efficiently than checking separate pools.
By sorting by (Sender,Nonce) all descendant tx of a tx can be visited efficiently, this is imported to update the state of transactions from the same sender.

If a new tx is added, or a block was mined, appropriate updates are derived which are then applied to the subpools (e.g.: move tx from queued to ready).

The pending pool returns an iterator (BestTransactions) that always returns the next best transaction.

todo:

  • simplify tx/pool types
  • handle more conditions
  • ...

@mattsse
Copy link
Collaborator Author

mattsse commented Oct 10, 2022

@rakita wdyt about these changes?

one thing I think needs to be changed is the Priority type.

I guess we could instead make this a generic compare(tx, tx) -> Ordering function instead? which is used to determine best/worst in the queued/basefee pool, so we can pop worst if we exceed size limits.

And for pending I think, we need a sort function that can rank a transaction in relation to other tx in the pool. This is a more advanced use case and maybe we should use compare here as well for now and revisit later.

I kept the internal mapping for Address -> u64 since this is used heavily in the total BtreeMap of all transactions.

@gakonst
Copy link
Member

gakonst commented Oct 10, 2022

As discussed, trust you to design this according to Erigon & the patterns for multi-tx pool, let's make sure to add a diagram later.

@mattsse mattsse mentioned this pull request Oct 11, 2022
7 tasks
Copy link
Collaborator

@rakita rakita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Priority seems okay for this level of abstraction, as you can put anything that you want to compare inside it. And it has Ord.

for anything you would do inside compare(tx, tx) -> Ordering as in tx1.price < tx1.price you are extracting data to Priority= tx.price and comparing price after that price1 < price2 it is same principle with having compare(tx,tx)

Maybe it would be a cleaner implementation but as I can tell you are getting similar functionality.

crates/transaction-pool/src/validate.rs Show resolved Hide resolved
/// Actual transaction.
pub(crate) transaction: Arc<ValidPoolTransaction<T::Transaction>>,
/// A transaction that is ready to be included in a block.
pub(crate) struct PendingTransactionRef<T: TransactionOrdering> {
/// Identifier that tags when transaction was submitted in the pool.
pub(crate) submission_id: u64,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use timestamp from ValidPoolTransaction for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've thought about this as well, but since Instant depends on the OS this could lead to issues. I saw weird timestamps in the past, especially after reboot.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instant can report time in past sometimes (few ns or very small margin), and panic would happen if you sub them with that assumption (had a bug with this :) ), for txpool where transactions come in arbitrary order in the span of seconds/minutes we just need a comparison we wouldn't care about value.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you sub them with that assumption (had a bug with this :)

same :D

makes sense, I'll use the timestamp instead of the id then

crates/transaction-pool/src/pool/pending.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@rakita rakita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need to define (broadly) what flexibility/functionality and use case we want to have in txpool, we could over abstract and have not so useful complexity if we are not sure how it is going to be used.

lgtm

@onbjerg onbjerg added C-enhancement New feature or request A-tx-pool Related to the transaction mempool labels Oct 11, 2022
@mattsse
Copy link
Collaborator Author

mattsse commented Oct 11, 2022

sg!

I wrote additional tests, will merge this as is, and then start smaller iterations. starting with docs + definition

@mattsse mattsse merged commit 3fed7cf into main Oct 11, 2022
@mattsse mattsse deleted the matt/add-tx-pool-2 branch October 11, 2022 15:10
@gakonst
Copy link
Member

gakonst commented Oct 11, 2022

Maybe we need to define (broadly) what flexibility/functionality and use case we want to have in txpool, we could over abstract and have not so useful complexity if we are not sure how it is going to be used.

Yeah let's start being explicit about what it provides, can provide in the future, and any limitations.

cjeva10 pushed a commit to cjeva10/reth that referenced this pull request Jul 25, 2023
…rli-forkid-test

Fix optimism_goerli_forkids test with genesis and regolith conditions
anonymousGiga added a commit to anonymousGiga/reth that referenced this pull request Feb 20, 2024
AshinGau added a commit to AshinGau/reth that referenced this pull request Sep 26, 2024
AshinGau added a commit to AshinGau/reth that referenced this pull request Oct 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tx-pool Related to the transaction mempool C-enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants