查看原文
其他

Filecoin:重力攻击手法 - 关于重量之三

胡飞瞳 胡飞瞳 2023-04-21

这应该是我写的第三篇关于 Filecoin 链重量的文章,因此加一个关于重量之三。当然,这也表明,后面还有之四、之五。要看连续剧的,敬请关注。


go-filecoin 0.5 版本一上线,大戏就上场了。那就是我在Filecoin网络:关于重量一文中提到的,重力攻击开始了,而且这种攻击一旦开始,就不会停歇。因为嗅觉灵敏的准矿工们,犹如游弋的鲨鱼,对血腥味十分敏感。在食物被咬一口之前,往往发现不了,但一旦开始滴血,就都来了。


尽管大多数人都希望看到一个稳定的 user-devnet,但事实上我们看到的是一次次的重复攻击。从第一次攻击开始到目前为止,攻击次数应该在10~20次之间。有一些得逞,也有没有得逞的。

我曾预言,会出现go-filecoin user-devnet 0.2.2版本出现的情况,事实上确实如此。我也没有期望鲨鱼能够自觉遵守期望的秩序,编队前行。在问题解决之前,任何一个人的尝试和冒犯都会对整个网络产生影响。最好的策略就是随他去。干点正事,分析一下代码,跟踪一下变化,考虑一下如何迎接测试网等等。


我的本意是等到问题修复之后再进行分析,但是,就目前的情况来看,很多人已经领会,公开不公开网络都不容易恢复。另外,现在Lotus发布,大家的注意力都转向了Lotus,而这里提到的重量计算问题在Lotus里面并不存在。另一个考虑是,在攻击连续发生时,有人@我,虽然我像大家一样希望网络尽快恢复正常,但实在是没有那个影响力来阻止攻击发生。我想圈我的目的可能更多的是希望我分析一下。既然如此,那就拼凑一篇,算是回复。



重量计算 - 没那么简单


在 go-filecoin的0.5.7 版本中,重量的计算方法已经发生了改变,用以解决利用重量进行长程攻击的问题,也就是说,解决的是 go-filecoin项目中的 Issue #3502。在新的重量算法中,引入了三个不同的因素用以兼顾分叉后短距离攻击和长距离攻击的问题。这三个因素分别是:总算力因素,当轮出块因素,空块因素。公式大致如此:



这里的几个因素都牵涉到不同的参数设置的问题,到底如何设置更加合理,需要进行理论的推算和实验的验证。不是说改就改,有一个过程。


关于这里的参数如何设置,以及这三个方面如何在防御攻击、保证预期共识的安全性上起作用,完全可以另起一篇文章,这里不赘述。


另外需要说明的是,尽管目前算法进行了改变,#3502问题得到了解决,但算法的完善工作还在进行之中,go-filecoin v0.5.7版本的重量计算方法仍然与设计中不一致,在接下来的版本中如果算法再次改变也完全是意料之中的事。


露个破绽 - 不公平的原型设计


go-filecoin 0.5.7之前的重力算法,按照设计者的说法,那是一个原型设计,并不是真正要使用的算法。那个这个算法的问题出在哪里呢?其实相关问题有些社区成员早就已经看出。比如我有一次在交流预期共识的算法的时候,有人提到,这个算法是偏向与算力高的矿工的。算力高的矿工能够增加更多的重量。也有人提出,这不是不公平吗?但问题的讨论就到此为止了。其实稍微深挖一点,就知道这里存在很大的问题。


首先来看一下原来的重量计算方法(摘自我早期分享的PPT): 


注意公式里的 miner_power_ratio,就是指爆块矿工的算力占比。一个矿工的算力占比在0到1之间,因此,每一轮重量增加大约10~110之间(仅考虑期望值,单轮由于可能多块,可能超过110)。


那么很显然,爆块矿工算力越高,其能够增加的重量越大。按照最重链原则,算力高的矿工在分叉聚合的过程中就会占便宜。


利用规则 - 最简单的分叉攻击


经过前面的介绍,我们知道了,大矿工因为自己能够增加较大的重量,如果利用好这一点,就可以通过分叉来攻击网络。一个最简单易行的做法是这样的(仅作为技术探讨,请勿模仿):

1)加入网络,尽量想办法增加算力(没有那么重要啦);

2)等拥有一定算力后,脱离网络,单独运行,继续增加算力(这个很重要),提高自己在私网中的算力占比(因为与主网隔开了,别人都不能增加算力,所以自己的比例越来越高,达到绝对统治地位,但这个过程可能相当费时。);

3)观察公网和私网的链重量,待私网链重量大于公网一定数量时,再次接入网络。


根据最重链法则,这时候公网的链和私网加入的链就会进行战斗,由于私网链更重一些,大家根据规则开始跟随你在私网里产生的这条链。等同步完成,攻击成功。


惩罚实现 - 为攻击助力


那么问题来了,为什么在 go-filecoin 的 0.5 版本中,重力攻击如此盛行,如此容易呢?10几次20次的攻击不是闹着玩的,说来就来吗?答案是YES。就是因为0.5版本实现的一些新功能,使得重力攻击变得非常容易。


其中最为重要的一个功能就是惩罚机制在0.5版本中实现了。其中实现的最主要的一个机制就是,当一个矿工在自己的证明区间里,如果不能完成并发送时空证明(PoSt)的话,其算力就会清零。


这在重力攻击中意味着什么呢?请看我们上一节的第二步,当你的节点从主网中脱离出来之后,因为其他节点不能再往你的私网发送消息,当然对于你维护的私链而言,他们就不能完成时空证明。也就是说,在一个证明周期的时间内,其他所有矿工的算力全部清零。网络中仅有你有算力,那么你就是100%。这样带来的好处是:1)每次都能爆块;2)每次都增加算力110。


而我们看主网, 由于那里有很多矿工,如果都是诚实矿工的话,每一位的算力不大,每一轮增加的重量一般可能是10几,20几。这样两个链的重量增加差别很大,很快重量就会拉开。这里不同网络增加算力的不同可以参考我前期文章:IPFS/Filecoin: 链的生命和性感(注:此文的算法目前已过时,我会根据最新算法更新一篇)。


其实,为重力攻击助力的新功能不仅仅是惩罚机制,还有其他方面,比如为了调试网络把证明区间改为300,有比如... (涉及到其他攻击方式,暂时保密)。


这还没完 - 有人玩的更嗨


看到这里,是不是认为重力攻击这么简单?要摩拳擦掌试一下。但是我劝你还是不要试了。因为现在试这个还是搞不赢。首先,网络高度不低了,你要慢慢积累算力,需要时间啊。花那么多时间不划算。但这不是最主要的。主要的是你在现在的网络中这么玩已经没用了。



有人利用了更有意思的玩法,那就是 go-filecoin 项目中 Issue #3523 中提到的,连弩齐发,一个高度可以增加数万重量,把自己吃成一个超级大胖子。这当然也是重力攻击,但这已经不是利用重量算法的漏洞了。所以不在这里分析。也不提倡现在试验。我会在此问题基本解决之后,另辟文章进行分析。


这种玩法已经没有太多意义了,因为理论上每一轮重量的增加几乎可以是无限的。也就是没有上限。如果大家都这么玩,也就没有下限了。除了在江湖上打一下名号,没有其他任何益处。正好现在 Lotus 出世,大家可以到一个池塘里去赏莲也不错。就不折腾 go-filecoin 了,等一些基本的bug修复了再回来吧。 




参考:




胡飞瞳

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存