Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
网络与协议指南阅读约 12 分钟

读取以太坊内存池:txpool 命名空间与待处理交易

了解以太坊内存池的工作原理,如何使用 txpool_* RPC 方法检查它,以及为什么托管提供商很少公开它。

TL;DR

以太坊内存池是节点本地的待处理交易暂存区,而非全局网络组件。txpool_* JSON-RPC 方法允许你检查该本地池,但大多数托管 RPC 提供商不公开它们,因为它们运行在共享基础设施上。本文解释了该机制,展示了如何查询自管理节点,并阐明了你可以和不可以推断的关于更广泛网络的信息。

以太坊内存池实际上是什么

当你通过 eth_sendRawTransaction 发送交易时,接收节点会验证它,如果有效,则将其放入其本地交易池(通常称为内存池)。该池不是以太坊共识的一部分;它是每个节点对已接受但尚未挖掘的交易的高速缓存。每个节点维护自己的池,因此内容因节点而异。该池通常组织为两个队列:pending(具有顺序 nonce 且准备好包含在区块中的交易)和 queued(具有 nonce 间隙或其他阻止立即包含条件的交易)。

txpool 命名空间的权威文档由执行客户端维护。例如,geth 的 txpool 文档reth 的 txpool 文档 描述了方法及其语义。这些是此处描述行为的主要来源。关键点是池是局部的:两个节点可以有不同的待处理集,一个节点池中的交易可能不存在于另一个节点中。

这种局部性对开发者有深远的影响。如果你依赖托管的 RPC 提供商,你通常与许多其他用户共享基础设施。提供商通常完全禁用 txpool 命名空间,因为公开它会泄露其用户的待处理交易信息,并可能被滥用。因此,你不能假设 txpool_* 方法在托管端点上可用。始终检查提供商的文档或直接测试该方法。

  • 内存池是节点本地的,不是全局网络组件。
  • 交易在验证后进入池中,并在挖掘或丢弃时离开。
  • 池不是共识的一部分;它是一个实现细节。
  • 托管提供商通常出于隐私和资源原因禁用 txpool_*

txpool 命名空间:方法和语义

txpool 命名空间提供了三种标准方法,在以太坊 JSON-RPC 规范中定义并由大多数客户端实现:txpool_contenttxpool_inspecttxpool_status。一些客户端添加了扩展,例如 txpool_contentFrom(geth)或 Besu 特定的历史方法,但这些不是标准化的,可用性各不相同。

txpool_content 返回池中的完整交易对象,按地址和 nonce 分组。响应有两个顶级键:pendingqueued。每个键将地址映射到另一个映射,该映射将 nonce 映射到交易对象。这是最详细的视图,但可能很大,并且提供商很少公开。

txpool_inspect 返回一个更轻量的摘要:对于每个地址和 nonce,它给出一个字符串,如 value: gasPrice: gasLimit(例如,0x...: 1000000000000 wei + 50000 gas × 20000000000 wei)。这对于快速评估 gas 竞争而不获取完整交易体很有用。

txpool_status 返回一个简单的对象,包含 pendingqueued 整数计数。这是检查池是否活跃以及大致有多少交易在等待的最便宜的方式。

一些客户端还提供 txpool_contentFrom(geth)来按发送者地址过滤,但同样,这并不普遍。Besu 有自己的 txpool_besu* 方法用于交易历史,但它们是 Besu 特定的。始终查阅你的客户端文档。

  • txpool_content:完整的交易对象,按地址和 nonce 分组。
  • txpool_inspect:带有 gas 价格和值估计的摘要。
  • txpool_status:待处理和排队计数。
  • txpool_contentFromtxpool_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_contenttxpool_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。这将返回完整的交易数据,包括 fromtogasgasPricevalueinput。响应可能很大,因此在繁忙的节点上使用时要小心。

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 服务详细信息。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始