本文介绍了 gossipsub v1.1 协议的扩展,旨在提高协议的安全性和抗攻击能力,包括显式对等协定、PRUNE 回退、洪泛发布和适应性 gossip 传播等新特性。这些扩展在保持向后兼容的同时,引入了同伴评分机制,以便更好地管理节点之间的连接和消息传播,确保网络的稳定性与安全性。
生命周期阶段 | 成熟度 | 状态 | 最新修订 |
---|---|---|---|
2A | 候选推荐 | 活跃 | r8, 2021-12-14 |
作者: @vyzo
兴趣小组: @yusefnapora, @raulk, @whyrusleeping, @Stebalien, @daviddias, @protolambda, @djrtwo, @dryajov, @mpetrunic, @AgeManning, @Nashatyrev, @mhchia
请参阅lifecycle document以获取有关成熟度水平和规范状态的上下文。
<!-- (!!!) WARN: anchor links generated by doctoc were monkey-patched to work around GitHub not encoding subscripts properly in anchors. -->
<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
本文档规定了对 gossipsub v1.0 的扩展,旨在改善引导启动和协议攻击的抗性。该扩展更改了规定本地对等行为的算法,并与协议的 v1.0 完全向后兼容。实施这些扩展的对等体,使用 /meshsub/1.1.0
作为协议字符串来宣传 v1.1 协议。
该协议现在支持节点操作员之间的明确对等协议。通过明确对等协议,应用程序可以指定一个对等体列表,以保持连接并无条件地相互转发消息,而不受对等评分系统和其他防御措施的影响。
对于每个明确的对等体,路由器必须建立并保持连接。连接在路由器启动时初步建立,并定期检查以确保连接状态,并在连接丢失时重新连接。推荐的连接检查周期为 5 分钟。
对等协议是带外建立和互惠的。明确的对等体位于网格之外:每一条新的有效传入消息都会转发给直接对等体,同时始终接受来自他们的传入 RPC。目前,在明确对等体上进行 GRAFT 是错误的,并且这种尝试应被记录并以 PRUNE 方式拒绝。
Gossipsub 依赖环境对等发现,以查找感兴趣主题中的对等体。这对可扩展的对等发现服务的实现施加了压力,以支持协议。通过对等交换,该协议现在可以从少量节点引导启动,而无需依赖外部对等发现服务。
对等交换(PX)在因为过度订阅而修剪网格时启动。相较于简单地告诉被修剪的对等体离开,修剪对等体 可以 提供一组其他对等体,以便被修剪对等体可以连接并重新建立其网格(参见下文的 对等评分)。
此外,被修剪的对等体与修剪对等体之间增加了一个回退期,在此期间他们将不会尝试重新接入。在回退期间,修剪对等体和被修剪对等体都会立即修剪一条 GRAFT
,并延长这个回退期。当一个对等体在过早尝试重新接入时,修剪对等体可能会对该行为施加行为惩罚,并通过 P₇ 处罚该对等体(参见下文的 对等评分)。
在从主题中取消订阅时,回退期应在再次订阅该主题之前结束,否则将很难达到健康的网格。如果出现取消订阅事件,可以使用较短的回退期,以允许更快地重新订阅。
推荐的回退期时长为 1 分钟,而推荐的交换对等体数量应大于 D_hi
,以便被修剪的对等体能够可靠地形成完整网格。为了正确同步两个对等体,修剪对等体应在 PRUNE 消息中包含回退期。被修剪对等体必须在尝试再次接入之前等待完整的回退期——加上一些弹性以弥补下一个清除回退的心跳——否则它会面临再次接入被拒绝的风险,并在尝试过早接入时被处罚其分数。
为了实现 PX,我们扩展了 PRUNE
控制消息,以包含被修剪对等体可以连接的一组可选对等体。该对等体集包括对等体 ID 和每个交换对等体的 签名 对等记录。为了便利 libp2p 生态系统过渡到使用签名对等记录,发布对等体在没有签名对等记录时可以省略该记录。在这种情况下,被修剪对等体必须依赖环境对等发现服务(如果已设置)来发现对等体的地址。
ControlPrune
消息扩展了一个 peers
字段,如下所示。
syntax = "proto2";
message ControlPrune {
optional string topicID = 1;
repeated PeerInfo peers = 2; // gossipsub v1.1 PX
optional uint64 backoff = 3; // gossipsub v1.1 回退时间(秒)
}
message PeerInfo {
optional bytes peerID = 1;
optional bytes signedPeerRecord = 2;
}
在 gossipsub v1.0 中,如果对等体订阅要发布的主题,则发布新消息给他们的网格成员。对等体还可以发布给未订阅的主题,此时他们将在其分发映射中选择对等体。
在 gossipsub v1.1 中,发布消息时(可选)将消息发布给所有连接的对等体,只要其分数高于发布阈值(参见下文的 对等评分)。这适用于无论发布者是否订阅该主题。在启用洪泛发布时,网格用于从其他对等体传播消息,但对等体自己的消息将始终发布给该主题中的所有已知对等体。
此行为是为了抵消蚀刻攻击并确保来自诚实节点的新发布消息将到达所有连接的诚实节点并传播到整个网络。当洪泛发布在使用时,当对等体只是纯粹的发布者且未订阅该主题时,利用分发映射或发出 Gossip 是没有意义的。
此行为还减少了消息传播延迟,因为消息会在网络中的更多点被注入。
在 gossipsub v1.0 中,Gossip 被发射给固定数量的对等体,按照 D_lazy
参数规定。在 gossipsub v1.1 中,Gossip 的传播是自适应的;而是向一定比例的对等体发射 Gossip,且最少为 D_lazy
个对等体。
控制 Gossip 发射的参数称为 Gossip 因子。当节点想在心跳期间发射 Gossip 时,首先选择所有分数高于 Gossip 阈值的对等体(参见下文的 对等评分)。然后,从这些对等体中随机选择 Gossip 因子对等体,最少为 D_lazy
,并将 Gossip 发射给所选对等体。
推荐的 Gossip 因子值为 0.25
,这样在每个消息的默认 3 轮 Gossip 确保每个对等体至少有 50% 的概率收到关于消息的 Gossip。更具体地说,对于 3 轮 Gossip,某个对等体 没有 收到新消息的 Gossip 的概率是 (3/4)³=27/64=0.421875
。因此,每个对等体接收到关于新消息的 Gossip 的概率为 0.578125
。
此行为是为了抵消 Sybil 攻击,确保来自诚实节点的消息以高可能性在网络中传播。
在 gossipsub v1.0 中,网格对等体是随机选择的,没有对连接的方向给予权重。相比之下,gossipsub v1.1 实现了出站连接配额,以便对等体尽可能保持一定数量的出站连接。
具体而言,我们定义了一个新的覆盖参数 D_out
,该参数必须设定在 D_lo
之下且至多为 D/2
,具体如下:
D_out
个出站连接的约束;另见下文的 对等评分。D_hi
或更高),它仅在该对等体是出站连接时才接受新的对等体进入网格。D_lo
个对等体但出站连接不够,则选择尽量补充所需对等体,以填充配额并将其接入网格。此行为是为了抵消 Sybil 攻击,并确保协调的入站攻击无法完全控制目标对等体的网格。
在 gossipsub v1.1 中,我们引入一个对等评分组件:每个单独的对等体为其他对等体维护一个分数。该分数由每个单独的对等体根据观察到的行为局部计算,并不共享。该分数是一个实值,计算方式为各参数的加权均值,并具有可插拔的应用特定评分。该分数在所有(配置的)主题中计算,并采用加权混合,这样在一个主题中的错误行为可以渗透到其他主题。此外,当某个对等体断开连接时,该分数会保留一段时间,以确保恶意对等体无法轻易将其分数重置为负值,并且行为良好的对等体不会因为断开连接而失去其状态。
目的是检测恶意或错误行为,并以负分数惩罚表现不佳的对等体。
该分数被嵌入到各种 gossipsub 算法中,以便从网格中删除分数为负的对等体。负分数差的对等体会被进一步惩罚甚至被忽视,如果分数过低则更是如此。
更具体而言,适用以下阈值:
0
:基线阈值;分数低于这个阈值的对等体将在心跳期间从网格中修剪,并在寻找 graft 的对等体时被忽略。此外,不向这些对等体发出任何 PX 信息,并且从它们处忽略 PX。再者,在进行 PX 时,仅交换非负分数的对等体。GossipThreshold
:当某个对等体的分数低于该阈值时,不向该对等体发出 Gossip,并且忽略来自该对等体的 Gossip。此阈值应为负值,以便可以在轻微负分数的对等体间传播一些信息。PublishThreshold
:当某个对等体的分数低于该阈值时,自发布的消息不会在洪泛发布时发送给该对等体。此阈值应为负值,并小于或等于 Gossip 阈值。GraylistThreshold
:当某个对等体的分数低于该阈值时,该对等体会被灰名单处理,且其 RPC 被忽略。此阈值必须为负值,并小于 Gossip/Publish 阈值。AcceptPXThreshold
:当某个对等体向我们发送与 pruned 的 PX 信息时,仅在源对等体的分数超过该阈值时,才接受并连接到所提供的对等体。此阈值应为非负值,出于增强安全性的考虑,对来自引导程序和其他可信良好连接对等体的分数可达大正值的设置。OpportunisticGraftThreshold
:当网格中的中位对等体分数低于该值时,路由器可能选择更多的分数高于中位数的对等体,以寻求机会接入网格(参见下文的机会接入)。此阈值应为正数,相较于可以通过主题贡献获得的分数应相对较小。在心跳维护期间明确检查分数:
D_score
评分对等体,并随机选择其余对等体。这样可保护网格免受攻击,确保最佳评分的对等体留在网格中。同时,我们还保留一些随机对等体,以便协议能够对新入网格的对等体做出响应。选择时需要遵循至少 %D_out%
个对等体是出站连接的约束;如果评分加随机选择无法导致出站连接足够,则用出站连接对等体替换随机和低分对等体。路由器可能会陷入由表现不佳的对等体组成的网格,无论是由于良好对等体的变化还是由于大规模的冷重启或隐蔽Flash攻击。发生这种情况时,路由器通常会通过网格失败惩罚进行反应(参见下文的评分函数),但该反应时间可能较慢:流失负分对等体的替代对等体将在无负分对等体中随机选择,这可能导致在 Sybil 污染的池中多轮选择。此外,Sybil 的数量可能如此之多,以至于粘滞网格失败惩罚在选择良好对等体之前完全衰减,从而使得 Sybil 重新符合接入条件。
为了从此类灾难场景中恢复并普遍自适应地优化网格,gossipsub v1.1 引入了机会接入机制。路由器定期检查网格中对等体的中位分数是否低于 OpportunisticGraftThreshold
。如果中位分数低于该阈值,路由器在网格中机会接入(至少)两个分数高于中位数的对等体。这通过引入可能已经向我们转发信息的良好评分对等体来改善未发挥作用的网格。这样还可以让路由器从粘滞的灾难状况中抽身,通过用在最近通过 Gossip 转发过消息的对等体替换试图蚀刻的 Sybil 对等体。
推荐的机会接入周期为 1 分钟,路由器应接入 2 个对等体(使用默认参数),以便拥有作为它们与评分类别之间的渠道的机会,并在网格中建立分数。然而,机会接入的对等体数量由应用控制。如果应用配置的网格比默认参数更大,那么接入更多对等体可能是理想的。
评分函数是各参数的加权混合,每个主题 4 个,全局适用 3 个。
Score(p) = TopicCap(Σtᵢ*(w₁(tᵢ)*P₁(tᵢ) + w₂(tᵢ)*P₂(tᵢ) + w₃(tᵢ)*P₃(tᵢ) + w₃b(tᵢ)*P₃b(tᵢ) + w₄(tᵢ)*P₄(tᵢ))) + w₅*P₅ + w₆*P₆ + w₇*P₇
其中 tᵢ
是每个主题的主题权重,适用于每个主题参数。
各参数定义如下:
P₁
:在网格中的时间。这是一个对等体在网格中存在的时间,限制为一个小值并与一个小的正权重混合。这旨在提升已经在网格中的对等体,以免由于过度订阅而被过早修剪。P₂
:首次消息传递。这是对等体在主题中首次传递的消息数量,带正权重。这旨在奖励首次转发有效消息的对等体。P₃
:网格消息传递速率。此参数是一个阈值,对应于主题中预期的消息传递速率。如果传递数量超过阈值,则该值为 0;如果数量低于阈值,则参数值为差值的平方。这旨在惩罚网格中未交付预期消息数量的对等体,以便将它们从网格中移除。该参数与负权重混合。P₃b
:网格消息传递失败。这是一个粘滞参数,计算网格消息传递失败的数量。每当某个对等体在负分下被修剪时,该参数由修剪时的缺口率增加。这旨在保持修剪历史,以确保因为未交付而被修剪的对等体无法快速重新进入网格。该参数与负权重混合。P₄
:无效消息。这是主题中传递的无效消息数量。此参数旨在惩罚根据特定应用验证规则转发无效消息的对等体,与负权重混合。P₅
:应用特定的分数。该分数组件由应用程序根据特定的应用规则分配给对等体。权重为正,但参数本身可以是任意实值,因此应用程序可以通过负分数来表示不当行为,或在特定的应用握手完成之前开展控制。P₆
:IP 合作因素。此参数是使用相同 IP 地址的对等体数量的阈值。如果同一 IP 地址的对等体数量超过阈值,则该值为盈余的平方,否则为 0。这旨在使得即使使用少量 IP 进行 Sybil 攻击也变得困难。该参数与负权重混合。P₇
:行为惩罚。此参数记录对不当行为施加的惩罚。该参数有相关的(衰减)计数器,通过路由器在特定事件上显式增加。参数值为计数器的平方,并与负权重混合。TopicCap
函数允许应用程序在所有主题之间指定对得分的贡献的可选上限。
主题参数通过在路由器内部维护的计数器实现,当事件发生时,计数器将被更新。计数器会周期性地 衰减,从而使其值不会不断增加,确保大型正值或负值的分数在对等体的生命周期内不会保持不变。
衰减间隔由应用程序配置,较短的间隔能够导致较快的衰减。
每个衰减参数可以有自己的衰减 因子,这是一个可配置的参数,控制每个衰减周期内参数衰减的程度。
衰减因子是范围在 (0.0, 1.0) 的浮点数,将乘以当前参数值在每个衰减间隔更新时。例如,假设 P₂
(首次传递) 的值为 120
,衰减因子为 FirstMessageDeliveriesDecay = 0.97
。在衰减间隔时,该值将更新到 120 * 0.97 == 110.4
。
衰减因子和衰减间隔共同决定每个参数的绝对衰减率。随着衰减间隔为 1 秒且衰减因子为 0.97
,参数将每秒衰减 3%,而 0.90
将导致其每秒衰减 10% 等等。
为了计算 P₁
,路由器记录对等体被 GRAFT 的时间。在衰减更新期间,慵懒地计算在网格中的时间,以避免对 gettimeofday
的大量调用。参数值为自 GRAFT 以来经过的时间与一个应用配置的量子值的比值。
例如,当量子为 1 秒时,某个对等体的 P₁
值将等于自其被 GRAFT 到网格以来经过的秒数。当量子为 5 分钟时,P₁
值将为自 GRAFT 的 5 分钟区间数。P₁
值将限制为应用程序可配置的最大值。
在伪 Go 中:
// 主题配置参数
var TimeInMeshQuantum time.Duration
var TimeInMeshCap float64
// 慵懒更新的在网格中的时间
var meshTime time.Duration
// P₁
p1 := float64(meshTime / TimeInMeshQuantum)
if p1 > TimeInMeshCap {
p1 = TimeInMeshCap
}
为了计算 P₂
,路由器维护一个计数器,该计数器在对等体首次传递主题中的消息时增加。参数在计数器增加时应用限制。
在伪 Go 中:
// 主题配置参数
var FirstMessageDeliveriesCap float64
// 每当首次消息传递发生活动时更新的计数器
var firstMessageDeliveries float64
// 计数器更新
firstMessageDeliveries += 1
if firstMessageDeliveries > FirstMessageDeliveriesCap {
firstMessageDeliveries = FirstMessageDeliveriesCap
}
// P₂
p2 := firstMessageDeliveries
为了计算 P₃
,路由器维护一个计数器,该计数器在网格中某个对等体首次或 近首次 消息传递发生时增加。近首次消息传递是指在第一条消息被首次接收并正在验证时发生的消息传递,或者在首次消息传递的验证可配置窗口内接收到的消息。该窗口是可配置的,但应保持较小(以毫秒为计算单位),以避免允许某个网格对等体仅通过反馈当前路由器接收到的消息来提高分数。此参数在增加时有一个限制。
为了避免过早触发惩罚,此参数具有激活窗口。此值是必须在网格中保持一定时间后该参数才能生效的可配置值。
在伪 Go 中:
// 主题配置参数
var MeshMessageDeliveriesCap, MeshMessageDeliveriesThreshold float64
var MeshMessageDeliveriesWindow, MeshMessageDeliveriesActivation time.Duration
// 在网格中的时间,慵懒更新
var meshTime time.Duration
// 每当网格对等体发生首次或近首次消息传递时更新的计数器
var meshMessageDeliveries float64
// 计数器更新
meshMessageDeliveries += 1
if meshMessageDeliveries > MeshMessageDeliveriesCap {
meshMessageDeliveries = MeshMessageDeliveriesCap
}
// P₃ 计算
var deficit float64
if meshTime > MeshMessageDeliveriesActivation && meshMessageDeliveries < MeshMessageDeliveriesThreshold {
deficit = MeshMessageDeliveriesThreshold - meshMessageDeliveries
}
p3 := deficit * deficit
为了计算 P₃b,路由器维护一个计数器,每当该对等体在消息传递中以负分被修剪时,该计数器将更新。此参数不受上限限制。
在伪 Go 中:
// 在修剪时更新的计数器
var meshFailurePenalty float64
// 计数器更新
if meshTime > MeshMessageDeliveriesActivation && meshMessageDeliveries < MeshMessageDeliveriesThreshold {
deficit = MeshMessageDeliveriesThreshold - meshMessageDeliveries
meshFailurePenalty += deficit * deficit
}
// P₃b
p3b := meshFailurePenalty
为了计算 P₄
,路由器维护一个计数器,每当消息无法通过验证时增加。参数值是计数器的平方,不设上限。
在伪 Go 中:
// 每当消息验证失败时更新的计数器
var invalidMessageDeliveries float64
// 计数器更新
invalidMessageDeliveries += 1
// P₄
p4 := invalidMessageDeliveries * invalidMessageDeliveries
与 P₂
、P₃
、P₃b
和 P₄
相关的计数器周期性地通过与可配置的衰减因子相乘进行衰减。当值低于阈值时,视为零。
在伪 Go 中:
// 衰减因子
var FirstMessageDeliveriesDecay, MeshMessageDeliveriesDecay, MeshFailurePenaltyDecay, InvalidMessageDeliveriesDecay float64
// 0阈值
var DecayToZero float64
// 周期性衰减计数器
firstMessageDeliveries *= FirstMessageDeliveriesDecay
if firstMessageDeliveries < DecayToZero {
firstMessageDeliveries = 0
}
meshMessageDeliveries *= MeshMessageDeliveriesDecay
if meshMessageDeliveries < DecayToZero {
meshMessageDeliveries = 0
}
meshFailurePenalty *= MeshFailurePenaltyDecay
if meshFailurePenalty < DecayToZero {
meshFailurePenalty = 0
}
invalidMessageDeliveries *= InvalidMessageDeliveriesDecay
if invalidMessageDeliveries < DecayToZero {
invalidMessageDeliveries = 0
}
待补充
:我们目前正在开发多种类型的仿真,以帮助我们确定如何最好地建议调优评分函数。一旦该工作完成,我们将更新此部分。
pubsub 子系统包含特定应用程序的消息验证器,以便应用程序可以指示无效的消息传递并触发 P₄ 惩罚。但是,可能会出现某些情况,其中消息不应传递到应用程序或转发到网络,但不应触发 P₄ 惩罚。已知的用例是在出现重复信标消息或应用程序同步其区块链时,在这种情况下,它将无法证明新消息的有效性。
为了解决这一情况,所有 gossipsub v1.1 实现 必须 支持带有枚举决策接口的扩展验证器。扩展验证的结果至少可以是三种情况之一:
添加到 gossipsub v1.1 的扩展介绍了几个新的应用程序可配置参数。本节总结了所有新参数以及简要的描述。
以下参数适用于全局:
参数 | 类型 | 描述 | 合理默认值 |
---|---|---|---|
PruneBackoff |
时长 | 修剪一个网格对等体后,在考虑再次接入它们之前的时间。 | 1分钟 |
UnsubscribeBackoff |
时长 | 当取消订阅主题时使用的回退。在到期之前不应重新订阅该主题。 | 10秒 |
FloodPublish |
布尔值 | 是否启用洪泛发布 | true |
GossipFactor |
浮点[0.0, 1.0] | 发送 Gossip 给对等体的比例,如果我们拥有超过 D_lazy 的数量可用 |
0.25 |
D_score |
整数 | 在因过度订阅而修剪时,根据得分保留的对等体数量 | 对于 D 为 6 时为 4 或 5。 |
D_out |
整数 | 网格中保持的出站连接数量。必须小于 D_lo 并至多为 D/2 |
对于 D 为 6 时为 2。 |
其余参数适用于 对等评分。由于许多参数相互关联且可能应用特定,此处未显示合理默认值。请参见 调优评分函数的指南,以理解如何根据应用需求调优参数。
以下对等评分参数适用于所有对等体和主题:
参数 | 类型 | 描述 | 约束条件 |
---|---|---|---|
GossipThreshold |
浮点 | 不向低于阈值的对等体发出 Gossip;忽略来自该对等体的入站 Gossip。 | 必须 < 0 |
PublishThreshold |
浮点 | 不向低于阈值的对等体发送自发布消息。 | 必须 <= GossipThreshold |
GraylistThreshold |
浮点 | 忽略来自低于该阈值的对等体的所有 RPC 消息。 | 必须 < PublishThreshold |
AcceptPXThreshold |
浮点 | 低于该阈值的对等体提供的 PX 信息被忽略。 | 必须 >= 0 |
OpportunisticGraftThreshold |
浮点 | 如果网格中的中位得分低于该阈值,则路由器可能机会接入得分更高的对等体。 | 必须 >= 0 |
DecayInterval |
时长 | 计算参数衰减的间隔。 | |
DecayToZero |
浮点 | 低于此限制的衰减参数被视为 “零”。 | 应接近 0.0 |
RetainScore |
时长 | 在对等体断开连接后,记住对等体分数的时间。 |
其余的对等评分参数影响根据每个对等体观察到的行为计算的分数。
参数类型为 Weight
的参数是浮点数,决定评分参数对对等体总体得分的贡献大小。有关详细信息,请参见 评分函数。
有一些参数适用于对等体 "整体" ,与它们所订阅的主题无关:
参数 | 类型 | 描述 | 约束条件 |
---|---|---|---|
AppSpecificWeight |
Weight | P₅ ,应用特定分数的权重。 |
必须是正数,但是分数值可以是负的。 |
IPColocationFactorWeight |
Weight | P₆ ,IP 合作分数的权重。 |
必须是负数,以惩罚有多个 IP 的对等体。 |
IPColocationFactorThreshold |
整数 | 对等体可以拥有的 IP 数量,达到后开始惩罚。 | 必须至少为 1。超过阈值的值将被惩罚。 |
BehaviourPenaltyWeight |
Weight | P₇ ,行为惩罚的权重。 |
必须是负数,以对不当行为进行惩罚。 |
BehaviourPenaltyDecay |
浮点 | P₇ 的衰减因子。 |
必须在 0 到 1 之间。 |
其余参数适用于对等体在单个主题中的行为。实现应能够接受针对多个主题的配置,以主题 ID 字符串进行键入。每个主题可能配置以下参数。如果未配置某个主题,则该对等体在该主题中的行为将不会对其分数产生影响。如果某个对等体在多个配置主题中,则每个主题将根据 TopicWeight
参数对其总体评分产生贡献。
参数 | 类型 | 描述 | 约束条件 |
---|---|---|---|
TopicWeight |
Weight | 该主题的行为对整体分数的贡献度是多少? | |
P₁ |
在 Mesh 中的时间 | ||
TimeInMeshWeight |
Weight | P₁ 的权重。 |
应为一个小的正值。 |
TimeInMeshQuantum |
Duration | 节点必须在 Mesh 中待多久才能为 P₁ 累积一个“点”。 |
|
TimeInMeshCap |
Float | P₁ 的最大值。 |
应为一个小的正值。 |
P₂ |
首条消息交付 | ||
FirstMessageDeliveriesWeight |
Weight | P₂ 的权重。 |
应为正值,以奖励快速的节点。 |
FirstMessageDeliveriesDecay |
Float | P₂ 的衰减因子。 |
|
FirstMessageDeliveriesCap |
Float | P₂ 的最大值。 |
|
P₃ |
Mesh 消息交付率 | ||
MeshMessageDeliveriesWeight |
Weight | P₃ 的权重。 |
应为负值,以惩罚低于阈值的节点。 |
MeshMessageDeliveriesDecay |
Float | P₃ 的衰减因子。 |
|
MeshMessageDeliveriesThreshold |
Float | 为 P₃ 设置的阈值,低于该值开始惩罚节点。 |
应为正值。该值根据主题的预期消息率而定。 |
MeshMessageDeliveriesCap |
Float | P₃ 的最大值。 |
必须 >= MeshMessageDeliveriesThreshold 。 |
MeshMessageDeliveriesActivation |
Duration | 节点必须在 Mesh 中待多久才能开始应用 P₃ 分数。 |
|
MeshMessageDeliveryWindow |
Duration | 首次交付后的时间,被视为“近首次交付”的时间。 | 应较小,例如 1-5 毫秒。 |
P₃b |
Mesh 消息交付失败 | ||
MeshFailurePenaltyWeight |
Weight | P₃b 的权重。 |
应为负值,以惩罚失败的交付。 |
MeshFailurePenaltyDecay |
Float | P₃b 的衰减因子。 |
|
P₄ |
无效消息 | ||
InvalidMessageDeliveriesWeight |
Weight | P₄ 的权重。 |
应为负值,以惩罚无效消息。 |
InvalidMessageDeliveriesDecay |
Float | P₄ 的衰减因子。 |
为了抵御引起反应和消耗资源的垃圾邮件,采取了一些措施:
GRAFT
消息会被忽略;在 gossipsub v1.0 中,路由器总是会用 PRUNE
响应,这为用垃圾邮件 GRAFT
消息进行洪水攻击和消耗资源打开了大门。IWANT
消息的响应在某个节点的重传次数上有限制;在 gossipsub v1.0 中,路由器总是会响应缓存中的 IWANT
消息。在 gossipsub v1.1 中,路由器对每个节点的响应次数有限制,以防止 IWANT
垃圾邮件导致资源的大量消耗。IHAVE
消息的数量限制为一定数量的 IHAVE
消息和每个心跳周期中广告化的消息 ID 的总数,以减少遭遇洪水的风险。如果接收的 IHAVE
广告数量超过限制(或广告的消息数量超过限制),则额外的 IHAVE
消息将被忽略。IHAVE
广告后产生的 IWANT
请求会被以概率方式跟踪。对于每个引发 IWANT
请求的 IHAVE
广告,路由器会在广告集内跟踪一个随机的消息 ID。如果在一段时间内未收到该消息(来自任何节点),则会通过 P₇
对广告节点施加行为性惩罚。
此措施通过快速标记和灰名单添加虚假消息 ID 广告并且未对 IWANT
请求进行跟踪的节点,帮助抵御垃圾邮件 IHAVE
洪水攻击。IHAVE
消息的响应,都会通过分数函数受到惩罚。发送大量垃圾邮件的节点会迅速被列入灰名单,从而减少垃圾邮件引起的计算消耗(例如验证)。如果垃圾邮件在负分数衰减后依然存在,应用程序可以采取进一步措施将该节点列入黑名单。部署 gossipsub 时需要考虑的一个重要问题是节点发现机制,它必须提供安全发现新节点的方式。 在 gossipsub v1.1 之前,运营商被要求利用外部节点发现机制来定位参与特定主题的节点;而在 gossipsub v1.1 中,这现在完全是可选的,网络可以仅通过一小组网络入口点(引导节点)通过 Peer Exchange 进行引导。换句话说,只要节点能够找到至少一个参与感兴趣主题的节点,gossipsub 1.1 现在在这方面已实现自给自足。
为了在没有发现服务的支持下成功引导网络,网络运营商应:
D=D_lo=D_hi=D_out=0
),并启用 Peer Exchange,利用签名节点记录。AcceptPXThreshold
设置为仅引导节点能够达到的高值。通过这种方式,引导节点仅充当传播和节点交换节点,从而促进网络的形成和维护。 注意,引导节点中仍然存在分数函数,这保证了无效消息、协同和行为惩罚适用于不当行为的节点,以便它们不会接收 PX 或被广告到网络的其他部分。 此外,网络运营商可以配置应用特定的评分函数,使得引导节点在接受新节点时施加进一步约束(如协议握手、股份参与等)。
应强调的是,节点发现服务的安全性影响系统安全引导和从大规模攻击中恢复的能力。 网络运营商必须确保他们选择的任何节点发现机制都具备抵抗攻击的能力,并始终能够返回一些诚实节点,以便在诚实节点之间建立连接。 此外,强烈建议任何外部发现服务都应该由配置为 Peer Exchange 并具有高应用特定分数的引导节点/目录节点进行增强,如上所述。
- 原文链接: github.com/libp2p/specs/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!