星際聯盟解讀| Filecoin中的WinningPoSt是什麼?區塊獎勵是如何產生的?

概述:

WinningPoSt是Filecoin網絡獎勵存儲提供者的機制,旨在構建一個安全、高效、可靠地分佈式存儲網絡。

Winning代表出塊權,Post就是在獲得出塊權時需要提交的時空證明。當存儲提供者通過EC共識的leader競選算法成功贏得出塊權後,便要進行WinningPoSt挑戰。 WinningPoSt挑戰的答案必須在短時間內提交,使得存儲提供者來不及通過密封找到挑戰的答案,以此保證挑戰者存儲了指定數據副本。證明答案會放進區塊中,每個成功創建區塊並被主鏈認可的存儲提供者會得到FIL獎勵,並且在區塊中打包消息,可以收取其他Filecoin參與者的費用。如果存儲提供者未能及時提交時空證明,便會失去本次打包區塊的機會,但不會受到任何懲罰。

本文將詳細分析Lotus代碼中WinningPost以及EC共識的設計。

源碼分析

(基於Lotus v1.11.1)

1. 啟動

使用lotus-miner init初始化一個miner,該miner將主要負責兩個任務,一個是worker的調度,另一個Mining協程就是負責出塊(WinningPoSt)。

2. m.mine()

類型 MiningBase 結構 {

TipSet * types.TipSet

NullRounds abi.ChainEpoch //從Base到當前高度,沒有產生區塊的輪次數

}

go m.doWinPoStWarmup() //喚醒WinningPoSt,log記錄本次喚醒時長

為了 {

為了 {

•Prebase = GetBestMiningCandidate //獲取最優Tipset

•如果base和prebase的高度、nullrounds相同,則退出循環進行出塊 //如果此時拿到的不是最優Tipset,出塊會形成孤塊

•waitFunc //等待一個網絡傳播延遲

•api.BeaconGetEntry(prebase.TipSet.Height()+prebase.NullRounds+1) //等待能夠獲得最新回合的隨機信標

•基地=預基地

}

b = m.mineone() //競選Winner

SyncSubmitBlock(b) //將新創建的區塊通過PubSub同步到網絡上

}

首先,Filecoin是一個由Tipset組成的鏈,一個高度對應一個Tipset,Tipset包含了對應高度生成的區塊,目前一個高度預期出塊數約為5,如果在一個高度沒有人出塊,則稱為空Tipset。

czNp5T9a2JfPHJjEMk840lO9o78Vvo3EldaRYmZW.png

Mine函數使用了兩層循環,裡面一層是為了獲取最優Tipset,最優Tipset是指從當前輪次向前推,上一個非空的完整的Tipset,稱為base,每有一個空Tipset,base.NullRounds加1。但由於產生空Tipset(即在該輪次全網沒有人出塊)的概率非常低,一般情況下NullRounds值為0。外層是獲取最優Tipset後開始競選Winner,競選的成功率基於泊松分佈,如果競選成功並創建區塊同步到網絡上,該區塊被主鏈認可後,便能得到FIL獎勵。

3. m.mineone()

//獲取Base的基本信息,包括Miner和全網算力、需要抽取的sector信息、用於生成隨機數的Beacon

MinerGetBaseInfo()

//獲取900個高度前的Tipset

GetLookbackTipSetForRound

計算票()

//依次寫入base回合隨機信標、加密類型、上一輪次和Miner地址計算Hash

Store.DrawRandoness

ComputeVRF //使用私鑰給Hash值簽名,生成一段可驗證的VRF輸出

IsRoundWinner()

//依次寫入本輪的隨機信標、加密類型、當前輪次和Miner地址計算Hash

Store.DrawRandoness

//若某Miner成功贏得選舉提交區塊,其他Miner可以通過提交的VRF輸出判斷winner是否符合條件

計算VRF

//計算贏得的獎勵數,算法基於泊松分佈

ComputeWinCount(MinerPower,NetworkPower)

//抽取一個Sector,併計算該Sector上的66個葉子的CommR

計算證明()

api.MpoolSelect() → CreateBlock() //從消息池中挑選一些Message打包成區塊

MinerGetBaseInfo獲取用於出塊的基本信息,需要注意的是其中GetLookbackTipSetForRound獲取了900個高度前的那個Tipset,因為此時可以認為該Tipset在鏈上的狀態是穩定的,幾乎不可能處於分叉鏈上。用於出塊的Miner算力、全網算力、抽查扇區和worker均是基於900個高度前的Tipset,而不是當前的情況。

其中抽查扇區邏輯使用cgo調用rust函數generate_winning_post_sector_challenge實現,具體如下:

讓 mut hasher = Sha256::new();

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

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

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

讓 hash = hasher.finalize();

讓扇區挑戰 = LittleEndian::read_u64(&hash[..8]);

讓扇區索引 = 扇區挑戰% 扇區集長度;

其將prove_id、隨機數和抽查扇區類型做sha256的hash計算,計算結果與扇區數取模,得到結果就是抽查的扇區ID。

這裡選擇抽查扇區ID時引入了隨機數,隨機數的生成基於DRand協議。 DRand是一個公開的可驗證隨機信標協議,使用基於BLS的(t,n)-閾值簽名方案。簡單來說,就是生成n份簽名,只需要收集到其中t份簽名就能重構出完整的BLS簽名,Filecoin使用blake2b散列算法將簽名轉換為一個256bit的字符串。 drand輪數和Filecoin高度之間存在映射關係,在winning競選前,MinerGetBaseInfo函數以當前高度和base高度為入參,得到相對應的DRand輪數來獲取隨機信標。如果DRand信標中斷則會打斷Filecoin區塊的產生,期間Miner只能發布空塊。不過DRand分發恢復後會快速產生drand值趕上當前回合,從而快速的恢復Filecoin區塊生產。

ComputeTicket得到的Ticket存放到創建的區塊中,用於該區塊在Tipset中的排序,Ticket最小的優先級最高,其打包的消息會被優先執行。

ComputeProof會調用Rust函數fil_generate_winning_post生成時空證明。該函數也引入了隨機數,以從上述ID對應的扇區抽查隨機的66個葉子節點,驗證是否可以正確計算出CommR和Merkle樹根。

EC共識

區塊鏈世界中,千千萬萬個Miner夜以繼日的工作為的就是取得出塊權,分配出塊權的機制稱為共識,像Bitcoin使用的是PoW工作量證明,誰先算出哈希難題,誰就有權出塊得到獎勵。

上面的mineone代碼邏輯中包含了Filecoin中最為重要的共識協議稱為EC共識(Expected Consensus)。 EC共識採用非交互的方式來選舉leader,即每個節點私下進行運算,如果運算成功,提交一個證明即可。在每個Epoch開始時,所有的存儲提供者都會運行一次leader選舉,選舉中它們做的是同一道題,計算量不大,只是每個人的參數不同,預期指定數量的參與者代入參數後答案不為0,競選成功獲得出塊權。 EC共識保證了競選獲勝者是隨機的,獲勝的機率僅僅與他們自身的算力大小相關,目前每一輪全網預期獲勝數為5,並且EC共識的計算量很小,是一個綠色環保的共識機制,使得存儲提供者更願意投入存儲空間而不是計算力。

1. 泊松分佈

X服從參數為λ的泊松分佈,則概率分佈為

Zuj1Ha9fiUxw3UWNc6ftKUMFSsSnG438Xuhz71On.png

期望E(X)= λ,λ很小時的泊松分佈圖像如下

bDL8kJjHkg7SQnaM3wymGyYUHpHxljlF4OZ2HZrw.png

2. ComputeWinCount函數

Lhs = blake2b.Sum256(ep.VRFProof).Int //獲取一個隨機數,位於[02^256)[02^256)

λ = power/totalpower * 5 //λ很小時,泊松分佈圖像如上圖所示

Rhs(j) = 1-P(X=0)-p(X=1)-…-p(X=j) * 2^256

for( j=0; Lhs

Wincount = j;

代碼的邏輯是當Lhs>=Rhs(j)或j>=15時退出循環, Wincount = j

不難理解,wincount=0概率為p(0),以此類推,wincount=i的概率為p(i)

∴ Wincount ~ P(λ)

3.WinCount

ssVFyevG6ppEj578DIyFZ6OMagK5Lq2439bhVVpI.png

E(Wincount(p)) = λ = p/t * 5

礦工的算力越大,獲得的Wincount期望越高

E(Wincount(2p)) = 2p/(t+p)∗5≈2p/t∗5=2E(Wincount(p))

由於單個礦工的算力相對於全網總算力非常小,所以wincount的期望與礦工的算力線性相關,礦工拆分算力獲得的獎勵和不拆分獲得的獎勵幾乎是一樣的

又設單個曠工算力為Pi ,則全網wincount總期望為

i9cX2nPBVGLIcLaQMJNOLctiZY6dSBXZ4U8WD6fL.png

所以每個Epoch全網預計wincount為5

4. 出塊率

當Wincount≠0時,Miner便能獲得出塊權。 Wincount >0時,Miner雖然只出一個塊,但可以獲得多份獎勵,Wincount的和會被計入Tipset的權重中

aQLVRJQS4AO632EoJzkxsIIzVbmU3x1Tt3iNTtXd.jpeg

9月8日全網總算力為10.4388EiB,得出塊率和算力的關係圖像如下

NpIUOVSdzwN33yBLrcp497PmmABn5YIOk3fuoV10.png

當Miner算力小於500PiB時,出塊率和算力大小幾乎成正比,每PiB獲得出塊權的概率約為0.00046。隨著全網算力持續增長,單P出塊率正持續下降。以8月8號為例,當日全網算力為8.77EiB計算得當日單P出塊率為0.00054,僅僅一個月的時間,單P產量就下降了15%,另外當前全網存儲總量已經超過了基線要求,有效算力高速增長致使出塊的獎勵也在減少,所以越早加入Filecoin網絡,獲取的收益率越高。

5. 共識錯誤懲罰

出於利益,存儲提供者可能會選擇無視共識協議,試圖分叉鏈,影響協議的公平性。為此,Filecoin為共識錯誤攻擊設置了相當嚴重的懲罰。

如在同一個區塊高度連續發布多個區塊,就可能觸發共識攻擊懲罰。根據合約ReportConsensusFault,一旦出現共識錯誤攻擊,所有網絡節點均可報告,檢驗屬實將會導致攻擊者接下來7.5個小時不能出塊,pre消息不能上鍊,並扣除一個區塊獎勵,舉報者可以獲得懲罰的1/20。

總結

Filecoin中每30秒存儲提供者競爭一次出塊權,全網預期贏得的區塊獎勵數為5。每個存儲提供者出塊的機率僅與自身的算力大小相關,當算力小於500PiB時,出塊率和算力大小幾乎成正比。此外,存儲提供者拆分算力和不拆分獲得的獎勵幾乎是一致的。獲得出塊權後需要對一個隨機扇區的隨機66個葉子節點進行驗證,並挑選消息打包區塊同步到網絡上,被主鏈認可後便能獲得區塊獎勵。

Filecoin使用了綠色環保的EC共識機制,有效的激勵存儲提供者積極封裝算力,為分佈式存儲的未來不斷添磚加瓦。而目前單P產量正處於快速下降中,對於存儲提供者來說,越早的加入Filecoin網絡才能獲得更高的收益率,而對於整個項目來說,這表明正有越來越多的人參與到Filecoin網絡的建設,有助於項目的長期發展和價值提升,未來的局面也越發令人期待!

Total
0
Shares
Related Posts