以太坊源码照抄 eth/handler
哈哈笑417
发表于 2023-1-5 18:37:02
173
0
0
eth主要的同步txs,block,header的入口都在这个文件里
type ProtocolManager struct {
...
downloader *downloader.Downloader // 名字是downloader 其实是就是在接受到数据后插入数据库
fetcher *fetcher.Fetcher // 声明新的块4 z2 _" B& H* u
peers *peerSet
SubProtocols []p2p.Protocol. F8 @5 G5 r: J# ?
...
方法 NewProtocolManager初始化一个ProtocolManager结构
这一步有一个重要的内容就是append(SubProtocols, p2p.Protocols{})
manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{
Name: ProtocolName,* s* Z) c5 m# d; j; ~" y
Version: version,
Length: ProtocolLengths,$ S: L9 I, {; @! [
Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
peer := manager.newPeer(int(version), p, rw)- z3 y+ ~0 k/ E4 A& T
select {8 R6 \' p: S4 E5 n2 f
case manager.newPeerCh
func pm.handle(), v. ]1 n- g) `( J1 c
这里newPeerCh接收到peer后调用pm.handle, 与pm同步txs,同时p同步pm.whiteList中的header5 a6 x9 z( P" x4 ?& E
for number := range pm.whitelist {
if err := p.RequestHeadersByNumber(number, 1, 0, false); err != nil {9 w" u2 k9 u+ ^; X! g
return err
}
}
同时进入循环处理来自peer的消息
for {- G/ P1 g( @$ V
if err := pm.handleMsg(p); err != nil {
p.Log().Debug("Ethereum message handling failed", "err", err)
return err
}
}& M/ S2 o2 p+ V+ Q4 a
func pm.handleMsg(p *peer)) O! M1 J5 O4 v& L
这个函数根据msg, err := p.rw.ReadMsg() msg的类型做出不同的处理,塞到fetcher 或者downloader中去等等 U+ R m& H+ y4 a! t
func.pm.BroadcastTxs(tx)( c. H% c/ E9 O w* H/ X4 J
找到pm.peers.PeersWithoutTx(tx.Hash()) 然后把tx塞给他
这个函数在 接受到消息时就会被调用
func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool)
这个就如题吧; c; v) e9 n) G, E' p4 [! s Y- O/ G
参数propagate为true就选出前Math.sqrt(peersLen)个节点,传播出块消息参数propagate为false 简单向所有节点声明我有这个块! H9 W! `" ^. N; |5 O8 I
调用:range pm.minedBlockSub.Chan() 如果管道里有消息会执行以下代码0 j+ u$ M4 O) N5 ~, f
pm.BroadcastBlock(ev.Block, true) // First propagate block to peers6 |6 {5 N7 C! h# {/ n- J8 P! L
pm.BroadcastBlock(ev.Block, false) // Only then announce to the rest
成为第一个吐槽的人