# Solana 停机事件的反思

By [mars511](https://paragraph.com/@mars511) · 2021-11-03

---

9月14日，Solana网络宕机17小时。没有资金损失，网络在24小时内恢复了全部功能。

9月14日12:00 UTC - Raydium推出了GRAPE IDO，与此同时，多个机器人发送的大量交易涌入网络，试图赢得IDO份额，这些交易对mainnet-beta 执行了DDos攻击。一些节点每秒收到超过30万笔交易，流量有时甚至超过了物理接口的容量。

Solana在Tour de SOL激励的测试网中安全度过了很多大型“交易洪水”，这一次有什么不同？

*   写锁
    

Solana Sealevel运行时，可以并行执行不冲突的事务。编写Solana程序的目标之一是优化账户锁定行为，以确保一个程序的交易不会写锁定同一组账户。其中一个bot的作者不知道或者忽视了这一点，他们的交易写锁了多达18个账户，包括管理SPL的Global Program以及Serum Program。这阻止了所有触及这些账户的交易被并行执行。

当然，系统允许这么做是一个错误，事实上这是一个已知的问题，事故发生前已经有人提交了修复代码。网络第一次重启纳入了这个修复，系统性能得到了增强。

*   转发、重试、投票拥堵
    

Solana没有mempool, 客户端直接提交交易到Leader 节点的交易处理单元（TPU）。任何剩余的交易，将自动转发到下一个leader--这是Solana的核心创新之一，称为Gulfstream。这种转发机制比mempool有很多优势，比如可以防止抢跑。 在这次事故中，leader互相转发剩余的交易加重了DDoS的程度。事故后引入了改进，会限制这种转发行为。 类似的，RPC节点会重试失败的交易。Solana 1.8.x版本会让重试更加智能。

Solana使用链上投票来达成共识，当交易处理管道被DDos阻断时，它导致leader不能纳入投票交易，很可能导致共识的丧失。此后，Solana提出了新的机制，对投票交易进行优先处理，这可以防止普通交易 "淹没 "投票交易。

*   第二次重启
    

第一次重启本来预期可以恢复网络么，但是一个非常意外的bug，导致了重启失败。 集群重新启动时，会验证是否有最多20%的离线stake。这部分程序代码之前已经被验证了很多次，但是这次碰到了一个无符号64位变量的溢出。正常来说需要发行18B SOL才会碰到这个上限（开发者其实考虑过这个问题），但是这个值被乘以100来和阈值做比较。。。

*   总结
    

Solana是有史以来最复杂的共识引擎之一。所有分布式系统都有一个共同点。一个执行错误就能让它崩溃。Solana进行了广泛的模拟网络测试，一个激励性的测试网和bug赏金计划，以保证质量，但无论多少测试和程序都不可能防止每个bug。Solana仍在积极开发中（目前是mainnet-beta），它已经非常可用和安全，但一些与有效性有关的功能还没有实现。虽然宕机仍然有很小可能，但mainnet-beta在早期的表现比绝大多数项目都要好得多。

著名的CAP定理：一个系统只能在一致性（每次读取都能看到之前所有的写入）、可用性（请求总是成功的）和分区容错（当节点之间有数据包丢失时继续工作）中选择两个。Solana，像大多数快速确认的PoS链一样，是一个CP系统。如果有问题，它将牺牲可用性（即停止），而不是提供过时的数据或允许不安全的写入。

参考：

完整过程记录

[https://jumpcrypto.com/reflections-on-the-sept-14-solana-outage/](https://jumpcrypto.com/reflections-on-the-sept-14-solana-outage/)

CAP定理：

[https://www.ruanyifeng.com/blog/2018/07/cap.html](https://www.ruanyifeng.com/blog/2018/07/cap.html)

---

*Originally published on [mars511](https://paragraph.com/@mars511/solana)*
