一切從main開始:
Node模組中還提供了各種pool,這些pool用於對網路中的proposal與vote進行驗證時的任務佇列。
下面這句開啟我們的agreement協議:
2. Agreement
協議是Algorand最重要的一個模組,在其中用service做一個總的任務除錯,狀態機負責對投票進行統計,demux負責具體action的執行,從網路上收集proposal與vote,是Algorand的二元拜占庭(BBA)實現的部分。
2.1 service
這一個模組中分為兩大部分:
模組A:具體的proposal、vote驗證,及轉發
模組B:狀態機機制:處理針對每個區塊共識週期內的投票統計
這兩個大模組之間透過三個chan來進行互相驅動:
模組A做完自己的具體工作,會給externalEvent通道寫入event,模組B從這些通道讀資料,進行對應的統計處理;
模組B做完自己的統計處理工作,會給action通道寫入對應的action,給externalDemuxSignals通道寫入對應的signal
這幾個chan促成了模組A與模組B之間的互動:
模組A是input的生產者,是output與ready的消費者;
模組B正好反過來,是input的消費者,是output與ready的生產者。
2.2 狀態機
這裡的程式碼主要是對vote與proposal進行統計,一個區塊共識週期內的兩輪多步投票的統計都是在這裡完成的,分為5層狀態機,每層只負責處理與自己有關的,上層處理不了的,移交給下層狀態機,下層狀態機將處理結果返回給上層狀態機,最終發出對應的action。
Player即playmachine實現了整個狀態機的最頂層功能,負責記錄當前哪個區塊第幾個階段第幾步的共識環節,以及超時等基礎資訊。
proposalManager是proposal的管理類,在這裡監測proposal是否已經超過閾值,如果超過,向上層發出proposalCommittable的事件。
voteAggregator是vote的管理類,也是用來監測是否vote已經超過閾值,向上層發出threshhold。
proposalStore是round層的主類,主要用來儲存proposal,以儲存的權重來最終判定proposal是否達到一定數量。
voteTracker是step層的主類,用來儲存vote,是最初發出vote超過閾值的地方。
各個類的具體功能,仔細檢視程式碼並不難理解。
在這一模組中定義有兩個類,一個是router介面,一個是routerHandle結構體。前者用於真正的event處理,而後者只是為了構造一個新的結構,加入寫日誌功能及標明狀態機型別,起輔助功能。routerHandle的dispatch最終其實是轉到了對應的router的dispatch中去執行的。
2.3. Action
狀態機針對vote與proposal進行統計後,會發出一系統的action,這些都由各個對應的類去處理。
在actions.go裡會看到不同種類的action,我們只要在對應的類裡去查就知道如何處理各個action,action就是對應我們實際要處理的各個動作。
2.4. 外部訊息
在demux.go檔案裡,next函式負責從訊息通道里獲取訊息,轉化成對應的事件傳給狀態機
3. MakeProposals與MakeVotes
MakeProposals發出一個proposal,其實就是提議一個區塊,同時自己對這個區塊進行投票。MakeVotes就是對proposal直接進行投票。
pseudonode裡MakeProposals,會經過pseudonodeVerifier這個service裡的這個物件做一個非同步佇列:
s.voteVerifier = MakeAsyncVoteVerifier(s.BacklogPool)
verificationPool,是基於backlogpool與POOL來實現的,最後每個任務的實際執行又回到了pseudonode裡的execute。兜兜轉轉一圈,其它都只是工具,主類還是這個pseudonode,在這裡makeproposal與makeVote,非同步呼叫的真正執行也是在這個類檔案裡,對應類的execute。.在這個execute裡才去做的makeProposal與makeVote.
4. 如何選出領導者
我們知道是對credential,也就是憑證做排序,最小的就是領導者。這些其實發生在每一個節點上,在每一個節點上對所有voteVerified的事件做處理,比較大小得到。
看程式碼,在狀態機proposalMachinePeriod對應的主類proposalTracker中,handle處理訊息的主函式
這裡的freezer就是proposalSeeker的一個物件,這個類負責記錄credential值最小的那一個,那停止時間是什麼呢,就是說這個時間段的結束時間是什麼呢?
proposalFrozenEvent這個訊息發出來後,在狀態機裡
這樣freeze就對leader完成了選定,我們再查什麼時候發出這個事件。這個是由超時函式來控制的,在主狀態機裡,timeout事件,當step是soft步驟時,超時,就進入cert階段,這時就得終止這個credential最小值的選擇了。
本篇並未對Algorand的每個細節知識進行深入的闡述,而是從程式碼的大框架上做一個簡單說明,希望可以幫助大家理清資料流的走向,把握原始碼架構。