概述
EVM mempool 在统一的池中同时管理 EVM 和 Cosmos 交易,从而支持与以太坊兼容的交易流程,包括乱序交易和 nonce 间隙处理。它替代了默认的 CometBFT FIFO mempool,以满足以太坊工具链的预期,同时保持与 Cosmos SDK 的兼容性。目的与设计
EVM mempool 充当以太坊交易管理模型与 Cosmos SDK 共识层之间的桥梁。 设计目标:- 以太坊兼容性:支持乱序提交交易、nonce 间隙处理、以更高手续费替换交易、标准
txpoolRPC 方法 - Cosmos 集成:为 EVM 和 Cosmos 交易提供统一 mempool、基于费用的优先级排序、与 ante handler 集成、保持共识终局性
架构
下面是 mempool 工作方式的总体架构图,重点展示 EVM 交易的处理流程。mempool 内还包含用于支持 Cosmos 交易的其他组件,不过 EVM mempool 主要关注 EVM 交易的性能,因此这里聚焦于它们。对于 Cosmos 交易,大多数组件都有对应的镜像实现,唯一的例外是 Cosmos 交易不允许存在 nonce 间隙。
交易流程
基于上述架构,下面说明一笔交易如何从接收开始,经由 JSON-RPC、P2P 或 BroadcastTx 进入系统,随后被校验并纳入区块。交易提交
JSON-RPC
通过eth JSON-RPC 提交的交易会直接加入 EVM mempool,不经过 CometBFT,也不会经过任何 CheckTx 校验(不过在插入时会执行__部分__从 geth 移植过来的 EVM mempool 校验逻辑)。
P2P
通过 P2P 提交的交易会先由 CometBFT 接收,再通过InsertTx ABCI 方法传递给应用。该方法通知应用将交易插入其 mempool,并按照应用自身的方式进行校验;这一步不要求在插入时同步完成。
通过 P2P 接收的 EVM 和 Cosmos 交易,都会先加入 mempool 的 InsertQueue,然后立即返回(RPC/本地交易同样会走这条 InsertQueue 路径,只是调用方会等待交易离开 InsertQueue 后才返回,因此不太明显)。应用不会等待任何校验完成。这保证了 P2P 流程足够快,因为在高 TPS 时段,它承受的流量最大。
BroadcastTx
不建议使用 CometBFT 的 BroadcastTx... 方法来获得最佳性能,但它仍然被完整支持,因为许多 Cosmos/EVM 链仍然需要非 EVM 交易,而这类交易无法通过应用侧 JSON-RPC 提交。
EVM mempool 提供了一个 CheckTx handler,它会调用同步的 Insert 函数。这会在插入热路径中运行 anteHanlder,并返回客户端熟悉的 BroadcastTx... 响应。
更多细节请参阅 CometBFT 关于 BroadcastTx... 的应用侧 mempool 文档。
交易校验
EVM 交易完全支持 nonce 间隙,这类交易会先在本地排队,直到具备执行条件。 为了判断一笔交易是否有效并已准备好执行(无论是因为 nonce 间隙而先进入本地队列,还是在插入后异步处理),应用会对该交易运行anteHandler 以确定其有效性。这可以确保所有被标记为可执行的交易(在 EVM mempool 中也称为 pending)都已经通过 anteHandler 校验(如果使用的不是 app mempool,这类校验通常会通过 CheckTx 完成)。
由于 anteHandler 的执行与交易插入是异步进行的,用户在插入时只能看到来自 geth 移植校验逻辑的错误。那些仅由 anteHandler 校验产生的错误不会暴露给用户;如果 anteHandler 失败,那么该交易会在插入成功后被静默丢弃,不过这种情况应当较少发生。
交易重新校验
实现app mempool 的一个关键点在于,CometBFT 不会在交易被区块纳入后驱动重新校验。
EVM mempool 会确保在每个区块之后,对每一笔交易(无论是排队中的还是待执行的)都进行重新校验;如果交易已经失效,就会将其从 mempool 中移除。对于因前序交易被移除而重新出现 nonce 间隙的 EVM 交易,还会执行降级处理(从待执行移动回排队状态)。Cosmos 交易不能存在 nonce 间隙,因此如果更早 nonce 的交易被移除,它们也会被直接丢弃。
这种重新校验通过异步方式驱动,可以依赖 CometBFT 的事件总线系统,也可以依赖 CosmosSDK 中的 PrepareCheckStater hook。PrepareCheckStater 会在区块提交后立即运行。首选方式是 CometBFT 事件总线(PrepareCheckStater 主要用于在底层没有 CometBFT 实例时驱动集成测试)。
交易 gossip
在anteHandler 校验成功后,交易会被推入 ReapList,下次当 CometBFT 调用 ReapTxs ABCI 方法时,它会将交易传递给 CometBFT。随后,CometBFT 会将该交易传播到网络中的其他节点。
需要注意的是,交易只会在第一次校验成功时被 reap。这意味着,如果一笔交易存在 nonce 间隙,它不会被传播(因为它尚未通过 anteHandler 校验)。如果一笔交易经历了已校验、失效、再次校验成功的过程,它也只会在第一次校验成功时被传播,而不会在第二次校验成功时再次传播。
有关交易通过 ABCI 边界之后的 gossip 细节,请参阅 CometBFT 应用侧 mempool 文档。
区块构建
app mempool 在创建新区块时不会从 CometBFT 接收任何交易(CometBFT 不存储交易,因此没有可提供的内容),因此所有将被纳入提案的交易都必须由 EVM mempool 提供并完成校验。这些交易会通过 SelectBy 函数以 CosmosSDK Iterator 的形式提供,CosmosSDK 会在 PrepareProposal ABCI 方法期间调用它。
EVM mempool 会特别注意在 EVM 和 Cosmos 交易之间保持公平。它按照相同规则对两类交易排序:nonce 和有效小费。有效小费的计算方式如下:
- EVM:
min(gas_tip_cap, gas_fee_cap - base_fee) - Cosmos:
fee_amount / gas_limit
应用要求与注意事项
由于 EVM mempool 是应用侧app mempool,应用必须满足一些特殊要求,才能保证被校验交易的正确性。
地址预留
EVM mempool 使用地址预留机制,确保同一个交易签名者不能同时在 EVM 子池和 Cosmos 子池中存在交易。也就是说,如果签名者 A 通过eth_SubmitRawTransaction JSON-RPC 提交了一笔 EVM 交易,那么在这第一笔 EVM 交易离开 EVM mempool 之前(要么已经上链,要么因校验错误被丢弃),用户 A 不能再通过 BroadcastTxSync RPC 方法提交 Cosmos 交易。
之所以有这个要求,是因为 mempool 内部两个池(EVM 与 Cosmos)之间的交易重检机制就是这样工作的。两个独立池中的重检都是异步执行的,彼此之间没有通信。如果同一个签名者同时出现在两个池中,就需要在两者之间进行同步,以确保交易按照正确的 nonce 顺序被校验。
Ante Handlers
AnteHandler 序列必须确保不会产生任何跨账户的状态变更。原因与上文相同:如果在 EVM 池中校验来自签名者 A 的交易,会突然影响到 Cosmos 池中签名者 B 的校验结果,那么这种行为就是未定义的,校验结果将取决于异步重检循环之间的执行顺序和时间点。
API 参考
mempool 暴露了与以太坊兼容的 RPC 方法。详细参考请参阅 JSON-RPC 方法文档:txpool_status,txpool_content,txpool_contentFrom,txpool_inspect
配置
基础配置与接线
辅助函数:集成
对于需要集成该 mempool 并查看完整配置细节的链开发者,请参阅 EVM Mempool 集成指南。测试
可以使用 cosmos/evm 中的测试脚本来验证 mempool 行为。tests/systemtests/Counter/script/SimpleSends.s.sol 脚本演示了典型的以太坊工具行为:10 笔连续交易以乱序方式到达。
Overview
The EVM mempool manages both EVM and Cosmos transactions in a unified pool, enabling Ethereum-compatible transaction flows including out-of-order transactions and nonce gap handling. It replaces the default CometBFT FIFO mempool to support Ethereum tooling expectations while maintaining Cosmos SDK compatibility.Purpose and Design
The EVM mempool serves as a bridge between Ethereum’s transaction management model and Cosmos SDK’s consensus layer. Design Goals:- Ethereum Compatibility: Out-of-order transaction submission, nonce gap handling, transaction replacement with higher fees, standard txpool RPC methods
- Cosmos Integration: Unified mempool for both EVM and Cosmos transactions, fee-based prioritization, integration with ante handlers, preservation of consensus finality Transaction Validation: The EVM mempool is an implementation of CometBFT’s application mempool type. This means that the application is fully responsible for transaction validation, transaction rechecking, and block building. Please see CometBFT’s mempool docs (section 3) for more info on this architecture.
Architecture
Below is a general architecture diagram of how the mempool works, specifically for EVM transactions. There are other components within the mempool to facilitate Cosmos transactions, however the EVM mempool is mostly concerned with the performance of EVM transactions, so this focuses on them. There is largely a mirror of each of these components for Cosmos transactions, with the exception of allowing nonce gapped transactions.
Transaction Flow
Given this architecture, we will now describe a transaction steps from ingestion, either via JSON-RPC, P2P, or BroadcastTx to being validated and included in a block.Transaction Submission
JSON-RPC
Transactions submitted via theeth JSON-RPC are directly added to the EVM
mempool without going through CometBFT or any CheckTx validation (however
some EVM mempool validation ported from
geth
is done at insert time).
P2P
Transactions submitted via P2P are received by CometBFT and passed to the application via theInsertTx ABCI method. This method signals to the
application that it should insert the transaction into its mempool and should
validate it on its own terms, it does not have to happen synchronously at
insertion time.
Both EVM & Cosmos transactions that are ingested via P2P are added to the
mempool’s
InsertQueue
before immediately returning (RPC/local transactions also use this
InsertQueue path, however the callers wait for the transaction to leave the
InsertQueue before returning, so it is less noticeable). The application does
not wait on any validation to happen. This ensures the P2P flow is extremely
fast since this sees the highest amount of traffic during high TPS periods.
BroadcastTx
Using CometBFT’s BroadcastTx... methods is not recommended for the best
performance however it fully supported since many Cosmos/EVM chains still
require non EVM transactions that cannot be submitted via the application side
JSON-RPC.
The EVM mempool provides a CheckTx handler that calls a synchronous Insert
function. This will run anteHanlder’s in the insert hot path and provide the
typical BroadcastTx... response clients are used to.
See CometBFT’s app mempool documentation on
BroadcastTx...
for more details.
Transaction Validation
Nonce gapped EVM transactions are fully supported and are queued locally until they are available for execution. To determine if a transaction is valid and ready for execution (either after being enqueued locally due to a nonce gap, or asynchronously after insertion), the applicationsanteHandler is run the tx in order to determine validity.
This ensures that all txs that are marked as executable (also called ‘pending’
within the EVM mempool) have passed anteHandler’s (this is the same
validation that would typically be done via CheckTx when using a non app
mempool).
Since the anteHandler execution is happening asynchronously from transaction
insertion, users will only see errors from the EVM mempools validation ported
from geth at insert time. Users will not see errors that stem only from
anteHandler validation and if the anteHandler fails, the transaction is
silently dropped after a successful insert, however this should be rare.
Transaction Revalidation
One of the key aspects of implementing anapp mempool is that CometBFT does
not drive revalidation of txs after block inclusion.
The EVM mempool ensures that after every block, each transaction (both queued
and pending execution) is either revalidated or removed from the mempool if it
has become invalid, and demoting (moving from pending execution -> queued) EVM
transactions that have now become nonce gapped due to the drop (Cosmos
transactions cannot have nonce gaps, so they are dropped if an earlier nonce tx
is dropped).
This revalidation is driven asynchronously either via CometBFT’s event bus
system, or via the PrepareCheckStater hook in the CosmosSDK.
PrepareCheckStater runs just after block commit. CometBFT’s event bus is the
preferred method (PrepareCheckStater is largely used to drive integration
tests running without a CometBFT instance under the hood).
Transaction gossip
Upon successfulanteHandler validation, transactions are pushed onto a
ReapList
that will pass the transaction to CometBFT the next time CometBFT calls the
ReapTxs ABCI method. CometBFT will then gossip the tx to the rest of the
network.
Note that reaping a transaction only happens the first time a transaction
is successfully validated. This means that if a transaction is nonce gapped, it
is not gossiped (it has not yet been validated via anteHandler’s). If a
transaction is validated, invalidated, and revalidated, it is only gossiped
upon the first validation, it is not re-gossipped upon the second
validation.
See the CometBFT app mempool documentation for more details on gossip once the transaction has passed the ABCI boundary.
Block Building
app mempools receive no transactions from CometBFT when creating a new block
(it stores none, so it has none to give), thus all transactions that are going
to be included in a proposal must be provided and validated via the EVM
mempool. These transactions are provided as a CosmosSDK Iterator via the
SelectBy function, that the CosmosSDK will call during the PrepareProposal
ABCI method.
The EVM mempool takes special care to be fair to both EVM and Cosmos
transactions. It orders both sets of transactions by the same rules, nonce and
effective tip. Effective tip is calculated as:
- EVM:
min(gas_tip_cap, gas_fee_cap - base_fee) - Cosmos:
fee_amount / gas_limitPreference is given to EVM transactions in the case of ties.
Application Requirements and Considerations
Given that the EVM mempool is anapp side mempool, there are special
considerations that must be taken by the application to ensure the correctness
of the transactions being validated.
Address reservations
The EVM mempool uses an address reservation system to ensure that no transaction signer can have a transaction in both the EVM subpool and the Cosmos subpool at the same time. That means, if signer A submits an EVM tx through theeth_SubmitRawTransaction JSON-RPC, user A cannot submit a Cosmos
transaction via the BroadcastTxSync RPC method until their first EVM
transaction has left the EVM mempool (either because it was included on chain,
or dropped due to a validation error).
This requirement is because of how the rechecking of transactions works
internally between the two (EVM & Cosmos) pools works within the mempool. The
rechecking runs asynchronously within each distinct pool, with no communicating
between the two. Having the same signer in both pools would require
synchronization between the two to ensure that the transactions are checked in
the correct nonce ordering.
Ante Handlers
AnteHandler sequences must ensure that they do not have any cross-account
state changes. This is due to the same reasoning as above, if validating a
transaction in the EVM pool from signer A, can suddenly effect the outcome of
validating signer B in the Cosmos pool, this is undefined behavior and the
validation would depend on the ordering and timing of the rechecks across
asynchronous loops.
API Reference
The mempool exposes Ethereum-compatible RPC methods. See JSON-RPC Methods documentation for detailed reference:txpool_status,txpool_content,txpool_contentFrom,txpool_inspect
Configuration
Basic Configuration & Wiring
The helper function:Integration
For chain developers integrating the mempool and looking for full configuration details, see the EVM Mempool Integration Guide.Testing
Verify mempool behavior using test scripts in cosmos/evm. Thetests/systemtests/Counter/script/SimpleSends.s.sol script demonstrates typical Ethereum tooling behavior with 10 sequential transactions arriving out of order.