graph TD
A1[HTTP API Request] --> A2{HTTP Rate Limit Check}
A2 -->|Rate Limited| A3[HTTP 429 Error]
A2 -->|Within Limit| A4[Parse Transaction]
A4 --> B{Validate Transaction}
A5[Network Gossip] --> B
B -->|Invalid| C[Mark Invalid]
B -->|Valid| D{Dependencies Satisfied?}
D -->|Yes| E[Add to Pool]
D -->|No| F[Add to Dep-Wait]
E --> G[In Ready Pool]
F --> H[Waiting for Dependencies]
H -->|Dependencies Arrive| E
G --> I[Block Builder Uses TX]
I --> J[Move to In-Block]
J --> K[Wait for Consensus]
K --> L{Block Outcome}
L -->|Immutable| M[Add to Finalized Cache]
L -->|Stale Our Block| N[Return to Pool]
N --> G
The Nomos mempool manages transaction hashes in memory with full transaction data in storage. It provides:
Component | Type | Capacity | Purpose | Eviction policy |
---|---|---|---|---|
Pool | LruCache<TxHash, ()> |
Configurable | Unused, ready transactions | LRU (access-based) |
In-Block | HashMap<TxHash, BlockId> |
Small | Our pinned transactions | None (removed on outcome) |
Dep-Wait | DepGraph |
Configurable | Missing dependencies | TTL + size limits |
Invalid Cache | TtlSet<TxHash> |
Configurable | Known invalid transactions | TTL expiry |
Finalized Cache | TtlSet<TxHash> |
Small | Track finalized transactions | TTL expiry |
When transaction hashes are evicted from the mempool, the corresponding transaction bodies are removed from storage to prevent unbounded growth.
Problem: If an evicted transaction later appears in a valid block, the node cannot validate that block because it no longer has the transaction data.
Solution: Implement a peer-to-peer fetch protocol to retrieve missing transactions:
This ensures nodes can validate blocks even when they previously evicted transactions due to mempool capacity management.
struct Mempool {
// Unused, ready transactions for proposals
pool: LruCache<TxHash, ()>,
// Our local in-block transactions (never evicted until outcome)
in_block: HashMap<TxHash, BlockId>,
// Reverse index
block_to_txs: HashMap<BlockId, Vec<TxHash>>,
// Transactions waiting for dependencies, first simple solution — as reported by consensus
dep_wait: DepGraph,
// Known invalid transactions (prevent reprocessing)
invalid_cache: TtlSet<TxHash>,
// Track finalized transactions to prevent re-adding on pruning
finalized_cache: TtlSet<TxHash>,
}
Validation steps: