17

Filecoin – winningPoSt逻辑介绍

 4 years ago
source link: https://www.lianyi.com/zixun/2600443
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Lotus的PoSt的部分从electionPoSt变成两种新的PoSt,一种是winningPoSt,一种是windowPoSt。先讲讲winningPoSt吧。winningPoSt,顾名思义,在winning的时候进行的PoSt。所谓的winning,也就是获取出块权。

简单的说,winningPoSt,随机抽查的一个sector,该sector中的66条随机抽查的merkle path都正确。代码逻辑从Lotus的go的代码说起。一切从出块开始 – lotus/miner/miner.go的Miner结构的mineOne函数。

func (m *Miner) mineOne(ctx context.Context, addr address.Address, base *MiningBase) (*types.BlockMsg, error) {

mbi, err := m.api.MinerGetBaseInfo(ctx, addr, round, base.TipSet.Key())

rand, err := m.api.ChainGetRandomness(ctx, base.TipSet.Key(), crypto.DomainSeparationTag_WinningPoStChallengeSeed, base.TipSet.Height()+base.NullRounds, nil)

prand := abi.PoStRandomness(rand)

postProof, err := m.epp.ComputeProof(ctx, mbi.Sectors, prand)

其中,MinerGetBaseInfo函数是获取一些基本信息,其中包括需要抽取的sector信息。ComputeProof函数就是计算winningPoSt证明。

因为这些逻辑的具体实现是在rust-fil-proofs,也就是rust语言实现的。从go到rust-fil-proofs,跨越了不少接口:

q6NFzyA.jpg!web

中间的接口就不介绍了,直接看rust-fil-proofs提供的两个API函数。

1. 抽查个数设置

Sector个数以及总的抽查的叶子个数的定义在rust-fil-proofs/filecoin-proofs/src/constants.rs中:

pub const WINNING_POST_CHALLENGE_COUNT: usize = 66;

pub const WINNING_POST_SECTOR_COUNT: usize = 1;

也就是说,要从有效Sector中抽取一个Sector,并在这个Sector上抽查66个叶子节点。

2. Sector的抽查逻辑

generate_winning_post_sector_challenge函数实现了Sector的抽查逻辑。核心逻辑显然是如何抽查Sector?具体的逻辑在fallback::generate_sector_challenges的函数中:

let mut hasher = Sha256::new();

hasher.input(AsRef::<[u8]>::as_ref(&prover_id));

hasher.input(AsRef::<[u8]>::as_ref(&randomness));

hasher.input(&n.to_le_bytes()[..]);

let hash = hasher.result();

let sector_challenge = LittleEndian::read_u64(&hash.as_ref()[..8]);

let sector_index = sector_challenge % sector_set_len;

简单的说,就是把prover_id, 随机信息,抽查Sector的编号做sha256的hash计算,计算结果和当前有限的Sector个数取模。也就是sector_index就是最终抽查的Sector的id。

3. Challenge的叶子抽查逻辑

generate_winning_post在抽查的Sector形成的merkle树(replica_r_last)上,抽查叶子节点。抽查叶子节点的计算逻辑在fallback::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);

把随机信息,sector id和挑战叶子的编号进行hash计算。计算的结果和叶子的总个数取模。32G的Sector,叶子个数为1G个。

4. 零知识证明电路

零知识证明的计算部分可以查看rust-fil-proofs/post/fallback目录。大体的逻辑模块和结构可以查看之前的文章介绍:

Filecoin – PoREP电路介绍

讲讲rust-fil-proofs/post/fallback/circuit.rs中的Sector结构吧。这个结构就代表一个抽查。从synthesize函数可以看出:

// 1. Verify comm_r

let comm_r_last_num = num::AllocatedNum::alloc(cs.namespace(|| “comm_r_last”), || {

comm_r_last

.map(Into::into)

.ok_or_else(|| SynthesisError::AssignmentMissing)

})?;

let comm_c_num = num::AllocatedNum::alloc(cs.namespace(|| “comm_c”), || {

comm_c

.map(Into::into)

.ok_or_else(|| SynthesisError::AssignmentMissing)

})?;

let comm_r_num = num::AllocatedNum::alloc(cs.namespace(|| “comm_r”), || {

comm_r

.map(Into::into)

.ok_or_else(|| SynthesisError::AssignmentMissing)

})?;

comm_r_num.inputize(cs.namespace(|| “comm_r_input”))?;

comm_r作为public输入,其他comm_r_last和comm_c作为private输入。

// 1. Verify H(Comm_C || comm_r_last) == comm_r

{

let hash_num = ::Function::hash2_circuit(

cs.namespace(|| “H_comm_c_comm_r_last”),

&comm_c_num,

&comm_r_last_num,

)?;

// Check actual equality

constraint::equal(

cs,

|| “enforce_comm_c_comm_r_last_hash_comm_r”,

&comm_r_num,

&hash_num,

);

}

验证comm_r是否由comm_c和comm_r_last计算得到。

// 2. Verify Inclusion Paths

for (i, (leaf, path)) in leafs.iter().zip(paths.iter()).enumerate() {

PoRCircuit::<Tree>::synthesize(

cs.namespace(|| format!(“challenge_inclusion_{}”, i)),

Root::Val(*leaf),

path.clone(),

Root::from_allocated::<CS>(comm_r_last_num.clone()),

true,

)?;

}

验证从叶子节点是否可以正确计算出Merkle树根。

总结:

Lotus的PoSt包括两部分:winningPoSt和windowPoSt。winningPoSt是在获取出块权时,需要提供的PoSt证明。从所有有效的Sector中,抽取一个Sector,并抽查该Sector上的66个叶子。

根据国家《 关于防范代币发行融资风险的公告 》,大家应警惕代币发行融资与交易的风险隐患。

本文来自 LIANYI 转载,不代表链一财经立场,转载请联系原作者。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK