Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。在Winning PoSt中,我们证明在生成块时已提交的部门数据。定期验证提交的部门数据,以确保正确保存数据。
本文将详细介绍WindowPoSt逻辑。
要了解Window PoSt,我们需要从管理智能合约中的部门开始。
以下是本文中使用的智能合约(specs-actors)最后提交的信息:
矿工的财产信息,抵押信息和部门状态保存在矿工状态中。我们选择与WindowPoSt相关的代码片段:
ProvingPeriodStart-每个验证周期的开始时间。
NewSectors —新区块的信息
截止时间-每个挑战窗口都分为多个窗口。每个窗口都有一个截止日期。这就是WindowPoSt取名的地方。
1.1 验证期
WindowPoSt的配置规范在specs-actors / actors / builtin / miner / policy.go中定义。
WPoStProvingPeriod —验证周期。每天需要证明一次。
WPoStChallengeWindow — ChallengeWindow为半小时。每个验证期分为47个ChallegeWindow。
WPoStPeriodDeadlines — ChallengeWindow的结尾。
WPoStChallengeLookback —从链中获取随机数据量并在每个ChallegeWindow中回顾先前块的时间。
总而言之,WindowPoSt的期限为一天,每个WindowPoSt分为48个窗口。扇区信息在窗口的不同时间段中有所不同。每个窗口都需要WindowPoSt提供的证明,并且窗口中的扇区数量决定了需要多少个证明。详细的逻辑将稍后介绍。
1.2截止日期
截止日期在specs-actor / actors / builtin / miner / deadlines.go中定义:
CurrentEpoch-当前截止时间。
PeriodStart —每个证明的开始冻结时间。
索引—截止日期(又名窗口)的索引。范围从0到47。
开放-在此窗口中允许提交证据的最早时间。
关闭-在此窗口中允许的最新时间或提交证据。
质询-此窗口中随机数的范围。
FaultCutoff-错误块只能在此截止块时间之前确定。
函数ComputeProvingPeriodDeadline在给定证明开始时间和当前块时间的情况下计算Deadline:
我们可以从当前块时间和开始时间获取deadlienIdx。使用该索引,将更容易获得其他变量。
WindowPoSt状态逻辑中有两个部分:调整每个windowPoSt证明的开始时间,以及更新需要证明的Sector信息。
2.1调整证明开始时间
创建矿工的智能合约时,将初始化证明的开始时间。
AssignProvingPeriodOffset,通过函数HashBlake2b在[0,WPoStProvingPeriod]中随机生成偏移量。
函数nextProvingPeriodStart如下所示:
简单地说,该函数查找具有给定偏移量的下一个证明开始时间。
在我们知道证明开始时间之后,未成年人的智能合约会在每个证明期结束时检查证明状态,并更新证明开始时间。
2.2更新行业信息
在矿工的智能合约中,NewSectors通过三个界面进行更新:
verifyCommitSector:在提交PoREPommi的同时向NewSectors添加新的部门信息。
TerminateSector:从NewSectors中删除Sector信息。
handleProvingPeriod:定期将NewSectors信息“分配”到截止日期。换句话说,此功能维护需要在矿工的智能合约中证明的所有部门的列表。它在每个windowPoSt的开始将扇区分配给不同的Windows。
使用功能AssignNewSectors,我们将需要验证的扇区分配到不同的Windows(截止日期):
请注意,partitionSize是一个分区中的扇区数:
对于32 GB的扇区,分区大小为2349。
AssignNewSectors中有2个步骤:
1、填充每个窗口,直到扇区数达到partitionSize。
2、如果步骤1/之后还有剩余的扇区,则根据partitionSize为每个窗口相应地分配它们。
总结扇区分配,将partitionSize作为一个单位,并将其分配到每个Window中。这意味着在一个窗口中可以有多个扇形分区单位。要特别注意输入变量种子。尽管该功能试图随机化扇区分配,但是尚未实现。
Lotus项目中WindowPoSt的校对逻辑。以下是本文中使用的Lotus源代码的最后一次提交中的信息:
完整的WindowPoSt调度逻辑流程图如下:
WindowPoStScheduler:侦听链上的状态。它尝试在新的块高度处执行doPoSt。doPoSt分为两部分:在wunPoSt运行时生成的WindowPoSt证明(来自rust-fil-proofs的输出),以及将证明推向链条的SubmitPoSt。一个证明期内的所有证明都将记录在链中。handleProvingPeriod:在每个周期结束时,浏览所有Windows中的所有证明状态。
作为本课程到目前为止所涵盖内容的摘要:
1、一个证明期需要一天。一个时期分为48个窗口。每个窗口需要30分钟。
2、每个窗口都有其截止日期(为了正确提交证明而被截断)。
3、现有分区将基于partitionSize(2349扇区)进行分配,以填充每个窗口。如果分配后还有剩余的扇区,请继续使用partitionSize单位填充Windows。
如果扇区大小为32GB,则为2349个扇区,即73T。如果每个窗口包含一个扇区分区,则总存储空间将为:73T * 48 = 2.25P。也就是说,对于4.5P的存储空间,每个窗口将包含2个扇区分区。
存储数据越多,部门将越多,Windows占用的空间也越多。因此,这导致这种计算更多的时间复杂度。
在基本了解过程逻辑之后,我们最终来看看如何在WindowPoSt中生成证明。这些逻辑以rust-fil-proof或rust形式实现。从防锈到防锈,我们会遇到很多接口:
在这里,我们跳过中间接口,直接使用rust-fil-proofs中的接口功能。
这里的post_config表示PoStConfig(configuration)。
随机性是随机信息,用于生成部门上质询的叶子数据。副本是WindowPoSt证明中生成的所有扇区的对应副本数据。
pub fn as_v1_config(self) -> PoStConfig {
match self {
...
StackedDrgWindow2KiBV1
| StackedDrgWindow8MiBV1
| StackedDrgWindow512MiBV1
| StackedDrgWindow32GiBV1 => PoStConfig {
typ: self.typ(),
sector_size: self.sector_size(),
sector_count: self.sector_count(),
challenge_count: constants::WINDOW_POST_CHALLENGE_COUNT,
priority: true,
}, // _ => panic!("Can only be called on V1 configs"),
}
}
请注意,在rust-fil-proofs/filecoin-proofs / src / constants.rs中定义了ector_count和challenge_count:
例如,当挑战数为10时,分区的2349个扇区组成,每个扇区的大小为32 GB。
5.2产生挑战
每个部门包含10个挑战叶子。
这是它的计算方式(storage-proofs/post/src/fallback/vanilla.rs中的函数prove_all_partitions):
Challenge_index是所有部门需要证明的挑战的索引。generate_leaf_challenge根据随机信息,扇区索引和质询索引生成叶子索引。
然后,我们对随机数据,扇区ID和质询叶索引使用哈希函数。对结果和叶子总数取mod。对于32 GB的Sector,我们获得16 GB的叶子。
5.3零知识证明电路
除了不同的变量外,此处提到的电路逻辑与WinningPoSt电路相同。
要特别注意WindowPoSt中分区大小的计数不是一。计算方法如下:
简而言之,分区数是副本数除以每个分区中的扇区数(2349)。
总结一下,证明的数量(分区)与需要证明的扇区数有关,并且等于副本数除以2349。在每个分区的证明中,将从每个扇区中提取10个叶节点。
WindowPoSt定期证明所提交的扇区数据中是否存在。每个验证期需要一天。一个时期包括48个窗口。每个窗口需要30分钟。
所有Windows都需要WindowPoSt证明计算。证明数量等于窗口中扇区的数量除以分区中扇区的数量。为了证明分区,我们从分区的每个扇区中绘制了10个叶节点。
——End——
声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。