上一篇講解了如何在工程上申請儲存礦工角色,本篇,我們將深度剖析儲存礦工物件的原始碼結構,方便大家從根本上理解礦工的事務,同時對一次挖礦的生命週期做一個總結。
儲存礦工物件剖析
首先,我們來深度剖析一個儲存礦工物件的原始碼結構,這樣便於大家從根本上理解礦工的事務。
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()
}
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
}
owner與worker儲存礦工角色有兩個不同的地址:
一個是worker:負責完成所有事務活動,參與ask訂單、提交證明,提交新扇區等。 另一個是owner:地址是建立礦工的地址,支付抵押品,並獲得出塊獎勵。
owner適合冷存金鑰,安全級別更高,worker常遷移和變更,安全級別更低。 如下圖所示,我們可以在~./filecoin/config.json下分別獲取到worker和owner的地址資料:
worker => mineraddress
owner => defaultaddress
儲存礦工的生命週期:
儲存交易 ——> 建立區塊 ——> 停止挖礦 ——> 失責懲罰(wip)
下面依次來介紹其生命週期中的這幾個過程: 3.7.1 儲存交易 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()來取回他們的抵押品,並停止挖礦程序。 備註:此過程也會參與鏈上操作。 失責懲罰(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