column hash的計算過程如下:
32GB的Sector,分割成1G個node。SDR的計算會生成11層的處理資料,每層都為32GB。每層的同一個編號的node資料,組合在一起後的hash的結果就是column hash的計算結果。Column hash的計算結果也是32GB。
針對column hash的計算結果,生成八叉樹(tree_c),樹根為comm_c。
label encoding的計算是將SDR的計算結果和原始資料進行encoding。所謂的encoding,目前就是大數的加法。encoding的結果,生成八叉樹(tree_r_last),樹根為comm_r_last。
上鍊的資料是兩個:comm_d和comm_r。其中,comm_r是comm_c和comm_r_last的posedion的hash結果。
整個Sector處理邏輯,總結整體如下圖:
2. Sector證明(Commit)過程
Commit過程分為兩個階段,分別是phase1以及phase2, 也就是階段1和階段2。Sector證明過程和零知識證明的過程密切相關。對零知識證明zk-SNARK理論和應用不熟悉的小夥伴,可以檢視我之前寫的相關文章。相關的介面函式在filecoin-proofs/src/api/seal.rs檔案中的seal_commit_phase1和seal_commit_phase2函式。
Sector證明的階段1,主要是準備電路需要的資料。這些資料即不完全是電路的公開資料,也不完全是電路的私有資料,而是電路資料需要的原始資料。階段1,並不會對Sector的32G對應的1G的節點做證明,而是挑選一些節點做證明。
所有挑選的這些節點分為9個Partition:
pub static ref POREP_PARTITIONS: RwLock<HashMap<u64, u8>> = RwLock::new(
[
(SECTOR_SIZE_2_KIB, 1),
(SECTOR_SIZE_8_MIB, 1),
(SECTOR_SIZE_512_MIB, 1),
(SECTOR_SIZE_32_GIB, 9)
]
每個Partition都隨機挑選一些節點。所有的挑選的節點個數不超過最小挑戰節點數:
pub static ref POREP_MINIMUM_CHALLENGES: RwLock<HashMap<u64, u64>> = RwLock::new(
[
(SECTOR_SIZE_2_KIB, 2),
(SECTOR_SIZE_8_MIB, 2),
(SECTOR_SIZE_512_MIB, 2),
(SECTOR_SIZE_32_GIB, 138)
]
也就是說,對於32G的Sector而言,9個Parititon,每個Partition隨機選擇16個節點進行挑戰。隨機選擇的具體演算法在storage-proofs/src/porep/stacked/vanilla/challenges.rs的derive_internal函式中。
Sector證明的階段2,就是零知識證明的電路處理以及生成零知識證明的過程。這部分的邏輯,總的框架和之前一樣,主要是SDR的演算法改動有一些變化。RUST-FIL-PROOF(FPS)實現了StackedCompound,專門用來實現Stacked DRG的資料處理證明。StackedCompound,將兩部分整合在一起,一部分是電路(Stacked Circuit),另一部分是Stacked Drg,實現電路資料的準備。這些部分又分成一個個的子功能(Window,Wrapper,ReplicaColumn等等)。在呼叫Bellman生成證明時,相應電路的synthesize介面就會被呼叫,從而完成整個電路生成R1CS的過程。
總結:
Lotus的原始碼更新比較頻繁。Testnet3將Sector的Precommit和Commit處理都分成了兩個階段(Phase1和Phase2)。SDR是演算法改動是最大的變化。零知識證明的CRS已經更新到V24版本。