ProtocolManager的分析

1.数据结构

//eth/handler.go
type ProtocolManager struct {
    networkId uint64

    fastSync  uint32 // Flag whether fast sync is enabled (gets disabled if we already have blocks)
    acceptTxs uint32 // Flag whether we're considered synchronised (enables transaction processing)

    txpool      txPool
    blockchain  *core.BlockChain
    chainconfig *params.ChainConfig
    maxPeers    int

    downloader *downloader.Downloader
    fetcher    *fetcher.Fetcher
    peers      *peerSet

    SubProtocols []p2p.Protocol

    eventMux      *event.TypeMux
    txCh          chan core.TxPreEvent
    txSub         event.Subscription
    minedBlockSub *event.TypeMuxSubscription

    // channels for fetcher, syncer, txsyncLoop
    newPeerCh   chan *peer
    txsyncCh    chan *txsync
    quitSync    chan struct{}
    noMorePeers chan struct{}

    // wait group is used for graceful shutdowns during downloading
    // and processing
    wg sync.WaitGroup
}

ProtocolManager结构体从启动时看可以分为两部分

  • SubProtocols,这部分走node.Start()=>p2p.Server.Start()的流程,
    注册的回调函数会在node(node/node.go)的p2p.Server中使用,具体使用入口见https://www.jianshu.com/p/f04fd9095e74第7节,而消息处理方法的注册如下
//eth/handler.go
manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{
            Name:    ProtocolName,
            Version: version,
            Length:  ProtocolLengths[i],
            Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
                peer := manager.newPeer(int(version), p, rw)
                select {
                case manager.newPeerCh <- peer:
                    manager.wg.Add(1)
                    defer manager.wg.Done()
                     //handler函数在eth/handler.go 251L
                    return manager.handle(peer)
                case <-manager.quitSync:
                    return p2p.DiscQuitting
                }
            },
            NodeInfo: func() interface{} {
                return manager.NodeInfo()
            },
            PeerInfo: func(id discover.NodeID) interface{} {
                if p := manager.peers.Peer(fmt.Sprintf("%x", id[:8])); p != nil {
                    return p.Info()
                }
                return nil
            },
        })
  • 其他部分走node.Start()=>Ethereum.Start()=>protocolManager.Start的流程,具体见https://www.jianshu.com/p/ae9920adcff6

你可能感兴趣的:(ProtocolManager的分析)