以太坊源码照抄 eth/handler
哈哈笑417
发表于 2023-1-5 18:37:02
83
0
0
eth主要的同步txs,block,header的入口都在这个文件里+ J+ }) J1 q# d% e
type ProtocolManager struct {) W8 f) v4 F, q$ S, A" D$ R3 m' n
...
downloader *downloader.Downloader // 名字是downloader 其实是就是在接受到数据后插入数据库8 ~3 }( Q0 H. n$ W5 e
fetcher *fetcher.Fetcher // 声明新的块 i6 [$ w8 [6 j: D; x* ^) L3 [+ K
peers *peerSet" V- L" Y7 B8 F4 H6 w. {
SubProtocols []p2p.Protocol. _5 H) G# p+ h( h0 J9 \
...
方法 NewProtocolManager初始化一个ProtocolManager结构
这一步有一个重要的内容就是append(SubProtocols, p2p.Protocols{})" @# w( N! o, `" [; @' L
manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{
Name: ProtocolName,- A o# y# w2 t/ }) g
Version: version,2 D) x$ v' B6 X! c& Y( L W1 ~
Length: ProtocolLengths,& b+ e! r3 C& n- L B& y5 q @/ u
Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
peer := manager.newPeer(int(version), p, rw)
select {* h3 d! `4 t1 e( ^/ o J+ m
case manager.newPeerCh / L2 K" g \/ _& E: a
func pm.handle()
这里newPeerCh接收到peer后调用pm.handle, 与pm同步txs,同时p同步pm.whiteList中的header
for number := range pm.whitelist {1 _4 x/ s9 P5 R7 r$ c8 {
if err := p.RequestHeadersByNumber(number, 1, 0, false); err != nil {! n. y0 ~. h& G0 S
return err4 T" Y# p, q: u; L( w8 @2 b
}+ y8 m6 m h5 I ~. l& @
}3 _0 E% k# R6 z9 M. f
同时进入循环处理来自peer的消息& J. q$ c& S8 ]7 Y: x. d5 W. V4 |$ B
for {
if err := pm.handleMsg(p); err != nil {
p.Log().Debug("Ethereum message handling failed", "err", err)
return err
}- n/ v- ?5 H* `
}
func pm.handleMsg(p *peer). u! C/ {0 w3 }) s5 k t
这个函数根据msg, err := p.rw.ReadMsg() msg的类型做出不同的处理,塞到fetcher 或者downloader中去等等
func.pm.BroadcastTxs(tx)
找到pm.peers.PeersWithoutTx(tx.Hash()) 然后把tx塞给他( V" Q) s9 @9 Q+ T0 Z
这个函数在 接受到消息时就会被调用7 O* d1 {; t; u9 |1 V0 H. t- ~
func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool)7 P2 n" c( r) z8 n5 W
这个就如题吧! i6 V1 \- e b4 Q# i
参数propagate为true就选出前Math.sqrt(peersLen)个节点,传播出块消息参数propagate为false 简单向所有节点声明我有这个块
调用:range pm.minedBlockSub.Chan() 如果管道里有消息会执行以下代码$ k3 s; o3 a. T! v# N( N
pm.BroadcastBlock(ev.Block, true) // First propagate block to peers
pm.BroadcastBlock(ev.Block, false) // Only then announce to the rest- H1 z5 \/ H! y* l. d1 |' |# k
成为第一个吐槽的人