LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 区块链资讯 > 储迅出品:Filecoin二测网络的算力恢复技巧之各显身手

储迅出品:Filecoin二测网络的算力恢复技巧之各显身手

2020-05-25 储迅 来源:区块链网络

前几天发表了一篇有关Filecoin测试网第二阶段的算力变化的技术分析:储迅出品:Filecoin二测网络之算力过山车?,引发了不少争议。当然,这篇文章也带来了很多正面的意义,大家都关注到算力的变化,各显神通,用不同手段进行算力保持和恢复,目前的算力变化图已经非常平稳。

为了避开江湖纷争,我们在这里只谈技术,切勿对号入座。同时,我们也认为,在分布式存储的赛道,Filecoin挖矿技术本身的优劣并不能带来长期的竞争力,只有愿意长期持续投入,才能打造一个伟大的企业。储迅也积极与大家分享相关的黑科技以及原创的深度技术解读,希望在这个领域,也能和行业内的厂商一起,加强中国在相关领域的核心竞争力。

江湖告急:掉算力,白了少年头

Window PoSt无法正常提交,相关证明周期的扇区全部被标记为fault,看到的算力断崖式下跌。运维着急,程序员着急,老板更着急。一个个电话打来,皆曰:代码有Bug。Bug也许可以背锅,但问题得解决,盯着排行榜的各大媒体可不管什么Bug不Bug的。

怎么办?最快速的解决方案,就是宣称官方的几个节点,比如t01001、t01002、t01003是自己跑的。但是……这几个节点的算力也掉到0了:

作为唯一的具有真实的可验证数据的几个节点,它们已经完成了使命,退出江湖了。剩下的事情,就交给芸芸众生。技术的事情得靠技术来解决,想点办法,各显神通吧。

乾坤大挪移:重穿马甲,江湖再见

现实可行的最快速方案就是重跑一个新节点。绕开之前遇到的问题。比如:采用多miner方案,短时间内提交太多扇区触发了某个漏洞……当然,能改改代码绕开也不错,只要不是智能合约部分的共识代码,都可以拿来利用。比如,储迅也针对某些情况,提了Bug和补丁,能够应对部分情况:

Bug:https://github.com/filecoin-project/lotus/issues/1824

补丁:https://github.com/filecoin-project/lotus/pull/1825

如果是自行修改了和证明代码相关的逻辑,处理起来就更麻烦点。因为不具通用性,这里就不多说。

九阴真经:漏洞猎手,下手狠成效快

如果已经积累了不少算力,即使受到惩罚,也仍保留了不少算力,怎么办?如果ID已经被人熟知,再更换,会引起舆论上的压力,怎么办?莫着急,自有武林秘籍来帮忙。

现阶段,Filecoin官方团队非常忙,忙于实现Spec上的相关功能,所以代码可以利用的地方还是有不少的。

自行修改代码的逻辑,比如,一般来说没有用处,我自己说我的扇区都没有问题,但别人不相信啊,除非我自己形成了51%的优势算力。那怎么办呢?Filecoin的specs-actors模块,是目前实现智能合约的主要模块,lotus和go-filecoin都依赖于它。这里面的代码,会在每一个矿工的机器上面执行,会对加到链上的每一个消息进行解析。思路来了:

要避免被惩罚,就要绕开Window PoSt的检查。注释掉本地代码对Window PoSt的调用,自己不发这个消息。

但是Filecoin有cron定时任务,会定时对矿工进行检查(每个证明周期的最后一个高度,如果该高度是空块就顺延)。如果发现没有做Window PoSt,就法不容情了,咔擦一下,对应扇区的算力全掉。

能绕开cron定时任务吗?显然不能,这个是强制执行的。一步步,执行到最后,会调用enrollCronEvent,添加下次证明周期的定时任务,一环扣一环,让你无路可逃。

如果cron定时任务构造某些异常的条件,让它中途退出,执行不到最后面的添加下次任务的步骤呢?放心,每个环节,写代码的时候也都想好了,想轻易构造这些条件,也是不容易的。

但是……凡事皆有但是。假设cron定时任务里面,有一个未被处理的异常,让程序崩溃了呢?

官方开发人员在跑go-filecoin版本的时候注意到了一个整数(big.Int类型)没有被赋初值的情况:

https://github.com/filecoin-project/specs-actors/issues/382

但变量不被赋值,在我学写代码的时候经常遇到,这又有什么关系呢?不就是一个小错误吗?

在miner_actor.go中,对矿工定期进行算力检查的函数会调用handleProvingPeriod(),该函数又会调用terminateSectors(),其中有如下变量定义:+

看样子也没有啥问题。提醒一下,重点留意变量penalty。它在下面的代码中被赋值了:

最后在这个地方使用该变量:

这些都是和惩罚相关的代码,看得我心惊肉跳。它们又有什么问题呢?大家注意到没有,给penalty赋值的时候,有一个条件,就是terminationType != power.SectorTerminationExpired。如果构造出一些扇区,让它们满足这个条件,不就成功得让penalty不被赋值但却被使用,于是引起异常,这样就执行不了后面的挂载下一次定时任务的代码,逃过算力惩罚。

最终在lotus库的chain/vm/runtime.go里面,会捕获异常进行处理:

defer函数里面会打印出相关的错误,然后继续执行下一次任务的调用。当前的cron定时任务没有完成,如何处理?都崩溃了,还能干吗?一切随风,相忘于江湖。

至于怎么构造有问题的扇区,就相对比较容易了。从条件terminationType != power.SectorTerminationExpired得知,需要有“过期”的扇区,但扇区参数中的Expiration是矿工自己传到链的,随便他怎么设置,只要躲过下面这个检查即可:

到执行cron定时任务的高度,发现当前矿工刚好有“过期”的扇区,就会触发直接使用未初始化的变量的Bug,于是导致定时任务终止。

这个漏洞利用得比较巧妙,下一个证明周期,就可以避免算力丢失的情况。因为它是specs-actors里的代码,所以能躲过每个矿工的验证。

随着代码的完善,以及社区的积极贡献,但我们相信这样的漏洞会越来越少。如果协议实验室能学习微软、谷歌、苹果等制定漏洞悬赏计划,我想Filecoin会越来越安全。至于找到0day漏洞的奖励?也许给FIL就可以了,羊毛出在羊身上,奖励出在公链上。

九阳真经:Window PoSt和算力恢复

自然,最佳方式就是让Window PoSt能提交成功,且可以把以前出错的扇区恢复。Filecoin实现了相关的错误恢复机制。只要出错的扇区不要经历太久的时间,对它提交DeclareFaultsRecovered的消息,再经过一次Window PoSt,算力是能够被恢复的。

这张图是我们跑的小规模集群的算力。具体内容请参考t01024节点——距离程序员最近的Filecoin矿场。这几天反复调试,提交和修复一些Bug并做相关验证,算力掉得有点惨不忍睹,超过80%的扇区出错,仅仅只有可怜的3TiB算力:

但通过修复后的代码,来了一次Window PoSt提交去,全部算力恢复:

证明这块的框架,储迅改动较大(针对集群做了优化),无法简单描述。但我们也提交了一些基本的改动,主要是修复一些常见的错误,比如超过2349个扇区,Window PoSt不能正常提交的问题:

整个恢复过程中用到的一些算法和技术细节,我们后面会逐渐公布。

对于Filecoin运维,我们希望做到:尽量避免错误,如果真的遇到了问题也尽全力恢复。此过程其实是没有什么魔法的。所谓的黑科技,一切都是来源于对每一行代码的深入解读和永远不停止的工程实践。

本文所接的代码,基于:

https://github.com/filecoin-project/specs-actors的v0.5.3 Tag,Commit ID为eac38c1d153cb985fa147c97113b28718361c90b。

https://github.com/filecoin-project/lotus的master分支,Commit ID为0d3f602d58ebb05943943a85d858d45566433964。

—-

编译者/作者:储迅

玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

LOADING...
LOADING...