前言
研究公链中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。