以太坊源码照抄 eth/handler
哈哈笑417
发表于 2023-1-5 18:37:02
164
0
0
eth主要的同步txs,block,header的入口都在这个文件里& O' h: P5 z; A o4 e3 V
type ProtocolManager struct {4 a6 a% R6 m& G# q9 h- {! k
...+ D+ K" U, N/ \5 Z1 h
downloader *downloader.Downloader // 名字是downloader 其实是就是在接受到数据后插入数据库
fetcher *fetcher.Fetcher // 声明新的块. B5 [. a% L. j5 Q# P
peers *peerSet
SubProtocols []p2p.Protocol
...1 r* D5 ]/ Q. m2 r! I
方法 NewProtocolManager初始化一个ProtocolManager结构- o. p# T: X, a0 h1 J
这一步有一个重要的内容就是append(SubProtocols, p2p.Protocols{})
manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{, g8 g, r, D1 D, c; `& v
Name: ProtocolName,6 r* f1 \0 `2 f* S5 j4 i
Version: version,9 i. Z" h+ O4 J! ]5 V5 t$ ~) n# C% X S
Length: ProtocolLengths,
Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {4 F* s$ ^% l0 U% b2 V* S
peer := manager.newPeer(int(version), p, rw)
select {' N3 Q, U- p# M. N* P7 G: D
case manager.newPeerCh ; s$ X0 f' U, c: S8 {; K- ~( p
func pm.handle()6 q$ X7 ^) Y- H: w K
这里newPeerCh接收到peer后调用pm.handle, 与pm同步txs,同时p同步pm.whiteList中的header
for number := range pm.whitelist {
if err := p.RequestHeadersByNumber(number, 1, 0, false); err != nil {
return err% A. ]/ j, o+ ]- o7 L" q! z( Q
}
}
同时进入循环处理来自peer的消息, t, A( h* A, a, A% f1 h) F
for {
if err := pm.handleMsg(p); err != nil {8 D; k+ I/ Y+ o2 I z8 l1 I
p.Log().Debug("Ethereum message handling failed", "err", err)! F9 I" N+ u6 G2 A
return err
}
}/ P, x" i q3 n( E8 e) t- ~
func pm.handleMsg(p *peer)5 k6 S3 `% i4 h, d
这个函数根据msg, err := p.rw.ReadMsg() msg的类型做出不同的处理,塞到fetcher 或者downloader中去等等
func.pm.BroadcastTxs(tx)9 S$ x+ k$ D1 F
找到pm.peers.PeersWithoutTx(tx.Hash()) 然后把tx塞给他* A: Z, ?7 n& ^# l9 y
这个函数在 接受到消息时就会被调用
func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool)) J0 r' l! b! @1 X6 z1 y
这个就如题吧5 l, a. w2 p: F+ u$ v# f
参数propagate为true就选出前Math.sqrt(peersLen)个节点,传播出块消息参数propagate为false 简单向所有节点声明我有这个块
调用:range pm.minedBlockSub.Chan() 如果管道里有消息会执行以下代码
pm.BroadcastBlock(ev.Block, true) // First propagate block to peers
pm.BroadcastBlock(ev.Block, false) // Only then announce to the rest
成为第一个吐槽的人