很差意思,這篇加了點八卦:html
原本是不太想說這事的,從18年看到如今,很多見圈裏的朋友和友商互相吐槽乃至攻擊...最近還鬧得比較大。這裏說兩句:區塊鏈存儲在中國是一個剛誕生的新興領域,探索階段有錯誤是常態,至少你們都願意把臉放下地在盤活這個行業。git
今天小編看到一句很深入的話:強者互持,弱者互撕,但願你們能意識到:由於同行者,你的存在和你所作的事情纔有意義...github
歡迎你們來到第三章的下篇,通過前章 【Filecoin源碼倉庫全解析】第三章(上):存儲提供方(礦工)的配置操做的內容閱讀後,咱們應該能會對Filecoin存儲市場機制和市場中的各角色職能有了更深入的認知,而且能夠配置自身節點角色,成爲存儲提供方(礦工),參與挖礦了。json
上一篇,咱們講解了如何在工程上申請存儲礦工角色,本篇,咱們將深度剖析存儲礦工對象的源碼結構,方便你們從根本上理解礦工的事務,並對一次挖礦的生命週期作一個總結。安全
首先,咱們來深度剖析一個存儲礦工對象的源碼結構,這樣便於你們從根本上理解礦工的事務。微信
咱們在鏈上成功註冊一個新的礦工身份後,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()
複製代碼
存儲礦工會有本身的鏈上狀態,僅在建立新區塊時更新,並全網同步可追溯,能夠理解爲這是Filecoin網絡爲礦工們所維護的一組狀態帳本:app
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
}
複製代碼
存儲礦工角色有兩個不一樣的地址:函數
小編認爲須要這樣區別和設計的緣由歸結爲八個字:各司其職,安全第一。post
例如:Owner適合冷存密鑰,安全級別更高,Worker常遷移和變動,安全級別更低。
以下圖所示,咱們能夠在~./filecoin/config.json下分別獲取到worker和Owner的地址數據:
注意:查詢Ask訂單,選擇交易時必定注意用worker地址來檢索
畫了一個腦海中的草圖,方便你們理解和記憶:
如圖所示,存儲礦工的生命線主要有四條:
下面依次來介紹其生命週期中的這幾個過程:
Step1:操做節點參與鏈上身份註冊,提交抵押與存儲容量,成爲一個存儲礦工
Step2:建立Ask訂單,與用戶節點交易。
Step3:密封數據並提交複製證實(PoRep)於鏈上,更新訂單狀態,完成交易,並開啓PoSt證實週期(證實期是礦工必須向網絡提交空間時間證實的固定時間。)
備註:這塊內容能夠繼續深挖,後面有時間考慮單開一章節:與FilecoinProof相關
Step4:存儲礦工收集證實集合,建立PoSt,計算ProveStorage和StoragePower(算力)。
備註:在證實期內,證實集會始終保持一致。在此期間系統增長的任何扇區都將順延至下一個證實期內。
Step5:當礦工完成他們的PoSt時,調用SubmitPoSt將其提交給網絡,並伴隨區塊更新同步狀態。
當經歷完存儲交易的過程後,存儲礦工已經具有了參與建立區塊節點的競選了,選票的生成邏輯以下所示:
//這塊函數體內部邏輯官方提示將改動,就不一一解析了
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。
若是須要中止採礦,礦工必須履行完全部存儲訂單(即:名下全部Ask訂單狀態爲Poster),並在PoSt提交期間將其從證實集中刪除。
以後,可經過客戶端指令調用DePledge()來取回他們的抵押品,並中止挖礦進程。
備註:此過程也會參與鏈上操做。
若是礦工因未能按時提交PoSt而被slashed,他們將失去全部抵押品。
備註:官方仍在Work in Process之中,須要更多社區的建議和討論,目前設置了多種保險和從新驗證機制,可見Filecoin也很是重視礦工的利益。
本章是一個基礎鋪墊,深挖了底層的原理,這是爲了讓咱們對Filecoin系統的理解,不光只停留在工程指令集的操做上面。
咱們將在下一章《【Filecoin源碼倉庫全解析】第四章(下):存儲需求方的配置操做》中重點介紹存儲需求方(用戶)的配置操做,並反過來驗證第三章中存儲礦工後續挖取新塊的過程,幫助你們融會貫通,並在工程上驗證整個挖礦行爲的生命週期。
本人從業經驗有限,難免有不足之處,歡迎指正和更多討論,可私信微信公衆號:jialesoho,或者加我微信:daijiale6239,若是以爲對您有幫助,能夠幫點擊好看推廣和打賞支持噢,感激涕零!
(識別圖中二維碼,關注嘉樂SOHO微信公衆號)