This page documents the architecture of the transaction pool (TxPool) service in fuel-core. The TxPool is responsible for managing pending transactions before they are included in blocks. It handles transaction validation, storage, ordering, and provides transactions to the block producer.
For information about transaction lifecycle and status tracking, see Transaction Lifecycle. For details on how transactions are validated during execution, see Transaction Execution. For transaction submission via GraphQL, see Query and Mutation Resolvers.
The TxPool service is one of the core sub-services managed by FuelService. It maintains a memory pool of validated, pending transactions and coordinates with multiple other services to process transactions from submission through block inclusion.
TxPool Service Definition
Sources: crates/fuel-core/src/service/sub_services.rs116 crates/fuel-core/src/service/sub_services.rs298-311 crates/fuel-core/src/service/adapters.rs317-325
The TxPool configuration is constructed from CLI arguments and encompasses multiple configuration substructures that control pool behavior, resource limits, and operational parameters.
Configuration Hierarchy
Sources: bin/fuel-core/src/cli/run.rs603-622 bin/fuel-core/src/cli/run.rs636-653 bin/fuel-core/src/cli/run.rs747-760
The following table summarizes key configuration parameters:
| Parameter | Type | CLI Argument | Description |
|---|---|---|---|
max_txs_ttl | Duration | --tx-pool-ttl | Time-to-live for transactions in the pool |
ttl_check_interval | Duration | --tx-ttl-check-interval | Interval for checking expired transactions |
max_txs | usize | --tx-max-number | Maximum number of transactions in the pool |
max_bytes_size | usize | --tx-max-total-bytes | Maximum total bytes of all transactions |
max_gas | u64 | --tx-max-total-gas | Maximum total gas of all transactions |
max_txs_chain_count | usize | --tx-max-chain-count | Maximum transaction chain depth |
number_threads_to_verify_transactions | usize | --tx-number-threads-to-verify-transactions | Thread pool size for transaction verification |
size_of_verification_queue | usize | --tx-size-of-verification-queue | Size of verification queue |
number_threads_p2p_sync | usize | --tx-number-threads-p2p-sync | Thread pool size for P2P sync |
size_of_p2p_sync_queue | usize | --tx-size-of-p2p-sync-queue | Size of P2P sync queue |
pending_pool_tx_ttl | Duration | --tx-pending-pool-ttl | TTL for transactions in pending pool |
max_pending_pool_size_percentage | u8 | --tx-pending-pool-size-percentage | Max percentage of pool for pending transactions |
Sources: bin/fuel-core/src/cli/run.rs603-622
The TxPool architecture consists of several key components that work together to manage transactions.
Core Component Architecture
Sources: crates/fuel-core/src/service/adapters.rs317-350 crates/fuel-core/src/service/sub_services.rs302-315 bin/fuel-core/src/cli/run.rs642-648
The TxPoolAdapter wraps TxPoolSharedState and provides the interface used by other services to interact with the transaction pool. It is defined at crates/fuel-core/src/service/adapters.rs317-325 as:
pub struct TxPoolAdapter {
service: TxPoolSharedState,
}
This adapter is used by:
The TransactionsSource is used by the block producer to retrieve transactions for block production. It maintains a reference to the TxPool and applies a minimum gas price filter. Defined at crates/fuel-core/src/service/adapters.rs327-339:
pub struct TransactionsSource {
tx_pool: TxPoolSharedState,
minimum_gas_price: u64,
}
The block producer creates a TransactionsSource with the current gas price to ensure only transactions meeting the minimum gas price threshold are selected for blocks.
The NewTxWaiter allows the block producer to efficiently wait for new transactions to arrive in the pool using a tokio watch channel. Defined at crates/fuel-core/src/service/adapters.rs341-350:
pub struct NewTxWaiter {
pub receiver: watch::Receiver<()>,
pub timeout: Instant,
}
When new transactions are added to the pool, a notification is sent via the watch channel, waking the block producer from its wait state. The timeout field ensures the producer doesn't wait indefinitely.
Sources: crates/fuel-core/src/service/adapters.rs317-350
The TxPool service is initialized during FuelService startup with dependencies on multiple other services and adapters.
TxPool Initialization Flow
Sources: crates/fuel-core/src/service/sub_services.rs298-311
The initialization parameters include:
| Parameter | Type | Purpose |
|---|---|---|
chain_id | ChainId | Validates transactions belong to correct chain |
config.txpool | TxPoolConfig | Configuration from CLI/config file |
p2p_adapter | P2PAdapter | Receives transactions from network peers |
importer_adapter | BlockImporterAdapter | Notified of newly imported blocks |
database.on_chain() | Database | Persistent storage for transaction state |
chain_state_info_provider | ChainStateInfoProvider | Access to chain state information |
last_height | BlockHeight | Current blockchain height |
universal_gas_price_provider | UniversalGasPriceProvider | Current gas price for validation |
executor | ExecutorAdapter | Transaction validation via VM execution |
new_txs_updater | watch::Sender<()> | Notifies block producer of new transactions |
preconfirmation_sender | PreconfirmationSender | Sends preconfirmation messages |
Sources: crates/fuel-core/src/service/sub_services.rs298-311
The TxPool manages two distinct pools with different lifecycle characteristics:
Pool Management Structure
Sources: bin/fuel-core/src/cli/run.rs629-634 bin/fuel-core/src/cli/run.rs636-648 bin/fuel-core/src/cli/run.rs747-760
The TxPool supports blacklisting specific addresses, coins, messages, and contracts to prevent certain transactions from entering the pool.
BlackList {
addresses: Vec<Address>,
coins: Vec<UtxoId>,
messages: Vec<Nonce>,
contracts: Vec<ContractId>
}
Sources: bin/fuel-core/src/cli/run.rs629-634
Three primary limits control pool resource usage:
When any limit is reached, transactions are evicted based on gas price priority.
Sources: bin/fuel-core/src/cli/run.rs636-640
The TxPool uses dedicated thread pools to offload expensive operations (transaction verification and P2P synchronization) from the main service loop, preventing blocking. This architecture ensures that the main service loop remains responsive even under heavy load.
Heavy Work Thread Pool Architecture
Sources: bin/fuel-core/src/cli/run.rs642-648
The HeavyWorkConfig structure (defined in fuel_core_txpool::config) configures thread pool parameters. Configuration is set via CLI arguments at bin/fuel-core/src/cli/run.rs642-648:
| Field | CLI Argument | Purpose |
|---|---|---|
number_threads_to_verify_transactions | --tx-number-threads-to-verify-transactions | Number of threads for transaction verification via executor |
size_of_verification_queue | --tx-size-of-verification-queue | Maximum pending verification tasks (backpressure) |
number_threads_p2p_sync | --tx-number-threads-p2p-sync | Number of threads for processing P2P transaction gossip |
size_of_p2p_sync_queue | --tx-size-of-p2p-sync-queue | Maximum pending P2P sync tasks (backpressure) |
When a queue is full, new work submissions block until capacity becomes available, providing automatic backpressure to prevent memory exhaustion. This prevents the system from accepting more work than it can process.
Sources: bin/fuel-core/src/cli/run.rs642-648
The TxPool enforces backpressure through bounded channels on read and write requests to prevent unbounded queue growth and protect against resource exhaustion. This is configured via the ServiceChannelLimits structure in fuel_core_txpool::config.
Channel Limit Architecture
Configuration via CLI arguments at bin/fuel-core/src/cli/run.rs650-653:
| Field | CLI Argument | Default | Purpose |
|---|---|---|---|
max_pending_read_pool_requests | --tx-max-pending-read-requests | configurable | Maximum concurrent read operations (queries, transaction retrieval) |
max_pending_write_pool_requests | --tx-max-pending-write-requests | configurable | Maximum concurrent write operations (insertions, deletions) |
When a channel limit is reached, new requests block until capacity becomes available. This provides:
Sources: bin/fuel-core/src/cli/run.rs650-653
The TxPool integrates with multiple other services through well-defined interfaces.
TxPool Service Integration Map
Sources: crates/fuel-core/src/service/sub_services.rs298-311 crates/fuel-core/src/service/adapters.rs317-350
P2PAdapter passes gossiped transactions to TxPoolTxPoolAdapter exposes methods for submission and queriesTransactionsSource provides filtered transaction listBlockImporterAdapter broadcasts import eventsExecutorAdapter validates transactionsUniversalGasPriceProvider provides current gas priceSources: crates/fuel-core/src/service/sub_services.rs298-311 crates/fuel-core/src/service/adapters.rs317-409
When the block producer needs transactions, it uses the TransactionsSource to retrieve an ordered list of transactions from the pool.
Transaction Selection Flow
Sources: crates/fuel-core/src/service/adapters.rs327-339
The selection process:
GasPriceProviderThe TxPool follows the standard service lifecycle managed by ServiceRunner.
TxPool Service Lifecycle
Sources: crates/fuel-core/src/service/sub_services.rs527-531 crates/services/src/service.rs256-321
Within FuelService, the TxPool is initialized in a specific order relative to other services to satisfy dependency requirements. The startup sequence is managed at crates/fuel-core/src/service/sub_services.rs550-589:
The TxPool must start before:
The TxPool requires these services to be available:
next_gas_price() validationSources: crates/fuel-core/src/service/sub_services.rs550-589
Sources: crates/fuel-core/src/service/config.rs247-250
Configured via command-line arguments:
Sources: bin/fuel-core/src/cli/run.rs603-622
Refresh this wiki