事故复盘 · 2026 年 3 月
提现于 3 月 18 日停滞 14 分钟
1. 摘要
On 2026-03-18 between 14:08:22 UTC and 14:22:11 UTC,我们的一个以太坊热钱包停止处理提现。 1,847 笔提现请求排队 停滞 14 分钟;钱包恢复后,所有交易均正常完成。客户资金始终没有处于风险之中,也没有任何客户被重复扣费。我们公开这份说明,是因为我们欠用户一个交代。
2. 时间线
- 14:08:22 — 热钱包 A 以 nonce 412,387 提交提现交易。
- 14:08:34 — 以太坊区块 22,107,402 出块;交易确认。
- 14:09:11 — 区块 22,107,402 被重组(3 个区块的重组,源于竞争性验证者提案)。
- 14:09:18 — 交易回到内存池;我们的钱包守护进程仍认为它已确认(对重组通知缓存未命中)。
- 14:09:30 — 守护进程提交下一笔 nonce 为 412,388 的交易。内存池拒绝它:nonce 412,387 仍未完成。
- 14:09:30 → 14:22:00 — 守护进程每 30 秒重试一次,全部被拒。没有告警触发,因为守护进程将"nonce 过低"归类为用户错误,而非基础设施错误。
- 14:22:00 — 值班工程师注意到交易仪表盘上的桑基图显示 ETH 提现 12 分钟以上为零;发送告警。
- 14:22:11 — 手动重新广播 nonce 412,387,清空队列。
3. 根本原因
两个原因:
- 我们的链重组观察服务与钱包守护进程运行在同一节点上。当守护进程开始针对被拒交易反复重试时,观察服务因 CPU 被占用而饿死,大约 15 秒未能收到链重组通知。
- 我们针对"钱包守护进程卡住"的告警规则基于提交次数,而非有效吞吐。当时提交一直在进行(也一直被拒),所以从计数上看一切正常。
4. 我们做了哪些改变
- 链重组观察服务已迁移至独立主机,并使用独立的 JSON-RPC 连接。不再与守护进程共享 CPU。
- 告警从
submissions/mintoeffective_throughput / submissions。如果提交持续进行却没有任何交易被确认,该比率会跌至 0.1 以下,告警将在 60 秒内触发。 - 提现队列仪表盘新增了一个"nonce 卡住"小组件,对值班团队与交易仪表盘一同可见。
- 操作手册已更新,人工重广播 nonce 改为需要两名工程师签字的 90 秒标准动作,不再是耗时 4 分钟的临时操作。
5. 影响与善意补偿
1,847 笔提现平均被延迟 9 分钟。我们对每一笔卡住的交易退还了网络手续费(在受影响账户中合计约 4,200 美元),并向每位受影响客户发放了一张可在下一次入金时使用的一次性费用豁免券。受影响客户在事件解决后 90 分钟内收到了相关邮件通知。
6. 我们坚持的做法
公开发布事故复盘的本能。我们本可以把这件事压下来 — 直接受影响的客户只有 1,847 名,链重组本身就足以为延迟提供"合理推诿",我们的 SOC 2 框架在此也并不强制要求披露。但选择公开,意味着交易团队会读到、做市商会读到,下一位值班工程师在掉进同一个陷阱之前也会读到。
历次事故复盘可在 博客索引查看。相关技术文章: 我们如何构建撮合引擎。可通过账户设置或 状态页面.