eos節點為什麼需要區塊回放,回放的過程是怎樣的,回放完畢後結果如何?
這些問題我們將在下面逐一講述。
區塊回放的前提條件
eos服務節點為什麼需要區塊回放呢?
eosio執行主網中,各個服務節點基於區塊保持了狀態一致性。當出現某個節點與其他節點的狀態不一致,無法持續保證一致性的情況下,這個時候就需要進行區塊回放。
那麼,服務節點什麼時候進行區塊回放呢?基本上是兩種情況,下面分別講述:
a.當服務節點執行出錯重啟服務提示資料庫髒資料時,這個時候節點的啟動命令中就會帶有回放的引數,節點需要根據自身的情況,清除髒資料,從正常主網節點中同步所有不可逆區塊到節點本地,並對這些區塊按照塊序號進行回放,如果本地節點還有可用的可逆塊表資料,則再將可逆塊按順序逐個回放。
如下圖所示,整個網路上目前是節點b出錯或異常重啟,所以節點b就需要執行區塊同步,然後將創世區塊外的所有區塊進行回放來對全網節點的區塊基線進行追趕:
b.當需要新增服務節點時,這個時候節點啟動後加入生產者列表,會從正常主網節點中同步所有不可逆區塊到節點本地,並對這些區塊按照塊序號進行回放。
如下圖所示,整個網路上目前存在節點a,b,現在新增節點c,節點c會先執行所有不可逆區塊同步,然後將創世區塊外的所有區塊進行回放來對全網節點的區塊基線進行追趕:
區塊回放呼叫的地方
eos節點呼叫進行replay()的地方只在節點初始化的時候,對應init()函式,如下圖所示:
區塊回放過程的解析
當乙個區塊落後節點試圖追趕全網節點的區塊基線時,主要的步驟是分成三步來執行:
a. 先通過net_plugin網路外掛程式從任何乙個正常節點進行區塊同步,將這些區塊獲取到本節點
b. 然後根據區塊的塊序號順序,逐個對區塊上的交易按照交易順序進行執行
c. 如果本地快取了可逆塊表資料,則接續不可逆區塊,將所有可逆區塊上的交易按順序進行執行
第2,3步迴圈處理區塊交易的步驟就是區塊的回放。下圖為三個步驟的示意:
我們再來看下區塊回放的**:
其中關鍵處理函式是replay_push_block(),這個是針對單個區塊進行回放的函式,其實現**如下:
其中的主要功能實現**是通過maybe_switch_forks()函式實現的,而該函式的處理思想則是:
處理區塊鏈分叉要盡量保證鏈的可用性和持續執行,因此,當嘗試最長鏈切換失敗時,就放棄該分支,繼續使用當前分支即可。該函式的具體的實現流程解析請見文章《節點接收區塊後的maybe_switch_forks的處理流程解析》。
區塊回放的結果
節點區塊回放完畢後,此時當前節點應該與全網其他節點的不可逆區塊達到一致,即落盤儲存的不可逆區塊數目和序號都完全一致。全網各個節點當前的唯一差異就在於個節點上的可逆區塊表內容及交易佇列內容不一致,如下圖所示。
此時,新增或重啟節點的狀態就正常了,可以參與正常的生產流程了。
鏈結星河公鏈
TCP從連線到釋放過程全解
參考書籍 計算機網路第5版 tcp是面向連線的協議,採用c s模型建立連線,由client主動發起連線請求,server端允許請求的模式建立連線,通常稱為三次握手建立tcp連線。準備條件 b的server端先建立傳輸控制塊tcb。準備接受client程序的連線請求,此時server程序處於liste...
TCP 連線建立過程和連線釋放過程
1 客戶端a向伺服器b傳送連線請求報文,此時首部的同步位syn 1,同時選擇乙個初始序號seq x.tcp規定syn報文 syn 1 不能攜帶資料,但是要消耗乙個序列號,這時tcp客戶程序進入syn sent 同步以傳送 狀態 2 伺服器b收到連線請求報文後,如果同意建立連線,則向a傳送確認,在確認...
C 記憶體配置和釋放過程
一般而言,c 的記憶體配置操作和釋放操作時這樣的 class foo foo pf new foo 配置記憶體,然後構造物件 delete pf 將物件折構,然後釋放記憶體其中new算式內含兩階段操作 1.呼叫 operator new 配置記憶體 2.呼叫foo foo 構造物件內容 delete...