Filecoin - Lotus儲存證明了什麼?

買賣虛擬貨幣
2019年,Filecoin算是火熱的區塊鏈專案。3月份,Filecoin公開了相關的程式碼後,第一時間看了看Filecoin的程式碼。區塊鏈部分的程式碼,比較簡單,偏功能驗證。個人對儲存證明的部分比較感興趣,也就是FPS。採用零知識證明技術,對儲存進行證明是個大膽的嘗試。Filecoin團隊,在2019年下半年出了個Lotus(蓮花)測試版本。測試網路的硬體配置比較高,256G記憶體 + Nvidia 2080TI的顯示卡。測試網路的節點排行榜,也成了競賽場。算力增長,出塊效率,是主要的指標。Lotus的電路邏輯比較複雜,電路規模達到了1億。證明生成的時間也非常長。整個證明計算過程,有很大的提升空間。對Lotus的證明效能提升感興趣的小夥伴,歡迎和我交流。別光看Filecoin在國內的熱度,深入介紹Filecoin/Lotus相關零知識證明的技術文章寥寥無幾。最近有點時間,梳理了一下Lotus的PoREP的資料處理(包括Sector處理以及採用零知識證明)的相關邏輯。

1. Lotus整體模組

簡單的說,Lotus/Filecoin專案由三部分組成:

1/ Lotus Blockchain部分 - 實現區塊鏈相關邏輯(共識演算法,P2P,區塊管理,虛擬機器等等)。注意的是,Lotus的區塊鏈相關的資料儲存在IPFS之上。go語言實現。

2/ RUST-FIL-PROOF部分 - 實現Sector的儲存以及證明電路。也就是FPS(Filecoin Proving Subsystem)。Rust語言實現。

3/ Bellman部分 - 零知識證明(zk-SNARK)的證明系統,主要是基於BLS12_381橢圓曲線上,實現了Groth26的零知識證明系統。Lotus官方推薦採用Nvidia的2080ti顯示卡,也主要做這部分的效能加速。Rust語言實現。

這篇文章,主要介紹第二部分(也就是Sector的儲存以及證明)的核心邏輯。

2. Stacked DRG

解釋具體的邏輯之前,介紹一下兩個基本術語:一個是Stacked DRG,一個是Sector。Sector相對比較簡單,就是一次資料處理的單位。知道硬碟結構的小夥伴都知道,硬碟的最小的儲存單元就叫“Sector”。Lotus採用的Sector的比較大,目前測試網路採用的是32G。

Stacked DRG是Sector資料處理的演算法。對儲存資料進一定的處理,並進行相應的證明是為了說明儲存服務方,確實如實地儲存了一些資料,而不是造假(攻擊)。Filecoin很早之前採用的是“Zig Zag DRG”演算法。可能因為太複雜(太慢),Lotus採用的是“簡化”的Stacked DRG演算法。兩種演算法的區別示意如下:

有兩點需要說明:

1/ Stacked DRG的每個節點以及每層之間不採用Zig Zag的依賴關係。也就是說,每個節點和其他節點的依賴關係是固定的。
2/ 在每層(Layer)之間增加節點的依賴關係。


3. Sector處理(Precommit)過程

Sector處理,也就是傳說中的precommit階段,主要由如下的資料處理組成:

a. 針對原始資料構造默克爾樹tree_d(sha256),樹根為comm_d。
b. Label & Encode計算:

原始資料,每32個位元組,稱為一個Node。每128M分為一個Window。32G的Sector有256個Window。每個Window,按照Stacked DRG演算法,生成4個layer的資料。從上一個Layer,透過Encode計算生成下一個Layer的資料。Encode計算,目前就是模加操作。將Window的編號和Stacked DRG的節點關係透過sha256演算法,生成“key”。將Key和原始資料進行模加生成Encode計算的結果。

c. Layer4的生成資料,構造默克爾樹tree_q(pedersen),樹根為comm_q。Layer4的生成資料,再經過一層exp的依賴關係,構造默克爾樹tree_r_last(pedersen),樹根為comm_r_last。

d. Column Hash計算

Layer4的256個Window的資料中,同一位置上的Node,拼接在一起,hash後生成Column Hash的結果。注意,Column Hash的計算結果只有一個Window大小。針對Column Hash的計算結果,構造默克爾樹tree_c,樹根為comm_c。

需要上鍊的資料是以上所有的默克爾樹的樹根:comm_d以及comm_r。其中comm_r是(comm_c|comm_q|comm_r_last)的pedersen hash的結果 。

核心程式碼在rust-fil-proofs/storage-proofs/src/stacked/proof.rs的transform_and_replicate_layers函式中。感興趣的小夥伴,可以根據下面的呼叫關係檢視具體的程式碼。

4. Sector證明(Commit)過程

在Sector處理後,需要對處理後的資料進行“證明”,畢竟不能把所有處理後的資料全部提交到區塊鏈上。Lotus使用Bellman的零知識證明庫,採用Groth26演算法進行資料處理的證明。

RUST-FIL-PROOF(FPS)實現了StackedCompound,專門用來實現Stacked DRG的資料處理證明。StackedCompound,將兩部分整合在一起,一部分是電路(Stacked Circuit),另一部分是Stacked Drg,實現電路資料的準備。這些部分又分成一個個的子功能(Window,Wrapper,ReplicaColumn等等)。在呼叫Bellman生成證明時,相應電路的synthesize介面就會被呼叫,從而完成整個電路生成R1CS的過程。

話說,Lotus的Sector的資料證明證明了什麼呢?Lotus的資料證明了如下的事實:

1/ 結合鏈上生成的隨機數,隨機挑選50個處理後資料Node,也就是在replica(複製資料)中,隨機挑選50個Node資料。
2/ 證明這些資料是從原始資料一步步處理生成的。而且,能構造出之前處理過程中生成的4個默克爾樹的樹根。
3/ 重複步驟1和2,10次。

步驟1/2的證明,如下圖所示:

簡單的說,從鏈上獲取了隨機資訊後(和區塊高度有關),隨機選擇了500個處理後的Node資料,並證明這些資料是透過Stacked DRG演算法從原始資料計算而來。並且,這些資料能構成之前遞交到鏈上的四個默克爾樹的樹根。

Lotus的電路邏輯比較複雜,電路規模達到了1億。證明生成的時間也非常長。

5. Sector證明鏈上驗證

提交到鏈上的資料包括:comm_d,comm_r以及proof證明資料。鏈上的miner智慧合約會驗證提交的證明是否正確:

func ValidatePoRep(ctx context.Context, maddr address.Address, ssize uint64, commD, commR, ticket, proof, seed []byte, sectorID uint64) (bool, ActorError)
具體的程式碼在lotus/chain/actors/actor_miner.go檔案。其中ticket和seed就是鏈上提供的隨機資訊。驗證過程就是RUST-FIL-PROOF模組呼叫Bellman驗證零知識證明是否正確。驗證過程比較快,毫秒級的計算。相對來說,儲存證明的生成過程時間比較長,有比較大的提升空間。

總結:

Lotus(蓮花),採用Stacked DRG演算法對儲存的資料進行處理,並採用Groth26零知識證明演算法對資料處理過程進行證明。Lotus的零知識證明,證明了隨機抽選的500個節點資料是正確地透過Stacked DRG演算法生成,並能生成指定的默克爾樹的樹根。Lotus的電路邏輯比較複雜,電路規模達到了1億,證明生成時間比較長。整個計算效能有很大的提升空間。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;