以太坊内存池是节点本地的待处理交易暂存区,而非全局网络组件。txpool_* JSON-RPC 方法允许你检查该本地池,但大多数托管 RPC 提供商不公开它们,因为它们运行在共享基础设施上。本文解释了该机制,展示了如何查询自管理节点,并阐明了你可以和不可以推断的关于更广泛网络的信息。
以太坊内存池实际上是什么
当你通过 eth_sendRawTransaction 发送交易时,接收节点会验证它,如果有效,则将其放入其本地交易池(通常称为内存池)。该池不是以太坊共识的一部分;它是每个节点对已接受但尚未挖掘的交易的高速缓存。每个节点维护自己的池,因此内容因节点而异。该池通常组织为两个队列:pending(具有顺序 nonce 且准备好包含在区块中的交易)和 queued(具有 nonce 间隙或其他阻止立即包含条件的交易)。
txpool 命名空间的权威文档由执行客户端维护。例如,geth 的 txpool 文档 和 reth 的 txpool 文档 描述了方法及其语义。这些是此处描述行为的主要来源。关键点是池是局部的:两个节点可以有不同的待处理集,一个节点池中的交易可能不存在于另一个节点中。
这种局部性对开发者有深远的影响。如果你依赖托管的 RPC 提供商,你通常与许多其他用户共享基础设施。提供商通常完全禁用 txpool 命名空间,因为公开它会泄露其用户的待处理交易信息,并可能被滥用。因此,你不能假设 txpool_* 方法在托管端点上可用。始终检查提供商的文档或直接测试该方法。
- 内存池是节点本地的,不是全局网络组件。
- 交易在验证后进入池中,并在挖掘或丢弃时离开。
- 池不是共识的一部分;它是一个实现细节。
- 托管提供商通常出于隐私和资源原因禁用
txpool_*。
txpool 命名空间:方法和语义
txpool 命名空间提供了三种标准方法,在以太坊 JSON-RPC 规范中定义并由大多数客户端实现:txpool_content、txpool_inspect 和 txpool_status。一些客户端添加了扩展,例如 txpool_contentFrom(geth)或 Besu 特定的历史方法,但这些不是标准化的,可用性各不相同。
txpool_content 返回池中的完整交易对象,按地址和 nonce 分组。响应有两个顶级键:pending 和 queued。每个键将地址映射到另一个映射,该映射将 nonce 映射到交易对象。这是最详细的视图,但可能很大,并且提供商很少公开。
txpool_inspect 返回一个更轻量的摘要:对于每个地址和 nonce,它给出一个字符串,如 value: gasPrice: gasLimit(例如,0x...: 1000000000000 wei + 50000 gas × 20000000000 wei)。这对于快速评估 gas 竞争而不获取完整交易体很有用。
txpool_status 返回一个简单的对象,包含 pending 和 queued 整数计数。这是检查池是否活跃以及大致有多少交易在等待的最便宜的方式。
一些客户端还提供 txpool_contentFrom(geth)来按发送者地址过滤,但同样,这并不普遍。Besu 有自己的 txpool_besu* 方法用于交易历史,但它们是 Besu 特定的。始终查阅你的客户端文档。
txpool_content:完整的交易对象,按地址和 nonce 分组。txpool_inspect:带有 gas 价格和值估计的摘要。txpool_status:待处理和排队计数。- 像
txpool_contentFrom和txpool_besu*这样的扩展是客户端特定的。
为什么托管提供商通常隐藏内存池
如果你使用托管的 RPC 服务,如 OnFinality 的 API 服务,你可能会发现 txpool_* 方法返回错误,例如 the method txpool_content does not exist/is not available。这不是一个错误;这是一个深思熟虑的设计选择。提供商运营共享基础设施,许多用户通过相同的节点发送交易。公开本地池会泄露所有用户的待处理交易,造成隐私风险并启用抢先交易。此外,为每个请求提供完整的池内容将耗费大量资源。
以太坊节点架构本身并不需要全局内存池。每个节点独立验证和存储待处理交易。当你向提供商发送交易时,它会被广播到网络,但提供商的节点只保留本地副本。其他节点可能在其池中有它,但你不能直接查询它们,除非你运行自己的节点。
因此,如果你的集成依赖于检查内存池,你有两条现实的路径:运行你自己的完整节点(或支持该命名空间的轻节点)并直接查询它,或者使用不依赖本地池的替代方法。对于大多数用例,例如检查交易是否被接受,eth_getTransactionByHash 和回执轮询更可靠,因为它们查询规范链状态,而不是本地缓存。
- 托管提供商通常出于隐私和资源原因禁用
txpool_*。 - 池是本地的,所以即使提供商公开它,它也只显示该提供商的视图。
- 对于交易状态,使用
eth_getTransactionByHash和回执轮询。 - 运行你自己的节点是获得完整
txpool_*访问权限的唯一方法。
实际用例及处理方法
导致本文的搜索查询通常来自试图回答三个问题之一的开发者:'我的交易是否已经在池中?'、'网络有多拥堵?'以及'我是否面临抢先交易风险?'。让我们逐一解决。
我的交易是否在池中? 如果你通过提供商发送交易,提供商的节点可能在其本地池中有它,但你通常无法查询该池。相反,使用 eth_getTransactionByHash 和你的交易哈希。如果交易仍在等待,此方法返回交易对象;如果已挖掘,它返回带有区块哈希的交易;如果未找到,它可能已被丢弃或从未被接受。轮询回执是确定它是否被挖掘的最终方法。
分析 gas 竞争。 如果你运行自己的节点,txpool_content 或 txpool_inspect 可以显示待处理交易及其 gas 价格。这有助于你估计在下一个区块中包含所需的最低 gas 价格。但是,请记住,这只是你节点的视图;其他节点可能有不同的交易。
抢先交易风险。 公共内存池是抢先交易和三明治攻击的已知向量。如果你正在构建对订单敏感的应用程序(例如,DEX 交易),你应该假设你的交易对任何监控池的人都是可见的。使用私有交易中继(如 Flashbots)是绕过公共池的单独通道,但这不是 OnFinality 的认可;它是一个你可以为你的用例评估的工具。
- 对于交易状态,使用
eth_getTransactionByHash和回执轮询。 - 对于 gas 分析,
txpool_inspect提供快速摘要。 - 公共内存池交易对所有用户可见;对于敏感流程,请考虑私有中继。
- 永远不要假设托管提供商公开池。
针对你自己的节点运行 txpool 方法
要使用 txpool 命名空间,你需要访问公开它的节点。这通常是一个自管理的完整节点,并启用了命名空间。以下 curl 示例假设你在 http://localhost:8545 有这样的端点。将 URL 替换为你的节点地址。
首先,检查池状态:
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"txpool_status","params":[],"id":1}'
# 预期响应(值会变化)
{"jsonrpc":"2.0","id":1,"result":{"pending":"12","queued":"3"}}示例:检查待处理交易
要查看待处理交易的摘要,请使用 txpool_inspect。输出是地址到 nonce 的映射,每个 nonce 都有一个描述交易值和 gas 的字符串。以下是一个示例:
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"txpool_inspect","params":[],"id":1}'
# 预期响应(截断)
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"pending": {
"0x...address1": {
"0": "0x...to: 1000000000000 wei + 50000 gas × 20000000000 wei"
}
},
"queued": {}
}
}示例:完整交易内容
要获取完整的交易对象,请使用 txpool_content。这将返回完整的交易数据,包括 from、to、gas、gasPrice、value 和 input。响应可能很大,因此在繁忙的节点上使用时要小心。
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"txpool_content","params":[],"id":1}'
# 预期响应(截断)
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"pending": {
"0x...address1": {
"0": {
"hash": "0x...",
"nonce": "0x0",
"from": "0x...",
"to": "0x...",
"value": "0xde0b6b3a7640000",
"gas": "0x5208",
"gasPrice": "0x4a817c800",
"input": "0x"
}
}
},
"queued": {}
}
}解释结果:填充表格
当你运行这些方法时,将你的观察记录在如下所示的表格中。这有助于你了解节点池在特定时间的状态。这些值不是基准;它们是快照,会因网络条件和节点配置而异。
- 待处理计数:准备好包含的交易数量。
- 排队计数:具有 nonce 间隙或其他问题的交易。
- 待处理中的最高 gas 价格:指示当前的竞争阈值。
- 待处理中的最低 gas 价格:显示尽快包含所需的最低价格。
- 唯一发送者数量:有助于评估池是否由少数地址主导。
故障排除:为什么我的交易不在池中?
如果你发送了交易,但它没有出现在池中(或者你无法看到它),请按照此清单进行检查。问题通常不是池本身,而是交易的有效性或提供商的行为。
1. 检查交易是否被接受。 使用 eth_getTransactionByHash。如果返回 null,则交易不在节点的池中,可能已被拒绝。如果返回交易对象,则它要么是待处理的,要么已挖掘。
2. 检查 nonce 错误。 拒绝的常见原因是 nonce 太低(已使用)或太高(间隙)。使用带有 pending 区块参数的 eth_getTransactionCount 来查看你的地址的下一个预期 nonce。有关详细信息,请参阅我们的 EVM nonce 管理和 eth_getTransactionCount 指南。
3. 检查 gas 价格。 如果你的 gas 价格太低,交易可能会卡在池中或被修剪低费用交易的节点丢弃。例如,Geth 有一个默认的价格限制,会丢弃低于它的交易。具体行为在客户端的源代码中有文档记录。
4. 检查池限制。 Geth 限制了每个账户的排队交易数量(默认为 64)和排队交易的总数(默认为 1024)。如果你超过这些限制,你的交易可能会被拒绝。这些是文档化的默认值;请查看你的客户端文档以获取当前值。
5. 考虑提供商行为。 如果你使用托管提供商,他们可能不会立即将你的交易广播到网络,或者他们可能有自己的验证规则。始终检查提供商的文档以了解任何限制。
- 使用
eth_getTransactionByHash确认接受。 - 使用
eth_getTransactionCount验证你的 nonce。 - 确保你的 gas 价格高于节点的最低要求。
- 注意每个账户和总池限制。
- 托管提供商可能有额外的限制。
限制、隐私和安全注意事项
公共内存池是一把双刃剑。一方面,它提供了透明度,允许任何人查看待处理交易。另一方面,它在你的意图最终确定之前就暴露了它们。如果你交易大量金额或执行套利,你的交易可能会被监控池的机器人抢先。这是 DeFi 中众所周知的问题。
为了缓解这种情况,一些开发者使用私有交易中继,直接将交易发送给矿工或验证者,绕过公共池。Flashbots 就是这样一种服务,但还有其他服务。OnFinality 不认可任何特定服务;你应该自己评估权衡。
另一个限制是内存池不是可靠的事实来源。因为它是节点本地的,你无法知道待处理交易的全局状态。一个交易可能在一个节点的池中,但不在另一个节点的池中,并且它可能在你看到之前就被挖掘了。因此,不要基于池反映整个网络的假设来构建关键逻辑。
最后,请注意,某些节点可能根本不实现 txpool 命名空间,或者可能出于安全原因将其限制为本地连接。在依赖该方法之前,始终在目标端点上测试它。
- 公共内存池交易对所有用户可见;敏感流程应考虑私有中继。
- 池是节点本地的,因此它不是全局视图。
- 某些节点出于安全原因禁用命名空间。
- 在构建之前始终测试方法的可用性。
后续步骤和进一步阅读
理解内存池只是以太坊 RPC 掌握的一部分。要构建健壮的应用程序,你还应该了解如何选择适合你需求的节点。我们的 选择以太坊 RPC 节点(RPC 助手) 指南解释了完整节点、归档节点和轻节点之间的差异,以及它们如何影响你对 txpool_* 等方法的访问。
如果你处理交易生命周期问题,请查看我们的指南 以太坊 RPC 超时和重试 和 以太坊 WebSocket 断开处理。这些是发送交易和监控其状态时的常见痛点。
有关以太坊网络交互的更广泛视角,请参阅 OnFinality Learn 中心 和 以太坊网络页面。如果你正在评估 RPC 提供商,我们的 RPC 定价 页面可以帮助你了解成本结构,API 服务 文档描述了 OnFinality 提供的内容。
最后,如果你正在监控自己的节点,我们的指南 监控 RPC 端点和节点健康 提供了保持基础设施可靠性的实用技巧。
- 了解节点类型及其功能。
- 了解超时和 WebSocket 处理以构建健壮的应用程序。
- 探索 OnFinality Learn 中心以获取更多指南。
- 如果你正在考虑提供商,请查看定价和 API 服务详细信息。