共识模块会将每条消息都写入 WAL(预写日志)。 它还会通过 File#Sync 对由本节点签名的消息发起 fsync 系统调用(以防止双重签名)。 其底层使用的是 autofile.Group, 当文件过大时(> 10MB)会自动轮转文件。 总最大大小为 1GB。我们实际上只需要最新的区块以及它之前的那个区块, 但如果前者在很多轮中持续拖延,我们希望保留所有这些轮次的数据。

重放

如果发生崩溃,共识模块会在重启前重放 WAL 中写入的最后一个高度的全部消息。 私有验证器在重放期间可能会尝试对消息进行签名,因为它以某种半自治方式运行,并不了解重放过程。 例如,如果 WAL 已经推进到 precommit,随后发生崩溃, 那么在我们重放提案消息后,私有验证器会尝试签署一个 prevote。 但它会失败。这是可以接受的,因为我们稍后会在 WAL 中看到这个 prevote。 接着它会进入 precommit,这一次就会成功,因为私有验证器中保存了 LastSignBytes, 然后我们会从 WAL 中重放该 precommit。 请务必阅读关于 WAL 损坏 及其恢复策略的说明。
Consensus module writes every message to the WAL (write-ahead log). It also issues fsync syscall through File#Sync for messages signed by this node (to prevent double signing). Under the hood, it uses autofile.Group, which rotates files when those get too big (> 10MB). The total maximum size is 1GB. We only need the latest block and the block before it, but if the former is dragging on across many rounds, we want all those rounds.

Replay

Consensus module will replay all the messages of the last height written to WAL before a crash (if such occurs). The private validator may try to sign messages during replay because it runs somewhat autonomously and does not know about replay process. For example, if we got all the way to precommit in the WAL and then crash, after we replay the proposal message, the private validator will try to sign a prevote. But it will fail. That’s ok because we’ll see the prevote later in the WAL. Then it will go to precommit, and that time it will work because the private validator contains the LastSignBytes and then we’ll replay the precommit from the WAL. Make sure to read about WAL corruption and recovery strategies.