Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第 21 章 一致性、证明与故障模型

Walrus 应用要面对两类一致性:

  • 链上一致性:Sui 对象和事件最终落在 checkpoint 中。
  • 数据可用性一致性:Blob 片段被足够多存储节点保存并可读取。

用户看到的“上传成功”只有在这两类状态都达到应用要求后才应该展示。

成功状态的定义

工程上建议把写入状态拆成:

状态含义
prepared本地文件已读取,参数已确认
storedWalrus 数据写入流程完成
registeredSui 交易成功,链上对象可查
indexed应用索引器已处理事件
verified后台读取和哈希校验通过

前端可以在 registered 后显示“已上传”,但后台仍应推进到 indexedverified。如果产品对可靠性要求高,比如审计日志或数据集登记,应等校验完成后再显示最终成功。

证明和校验

开发者常用三层校验:

  1. 协议/SDK 校验:确认读取到的是目标 blob_id 的内容。
  2. 业务哈希校验:确认内容等于用户上传或后端生成的原始字节。
  3. 链上状态校验:确认业务对象引用的 Blob 与当前 owner、版本、epoch 匹配。

不要省掉第三层。否则用户可能拿一个真实存在的 Blob 替换业务对象语义,造成“内容有效但引用非法”。

常见故障

故障表现处理
publisher 超时上传接口无响应查 Sui 交易和 Blob 状态,避免重复写
aggregator 失败下载 5xx 或超时换 aggregator,重试,检查是否过期
Blob 过期读取失败或状态不可用触发续期或展示已过期
Sui RPC 落后查不到刚提交对象换 RPC 或等待 checkpoint
索引器延迟前端列表没更新直接查 tx/object 兜底,后台补索引
版本不匹配CLI/服务报协议错误升级到目标网络对应 release
网络混用testnet Blob 在 mainnet 查询失败所有记录带 network 字段

重试策略

重试要按阶段设计:

  • 本地编码失败:不重试,提示文件或内存问题。
  • HTTP 429:指数退避,尊重服务限流。
  • HTTP 5xx:换 endpoint 或短退避重试。
  • Sui 交易不确定:先按 digest 查询,不要盲目重发。
  • 校验失败:不要返回内容,记录严重告警。

推荐保存一个 upload job:

job_id
file_hash
network
blob_id
blob_object_id
tx_digest
state
retry_count
last_error

这样服务重启后可以继续推进,不会因为内存状态丢失而重复上传。

故障隔离

生产环境至少准备两个读取 endpoint。前端可以配置主 aggregator 和备用 aggregator;后端可以根据健康检查动态选择。

隔离原则:

  • 写入服务和读取服务分开扩容。
  • 索引器失败不应影响已知 Blob 的直接读取。
  • CDN 失败时能回源 aggregator。
  • 单个 RPC provider 落后时能切换。
  • 后台校验失败不应默默覆盖成功状态。

最终一致的用户体验

最终一致不是让用户猜。界面和 API 应明确状态:

  • processing:交易或索引还没完成。
  • available:可读取并通过校验。
  • renew_required:快过期。
  • expired:超过存储期。
  • unverified:已上链但后台校验未完成。
  • failed:写入或校验失败。

把这些状态暴露给产品,比把所有异常都显示成“网络错误”更容易运营。