Skip to content

fork-aware transaction pool added#4639

Merged
michalkucharczyk merged 381 commits intomasterfrom
mku-fork-aware-tx-pool
Oct 15, 2024
Merged

fork-aware transaction pool added#4639
michalkucharczyk merged 381 commits intomasterfrom
mku-fork-aware-tx-pool

Conversation

@michalkucharczyk
Copy link
Copy Markdown
Contributor

@michalkucharczyk michalkucharczyk commented May 29, 2024

Fork-Aware Transaction Pool Implementation

This PR introduces a fork-aware transaction pool (fatxpool) enhancing transaction management by maintaining the valid state of txpool for different forks.

High-level overview

The high level overview was added to sc_transaction_pool::fork_aware_txpool module. Use:

cargo  doc --document-private-items -p sc-transaction-pool --open

to build the doc. It should give a good overview and nice entry point into the new pool's mechanics.

Quick overview (documentation excerpt)

View

For every fork, a view is created. The view is a persisted state of the transaction pool computed and updated at the tip of the fork. The view is built around the existing ValidatedPool structure.

A view is created on every new best block notification. To create a view, one of the existing views is chosen and cloned.

When the chain progresses, the view is kept in the cache (retracted_views) to allow building blocks upon intermediary blocks in the fork.

The views are deleted on finalization: views lower than the finalized block are removed.

The views are updated with the transactions from the mempool—all transactions are sent to the newly created views.
A maintain process is also executed for the newly created views—basically resubmitting and pruning transactions from the appropriate tree route.

View store

View store is the helper structure that acts as a container for all the views. It provides some convenient methods.

Submitting transactions

Every transaction is submitted to every view at the tips of the forks. Retracted views are not updated.
Every transaction also goes into the mempool.

Internal mempool

Shortly, the main purpose of an internal mempool is to prevent a transaction from being lost. That could happen when a transaction is invalid on one fork and could be valid on another. It also allows the txpool to accept transactions when no blocks have been reported yet.

The mempool removes its transactions when they get finalized. Transactions are also periodically verified on every finalized event and removed from the mempool if no longer valid.

Events

Transaction events from multiple views are merged and filtered to avoid duplicated events.
Ready / Future / Inblock events are originated in the Views and are de-duplicated and forwarded to external listeners.
Finalized events are originated in fork-aware-txpool logic.
Invalid events requires special care and can be originated in both view and fork-aware-txpool logic.

Light maintain

Sometime transaction pool does not have enough time to prepare fully maintained view with all retracted transactions being revalidated. To avoid providing empty ready transaction set to block builder (what would result in empty block) the light maintain was implemented. It simply removes the imported transactions from ready iterator.

Revalidation

Revalidation is performed for every view. The revalidation process is started after a trigger is executed. The revalidation work is terminated just after a new best block / finalized event is notified to the transaction pool.
The revalidation result is applied to the newly created view which is built upon the revalidated view.

Additionally, parts of the mempool are also revalidated to make sure that no transactions are stuck in the mempool.

Logs

The most important log allowing to understand the state of the txpool is:

              maintain: txs:(0, 92) views:[2;[(327, 76, 0), (326, 68, 0)]] event:Finalized { hash: 0x8...f, tree_route: [] }  took:3.463522ms
                             ^   ^         ^     ^   ^  ^      ^   ^  ^        ^                                                   ^
unwatched txs in mempool ────┘   │         │     │   │  │      │   │  │        │                                                   │
   watched txs in mempool ───────┘         │     │   │  │      │   │  │        │                                                   │
                     views  ───────────────┘     │   │  │      │   │  │        │                                                   │
                      1st view block # ──────────┘   │  │      │   │  │        │                                                   │
                           number of ready tx ───────┘  │      │   │  │        │                                                   │
                                numer of future tx ─────┘      │   │  │        │                                                   │
                                        2nd view block # ──────┘   │  │        │                                                   │
                                      number of ready tx ──────────┘  │        │                                                   │
                                           number of future tx ───────┘        │                                                   │
                                                                 event ────────┘                                                   │
                                                                       duration  ──────────────────────────────────────────────────┘

It is logged after the maintenance is done.

The debug level enables per-transaction logging, allowing to keep track of all transaction-related actions that happened in txpool.

Integration notes

For teams having a custom node, the new txpool needs to be instantiated, typically in service.rs file, here is an example:

let transaction_pool = Arc::from(
sc_transaction_pool::Builder::new(
task_manager.spawn_essential_handle(),
client.clone(),
config.role.is_authority().into(),
)
.with_options(config.transaction_pool.clone())
.with_prometheus(config.prometheus_registry())
.build(),
);

To enable new transaction pool the following cli arg shall be specified: --pool-type=fork-aware. If it works, there shall be information printed in the log:

2024-09-20 21:28:17.528  INFO main txpool: [Parachain]  creating ForkAware txpool.

For debugging the following debugs shall be enabled:

      "-lbasic-authorship=debug",
      "-ltxpool=debug",

note: trace for txpool enables per-transaction logging.

Future work

The current implementation seems to be stable, however further improvements are required.
Here is the umbrella issue for future work:

Partially fixes: #1202

@brenzi
Copy link
Copy Markdown
Contributor

brenzi commented Jun 12, 2024

I can offer field testing service on Integritee-Paseo. We suffer from #1202 and need to restart one paseo collator authority every 5 min to get all extrinsics in which originate from a single wallet.
integritee-network/worker#1594

@michalkucharczyk
Copy link
Copy Markdown
Contributor Author

I can offer field testing service on Integritee-Paseo. We suffer from #1202 and need to restart one paseo collator authority every 5 min to get all extrinsics in which originate from a single wallet. integritee-network/worker#1594

@brenzi: The code still needs polishing but it is ready to be tested in testnet. So if you can give it a try that would be greate, I can assist with debugging.

Following option shall be provided to enable new txpool: --pool-type=fork-aware
For better understanding how new implementation behaves and help me with debugging please enable following logs:

      "-lbasic-authorship=debug",
      "-ltxpool=debug",
      "-lsync=debug",

@girazoki
Copy link
Copy Markdown
Contributor

@michalkucharczyk just cherry-picking this PR would suffice to test it? I can also try to test it in our testnet

@michalkucharczyk
Copy link
Copy Markdown
Contributor Author

@michalkucharczyk just cherry-picking this PR would suffice to test it? I can also try to test it in our testnet

Yes. But if you have custom node, you will also need to instantiate new txpool, here is example:

let transaction_pool = sc_transaction_pool::Builder::new()
.with_options(config.transaction_pool.clone())
.build(
config.role.is_authority().into(),
config.prometheus_registry(),
task_manager.spawn_essential_handle(),
client.clone(),
);

@girazoki
Copy link
Copy Markdown
Contributor

@michalkucharczyk just cherry-picking this PR would suffice to test it? I can also try to test it in our testnet

Yes. But if you have custom node, you will also need to instantiate new txpool, here is example:

let transaction_pool = sc_transaction_pool::Builder::new()
.with_options(config.transaction_pool.clone())
.build(
config.role.is_authority().into(),
config.prometheus_registry(),
task_manager.spawn_essential_handle(),
client.clone(),
);

thank you, we will try it

girazoki added a commit to moondance-labs/polkadot-sdk that referenced this pull request Jun 19, 2024
This should reduce the number of empty blocks, which are built when
block builder is building upon blocks that are unknown to transaction
pool.

The ligh-maintain fallback will also be implemented.
ffarall added a commit to datahaven-xyz/datahaven that referenced this pull request Apr 30, 2025
This PR adds Ethereum RPC API support to the node, enabling the
interaction with the node using standard Ethereum tools.

1. Integration of Frontier's Ethereum RPC modules (eth, net, web3,
txpool)
2. Added RPC configurations necessary for Ethereum compatibility
3. Implemented a BABE consensus data provider for handling pending
blocks
4. Added required dependencies and configurations in the node's service
5. Created necessary filter pools, block data caches, and notification
systems
6. Configured the RPC system to handle Ethereum API calls
7. Changed the transaction pool implementation to be compatible with the
fork-aware transaction pool
(paritytech/polkadot-sdk#4639)

EDIT:
The new `transaction_pool` in `polkadot-stable2412` that comes with a
`fork-aware` feature, allowing different views of the transaction pool,
is not compatible with the current state in Frontier.
In Frontier the only supported pool is the `BasicPool`, that maintains a
similar behaviour to the one in `polkadot-stable2409`. I used this pool
directly.

---------

Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
undercover-cactus added a commit to Moonsong-Labs/storage-hub that referenced this pull request May 21, 2025
* rename `state_version` to `system_version` for xcm-simulator

* replace 'sp_runtime::RuntimeString' with 'alloc::string::String' (see paritytech/polkadot-sdk#5693)

* missed a place to rename state_version to system_version

* update dry_run_call to include xcm result version (see paritytech/polkadot-sdk#7438)

* introduce SelectCore into the runtime for the parachain system pallet (see paritytech/polkadot-sdk#8153)

* introduce DoneSlashHandler in the runtime for the balances pallet and set it empty because we are not using it (see paritytech/polkadot-sdk#5623)

* introduce WeightInfo type for transaction pallets which is part of the biggest change regarding the TransactionExtension (see paritytech/polkadot-sdk#3685)

* fix conversion from String to str

* replicate the changes in xcm-simulator

* DispatchInfo is now DispatchEventInfo in the client (see paritytech/polkadot-sdk#3685)

* sc_offchain::Offchainworker::new() now return Result fix (see paritytech/polkadot-sdk#5919)

* Update TransactionPool build to work with the new pool struct (see paritytech/polkadot-sdk#4639)

* fix instant sealing command

* enable runtime upgrade in dev mode (see paritytech/polkadot-sdk#6885)

* check for default backend network when starting node

* fix unresolved import in benchmarking

* fix format error in benchmarking

* fix mock pallets

* fixing xcm simulator

* forgot to save file before commit

* fix xcm test

* upgrade @PolkaDot to 15.10.2; fix typegen;

* update utils polkadot deps

* attempting to fix zombienet

* use a more recent polkadot binary

* install stable2412 binary in CI too

* fix fee in reaping account test

* typegen

* fix last test

* remove console.log; use rpc_port config everywhere

* spec version updated in test

---------

Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
margaretphillips96627margaretphillips added a commit to margaretphillips96627margaretphillips/storage-hub that referenced this pull request Oct 6, 2025
* rename `state_version` to `system_version` for xcm-simulator

* replace 'sp_runtime::RuntimeString' with 'alloc::string::String' (see paritytech/polkadot-sdk#5693)

* missed a place to rename state_version to system_version

* update dry_run_call to include xcm result version (see paritytech/polkadot-sdk#7438)

* introduce SelectCore into the runtime for the parachain system pallet (see paritytech/polkadot-sdk#8153)

* introduce DoneSlashHandler in the runtime for the balances pallet and set it empty because we are not using it (see paritytech/polkadot-sdk#5623)

* introduce WeightInfo type for transaction pallets which is part of the biggest change regarding the TransactionExtension (see paritytech/polkadot-sdk#3685)

* fix conversion from String to str

* replicate the changes in xcm-simulator

* DispatchInfo is now DispatchEventInfo in the client (see paritytech/polkadot-sdk#3685)

* sc_offchain::Offchainworker::new() now return Result fix (see paritytech/polkadot-sdk#5919)

* Update TransactionPool build to work with the new pool struct (see paritytech/polkadot-sdk#4639)

* fix instant sealing command

* enable runtime upgrade in dev mode (see paritytech/polkadot-sdk#6885)

* check for default backend network when starting node

* fix unresolved import in benchmarking

* fix format error in benchmarking

* fix mock pallets

* fixing xcm simulator

* forgot to save file before commit

* fix xcm test

* upgrade @PolkaDot to 15.10.2; fix typegen;

* update utils polkadot deps

* attempting to fix zombienet

* use a more recent polkadot binary

* install stable2412 binary in CI too

* fix fee in reaping account test

* typegen

* fix last test

* remove console.log; use rpc_port config everywhere

* spec version updated in test

---------

Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
dominic5perezd added a commit to dominic5perezd/storage-hub that referenced this pull request Oct 10, 2025
* rename `state_version` to `system_version` for xcm-simulator

* replace 'sp_runtime::RuntimeString' with 'alloc::string::String' (see paritytech/polkadot-sdk#5693)

* missed a place to rename state_version to system_version

* update dry_run_call to include xcm result version (see paritytech/polkadot-sdk#7438)

* introduce SelectCore into the runtime for the parachain system pallet (see paritytech/polkadot-sdk#8153)

* introduce DoneSlashHandler in the runtime for the balances pallet and set it empty because we are not using it (see paritytech/polkadot-sdk#5623)

* introduce WeightInfo type for transaction pallets which is part of the biggest change regarding the TransactionExtension (see paritytech/polkadot-sdk#3685)

* fix conversion from String to str

* replicate the changes in xcm-simulator

* DispatchInfo is now DispatchEventInfo in the client (see paritytech/polkadot-sdk#3685)

* sc_offchain::Offchainworker::new() now return Result fix (see paritytech/polkadot-sdk#5919)

* Update TransactionPool build to work with the new pool struct (see paritytech/polkadot-sdk#4639)

* fix instant sealing command

* enable runtime upgrade in dev mode (see paritytech/polkadot-sdk#6885)

* check for default backend network when starting node

* fix unresolved import in benchmarking

* fix format error in benchmarking

* fix mock pallets

* fixing xcm simulator

* forgot to save file before commit

* fix xcm test

* upgrade @PolkaDot to 15.10.2; fix typegen;

* update utils polkadot deps

* attempting to fix zombienet

* use a more recent polkadot binary

* install stable2412 binary in CI too

* fix fee in reaping account test

* typegen

* fix last test

* remove console.log; use rpc_port config everywhere

* spec version updated in test

---------

Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T0-node This PR/Issue is related to the topic “node”.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Improve transaction handling for Parachains

9 participants