---
title: Gossip Service（八卦服务）
---

Gossip服务在控制平面中充当一个网关的角色。 验证节点使用该服务来确保集群中的所有其他节点都可以获取信息。 服务通过Gossip协议来广播相关的消息。

## 八卦传播概览

节点之间不断共享签名数据对象，以便管理集群。 例如，它们相互共享联系消息、区块高度和投票。

每十分之一秒，每个节点发送一个“推送”消息和/或“拉取”消息。 推送和拉取消息可能会引发响应，推送消息可能转发到集群中的其他节点。

Gossip在已知的UDP/IP端口或已知范围内的端口上运行。 一旦集群被触发，节点就会互相通告在哪里找到它们的对等端点\(一个 socket 地址\)。

## Gossip 记录

通过gossip共享的记录是任意的，但是需要根据需要进行签名和版本控制\(带有时间戳\) ，以便对接收它们的节点有意义。 如果一个节点从同一个源接收到两条记录，它将用带有最新时间戳的记录更新自己的副本。

## Gossip 服务接口

### 推送消息

节点发送一个push消息，告诉集群它有要共享的信息。 节点向 `PUSH_FANOUT` 发送消息到对等节点。

当节点接收到消息后，做如下检查：

1. 复制：如果这个消息之前发送过，节点丢掉数据并返回 `PushMessagePrune` 如果这个数据是从低权重的节点发送的
2. 新数据：如果这个数据是新来的

   - 将带有新版本的新消息存储在群集当中，

     清除以前的旧值

   - 把消息存储在`pushed_once`当中\(

     用来检测重复的消息，在`PUSH_MSG_TIMEOUT * 5`后擦除\)

   - 将消息重新传输到自己的对等节点

3. 过期：当超过`PUSH_MSG_TIMEOUT`这个时间间隔时，节点丢弃相关的消息

### 推送消息到对等节点，消息剪枝

节点从已知节点的活跃集合中随机选择其推送节点。 节点将此选择保留相对较长的时间。 当接收到修剪消息时，节点丢弃发送该消息的推送对等方。 Prune表示有另一个比直接推送更加复杂的路径到达该节点。

每隔`PUSH_MSG_TIMEOUT/2`毫秒，推送的节点集合都会进行更新，保证推送节点是比较新的。

### 拉取消息

节点发送一条"拉取"消息，询问集群是否有新信息。 拉取消息随机发送到单个对等点，包括节点已经拥有的内容的Bloom过滤器。 接收“拉取”消息的节点对其bloom过滤器进行迭代，并构造一个“拉取”响应，该响应包含未命中过滤器且适合消息的内容。

节点通过迭代当前值来构造pull Bloom过滤器。

节点处理pull响应中的记录的方式与处理push消息中的新数据的方式相同。

## 消息剪枝

节点保留较早的消息(通过推送和拉取更新的数据) 和过期的值(比`GOSSIP_PULL_CRDS_TIMEOUT_MS`更旧的值)`purged_values`(最新拥有的)。 节点修剪`purged_values`比`5*GOSSIP_PULL_CRDS_TIMEOUT_MS`这个时间间隔长。

## 日食攻击

日食攻击是试图接管大量节点的节点集合。

下面两个方面的因素是我们实现中需要考虑的。

- 拉取消息会从网络中随机的选择一个节点。 对_拉取消息_继续的日食攻击会影响节点的随机选择，从而只选择恶意节点进行数据同步。
- 节点维护一组活跃的节点用于随机扩散消息。 日食攻击者会影响活跃的节点集合，这样_发送_的消息会传播到恶意节点。

### Time and Stake based weights（基于时间和质押的权重）

权重是基于`上次当选的时间` 和 `质押权重` 的 `自然对数`而组成。

采用`ln`的权值可以使所有节点在合理的时间内获得更公平的网络覆盖机会。 它有助于规范化节点之间可能存在的`质押权重`差异较大的情况。 通过这样，与`质押权重`较大的节点相比，`质押权重`较低的节点只需等待几倍的ln\(`质押`\) 时间就可以被选中。

攻击节点无法影响这些参数。

### 拉取消息

上述计算权重的方法作为拉取信息来选择节点。

### 推送消息

剪枝只能从潜在连接中删除。

就像_拉取消息_一样，节点是根据权重来添加到活跃的节点集合中的。

## PlumTree的主要区别

本文描述的主动推送协议基于[Plum Tree](https://haslab.uminho.pt/sites/default/files/jop/files/lpr07a.pdf)。 主要区别是：

- 推送的消息带有发送节点的时间戳。 当时间戳过期后数据就被删除了。 跃点限制很难在对抗性环境中实施。
- 延迟推送之所以没有实施，是因为它不清楚如何阻止对手伪造消息指纹。 一个简单的方法允许对手根据它们的输入优先级进行拉取。
