构建自己的客户端

本指南提供了一些建议,以确保 Universal Ledger 客户端实现与网络安全可靠地交互。了解如何:

  • 利用网络拓扑实现高可用性。
  • 提交事务并了解执行结果。
  • 实现轮询、超时和重试策略。

网络拓扑和高可用性

Universal Ledger 网络由分布在多个可用区和区域中的多个验证器组成,从而确保整个网络具有高可用性。

  • 可用区故障: 如果云可用区中的单个验证器发生故障,同一区域中的其他验证器将无缝地继续处理请求。

  • 区域中断: 如果整个区域都不可用,其他区域中的验证器仍会正常运行。如需继续提交事务,您的客户端可以安全地回退并尝试通过其他端点重新提交事务。

事务执行特征

  • 原子执行: 事务要么完全成功,要么完全失败。 绝不会出现部分事务执行的情况,例如因余额不足而仅转移部分请求的资金。这 包括 事务链, 让您可以将多个任意事务组合成一个原子 序列。

  • 无自动重试: 网络会尝试准确执行一次提交的事务。如果执行失败,账本不会自动将事务排队或重试。

  • 幂等重新提交: 每个提交的事务都会根据其确切的序列化载荷(包括序列号和发送者)生成唯一的事务 ID。多次提交完全相同的载荷会生成相同的事务 ID。账本可确保事务最多执行一次,因此,如果某个端点似乎不可用,您可以安全地将同一事务载荷重新提交到其他端点。

    如需了解详情,请参阅 SubmitTransactionRequest 参考页面。

延迟时间、轮询和重试策略

提交事务时,验证器会先执行快速检查,确保其签名和序列号有效。如果成功, Universal Ledger API 会立即响应 SubmitTransactionResponse ,其中包括分配的事务 ID。

大多数事务会在 3 秒内完成。如需检查事务 状态,请使用提供的事务 ID 轮询 QueryTransactionState 方法。

  • 如果事务状态仍为 PENDING,请使用指数退避算法策略再次检索状态。例如,以 3 秒、9 秒、27 秒和 60 秒 的间隔进行查询。

  • 如果 QueryTransactionState 返回 NOT_FOUND,请重新提交事务。

事务尝试 FINALIZED 后,响应还会包含一个 TransactionCertificate,其中包含各种 详细信息,例如:

  • 事务完成时的轮次 ID。
  • 执行状态(正常或失败)。
  • 事务事件,包括任何事务输出。

超时协议

在极少数情况下,如果事务在 60 秒后仍处于 PENDINGNOT_FOUND 状态,请假定为您的请求提供服务的验证器无法跟上网络中其他验证器的速度。请完成以下步骤:

  1. 在其他网络区域中选择其他端点。
  2. 重新提交完全相同的已签名事务载荷。
  3. 如需报告问题,请发送电子邮件至 gcul-help@google.com,以便 Universal Ledger 团队进行调查。

检查事务状态时,如果您多次提交相同的载荷,响应可能会包含多个 TransactionAttempt消息。最多一次尝试会以“正常”事务状态完成, 该状态可在 TransactionEffects中找到, 而其他尝试要么处于待处理状态,要么处于失败状态。这是预期行为;账本成功执行了其中一个事务提交,并正确拒绝或最终将拒绝重复的重新提交。

网络一致性

  • 已完成的事务: 一旦某个验证器报告某个事务已完成,同一网络上的所有其他验证器都应最终处理该事务并重现完全相同的结果。 使用事务完成时的轮次 ID(可在其 TransactionCertificate中找到)提交 QueryAccountRequest会在所有同步的验证器上产生相同的结果。

  • 未完成的事务: 由于事务在网络中以异步方式传播,因此,不同验证器报告的事务是否已完成可能会有所不同。

    从中断中恢复或遇到同步延迟的验证器可能会暂时将已完成的事务报告为 PENDINGNOT_FOUND。验证器赶上进度后,事务状态将得到解决。

客户端责任和错误处理

后续步骤