本地發送了一個交易,或者是接收到別人發來的交易信息。 txpool會產生一條消息,消息被傳遞到txCh通道。而後被goroutine txBroadcastLoop()處理, 發送給其餘不知道這個交易的peer。緩存
ProtocolManager在Start的時候,訂閱TxPreEvent並啓動txBroadcastLoop協程監聽事件。併發
當監聽到事件後,調用BroadcastTx進行廣播,廣播按照委員及候選委員,接入節點,輕節點逐層廣播。app
發送交易以前,會把tx.Hash放到peer的knownTxs中:函數
txsyncLoop負責每一個新鏈接的初始事務同步。 當新的peer出現時,咱們轉發全部當前待處理的事務。oop
在txsyncLoop函數中定義了一個send函數來廣播交易信息:區塊鏈
ProtocolManager在Start的時候,訂閱NewMinedBlockEvent並啓動 minedBroadcastLoop()協程監聽事件。fetch
監聽到事件後,開始廣播區塊信息。編碼
先根據BroadcastBlock輸入的參數propagate決定是否廣播區塊,當propagate爲true時,廣播區塊信息。以後開始廣播區塊哈希。spa
廣播時,先把hash放到knownBlocks裏面,在廣播區塊和區塊哈希協程
Fetcher Start函數中啓動協程:
Fetcher模塊的queue裏面緩存了已經完成fetch的block,等待按照順序插入到本地的區塊鏈中。優先級別就是他們的區塊號,這樣區塊數小的排在最前面。最後調用insert方法把給定的區塊插入本地的區塊鏈。
在insert函數中,有兩處廣播:一是若是區塊頭經過驗證,那麼立刻對區塊進行廣播;二是若是插入成功, 那麼廣播區塊,第二個參數爲false,那麼只會對區塊的hash進行廣播。
syncer中會定時的同BestPeer()來同步信息: 當有新的Peer增長的時候 會同步, 這個時候可能觸發區塊廣播; 定時觸發 10秒一次。
參照SendNewBlockHashes的處理流程。
在經過握手後runPeer時,會運行protocol的run函數,接着調用startProtocols函數,進而進入NewProtocolManager的時候定義的Run,每個SubProtocols都有一個Run。
這個run方法首先建立了一個peer對象,而後調用了handle方法來處理這個peer。注意,這裏的peer區別於p2p中的peer,可是它包含p2p的peer。
在handle最後,循環調用handleMsg, 這個方法很長,主要是處理接收到各類消息以後的應對措施。
對於GetBlockHeadersMsg的消息處理,結果調用SendBlockHeaders返回給對端:
首先解碼msg,解析出getBlockHeadersData結構體。
查找方式:
從Hash指定的開始朝創世區塊移動,也就是反向移動。
從Hash指定的開始正向移動。
經過Number反向查找。
經過Number正向查找。
查找結果發給對端:
沒有用到。
調用流程參考「4 發送區塊頭信息SendBlockHeaders」。
收到GetBlockBodiesMsg,解析msg信息,組織bodies併發送給對端。
調用流程參考「4 發送區塊頭信息SendBlockHeaders」。
GetNodeDataMsg對應的協議版本要大於等於eth63。
調用流程參考「4 發送區塊頭信息SendBlockHeaders」。
調用流程參考「4 發送區塊頭信息SendBlockHeaders」。
首先,在協議初始化的時候,調用protocolManager.Start
以後啓動syncer(), syncer中會定時的同BestPeer()來同步信息: 當有新的Peer增長的時候 會同步; 定時觸發 10秒一次同步。
pm.synchronise會調用中 Downloader中的同步函數。 Synchronise試圖和一個peer來同步,若是同步過程當中遇到一些錯誤,那麼會刪除掉Peer。而後會被重試。
最後,在syncWithPeer中會啓動幾個fetcher 分別負責header,bodies,receipts處理。spawnSync給每一個fetcher啓動一個goroutine, 而後阻塞的等待fetcher出錯。
在fetchHeight中,會發出RequestHeadersByHash請求。
fetchHeaders方法用來獲取header。 而後根據獲取的header去獲取body和receipt等信息。fetchHeaders不斷的重複這樣的操做,發送header請求,等待全部的返回,直到完成全部的header請求。
調用流程參考「10 經過Hash請求區塊頭RequestHeadersByHash」。
調用流程參考「10 經過Hash請求區塊頭RequestHeadersByHash」。
調用流程參考「10 經過Hash請求區塊頭RequestHeadersByHash」。
在建立Downloader的時候,會同時啓動協程 startFetcher,進而啓動runStateSync。
head是當前的區塊頭,genesis是創世區塊的信息,只有創世區塊相同才能握手成功。若是接收到任何一個錯誤(發送,接收),或者是超時,那麼就斷開鏈接,握手失敗。
readStatus,檢查對端返回的各類狀況。