Filecoin解读|Window PoST是什么?
Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。在Winning PoSt中,我们证明在生成块时已提交的部门数据。定期验证提交的部门数据,以确保正确保存数据。
本文将详细介绍WindowPoSt逻辑。
要了解Window PoSt,我们需要从管理智能合约中的部门开始。
以下是本文中使用的智能合约(specs-actors)最后提交的信息:
Author: Alex North<445306+anorth@users.noreply.github.com>
Date: Wed May 6 10:08:31 2020 +1000Set ConsensusMinerMinPower to 10TiB (#344)
矿工的财产信息,抵押信息和部门状态保存在矿工状态中。我们选择与WindowPoSt相关的代码片段:
...
ProvingPeriodStart abi.ChainEpoch
NewSectors *abi.BitField
Deadlines cid.Cid
...
}
ProvingPeriodStart-每个验证周期的开始时间。
NewSectors —新区块的信息
截止时间-每个挑战窗口都分为多个窗口。每个窗口都有一个截止日期。这就是WindowPoSt取名的地方。
1.1 验证期
WindowPoSt的配置规范在specs-actors / actors / builtin / miner / policy.go中定义。
const SecondsInYear = 31556925
const SecondsInDay = 86400
const WPoStProvingPeriod = abi.ChainEpoch(SecondsInDay / EpochDurationSeconds)const WPoStChallengeWindow = abi.ChainEpoch(1800 / EpochDurationSeconds) // Half an hour (=48 per day)
const WPoStPeriodDeadlines = uint64(WPoStProvingPeriod / WPoStChallengeWindow)
const WPoStChallengeLookback = abi.ChainEpoch(20)
WPoStProvingPeriod —验证周期。每天需要证明一次。
WPoStChallengeWindow — ChallengeWindow为半小时。每个验证期分为47个ChallegeWindow。
WPoStPeriodDeadlines — ChallengeWindow的结尾。
WPoStChallengeLookback —从链中获取随机数据量并在每个ChallegeWindow中回顾先前块的时间。
总而言之,WindowPoSt的期限为一天,每个WindowPoSt分为48个窗口。扇区信息在窗口的不同时间段中有所不同。每个窗口都需要WindowPoSt提供的证明,并且窗口中的扇区数量决定了需要多少个证明。详细的逻辑将稍后介绍。
1.2截止日期
截止日期在specs-actor / actors / builtin / miner / deadlines.go中定义:
CurrentEpoch abi.ChainEpoch // Epoch at which this info was calculated.
PeriodStart abi.ChainEpoch // First epoch of the proving period (<= CurrentEpoch).
Index uint64 // Current deadline index, in [0..WPoStProvingPeriodDeadlines), or WPoStProvingPeriodDeadlines if period elapsed.
Open abi.ChainEpoch // First epoch from which a proof may be submitted, inclusive (>= CurrentEpoch).
Close abi.ChainEpoch // First epoch from which a proof may no longer be submitted, exclusive (>= Open).
Challenge abi.ChainEpoch // Epoch at which to sample the chain for challenge (< Open).
FaultCutoff abi.ChainEpoch // First epoch at which a fault declaration is rejected (< Open).
}
CurrentEpoch-当前截止时间。
PeriodStart —每个证明的开始冻结时间。
索引—截止日期(又名窗口)的索引。范围从0到47。
开放-在此窗口中允许提交证据的最早时间。
关闭-在此窗口中允许的最新时间或提交证据。
质询-此窗口中随机数的范围。
FaultCutoff-错误块只能在此截止块时间之前确定。
函数ComputeProvingPeriodDeadline在给定证明开始时间和当前块时间的情况下计算Deadline:
periodProgress := currEpoch - periodStart
...
deadlineIdx := uint64(periodProgress / WPoStChallengeWindow)
if periodProgress < 0 { // Period not yet started.
deadlineIdx = 0
}
deadlineOpen := periodStart + (abi.ChainEpoch(deadlineIdx) * WPoStChallengeWindow)
return &DeadlineInfo{
CurrentEpoch: currEpoch,
PeriodStart: periodStart,
Index: deadlineIdx,
Open: deadlineOpen,
Close: deadlineOpen + WPoStChallengeWindow,
Challenge: deadlineOpen - WPoStChallengeLookback,
FaultCutoff: deadlineOpen - FaultDeclarationCutoff,
}
}
我们可以从当前块时间和开始时间获取deadlienIdx。使用该索引,将更容易获得其他变量。
WindowPoSt状态逻辑中有两个部分:调整每个windowPoSt证明的开始时间,以及更新需要证明的Sector信息。
2.1调整证明开始时间
创建矿工的智能合约时,将初始化证明的开始时间。
periodStart := nextProvingPeriodStart(currEpoch,
AssignProvingPeriodOffset,通过函数HashBlake2b在[0,WPoStProvingPeriod]中随机生成偏移量。
函数nextProvingPeriodStart如下所示:
currModulus := currEpoch % WPoStProvingPeriod
var periodProgress abi.ChainEpoch // How far ahead is currEpoch from previous offset boundary.
if currModulus >= offset {
periodProgress = currModulus - offset
} else {
periodProgress = WPoStProvingPeriod - (offset - currModulus)
}
periodStart := currEpoch - periodProgress + WPoStProvingPeriod
Assert(periodStart > currEpoch)
return periodStart
}
简单地说,该函数查找具有给定偏移量的下一个证明开始时间。
在我们知道证明开始时间之后,未成年人的智能合约会在每个证明期结束时检查证明状态,并更新证明开始时间。
...
if deadline.PeriodStarted() {
st.ProvingPeriodStart = st.ProvingPeriodStart + WPoStProvingPeriod
}
...
err = st.ClearPoStSubmissions()
...
}
2.2更新行业信息
在矿工的智能合约中,NewSectors通过三个界面进行更新:
verifyCommitSector:在提交PoREPommi的同时向NewSectors添加新的部门信息。
TerminateSector:从NewSectors中删除Sector信息。
handleProvingPeriod:定期将NewSectors信息“分配”到截止日期。换句话说,此功能维护需要在矿工的智能合约中证明的所有部门的列表。它在每个windowPoSt的开始将扇区分配给不同的Windows。
使用功能AssignNewSectors,我们将需要验证的扇区分配到不同的Windows(截止日期):
请注意,partitionSize是一个分区中的扇区数:
...
case RegisteredProof_StackedDRG32GiBSeal:
return 2349, nil
case RegisteredProof_StackedDRG2KiBSeal:
return 2, nil
case RegisteredProof_StackedDRG8MiBSeal:
return 2, nil
case RegisteredProof_StackedDRG512MiBSeal:
return 2, nil
default:
return 0, errors.Errorf("unsupported proof type: %v", p)
...
}
对于32 GB的扇区,分区大小为2349。
AssignNewSectors中有2个步骤:
1、填充每个窗口,直到扇区数达到partitionSize。
2、如果步骤1/之后还有剩余的扇区,则根据partitionSize为每个窗口相应地分配它们。
总结扇区分配,将partitionSize作为一个单位,并将其分配到每个Window中。这意味着在一个窗口中可以有多个扇形分区单位。要特别注意输入变量种子。尽管该功能试图随机化扇区分配,但是尚未实现。
Lotus项目中WindowPoSt的校对逻辑。以下是本文中使用的Lotus源代码的最后一次提交中的信息:
Merge: 1d887b55 1831613f
Author: Łukasz Magiera
Date: Wed May 6 01:45:33 2020 +0200Merge pull request #1670 from filecoin-project/feat/update-markets-0.2.0
Update go-fil-markets
完整的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,
randomness: &ChallengeSeed,
replicas: &BTreeMap<SectorId, PrivateReplicaInfo
prover_id: ProverId,
) -> Result
这里的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:
[
(SECTOR_SIZE_2_KIB, 2),
(SECTOR_SIZE_4_KIB, 2),
(SECTOR_SIZE_16_KIB, 2),
(SECTOR_SIZE_32_KIB, 2),
(SECTOR_SIZE_8_MIB, 2),
(SECTOR_SIZE_16_MIB, 2),
(SECTOR_SIZE_512_MIB, 2),
(SECTOR_SIZE_1_GIB, 2),
(SECTOR_SIZE_32_GIB, 2349), // this gives 133,977,564 constraints, fitting just in a single partition
(SECTOR_SIZE_64_GIB, 2300), // this gives 131,182,800 constraints, fitting just in a single partition
]
.iter()
.copied()
.collect()
);
例如,当挑战数为10时,分区的2349个扇区组成,每个扇区的大小为32 GB。
5.2产生挑战
每个部门包含10个挑战叶子。
这是它的计算方式(storage-proofs/post/src/fallback/vanilla.rs中的函数prove_all_partitions):
.into_par_iter()
.map(|n| {
let challenge_index = ((j * num_sectors_per_chunk + i)
* pub_params.challenge_count
+ n) as u64;
let challenged_leaf_start = generate_leaf_challenge(
pub_params,
pub_inputs.randomness,
sector_id.into(),
challenge_index,
)?;tree.gen_cached_proof(challenged_leaf_start as usize, levels)
})
.collect::<Result<Vec<_>>>()?;
Challenge_index是所有部门需要证明的挑战的索引。generate_leaf_challenge根据随机信息,扇区索引和质询索引生成叶子索引。
hasher.input(AsRef::<[u8]>::as_ref(&randomness));
hasher.input(§or_id.to_le_bytes()[..]);
hasher.input(&leaf_challenge_index.to_le_bytes()[..]);
let hash = hasher.result();let leaf_challenge = LittleEndian::read_u64(&hash.as_ref()[..8]);let challenged_range_index = leaf_challenge % (pub_params.sector_size / NODE_SIZE as u64);
然后,我们对随机数据,扇区ID和质询叶索引使用哈希函数。对结果和叶子总数取mod。对于32 GB的Sector,我们获得16 GB的叶子。
5.3零知识证明电路
除了不同的变量外,此处提到的电路逻辑与WinningPoSt电路相同。
要特别注意WindowPoSt中分区大小的计数不是一。计算方法如下:
total_sector_count: usize,
post_config: &PoStConfig,
) -> Option
let partitions = (total_sector_count as f32 / post_config.sector_count as f32).ceil() as usize;if partitions > 1 {
Some(partitions)
} else {
None
}
}
简而言之,分区数是副本数除以每个分区中的扇区数(2349)。
总结一下,证明的数量(分区)与需要证明的扇区数有关,并且等于副本数除以2349。在每个分区的证明中,将从每个扇区中提取10个叶节点。
WindowPoSt定期证明所提交的扇区数据中是否存在。每个验证期需要一天。一个时期包括48个窗口。每个窗口需要30分钟。
所有Windows都需要WindowPoSt证明计算。证明数量等于窗口中扇区的数量除以分区中扇区的数量。为了证明分区,我们从分区的每个扇区中绘制了10个叶节点。
——End——
声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。
-
选择去中心化存储与Filecoin几大理由(上)
2022-05-18 filecoin -
【图说100问·Filecoin】第62问:什么是网络基线?
2021-04-04 filecoin -
Filecoin 中的信誉系统
2021-02-19 filecoin -
Filecoin上演大逃亡?投资者:冲高之后就开空
2020-10-15 filecoin -
千年鸽王 Filecoin 终于要上线!它其实是个国产项目
2020-10-15 filecoin
更多 推荐专栏
- 吴说区块链
- 知名自媒体,作者曾获中国新闻奖。为您提供加密行业、科技公司独家可靠的信息与观点。
- 挖币网评测
- 挖币网专业测评
- 区块鲁班
- 元宇宙工程师——区块鲁班,是一个具备全球化服务能力的公司品牌。提供矿机采购、维修、测试、托管、运维、出口等一站式服务。我们与比特大陆、比特微、嘉楠国际、芯动科技等全球头部矿机生产厂家建立了良好的合作关系,共同开创矿机国际化服务标准,并携手在全球布局矿机服务中心,为全球加密货币行业参与者提供专业、高效、全面的解决方案。
- HashPool
- 多币种数字货币矿池,关注最新最有潜力币种 HashPool 链接每一个算力
- 巴比特资讯
- 巴比特是国内领先的区块链信息服务商,以价值投资为导向,为区块链创新者服务。 我们以论坛启锚远征,让资讯为瞭望景观,聚集区块链技术和应用弄潮儿。目前已发展成集资讯内容、线下活动、培训、孵化器、投资和区块链技术落地应用于一体的生态体平台。全网覆盖用户超100万人,遍及中国大陆、韩国,日本,美国,香港等国家和地区。