本文详细介绍了以太坊2.0中最小委员会规模的概念,阐述了委员会中诚实验证者比例的重要性以及如何通过数学模型分析委员会规模与系统安全性之间的关系。文章解释了112个验证者的推荐数量,并提供了多个数学公式与Python代码示例,以帮助读者理解如何计算和优化委员会规模,以提升网络安全。
感谢 Vitalik Buterin 和 Yahsin Huang 的审阅和反馈
触发警告:高中数学
在 eth2.0 分片中,验证者被随机分配到委员会中以生成跨链接。每个委员会必须至少有一个称为“最低委员会大小”的最小成员数。在 Eth2.0 规范 中,附注指出推荐的验证者数量是 111 个。选择了一个常量 TARGET_COMMITTEE_SIZE
为 128,作为 111 的近似数,因为规范中的每个常量都定义为 2 的幂。2 的幂更容易记忆和仅用人脑进行计算。
本文带你了解这个 111 魔法数字如何影响整个系统的安全性。
委员会的安全性是如何定义的。假设协议几乎拥有所有验证者的诚实多数,即,2/3 的诚实验证者 😇 和 1/3 的恶意验证者 😈,我们希望每个委员会在协议将这些验证者随机分配到委员会时仍然拥有诚实多数。
举个具体的例子,假设我们有 30 万个总验证者,其中有 10 万个是攻击者。该协议有 1024(1K)个委员会,每个委员会分配 300 个验证者。如果一个委员会不幸有 200 个攻击者,那么这个委员会就不安全。
这种情况类似于从箱子中抽球。假设有一个巨大的箱子,里面装有数百万个球,你恰好知道 2/3 的球是黄色的 😇,而 1/3 是紫色的 😈。我们想抽取 3 个球,并要求不超过 1 个为紫色。
我们可以用一些公式来分析“抽到 2 或 3 个紫色球”的事件概率。
将上述步骤整理成一些 Python 函数之后,我们可以得出从抽球数量到不良结果概率的映射。
# 来源: https://vitalik.ca/files/Ithaca201807\_Sharding.pdf 页 11
deffac(n):
return n * fac(n-1) ifnelse1
defchoose(n, k):
returnfac(n) //fac(k) //fac(n-k)
defprob(n, k, p):
return p * * k * (1-p) * * (n-k) * choose(n, k)
defprobgte(n, k, p):
return sum(\[prob(n, i, p) foriinrange(k, n+1)\])
prob
给出了从 3 个球抽取中得到 2 个紫色 😈 的概率,而 probgte
给出了获取 2 个或更多紫色 😈 的概率(即 2 和 3)。这是将 k=2 和 n=3 作为函数参数传递的。
正如下图所示,随着抽取球的数量增加,概率降低。当 k 恰好是 n 的 2/3 时,出现锯齿状。
注意:在某些数据点上,我错误地将未通过 2/3 的概率包含在计算中。例如,在抽取 4 个球的情况下,2 个紫色的概率不应加上。我错误地使用 int 而不是 ceil 将 Python 中的分数转换成整数。
>>> list(range(int(4*2/3), 4+1 )) # 错误
[2, 3, 4]
>>> list(range(ceil(4*2/3), 4+1 )) # 正确
[3, 4]
感谢 Gusti Albrecht 指出图表中的错误!
如果你不相信,当数字较大时,趋势更显著。
将上述事实翻译到委员会问题中,这意味着我们可以增加委员会的大小,以减少委员会中有 2/3 的攻击者的概率。通过指定一个我们可以接受的小概率,我们可以确定所需的最小委员会大小。
假设概率为 2 -40,委员会至少需要 111 名成员。
请注意,y 轴为对数比例
一些其他因素可能会影响这个委员会的大小。
再次感谢 Gusti Albrecht 对此总结的贡献。
x= \[\]
y= \[\]
lable\_1\_p=None
foriinrange(3, 20):
two\_third=int(i * 2/3)
p=probgte(i, two\_third, 1/3)
x.append(i)
y.append(p)
ifi==3:
lable\_1\_p=p
plt.plot(x, y)
plt.plot(3, lable\_1\_p, 'o')
plt.text(3, lable\_1\_p, r' prob: %s'%lable\_1\_p)
plt.ylabel('Prob. 紫色球获得多数')
plt.xlabel('抽取球数量')
plt.show()
x= \[\]
y= \[\]
foriinrange(3, 100):
two\_third=int(i * 2/3)
p=probgte(i, two\_third, 1/3)
x.append(i)
y.append(p)
plt.ylabel('Prob. 紫色球获得多数')
plt.xlabel('抽取球数量')
plt.plot(x, y)
plt.show()
x= \[\]
y= \[\]
label\_1=None
label\_2=None
foriinrange(100, 300):
two\_third=int(i * 2/3)
p=probgte(i, two\_third, 1/3)
x.append(i)
y.append(p)
ifp<2 * * -40andlabel\_1isNone:
label\_1= (i, p)
ifp<2 * * -80andlabel\_2isNone:
label\_2= (i, p)
plt.yscale('log')
plt.plot(x, y)
plt.plot( * label\_1, 'o')
plt.text( * label\_1, r' prob: $2^{-40}$ at size %s'%label\_1\[0\])
plt.plot( * label\_2, 'o')
plt.text( * label\_2, r' prob: $2^{-80}$ at size %s'%label\_2\[0\])
plt.ylabel('Prob. 恶意验证者获得多数 (对数)')
plt.xlabel('委员会大小')
plt.show()
fromscipy.specialimportcomb
defprob(n, k, p):
return p * * k * (1-p) * * (n-k) * comb(n, k)
defprobgte(n, k, p):
return sum(\[prob(n, i, p) foriinrange(k, n+1)\])
查看原始代码 ```
importmatplotlib.pyplotasplt
plt.style.use('seaborn')
查看原始代码 ```
foriinrange(100, 350):
majority=int(i * 3/5)
p=probgte(i, majority, 2/5)
ifp<2 * * -40:
print(i)
- 原文链接: medium.com/@chihchenglia...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!