Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

以太坊源码照抄 eth/handler

哈哈笑417
164 0 0
不想写了,啊啊啊( E: M# M5 p) ]4 Q. s, O& b
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 其实是就是在接受到数据后插入数据库
. r/ @9 s: F* _/ u/ u        fetcher    *fetcher.Fetcher  // 声明新的块. B5 [. a% L. j5 Q# P
        peers      *peerSet
% z  [; m1 m6 T2 h% M        SubProtocols []p2p.Protocol
4 h/ `: G! h% E        ...1 r* D5 ]/ Q. m2 r! I
方法 NewProtocolManager初始化一个ProtocolManager结构- o. p# T: X, a0 h1 J
这一步有一个重要的内容就是append(SubProtocols, p2p.Protocols{})
5 O9 W1 z/ F& omanager.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,
$ R; m, B3 [" Y3 q$ Z        Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {4 F* s$ ^% l0 U% b2 V* S
                peer := manager.newPeer(int(version), p, rw)
& C. |0 p2 \  j+ J. f                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
2 k4 I7 R  J4 r& B& ofor number := range pm.whitelist {
4 R( t8 _; n! T& O& ~5 Z6 ]1 B7 D        if err := p.RequestHeadersByNumber(number, 1, 0, false); err != nil {
" b3 H6 K8 j& ^! m; g                return err% A. ]/ j, o+ ]- o7 L" q! z( Q
        }
0 `4 ?1 W( v% [! y2 C& T}
- M% N: O9 \( z* i% ~) H: w同时进入循环处理来自peer的消息, t, A( h* A, a, A% f1 h) F
for {
4 d  x7 r% e& i- i        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
5 M. V! y% L& e3 L        }
9 F8 [. v7 W6 g9 W! K}/ 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中去等等
, \4 y4 q( l" Tfunc.pm.BroadcastTxs(tx)9 S$ x+ k$ D1 F
找到pm.peers.PeersWithoutTx(tx.Hash()) 然后把tx塞给他* A: Z, ?7 n& ^# l9 y
这个函数在 接受到消息时就会被调用
' @0 W; @% L! h3 s! p: ~+ ^; Z1 y. yfunc (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 简单向所有节点声明我有这个块
& H- d$ n: {  _, Z

0 F- _1 e3 H6 }; H! m调用:range pm.minedBlockSub.Chan() 如果管道里有消息会执行以下代码
+ f% D! O! j6 xpm.BroadcastBlock(ev.Block, true)  // First propagate block to peers
' e0 `+ B  V1 [( [  Zpm.BroadcastBlock(ev.Block, false) // Only then announce to the rest
) Z9 E6 A/ B7 W/ ?& p8 O
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

哈哈笑417 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    11