一、復制證明簡介
引用官方的解釋就是:“InordertoregisterasectorwiththeFilecoinnetwork,thesectorhastobesealed.Sealingisacomputation-heavyprocessthatproducesauniquerepresentationofthedataintheformofaproof,calledProof-of-ReplicationorPoRep.”簡單來說,復制證明就是在對扇區進行封裝的過程中生成的扇區唯一標識。
復制證明要用到三種特殊參數:數據本身、執行密封的礦工參與者、特定礦工密封特定數據的時間。一旦其中的一個參數發生變化,那么得到的復制證明結果將會完全不同。換句話說,如果同一個礦工稍后試圖密封相同的數據,那么這將導致不同的PoRep證明。
復制證明是一個很大的計算過程,接下來我將會分為兩部分:P1、P2,從代碼的形式給讀者介紹復制證明的工作原理。
二、P1代碼解析
在本次文章,我將主要介紹32GB封裝的P1的過程。在此階段,會發生PoRep的SDR編碼和復制。
因為是第一次,我這里提一句,扇區的不同狀態會觸發miner不同的執行方法,1.16版本可以看externstorage-sealingfsm.go文件約460行代碼內容,代碼中記錄了miner不同的狀態以及觸發方法。這里我只放P1狀態的代碼。
????????...
????????...
????????case?Packing:
????????????????return?m.handlePacking,?processed,?nil
????????case?GetTicket:
????????????????return?m.handleGetTicket,?processed,?nil
????????case?PreCommit1:
????????????????return?m.handlePreCommit1,?processed,?nil
????????case?PreCommit2:
????????????????return?m.handlePreCommit2,?processed,?nil
????????...
????????...
可以看到,PreCommit1調用的是handlePreCommit1方法,從下邊可以看出,利用SealPreCommit1方法得到P1結果。
func?(m?*Sealing)?handlePreCommit1(ctx?statemachine.Context,?sector?SectorInfo)?error?{
????????...
????????...
????????pc1o,?err?:=?m.sealer.SealPreCommit1(sector.sealingCtx(ctx.Context()),?m.minerSector(sector.SectorType,?sector.SectorNumber),?sector.TicketValue,?sector.pieceInfos())
????????if?err?!=?nil?{
????????????????return?ctx.Send(SectorSealPreCommit1Failed{xerrors.Errorf("seal?pre?commit(1)?failed:?%w",?err。)
????????}
????????return?ctx.Send(SectorPreCommit1{
????????????????PreCommit1Out:?pc1o,
????????})
}
讓我們深入看一下SealPreCommit1方法,這里我們最終調用的是:func(sb*Sealer)SealPreCommit1(...)方法。方法中有我們常常遇到的方法:AcquireSector(...)、Unpadded()。
AcquireSector方法是根據傳入的類型與sectorID一起,組合成對應的path。
Uppadded方法是返回一個Piece的未填充大小,以字節為單位,計算公式是:s-(s/128)。有未填充大小,自然就有填充大小,填充大小的計算方法為Padded(),計算公式是:s+(s/127)
func?(sb?*Sealer)?SealPreCommit1(ctx?context.Context,?sector?storage.SectorRef,?ticket?abi.SealRandomness,?pieces?abi.PieceInfo)?(out?storage.PreCommit1Out,?err?error)?{
????????paths,?done,?err?:=?sb.sectors.AcquireSector(ctx,?sector,?storiface.FTUnsealed,?storiface.FTSealed|storiface.FTCache,?storiface.PathSealing)
????????if?err?!=?nil?{
????????????????return?nil,?xerrors.Errorf("acquiring?sector?paths:?%w",?err)
????????}
????????...
????????...
????????...
????????var?sum?abi.UnpaddedPieceSize
????????for?_,?piece?:=?range?pieces?{
????????????????sum?+=?piece.Size.Unpadded()
????????}
????????//?根據扇區證明類型獲取扇區大小
????????ssize,?err?:=?sector.ProofType.SectorSize()
US3R Network發布Web3動態數據基礎設施:4月11日消息,US3R Network 近日宣布推出其用于 Web3 的鏈下數據基礎設施。Web3 和 dApps 領域正在快速增長,但目前 dApps 主要用于金融和金融科技,數據存儲限于靜態文件,與 Web2 數據庫相比,鏈上存儲動態數據昂貴且緩慢,難以開發數據量大的社交和用戶生成數據 (UGC) 場景。[2023/4/12 13:57:45]
????????if?err?!=?nil?{
????????????????return?nil,?err
????????}
????????//?這里比較一次總piece大小和要求的扇區大小是否一致
????????ussize?:=?abi.PaddedPieceSize(ssize).Unpadded()
????????if?sum?!=?ussize?{
????????????????return?nil,?xerrors.Errorf("aggregated?piece?sizes?don't?match?sector?size:?%d?!=?%d?(%d)",?sum,?ussize,?int64(ussize-sum))
????????}
????????//?TODO:?context?cancellation?respect
????????p1o,?err?:=?ffi.SealPreCommitPhase1(
????????????????sector.ProofType,
????????????????paths.Cache,
????????????????paths.Unsealed,
????????????????paths.Sealed,
????????????????sector.ID.Number,
????????????????sector.ID.Miner,
????????????????ticket,
????????????????pieces,
????????)
????????...
????????...
}
接下來,一切準備就緒,我們將要開始我們的P1遠游了,因為接下來的代碼都不屬于lotus,上面方法中我們可以看到ffi.SealPreCommitPhase1,ffi其實使用的是https://github.com/filecoin-project/filecoin-ffi庫,我們通過這個庫的如下方法,轉入rust語言去實現P1。
func?SealPreCommitPhase1(registeredProof?RegisteredSealProof,?cacheDirPath?SliceRefUint8,?stagedSectorPath?SliceRefUint8,?sealedSectorPath?SliceRefUint8,?sectorId?uint64,?proverId?*ByteArray32,?ticket?*ByteArray32,?pieces?SliceRefPublicPieceInfo)?(byte,?error)?{
????????resp?:=?C.seal_pre_commit_phase1(registeredProof,?cacheDirPath,?stagedSectorPath,?sealedSectorPath,?C.uint64_t(sectorId),?proverId,?ticket,?pieces)
????????defer?resp.destroy()
????????if?err?:=?CheckErr(resp);?err?!=?nil?{
????????????????return?nil,?err
????????}
????????return?resp.value.copy(),?nil
}
C庫其實就是ffi庫自身的rust庫,調用的方法如下所示:
fn?seal_pre_commit_phase1(
????registered_proof:?RegisteredSealProof,
????cache_dir_path:?c_slice::Ref<u8>,
????staged_sector_path:?c_slice::Ref<u8>,
????sealed_sector_path:?c_slice::Ref<u8>,
????sector_id:?u64,
????prover_id:?&,
????ticket:?&,
????pieces:?c_slice::Ref<PublicPieceInfo>,
)?->?repr_c::Box<SealPreCommitPhase1Response>?{
????catch_panic_response("seal_pre_commit_phase1",?||?{
????????let?public_pieces:?Vec<PieceInfo>?=?pieces.iter().map(Into::into).collect();
????????let?result?=?seal::seal_pre_commit_phase1(
????????????registered_proof.into(),
????????????as_path_buf(&cache_dir_path)?,
????????????as_path_buf(&staged_sector_path)?,
????????????as_path_buf(&sealed_sector_path)?,
????????????*prover_id,
????????????SectorId::from(sector_id),
Paxos:現有的BUSD至少在2024年2月之前仍然得到充分支持和贖回:2月13日消息,Paxos表示,現有的BUSD至少在2024年2月之前仍然得到充分支持和贖回。[2023/2/13 12:04:23]
????????????*ticket,
????????????&public_pieces,
????????)?;
????????let?result?=?serde_json::to_vec(&result)?;
????????Ok(result.into_boxed_slice().into())
????})
}
上面的seal庫是:https://github.com/filecoin-project/rust-filecoin-proofs-api。在這個方法對應的文件中,我們可以看到很多方法都對應了一個*__inner方法。實際上seal_pre_commit_phase1只是做了個中轉。我們可以直接看seal_pre_commit_phase1_inner方法
pub?fn?seal_pre_commit_phase1<R,?S,?T>(
????registered_proof:?RegisteredSealProof,
????cache_path:?R,
????in_path:?S,
????out_path:?T,
????prover_id:?ProverId,
????sector_id:?SectorId,
????ticket:?Ticket,
????piece_infos:?&,
)?->?Result<SealPreCommitPhase1Output>
where
????R:?AsRef<Path>,
????S:?AsRef<Path>,
????T:?AsRef<Path>,
{
????ensure!(
????????registered_proof.major_version()?==?1,
????????"unusupported?version"
????);
????with_shape!(
????????u64::from(registered_proof.sector_size()),
????????seal_pre_commit_phase1_inner,
????????registered_proof,
????????cache_path.as_ref(),
????????in_path.as_ref(),
????????out_path.as_ref(),
????????prover_id,
????????sector_id,
????????ticket,
????????piece_infos
????)
}
在inner方法中,filecoin_proofs_v1::seal_pre_commit_phase1,會調用證明子系統的實現部分。filecoin_proofs_v1使用的庫是:https://github.com/filecoin-project/rust-fil-proofs。
fn?seal_pre_commit_phase1_inner<Tree:?'static?+?MerkleTreeTrait>(
????registered_proof:?RegisteredSealProof,
????cache_path:?&Path,
????in_path:?&Path,
????out_path:?&Path,
????prover_id:?ProverId,
????sector_id:?SectorId,
????ticket:?Ticket,
????piece_infos:?&,
)?->?Result<SealPreCommitPhase1Output>?{
????let?config?=?registered_proof.as_v1_config();
????let?output?=?filecoin_proofs_v1::seal_pre_commit_phase1::<_,?_,?_,?Tree>(
????????config,
????????cache_path,
????????in_path,
????????out_path,
????????prover_id,
????????sector_id,
????????ticket,
????????piece_infos,
????)?;
????let?filecoin_proofs_v1::types::SealPreCommitPhase1Output::<Tree>?{
????????labels,
????????config,
????????comm_d,
????}?=?output;
????Ok(SealPreCommitPhase1Output?{
????????registered_proof,
????????labels:?Labels::from_raw::<Tree>(registered_proof,?&labels)?,
CZ:幣安已將用戶安全資產基金再次充值至10億美元等值:11月9日消息,幣安創始人趙長鵬(CZ)發推稱,為了適應最近的價格波動,幣安已將用戶安全資產基金(SAFU)再次充值至10億美元等值,BUSD和BNB地址約7億美元,BTC地址約3億美元。
注,用戶安全資產基金(SAFU)是幣安于2018年7月為保障用戶資金安全而設立的應急保險基金。該基金成立時,幣安承諾了一定比例的交易費用,以將其增長到可觀的水平以保護用戶。[2022/11/9 12:37:51]
????????config,
????????comm_d,
????})
}
filecoin_proofs_v1::seal_pre_commit_phase1方法就是真正實現P1的地方,我將會在這里詳細講解P1,使P1將在這里一一浮出水面。
pub?fn?seal_pre_commit_phase1<R,?S,?T,?Tree:?'static?+?MerkleTreeTrait>(
????porep_config:?PoRepConfig,
????cache_path:?R,
????in_path:?S,
????out_path:?T,
????prover_id:?ProverId,
????sector_id:?SectorId,
????ticket:?Ticket,
????piece_infos:?&,
)?->?Result<SealPreCommitPhase1Output<Tree>>
where
????R:?AsRef<Path>,
????S:?AsRef<Path>,
????T:?AsRef<Path>,
{
????info!("seal_pre_commit_phase1:start:?{:?}",?sector_id);
????//?Sanity?check?all?input?path?types.
????ensure!(
????????metadata(in_path.as_ref())?.is_file(),
????????"in_path?must?be?a?file"
????);
????ensure!(
????????metadata(out_path.as_ref())?.is_file(),
????????"out_path?must?be?a?file"
????);
????ensure!(
????????metadata(cache_path.as_ref())?.is_dir(),
????????"cache_path?must?be?a?directory"
????);
????let?sector_bytes?=?usize::from(PaddedBytesAmount::from(porep_config));
????fs::metadata(&in_path)
????????.with_context(||?format!("could?not?read?in_path={:?})",?in_path.as_ref().display()))?;
????fs::metadata(&out_path)
????????.with_context(||?format!("could?not?read?out_path={:?}",?out_path.as_ref().display()))?;
????//?Copy?unsealed?data?to?output?location,?where?it?will?be?sealed?in?place.
????fs::copy(&in_path,?&out_path).with_context(||?{
????????format!(
????????????"could?not?copy?in_path={:?}?to?out_path={:?}",
????????????in_path.as_ref().display(),
????????????out_path.as_ref().display()
????????)
????})?;
????let?f_data?=?OpenOptions::new()
????????.read(true)
????????.write(true)
????????.open(&out_path)
????????.with_context(||?format!("could?not?open?out_path={:?}",?out_path.as_ref().display()))?;
????//?Zero-pad?the?data?to?the?requested?size?by?extending?the?underlying?file?if?needed.
????f_data.set_len(sector_bytes?as?u64)?;
????let?data?=?unsafe?{
????????//?創建由文件支持的可寫內存映射
????????MmapOptions::new()
????????????.map_mut(&f_data)
????????????.with_context(||?format!("could?not?mmap?out_path={:?}",?out_path.as_ref().display()))?
????};
加密總市值上漲至1萬億美元上方:金色財經報道,據CoinGecko數據,當前加密總市值約為1,028,362,620,948億美元,過去24小時上漲5.6%。24小時交易量約為97,368,371,705億美元,當前BTC占比為38%,ETH占比17.8%。[2022/10/26 16:39:42]
????let?compound_setup_params?=?compound_proof::SetupParams?{
????????vanilla_params:?setup_params(
????????????PaddedBytesAmount::from(porep_config),
????????????usize::from(PoRepProofPartitions::from(porep_config)),
????????????porep_config.porep_id,
????????????porep_config.api_version,
????????)?,
????????partitions:?Some(usize::from(PoRepProofPartitions::from(porep_config))),
????????priority:?false,
????};
????//?利用param得到public_params,其vanilla_params.graph字段,就是構建出來的圖的數據結構。
????let?compound_public_params?=?<StackedCompound<Tree,?DefaultPieceHasher>?as?CompoundProof<
????????StackedDrg<'_,?Tree,?DefaultPieceHasher>,
????????_,
????>>::setup(&compound_setup_params)?;
????trace!("building?merkle?tree?for?the?original?data");
????let?(config,?comm_d)?=?measure_op(Operation::CommD,?||?->?Result<_>?{
????????let?base_tree_size?=?get_base_tree_size::<DefaultBinaryTree>(porep_config.sector_size)?;
????????let?base_tree_leafs?=?get_base_tree_leafs::<DefaultBinaryTree>(base_tree_size)?;
????????ensure!(
????????????compound_public_params.vanilla_params.graph.size()?==?base_tree_leafs,
????????????"graph?size?and?leaf?size?don't?match"
????????);
????????trace!(
????????????"seal?phase?1:?sector_size?{},?base?tree?size?{},?base?tree?leafs?{}",
????????????u64::from(porep_config.sector_size),
????????????base_tree_size,
????????????base_tree_leafs,
????????);
????????let?mut?config?=?StoreConfig::new(
????????????cache_path.as_ref(),
????????????CacheKey::CommDTree.to_string(),
????????????default_rows_to_discard(base_tree_leafs,?BINARY_ARITY),
????????);
????????let?data_tree?=?create_base_merkle_tree::<BinaryMerkleTree<DefaultPieceHasher>>(
????????????Some(config.clone()),
????????????base_tree_leafs,
????????????&data,
????????)?;
????????drop(data);
????????config.size?=?Some(data_tree.len());
????????let?comm_d_root:?Fr?=?data_tree.root().into();
????????let?comm_d?=?commitment_from_fr(comm_d_root);
????????drop(data_tree);
????????Ok((config,?comm_d))
????})?;
????trace!("verifying?pieces");
????ensure!(
????????verify_pieces(&comm_d,?piece_infos,?porep_config.into())?,
????????"pieces?and?comm_d?do?not?match"
????);
????let?replica_id?=?generate_replica_id::<Tree::Hasher,?_>(
????????&prover_id,
俄羅斯計劃2024年推出數字盧布并連接所有銀行和信貸機構:8月12日消息,俄羅斯央行繼續致力于即將采用的央行數字貨幣(CBDC),計劃在幾年內推出官方數字盧布。
根據俄羅斯央行最新的貨幣政策更新,該機構將于2024年開始將所有銀行和信貸機構連接到數字盧布平臺。這對俄羅斯來說將是重要的一年,因為俄羅斯預計將在2024年3月舉行總統選舉,現任總統弗拉基米爾·普京(Vladimir Putin)有憲法賦予的連任權利。
在2023年,俄羅斯央行還打算對基于數字盧布的智能合約進行beta測試,供有限的參與者進行交易。(Cointelegraph)[2022/8/13 12:22:16]
????????sector_id.into(),
????????&ticket,
????????comm_d,
????????&porep_config.porep_id,
????);
????let?labels?=?StackedDrg::<Tree,?DefaultPieceHasher>::replicate_phase1(
????????&compound_public_params.vanilla_params,
????????&replica_id,
????????config.clone(),
????)?;
????let?out?=?SealPreCommitPhase1Output?{
????????labels,
????????config,
????????comm_d,
????};
????info!("seal_pre_commit_phase1:finish:?{:?}",?sector_id);
????Ok(out)
}
P1實現解釋
上邊seal_pre_commit_phase1的代碼中,我們可以看到有三個path,這三個path分別對應:in_path->unsealedpath、out_path->sealedpath、cache_path->cachepath。代碼會先去檢查這三個path,他們兩個是文件,一個是文件夾。
檢查完path后我們可以看到fs::copy方法,它將unsealed文件拷貝到了sealed文件中,完成封裝。
Copy完成后拿出sealed文件的數據,并利用.set_len()方法填充數據(或刪減),使sealed數據達到證明類型配置規定的扇區大小。
setup_params()
setup_params()方法利用證明類型配置構建啟動參數。這里傳入的參數為:扇區大小、分區數、證明類型id、證明類型版本。分區數可看https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/23ae2893741829bddc29d7211e06c914bab5423c/src/registry.rs中的partitions()方法,在對應https://github.com/filecoin-project/rust-fil-proofs/blob/ec2ef88a17ffed991b64dc8d96b30c36b275eca0/filecoin-proofs/src/constants.rs得到具體值。我分析以32GB扇區為主,因此分區數為10。另外三個就不講了,跟分區數一樣,都是從這兩個文件得到的。
pub?fn?setup_params(
????sector_bytes:?PaddedBytesAmount,
????partitions:?usize,
????porep_id:?,
????api_version:?ApiVersion,
)?->?Result<stacked::SetupParams>?{
????//?得到挑戰層數和最大挑戰次數
????let?layer_challenges?=?select_challenges(
????????partitions,
????????*POREP_MINIMUM_CHALLENGES
????????????.read()
????????????.expect("POREP_MINIMUM_CHALLENGES?poisoned")
????????????.get(&u64::from(sector_bytes))
????????????.expect("unknown?sector?size")?as?usize,
????????*LAYERS
????????????.read()
????????????.expect("LAYERS?poisoned")
????????????.get(&u64::from(sector_bytes))
????????????.expect("unknown?sector?size"),
????);
????let?sector_bytes?=?u64::from(sector_bytes);
????ensure!(
????????sector_bytes?%?32?==?0,
????????"sector_bytes?({})?must?be?a?multiple?of?32",
????????sector_bytes,
????);
????let?nodes?=?(sector_bytes?/?32)?as?usize;????//?節點數,SDR共有11層,每一層的節點數量相當于1GiB的字節數量。
????let?degree?=?DRG_DEGREE;????//?用于所有?DRG?圖的基礎度數,?DRG_DEGREE=6。
????let?expansion_degree?=?EXP_DEGREE;?//大小是8,上一層中抽取的節點數量,用來計算當前層的節點數據
????Ok(stacked::SetupParams?{
????????nodes,
????????degree,
????????expansion_degree,
????????porep_id,
????????layer_challenges,
????????api_version,
????})
}
Merkletree和對應comm_d的生成
看完setup_params方法,讓我們繼續看seal_pre_commit_phase1中的compound_public_params參數,這里實際上set_up的時候,將compound_setup_params參數的值賦予進去,并增加了一個至關重要的vanilla_params.graph字段,就是構造出來的圖的數據結構
??接下來我們可以看到seal_pre_commit_phase1方法的70行,在這一段代碼用于生成markletree和comm_d
????let?(config,?comm_d)?=?measure_op(Operation::CommD,?||?->?Result<_>?{
????????let?base_tree_size?=?get_base_tree_size::<DefaultBinaryTree>(porep_config.sector_size)?;
????????let?base_tree_leafs?=?get_base_tree_leafs::<DefaultBinaryTree>(base_tree_size)?;
????????ensure!(
????????????compound_public_params.vanilla_params.graph.size()?==?base_tree_leafs,
????????????"graph?size?and?leaf?size?don't?match"
????????);
????????trace!(
????????????"seal?phase?1:?sector_size?{},?base?tree?size?{},?base?tree?leafs?{}",
????????????u64::from(porep_config.sector_size),
????????????base_tree_size,
????????????base_tree_leafs,
????????);
????????let?mut?config?=?StoreConfig::new(
????????????cache_path.as_ref(),
????????????CacheKey::CommDTree.to_string(),
????????????default_rows_to_discard(base_tree_leafs,?BINARY_ARITY),
????????);
????????//?創建默克爾樹,根據其樹根得到comm_d
????????let?data_tree?=?create_base_merkle_tree::<BinaryMerkleTree<DefaultPieceHasher>>(
????????????Some(config.clone()),
????????????base_tree_leafs,
????????????&data,
????????)?;
????????drop(data);
????????config.size?=?Some(data_tree.len());
????????let?comm_d_root:?Fr?=?data_tree.root().into();
????????let?comm_d?=?commitment_from_fr(comm_d_root);
????????drop(data_tree);
????????Ok((config,?comm_d))
????})?;
這里我們會生成treestoreconfig,然后利用config、base_tree_leafs、sealed填充數據,生成一個merkletree。得到了merkletree后就可以得到merkletree的根。再利用merkletree的根,通過commitment_from_fr算出comm_d。
生成副本id(replica_id)
當我們拿到了comm_d后,會利用verify_pieces方法驗證一下comm_d,這個就不講了,感興趣的可以自己去看代碼。
讓我們看一下副本id是如何生成的
????let?replica_id?=?generate_replica_id::<Tree::Hasher,?_>(
????????&prover_id,
????????sector_id.into(),
????????&ticket,
????????comm_d,
????????&porep_config.porep_id,
????);
利用數據本身生成得到了comm_d,這里再加上礦工id、扇區id、ticket,證明類型id。就能得到replicaid值。
///?Generate?the?replica?id?as?expected?for?Stacked?DRG.
pub?fn?generate_replica_id<H:?Hasher,?T:?AsRef<>>(
????prover_id:?&,
????sector_id:?u64,
????ticket:?&,
????comm_d:?T,
????porep_seed:?&,
)?->?H::Domain?{
????//?以鏈式方式處理輸入數據。
????let?hash?=?Sha256::new()
????????.chain_update(prover_id)
????????.chain_update(§or_id.to_be_bytes())
????????.chain_update(ticket)
????????.chain_update(&comm_d)
????????.chain_update(porep_seed)
????????.finalize();
????bytes_into_fr_repr_safe(hash.as_ref()).into()????//通過將?le_bytes?的最重要的兩位歸零,將?32?字節的切片轉換為?Fr::Repr。
}
生成labels
接下來就是P1最后的操作:生成labels。將public_params、復制id和treestoreconfig作為參數傳入。
????pub?fn?replicate_phase1(
????????pp:?&'a?PublicParams<Tree>,
????????replica_id:?&<Tree::Hasher?as?Hasher>::Domain,
????????config:?StoreConfig,
????)?->?Result<Labels<Tree>>?{
????????info!("replicate_phase1");
????????let?labels?=?measure_op(Operation::EncodeWindowTimeAll,?||?{
????????????Self::generate_labels_for_encoding(&pp.graph,?&pp.layer_challenges,?replica_id,?config)
????????})?
????????.0;
????????Ok(labels)
????}
這里可以看到,代碼提取出了public_params的.graph字段,就是構造出來的圖的數據結構,和public_params中包含挑戰層數和最大挑戰次數的layer_challenges。
接下來看generate_labels_for_encoding。這里可以分為多核與單核進行SDR編碼,創建labels。
????pub?fn?generate_labels_for_encoding(
????????graph:?&StackedBucketGraph<Tree::Hasher>,
????????layer_challenges:?&LayerChallenges,
????????replica_id:?&<Tree::Hasher?as?Hasher>::Domain,
????????config:?StoreConfig,
????)?->?Result<(Labels<Tree>,?Vec<LayerState>)>?{
????????let?mut?parent_cache?=?graph.parent_cache()?;
????????#
????????{
????????????if?SETTINGS.use_multicore_sdr?{
????????????????info!("multi?core?replication");
????????????????create_label::multi::create_labels_for_encoding(
????????????????????graph,
????????????????????&parent_cache,
????????????????????layer_challenges.layers(),
????????????????????replica_id,
????????????????????config,
????????????????)
????????????}?else?{
????????????????info!("single?core?replication");
????????????????create_label::single::create_labels_for_encoding(
????????????????????graph,
????????????????????&mut?parent_cache,
????????????????????layer_challenges.layers(),
????????????????????replica_id,
????????????????????config,
????????????????)
????????????}
????????}
????????#
????????{
????????????info!("single?core?replication");
????????????create_label::single::create_labels_for_encoding(
????????????????graph,
????????????????&mut?parent_cache,
????????????????layer_challenges.layers(),
????????????????replica_id,
????????????????config,
????????????)
????????}
????}
我將生成label的地址放在這里,想看的可以去看一下,這里就不細講了。
多核:https://github.com/filecoin-project/rust-fil-proofs/blob/master/storage-proofs-porep/src/stacked/vanilla/create_label/multi.rs
單核:https://github.com/filecoin-project/rust-fil-proofs/blob/master/storage-proofs-porep/src/stacked/vanilla/create_label/single.rs
三、總結
其實rust語言我接觸不多,開始的時候看得有點頭痛,最后也是硬著頭皮啃下來的。
如有大佬認為文章有不對的地方,歡迎糾正。
來源:金色財經
Tags:COMTORECTATHCompound USD Coinstorj幣前景Ejection MoonWeather Finance
老安—— ???????交易之道,守不敗之地,攻可贏之敵。衷心的希望各位交易者能夠在數字貨幣市場里游刃有余,撈到屬于自己的那桶鑫!昨日老安給出ETH多空思路空單入場點參考1350/其次1380?.
1900/1/1 0:00:00作為不需要可信設置的零知識證明算法代表之一,STARK算法被應用于StarkNet生態的各個項目中,比如dydx,immutableX等,并表現出了不俗的性能.
1900/1/1 0:00:00ALEO,它是第一個用于構建完全私有、可擴展且具有成本效益的應用程序的開發人員平臺。使用零知識密碼學,Aleo將智能合約執行轉移到鏈下,以支持各種去中心化應用程序,這些應用程序既完全私有又可以擴.
1900/1/1 0:00:00近期,自Infiblue宣布進軍元宇宙市場后,首推集SocialFi、P2E、DAO于一體的InfiblueWorld元宇宙生態系統.
1900/1/1 0:00:00各位幣友們,大家下午好,今天是北京時間9月26號。我是幣天王。莫愁前路無知己,投資路上有知音,很高興能夠在周一的這個時間跟各位一起盤點一下過去的行情,也對后續的走勢做出我們的預判.
1900/1/1 0:00:00今天享一個Paraluni平行宇宙單幣借貸的循環挖法,單幣循環借貸,收益高的時候能達到年化百分幾十到百分之百.
1900/1/1 0:00:00