跳转到内容

交易管理

本指南说明如何构建可在 Aptos 区块链上扩展的交易管理框架。

在 Aptos 中,交易会根据签署或授权该交易的实体映射回账户,并使用基于账户的序列号。Aptos 网络接收新交易时,需遵循以下规则:

  • 从账户发送的交易必须由该账户正确授权。
  • 最近账本更新定义的当前时间必须早于交易的到期时间戳。
  • 交易序列号必须等于或大于该账户的链上序列号。

初始节点接受交易后,交易还会依据另一条规则在系统中传递:若交易序列号高于当前链上序列号,只有路径上的每个节点都已看到介于链上状态与当前序列号之间的交易时,该交易才能向共识推进。

示例:

Alice 拥有一个账户,其当前链上序列号为 5。

Alice 向节点 Bob 提交序列号为 6 的交易。

节点 Bob 接受了该交易,但不会转发,因为 Bob 尚未看到序列号为 5 的交易。

为取得进展,Alice 必须将序列号为 5 的交易发送给 Bob,或者 Bob 必须从共识获知序列号 5 已提交。后一种情况中,Alice 是通过另一节点提交交易的。

除此之外,还有两项原则:

  • 单个账户最多可向区块链提交 100 笔未提交交易。超过该数量将被拒绝。若 Alice 将前 100 笔提交给节点 Bob,随后 100 笔提交给节点 Carol,可能会发生静默拒绝。如果两个节点共享同一上游节点,该上游节点将接受经由 Bob 发送的 100 笔交易,但会静默拒绝经由 Carol 发送的 100 笔。
  • 向多个节点提交不同交易会导致解决缓慢,因为交易在提交节点获知此前所有交易均已提交前,无法继续推进。例如,Alice 通过 Bob 发送前 50 笔,又通过 Carol 发送后 50 笔。

了解交易的这些细节后,下面构建一个健壮的交易管理器。它由以下核心组件组成:

  • 一个序列号生成器,为单个账户分配和管理可用序列号。
  • 一个交易管理器:它从应用或用户接收载荷,从序列号生成器接收序列号,并访问账户密钥,将三者组合为可用的已签名交易。它还负责将交易推送到区块链。
  • 一个链上工作器-领导者框架,使多个账户能够共享单个共享账户的签名者。

目前,该框架假定网络不会构建大量队列,即提交的交易几乎无延迟地执行和提交。为应对高需求,工作还需扩展以下组件:

  • 优化 base_gas_unit 价格,确保优先交易可提交到区块链。
  • 进一步处理交易处理速率,确保正确设置到期计时器。
  • 处理交易失败:根据预期结果忽略或重新提交。

请注意,一个账户应由交易管理器的单个实例管理。否则,各实例的内存状态可能过期,从而导致序列号重叠。

每笔交易都需要与此前已提交交易顺序连续的唯一序列号。可使用以下流程提供序列号:

  1. 启动时,查询区块链获取账户当前序列号。
  2. 同时支持最多 100 笔在途交易,即无需确认任何交易已提交即可分配 100 个序列号。
  3. 若有 100 笔在途交易,通过查询网络确定实际已提交状态。这会更新当前序列号。
  4. 若在途交易少于 100 笔,返回第 2 步。
  5. 否则,休眠 0.1 秒并持续重新评估当前链上序列号。
  6. 所有交易都应有到期时间。若到期时间已过,假定发生失败并重置序列号。最简单的情形是仅在在途交易数达到最大值时监控失败,其他情况交由其他服务管理。

同时,监控新提交的交易。一旦最早交易的到期时间已过,同步到该交易。然后对下一笔交易重复此过程。

如发生任何失败,等待所有未完成交易超时,并由应用决定后续操作,例如重放失败交易。等待未完成交易的最佳方法是查询账本时间戳,确保它至少超过自上次交易提交时间起的最大超时值。然后使用 mempool 验证自上次已知提交交易以来的所有交易均已提交,或不再存在于 mempool 中。这可通过 REST API 查询特定账户的交易实现:指定当前正在评估的序列号,并将限制设为 1。完成这些检查后,可重新同步本地交易编号。

这些失败处理步骤至关重要,原因如下:

  • Mempool 不会立即逐出已过期交易。
  • 新交易不能覆盖现有交易,即使现有交易已经过期。
  • 共识(即账本时间戳)决定到期;本地节点只有在看到交易到期时间之后的已提交时间戳且完成垃圾回收后,才会使交易到期。

提交交易后,它会经历多个步骤:

  1. 提交到 REST 端点。
  2. 提交时在 Mempool 中进行预执行验证。
  3. 在 Mempool 之间传输,并在每个上游节点进行预执行验证。
  4. 纳入共识提案。
  5. 再进行一次预执行验证。
  6. 执行并提交到存储。

必须考虑许多潜在失败情况:

  • 交易提交期间失败(1 和 2):
    • 可见性:应用将收到错误,表明网络不可用或交易未通过预执行验证。
    • 若错误与可用性或重复序列号相关,等待访问恢复且序列号重新同步。
    • 除重复序列号外,预执行验证失败目前不在范围内;账户问题可能与账户无效密钥或缺少足够 Gas 资金有关。
  • 提交与执行之间失败(3、4 和 5):
    • 可见性:只有等待交易到期后才能得知。
    • 这些与其他预执行验证错误相同,原因是先前交易执行时账户发生变化。很可能是重复序列号,或账户缺少足够 Gas 资金。
  • 执行期间失败(6):
    • 可见性:这些交易会提交到区块链。
    • 这些错误由链上状态问题导致,通常特定于应用,例如拍卖中新出价可能实际上未高于当前出价。

使用上述框架,单个账户可以从一个区块开始到结束推送超过 100 笔交易。假设所有 100 笔交易均在 1 个区块内被消耗,下一批 100 个槽位需要一段时间才能可用。这是由网络延迟和多阶段验证者流水线造成的。

要充分利用区块链实现大规模吞吐量,单个用户账户不足以胜任。为此,Aptos 支持工作器账户的概念:它们可分担通过共享账户(也称资源账户)推送工作的责任。

在此模型中,每个工作器都可以访问共享账户的 SignerCap,这使其能够模拟共享账户,或为共享账户生成 signer。获得 signer 后,交易即可执行受共享账户签名者保护的逻辑。

如果可行,另一种模型是将 signer 完全与权限解耦,并使其成为特定于应用的能力。然后可将该能力赋予每个工作器,使它们能够操作共享基础设施。

请注意,如果任何交易存在读写冲突,共享基础设施上的并行化可能受到限制。这不会阻止多笔交易在一个区块内执行,但会影响区块链的最大性能。