Section1.6 communication

备注:文中所提到的函数都未带参数或参数不全,与源代码不同,并且挑选了关键函数,只用于说明。">>"代表调用。

geth>>startNode()>>utils.StartNode()>>Node.start()

位于node/node.go中的 func (n *Node) Start() error 用于创建一个p2p node,并运行它。

func (n *Node) Start() error {
    ...
    // Initialize the p2p server. This creates the node key and discovery databases.
    n.serverConfig = n.config.P2P
    ...
    running := &p2p.Server{Config: n.serverConfig}
    ...

    // Otherwise copy and specialize the P2P configuration
    services := make(map[reflect.Type]Service)
    for _, constructor := range n.serviceFuncs {
        // Create a new context for the particular service
        ctx := &ServiceContext{
            ...
        }
        for kind, s := range services { // copy needed for threaded access
            ctx.services[kind] = s
        }
        // Construct and save the service
        service, err := constructor(ctx)
        ...
        kind := reflect.TypeOf(service)
        ...
        services[kind] = service
    }
    // Gather the protocols and start the freshly assembled P2P server
    for _, service := range services {
        running.Protocols = append(running.Protocols, service.Protocols()...)
    }
    if err := running.Start(); err != nil {
        ...
    }
    // Start each of the services
    started := []reflect.Type{}
    for kind, service := range services {
        // Start the next service, stopping all previous upon failure
        if err := service.Start(running); err != nil {
            ...
        }
        // Mark the service started for potential cleanup
        started = append(started, kind)
    }
    // Lastly start the configured RPC interfaces
    if err := n.startRPC(services); err != nil {
        ...
    }
    // Finish initializing the startup
    n.services = services
    n.server = running
    n.stop = make(chan struct{})

    return nil
}

其中,Node.Start()又调用了ethereum/go-ethereum/p2p/server.go中的Server.Start()>>goroutine,Server.run()

Server.run()会调用newPeer()>>matchProtocols() ,matchProtocols() creates structures for matching named subprotocols.

Server.run()会调用runPeer()>>Peer.run()>>Peer.startProtocols()>>proto.Run(p, proto)

其中Run为结构体Protocol的成员变量,类型为func(peer *Peer, rw MsgReadWriter) error,在eth/handler.go中的NewProtocolManager()中赋值

该函数会间接调用ProtocolManager.handle(peer)>>ProtocolManager.handleMsg()

注意:通信过程涉及两个peer.go文件,一个位于ethereum/go-ethereum/p2p/peer.go,结构体为Peer(大写P);另一个geth-pbft/eth/peer.go,结构体为peer;

Last updated

Was this helpful?