【Filecoin原始碼倉庫全解析】第三章(下):儲存提供方(礦工)的配置操作 | 嘉樂的SOHO
不好意思,這篇加了點八卦:
本來是不太想說這事的,從18年看到現在,不少見圈裡的朋友和友商互相吐槽乃至攻擊...最近還鬧得比較大。這裡說兩句:區塊鏈儲存在中國是一個剛誕生的新興領域,探索階段有錯誤是常態,至少大家都願意把臉放下地 在盤活這個行業 。
今天小編看到一句很深刻的話: 強者互持,弱者互撕 ,希望大家能意識到: 因為同行者,你的存在和你所做的事情才有意義 ...
歡迎大家來到第三章的下篇,經過前章 【Filecoin原始碼倉庫全解析】第三章(上):儲存提供方(礦工)的配置操作 的內容閱讀後,我們應該能會對Filecoin儲存市場機制和市場中的各角色職能有了更深刻的認知,並且可以配置自身節點角色,成為儲存提供方(礦工),參與挖礦了。
上一篇,我們講解了如何 在工程上 申請儲存礦工角色,本篇,我們將深度剖析儲存礦工物件的 原始碼結構 ,方便大家從根本上理解礦工的事務,並對一次挖礦的生命週期做一個總結。
3.6 儲存礦工物件剖析
首先,我們來深度剖析一個儲存礦工物件的 原始碼結構 ,這樣便於大家從根本上理解礦工的事務。
3.6.1 StorageMinerActor
我們在鏈上成功註冊一個新的礦工身份後,Filecoin儲存市場Actor(上帝)將呼叫CreateMiner()方法為我們生成一個新的儲存礦工例項物件(StorageMinerActor),並返回其地址,這個新的例項物件結構如下:
type StorageMinerActor interface { //礦工向儲存市場傳送訂單的方法。 AddAsk(price TokenAmount, expiry uint64) AskID //提交扇區的方法。 CommitSector(commD, commR, commRStar []byte, proof SealProof) SectorID //用於向鏈上提交時空證明的方法,證明礦工已實際儲存了其聲稱的檔案。 SubmitPoSt(p PoSt, faults []FailureSet, recovered SectorSet, doneSet SectorSet) // 允許礦工為網路提供更多儲存空間的方法 IncreasePledge(addspace Integer) // 若缺乏複製證明證據,將用此方法懲罰礦工 SlashStorageFault()
3.6.2 StorageMinerState
儲存礦工會有自己的鏈上狀態,僅在建立新區塊時更新,並全網同步可追溯,可以理解為這是Filecoin網路為礦工們所維護的一組狀態賬本:
type StorageMinerState struct { //Owner 是擁有此礦工節點的賬戶地址 Owner Address //Worker 是此礦工節點的工作賬號地址 Worker Address //PeerID 是應該用於連線這個礦工節點的libp2p對等身份 PeerID peer.ID //PublicKey是礦工用於對區塊進行簽名的金鑰的公共部分 PublicKey PublicKey //PledgeBytes是此礦工提供給網路的空間量 PledgeBytes BytesAmount //被鎖定的抵押金額 Collateral TokenAmount //當前抵押金額 ActiveCollateral TokenAmount //未提取的抵押金額 DePledgedCollateral TokenAmount //提取抵押幣的時間 DePledgeTime BlockHeight //Sectors 扇區集合 Sectors SectorSet //提交PoSt證明的扇區 ProvingSet SectorSet //在上一次PoSt提交期間狀態變更為“完成”的一組扇區。 NextDoneSet SectorSet //礦工所擁有的算力算量 Power BytesAmount }
3.6.3 Owner與Worker
儲存礦工角色有兩個不同的地址:
- 一個是Worker:負責完成所有事務活動, 參與Ask訂單 、提交證明,提交新扇區等。
- 另一個是Owner:地址是建立礦工的地址,支付抵押品,並獲得出塊獎勵。
小編認為需要這樣區別和設計的原因歸結為八個字: 各司其職,安全第一 。
例如:Owner適合冷存金鑰,安全級別更高,Worker常遷移和變更,安全級別更低。
如下圖所示,我們可以在~./filecoin/config.json下分別獲取到worker和Owner的地址資料:
- Worker => minerAddress
- Owner => defaultAddress
注意:查詢Ask訂單,選擇交易時一定注意用worker地址來檢索
3.7 儲存礦工的生命週期
畫了一個腦海中的草圖,方便大家理解和記憶:
如圖所示,儲存礦工的生命線主要有四條:
- 儲存交易
- 建立區塊
- 停止挖礦
- 失責懲罰(WIP)
下面依次來介紹其生命週期中的這幾個過程:
3.7.1 儲存交易
Step1:操作節點參與鏈上身份註冊,提交抵押與儲存容量,成為一個儲存礦工
Step2:建立Ask訂單,與使用者節點交易。
Step3:密封資料並提交複製證明(PoRep)於鏈上,更新訂單狀態,完成交易,並開啟PoSt證明週期(證明期是礦工必須向網路提交空間時間證明的固定時間。)
備註:這塊內容可以繼續深挖,後面有時間考慮單開一章節:與FilecoinProof相關
Step4:儲存礦工收集證明集合,建立PoSt,計算ProveStorage和StoragePower(算力)。
備註:在證明期內,證明集會始終保持一致。在此期間系統增加的任何扇區都將順延至下一個證明期內。
Step5:當礦工完成他們的PoSt時,呼叫SubmitPoSt將其提交給網路,並伴隨區塊更新同步狀態。
3.7.2 建立區塊
當經歷完儲存交易的過程後,儲存礦工已經具備了參與建立區塊節點的競選了,選票的生成邏輯如下所示:
//這塊函式體內部邏輯官方提示將改動,就不一一解析了 func IsTicketAWinner(t Ticket, minersPower, totalPower Integer) bool { return ToFloat(sha256.Sum(ticket)) * totalPower < minersPower } pTipSet := getHeaviestTipSet() smallestTicket := selectSmallestTicket(pTipSet) var tickets []Signature baseTicket := smallestTicket for { challenge := sha256.Sum(baseTicket.Bytes()) postCount := estimator.GetPostCount(chain, pTipSet) proof := post.Prove(storage, challenge, postCount) ticket := minerPrivKey.Sign(sha256.Sum(proof.Bytes())) tickets = append(tickets, ticket) totalPower := getTotalPower(pTipSet) ourPower := getMinerPower(pTipSet, minerID) if IsTicketAWinner(ticket, ourPower, totalPower) { return tickets } else { baseTicket = ticket } }
同時,為了防止女巫攻擊,選票需要被其他節點驗證,同時,自身也將驗證其他節點的選票:
//這塊函式體內部邏輯官方提示將改動,就不一一解析了 func VerifyTicket(b Block) error { curTicket := selectSmallestTicket(b.Parents) for _, ticket := range b.Tickets { challenge := sha256.Sum(curTicket) if !VerifyProof(b.Proof, b.Miner, challenge) { return "Proof failed to validate" } pubk := getPublicKeyForMiner(b.Miner) if !pubk.VerifySignature(ticket, sha256.Sum(b.Proof.Bytes())) { return "Ticket was not a valid signature over the proof" } curTicket = ticket } state := getStateTree(b.Parents) minersPower := state.getPowerForMiner(b.Miner) totalPower := state.getTotalPower() if !IsTicketAWinner(curTicket, minersPower, totalPower) { return "Ticket was not a winning ticket" } return nil }
建立區塊之前,首先要贏得選票,令所有對等節點之間達成一致。這裡涉及到 預期(Expected Consensus)共識 ,簡而言之:
是Filecoin基於拜占庭容錯基礎上的改進版,策略是每一輪裡選舉出來一名或者多名儲存礦工來建立新的區塊,贏選票的可能性和礦工 已分配的儲存(即與上文中ProveStorage、StoragePower強相關) 成比例。
備註:這塊內容也可以繼續深挖,後面有時間考慮單開一章節:與Expected Consensus相關
當你僥倖獲得一張優勝選票時,將建立新塊,結構體如下所示:
//這塊函式體內部邏輯官方提示TODO,應該後期改動會比較大 type Block struct { Parents []*cid.Cid Tickets []Signature Proof post.Proof Ticket Signature MsgRoot *cid.Cid ReceiptsRoot *cid.Cid StateRoot *cid.Cid BlockSig Signature }
當完成區塊建立之後,隨之而來的是豐厚的上帝獎勵(FIL分發), 具體的分發策略也處於WIP狀態,目前測試網階段是1000FIL/Block。
3.7.3 停止挖礦
如果需要停止採礦,礦工必須履行完所有儲存訂單(即:名下所有Ask訂單狀態為Poster),並在PoSt提交期間將其從證明集中刪除。
之後,可通過客戶端指令呼叫DePledge()來取回他們的抵押品,並停止挖礦程序。
備註:此過程也會參與鏈上操作。
3.7.4 失責懲罰(WIP)
如果礦工因未能按時提交PoSt而被slashed,他們將失去所有抵押品。
備註:官方仍在Work in Process之中,需要更多社群的建議和討論,目前設定了多種保險和重新驗證機制,可見Filecoin也非常重視礦工的利益。
參考文獻:
- https://github.com/filecoin-project/specs/blob/master/mining.md
-
https://github.com/filecoin-project/specs/blob/master/expected-consensus.md
本章是一個基礎鋪墊,深挖了底層的原理,這是為了讓我們對Filecoin系統的理解,不光只停留在工程指令集的操作上面。
我們將在下一章《【Filecoin原始碼倉庫全解析】第四章(下):儲存需求方的配置操作》中重點介紹儲存需求方(使用者)的配置操作,並反過來驗證第三章中儲存礦工後續挖取新塊的過程,幫助大家融會貫通,並在工程上驗證整個挖礦行為的生命週期。
本章贊助品牌:
搜搜IPFS :是專注於IPFS生態的垂直媒體。內容涵蓋IPFS的行業資訊、新聞動態、專案評測、人物專訪等。我們努力為IPFS使用者們創造更豐富,更有趣,更靠譜的媒體服務,致力於成為IPFS愛好者服務的媒體。目前已成為華中區最大、最具影響力的IPFS垂直媒體。
感謝 搜IPFS 對 嘉樂SOHO 的原創內容提供支援。
聯絡作者:
本人從業經驗有限,不免有不足之處,歡迎指正和更多討論,可私信 微信公眾號:jialesoho ,或者加我 微信:daijiale6239 ,如果覺得對您有幫助,可以 幫點選好看推廣 和 打賞支援 噢,感激不盡!
(識別圖中二維碼,關注嘉樂SOHO微信公眾號)