以太坊源碼學習(1):消息機制

前言

研究公鏈中msg互相觸發關係,學習一下以太坊中消息廣播的邏輯順序。
帶寬要求和消息轉發之間有沒有相對關係。

消息監聽機制 handleMsg: server,client,ProtocolManager
消息廣播機制 broadcast: transaction,block,blockHash

尋找轉發點

找msg的監聽循環,代碼中類似handleMsg之類的函數

ProtocolManager.handeMsg 中的轉發邏輯

在ProtocolManager.handleMsg中把所有消息的觸發關係梳理了一遍。
內容如下
在這裏插入圖片描述

舉例 GetBlockHeadersMsg

在共識過程中,如果節點收到了區塊頭的消息。
會觸發消息監聽中的GetBlockHeadersMsg事件。
代碼如下
handler.go line386

case msg.Code == GetBlockHeadersMsg:
        ...
        if err := msg.Decode(&query); err != nil {
			return errResp(ErrDecode, "%v: %v", msg, err)
		}
        ...
return p.SendBlockHeaders(headers)

其中peer.SendBlockHeaders函數的定義如下

func (p *peer) SendBlockHeaders(headers []*types.Header) error {
	return p2p.Send(p.rw, BlockHeadersMsg, headers)
}

emmmm,就是簡單地把區塊頭廣播出去。

在return之前還有一個返回點

if err := msg.Decode(&query); err != nil {
			return errResp(ErrDecode, "%v: %v", msg, err)
		}

可見節點收到的區塊頭會被廣播出去的條件是msg要能夠正常的Decode.

其他msg分析過程同上。

serverHandler.handleMsg

serverHandler的監聽中,所有消息觸發情況如下圖。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mhHlmgWL-1580883855712)(evernotecid://6788BEDA-B14F-4031-A555-23EB62241656/appyinxiangcom/22809680/ENResource/p977)]

哭了,沒有消息閉環。

clientHandler.handleMsg

clientHandler的監聽,作用是對Server返回的結果進行對應的處理
收到的消息及其對應關係如下。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HK5ExGju-1580883855713)(evernotecid://6788BEDA-B14F-4031-A555-23EB62241656/appyinxiangcom/22809680/ENResource/p978)]

尋找廣播點

廣播的底層在於peer類的boardcast函數

func (p *peer) broadcast() {
	for {
		select {
		case txs := <-p.queuedTxs:
			if err := p.SendTransactions(txs); err != nil {
				return
			}
			p.Log().Trace("Broadcast transactions", "count", len(txs))

		case prop := <-p.queuedProps:
			if err := p.SendNewBlock(prop.block, prop.td); err != nil {
				return
			}
			p.Log().Trace("Propagated block", "number", prop.block.Number(), "hash", prop.block.Hash(), "td", prop.td)

		case block := <-p.queuedAnns:
			if err := p.SendNewBlockHashes([]common.Hash{block.Hash()}, []uint64{block.NumberU64()}); err != nil {
				return
			}
			p.Log().Trace("Announced block", "number", block.Number(), "hash", block.Hash())

		case <-p.term:
			return
		}
	}
}

emmmmmmm 爲啥剛纔沒搜到

三個channel用於廣播

p.queuedProps 廣播塊
p.queuedAnns 廣播哈希
p.queuedTxs 廣播交易

廣播交易 廣播哈希

當節點自己挖到block時
w.mux.Post(core.NewMinedBlockEvent{Block: block})
其中會在本地生成NewMinedBlockEvent事件
該事件觸發minedBroadcastLoop循環

		if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok {
			pm.BroadcastBlock(ev.Block, true)  // First propagate block to peers
			pm.BroadcastBlock(ev.Block, false) // Only then announce to the rest
		}

其中BroadcastBlock函數根據第二個參數,選擇廣播整個區塊還是隻廣播區塊的hash

交易廣播

廣播交易監聽txBroadcastLoop循環

select {
		case event := <-pm.txsCh:
			pm.BroadcastTxs(event.Txs)

觸發廣播需要pm.txsCh
然而沒找到這個信道的賦值在哪

帶寬消耗

文獻描述

試圖從以太坊的白皮書中找到對帶寬的描述
https://github.com/ethereum/wiki/wiki/[中文]-以太坊白皮書
但是並沒有相關內容
更多是在描述原理

查到了bitmex網,這裏有一些對節點性能的測量標準。
BitMEX 研究推出以太坊節點指標網站——Nodestats.org

https://blog.bitmex.com/zh_cn-bitmex-research-launches-ethereum-node-monitoring-website-nodestats-org/

從中我們可以找到一些geth的節點帶寬要求
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FnkSAY7b-1580883855709)(evernotecid://6788BEDA-B14F-4031-A555-23EB62241656/appyinxiangcom/22809680/ENResource/p971)]

Geth的上行帶寬 要求 4kb/s
Geth的下行帶寬 要求 60kb/s

代碼中的限制

rlpx.go line603

if fsize > maxUint24 {

每個msg最大256byte。

發佈了7 篇原創文章 · 獲贊 3 · 訪問量 597
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章