Solana Turbine Block Propagation
Solana中的共识节点称之为 validators,所有的 validators 构成一个 cluster(簇)。每次只有一个共识节点负责出块,这个负责出块的节点称之为 Leader(领导)。每个 Leader 有固定的出块区间,Solana中将其称之为 slot。
当一个 Leader 生产一个新区块后,需要尽快将其分发给其他 validator,为此,Solana 使用了一种称之为 Turbine 的方法。在这种方法中,当 Leader 分发新区块时,使用纠删码对新区块进行切分成若干份,随后将每一份数据分发给一个 validator。每个 validator 收到一份数据后,再将自己收到的数据分发给其他 validator。这是一种树形分发方式,其方式完全就是 split-stream 的翻版。
数据分发结构
当 Leader 分发区块时,会选择 DATA_PLANE_FANOUT 个节点,并向这些节点分发数据。DATA_PLANE_FANOUT 是配置的一个值。当前 Leader 选择时,直接按照各个 validator 质押的 stake 份额的高低选择,Leader 会按照从高到低选择一批节点,然后使用随机选取 DATA_PLANE_FANOUT 个节点,进行随机选择的目的是为了提高安全性。可以看出,质押份额越高的节点是最快收到新区块的节点。
假设 Leader 是分发过程中的根节点,构成了第 0 层(layer),那么 Leader 刚开始选择的这些节点构成了第 1 层,第一层的节点再次选择其他节点构成第 3 层,依次类推,最终,整个数据的分发方式构成了一个多播树,其方式类似下图,每个节点的子节点数由 DATA_PLANE_FANOUT 决定,当前这个值是在系统启动时配置好的。

Shred 分发过程
当 Leader 分发新区块时,Leader 在第 0 层。然后把编码为若干个分片,每个分片称之为一个 Shred。
当分发一个 Shred 时,Leader 节点选择并发送给一个特定的节点,这个节点称之为这个Turbine 树的根节点(root node)或者锚节点(anchor node)。锚节点会将该 Shred 分发给第 1 层的节点,同时还会发送给第 2 层的节点。因此,一个 锚节点需要将一个 Shred 分发给 个节点,而普通节点只需要发送给下一层的 个节点。
下图展示了一个 Leader 在 fanout 设置为 2 的情况下把一个 Shred 分发给 Neighborhood 0 的过程。Leader 首先选择将 Shred 发送给 Validator 1(根节点),随后 Validator 1 将 Shred 转发给 Validator 2,而 Validator 1 和 Validator 2 构成了第 1 层。

如下图所示,Validator 1 和 Validator 2 继续将 Shred 发送给第 2 层的节点。可以看出,Validator 1 作为锚节点总共发送了 次,而 Validator 2 只发送了 次。

需要说明的是,上述图解只是如何发送一份 Shred 的过程,实际上,Leader 会使用纠删码把一个区块编码为多个 Shred,然后针对每一个 Shred,把每个 Shred 发送给不同的根节点。假设整个区块被编码为 2 个 Shred,随后 Validator 1 将收到的 Shred 1 发送给 Validator2,而 Validator 2 会将收到的 Shred 2 发送给 Validator 2。最终 Validator 1 和 Validator 2 都可以通过纠删码解码原始的区块。
为了快速传输数据,Solana 使用 UDP 协议进行传输,而 UDP 不是可靠传输,因此,传输过程中加入 FEC 以增加数据的鲁棒性。