1. 首页
  2. 新闻资讯

Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。

Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。在Winning PoSt中,我们证明在生成块时已提交的部门数据。定期验证提交的部门数据,以确保正确保存数据。本文将详细介绍WindowPoSt逻辑。要了解Window PoSt,我们需要从管理智能合约中的部门开始。以下是本文中使用的智能合约(specs-actors)最后提交的信息:commit 382017dd33e9e818a51503893433628fab643dd3
Author: Alex North 445306+anorth@users.noreply.github.com
Date: Wed May 6 10:08:31 2020 +1000Set ConsensusMinerMinPower to 10TiB (#344)

矿工州
矿工的财产信息,抵押信息和部门状态保存在矿工状态中。我们选择与WindowPoSt相关的代码片段:
type State struct {

ProvingPeriodStart abi.ChainEpoch
NewSectors *abi.BitField
Deadlines cid.Cid

}
ProvingPeriodStart-每个验证周期的开始时间。NewSectors —新区块的信息截止时间-每个挑战窗口都分为多个窗口。每个窗口都有一个截止日期。这就是WindowPoSt取名的地方。1.1 验证期WindowPoSt的配置规范在specs-actors / actors / builtin / miner / policy.go中定义。
const EpochDurationSeconds = 25
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中定义:
type DeadlineInfo struct {
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:
func ComputeProvingPeriodDeadline(periodStart, currEpoch abi.ChainEpoch) *DeadlineInfo {
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调整证明开始时间创建矿工的智能合约时,将初始化证明的开始时间。
offset, err := assignProvingPeriodOffset(rt.Message().Receiver(), currEpoch, rt.Syscalls().HashBlake2b)
periodStart := nextProvingPeriodStart(currEpoch,AssignProvingPeriodOffset,通过函数HashBlake2b在[0,WPoStProvingPeriod]中随机生成偏移量。函数nextProvingPeriodStart如下所示:
func nextProvingPeriodStart(currEpoch abi.ChainEpoch, offset abi.ChainEpoch) abi.ChainEpoch {
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
}
简单地说,该函数查找具有给定偏移量的下一个证明开始时间。在我们知道证明开始时间之后,未成年人的智能合约会在每个证明期结束时检查证明状态,并更新证明开始时间。
func handleProvingPeriod(rt Runtime) {

if deadline.PeriodStarted() {
st.ProvingPeriodStart = st.ProvingPeriodStart + WPoStProvingPeriod
}

err = st.ClearPoStSubmissions()

}
2.2更新行业信息在矿工的智能合约中,NewSectors通过三个界面进行更新:Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。verifyCommitSector:在提交PoREPommi的同时向NewSectors添加新的部门信息。TerminateSector:从NewSectors中删除Sector信息。handleProvingPeriod:定期将NewSectors信息“分配”到截止日期。换句话说,此功能维护需要在矿工的智能合约中证明的所有部门的列表。它在每个windowPoSt的开始将扇区分配给不同的Windows。

部门分配
使用功能AssignNewSectors,我们将需要验证的扇区分配到不同的Windows(截止日期):
func AssignNewSectors(deadlines *Deadlines, partitionSize uint64, newSectors []uint64, seed abi.Randomness) error {
请注意,partitionSize是一个分区中的扇区数:
func (p RegisteredProof) WindowPoStPartitionSectors() (uint64, error) {

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中。这意味着在一个窗口中可以有多个扇形分区单位。要特别注意输入变量种子。尽管该功能试图随机化扇区分配,但是尚未实现。

WindowPoSt证明分派

Lotus项目中WindowPoSt的校对逻辑。以下是本文中使用的Lotus源代码的最后一次提交中的信息:
commit 10fe6084f1374891a6666fad61b9c3aa448b4554
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调度逻辑流程图如下:
Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。
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证明
在基本了解过程逻辑之后,我们最终来看看如何在WindowPoSt中生成证明。这些逻辑以rust-fil-proof或rust形式实现。从防锈到防锈,我们会遇到很多接口:Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。在这里,我们跳过中间接口,直接使用rust-fil-proofs中的接口功能。
pub fn generate_window_post Tree: static + MerkleTreeTrait (
post_config: PoStConfig,
randomness: ChallengeSeed,
replicas: BTreeMap SectorId, PrivateReplicaInfo ,
prover_id: ProverId,
) – Result{
这里的post_config表示PoStConfig(configuration)。随机性是随机信息,用于生成部门上质询的叶子数据。副本是WindowPoSt证明中生成的所有扇区的对应副本数据。

PoStConfig
PoStConfig在rust-filecoin-proofs-api/src/ registry.rs中定义:
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:
pub const WINDOW_POST_CHALLENGE_COUNT: usize = 10;pub static ref WINDOW_POST_SECTOR_COUNT: RwLock HashMap = RwLock::new(
[
(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):
let inclusion_proofs = (0..pub_params.challenge_count)
.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根据随机信息,扇区索引和质询索引生成叶子索引。
let mut hasher = Sha256::new();
hasher.input(AsRef:: [u8] ::as_ref( randomness));
hasher.input( sector_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中分区大小的计数不是一。计算方法如下:
let partitions = get_partitions_for_window_post(replicas.len(), post_config);fn get_partitions_for_window_post(
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——
Lotus提供的PoSt算法有两种方案:Winning PoSt和Window PoSt。
声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。

原创文章,作者:admin,如若转载,请注明出处:https://www.369ok.com/13156.html

联系我们

171-8118-8815

在线咨询:点击这里给我发消息

邮件:zyw30520@qq.com

工作时间:8:00-23:00,全年不休息

QR code