本篇主要介紹Algorand源碼中關于agreement的模塊結構及業(yè)務邏輯架構,也是源碼中比較難以理解的地方,其它諸如節(jié)點、區(qū)塊、密碼、P2P網(wǎng)絡的結構與其它區(qū)塊鏈項目都是大同小異,很容易理解,這里就不再贅述。
1. 節(jié)點啟動
一切從main開始:
Node模塊中還提供了各種pool,這些pool用于對網(wǎng)絡中的proposal與vote進行驗證時的任務隊列。
下面這句開啟我們的agreement協(xié)議:
2. Agreement
協(xié)議是Algorand最重要的一個模塊,在其中用service做一個總的任務調試,狀態(tài)機負責對投票進行統(tǒng)計,demux負責具體action的執(zhí)行,從網(wǎng)絡上收集proposal與vote,是Algorand的二元拜占庭(BBA)實現(xiàn)的部分。
2.1 service
這一個模塊中分為兩大部分:
模塊A:具體的proposal、vote驗證,及轉發(fā)
模塊B:狀態(tài)機機制:處理針對每個區(qū)塊共識周期內的投票統(tǒng)計
這兩個大模塊之間通過三個chan來進行互相驅動:
模塊A做完自己的具體工作,會給externalEvent通道寫入event,模塊B從這些通道讀數(shù)據(jù),進行對應的統(tǒng)計處理;
模塊B做完自己的統(tǒng)計處理工作,會給acTIon通道寫入對應的acTIon,給externalDemuxSignals通道寫入對應的signal
這幾個chan促成了模塊A與模塊B之間的互動:
模塊A是input的生產(chǎn)者,是output與ready的消費者;
模塊B正好反過來,是input的消費者,是output與ready的生產(chǎn)者。
2.2 狀態(tài)機
這里的代碼主要是對vote與proposal進行統(tǒng)計,一個區(qū)塊共識周期內的兩輪多步投票的統(tǒng)計都是在這里完成的,分為5層狀態(tài)機,每層只負責處理與自己有關的,上層處理不了的,移交給下層狀態(tài)機,下層狀態(tài)機將處理結果返回給上層狀態(tài)機,最終發(fā)出對應的acTIon。
Player即playmachine實現(xiàn)了整個狀態(tài)機的最頂層功能,負責記錄當前哪個區(qū)塊第幾個階段第幾步的共識環(huán)節(jié),以及超時等基礎信息。
proposalManager是proposal的管理類,在這里監(jiān)測proposal是否已經(jīng)超過閾值,如果超過,向上層發(fā)出proposalCommittable的事件。
voteAggregator是vote的管理類,也是用來監(jiān)測是否vote已經(jīng)超過閾值,向上層發(fā)出threshhold。
proposalStore是round層的主類,主要用來存儲proposal,以存儲的權重來最終判定proposal是否達到一定數(shù)量。
voteTracker是step層的主類,用來存儲vote,是最初發(fā)出vote超過閾值的地方。
各個類的具體功能,仔細查看代碼并不難理解。
在這一模塊中定義有兩個類,一個是router接口,一個是routerHandle結構體。前者用于真正的event處理,而后者只是為了構造一個新的結構,加入寫日志功能及標明狀態(tài)機類型,起輔助功能。routerHandle的dispatch最終其實是轉到了對應的router的dispatch中去執(zhí)行的。
2.3. AcTIon
狀態(tài)機針對vote與proposal進行統(tǒng)計后,會發(fā)出一系統(tǒng)的action,這些都由各個對應的類去處理。
在actions.go里會看到不同種類的action,我們只要在對應的類里去查就知道如何處理各個action,action就是對應我們實際要處理的各個動作。
2.4. 外部消息
在demux.go文件里,next函數(shù)負責從消息通道里獲取消息,轉化成對應的事件傳給狀態(tài)機
3. MakeProposals與MakeVotes
MakeProposals發(fā)出一個proposal,其實就是提議一個區(qū)塊,同時自己對這個區(qū)塊進行投票。MakeVotes就是對proposal直接進行投票。
pseudonode里MakeProposals,會經(jīng)過pseudonodeVerifier這個service里的這個對象做一個異步隊列:
s.voteVerifier = MakeAsyncVoteVerifier(s.BacklogPool)
verificationPool,是基于backlogpool與POOL來實現(xiàn)的,最后每個任務的實際執(zhí)行又回到了pseudonode里的execute。兜兜轉轉一圈,其它都只是工具,主類還是這個pseudonode,在這里makeproposal與makeVote,異步調用的真正執(zhí)行也是在這個類文件里,對應類的execute。。在這個execute里才去做的makeProposal與makeVote.
4. 如何選出領導者
我們知道是對credential,也就是憑證做排序,最小的就是領導者。這些其實發(fā)生在每一個節(jié)點上,在每一個節(jié)點上對所有voteVerified的事件做處理,比較大小得到。
看代碼,在狀態(tài)機proposalMachinePeriod對應的主類proposalTracker中,handle處理消息的主函數(shù)
這里的freezer就是proposalSeeker的一個對象,這個類負責記錄credential值最小的那一個,那停止時間是什么呢,就是說這個時間段的結束時間是什么呢?
proposalFrozenEvent這個消息發(fā)出來后,在狀態(tài)機里
這樣freeze就對leader完成了選定,我們再查什么時候發(fā)出這個事件。這個是由超時函數(shù)來控制的,在主狀態(tài)機里,timeout事件,當step是soft步驟時,超時,就進入cert階段,這時就得終止這個credential最小值的選擇了。
本篇并未對Algorand的每個細節(jié)知識進行深入的闡述,而是從代碼的大框架上做一個簡單說明,希望可以幫助大家理清數(shù)據(jù)流的走向,把握源碼架構。
來源;眾享比特?