통신 프로세스

6701 단어 ethereum

통신 프로세스


비고: 글에서 언급한 함수는 매개 변수가 없거나 매개 변수가 완전하지 않으며 원본 코드와 다르며 관건적인 함수를 선택하여 설명에만 사용합니다.">>대표 호출.
geth>>startNode()>>utils.StartNode()>>Node.start() node/node.go에 있는 func (n *Node) Start() error 은 p2pnode를 만들고 실행하는 데 사용됩니다.
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()
func (srv *Server) run(dialstate dialer) {
    ...
    for {
        ...
        select {
        ...
        case c := // At this point the connection is past the protocol handshake.
            // Its capabilities are known and the remote identity is verified.
            glog.V(logger.Detail).Infoln(", c)
            err := srv.protoHandshakeChecks(peers, c)
            if err != nil {
                glog.V(logger.Detail).Infof("Not adding %v as peer: %v", c, err)
            } else {
                // The handshakes are done and it passed all checks.
                p := newPeer(c, srv.Protocols)
                peers[c.id] = p
                go srv.runPeer(p)
            }
            // The dialer logic relies on the assumption that
            // dial tasks complete after the peer has been added or
            // discarded. Unblock the task last.
            c.cont 

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의 New ProtocolManager () 에 값 할당
func NewProtocolManager(...) (*ProtocolManager, error) {
    // Create the protocol manager with the base fields
    manager := &ProtocolManager{
        ...
    }
    ...
    manager.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions))
    for i, version := range ProtocolVersions {
        ...
        manager.SubProtocols = append(manager.SubProtocols, p2p.Protocol{
            ...
            Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
                peer := manager.newPeer(int(version), p, rw)
                select {
                case manager.newPeerCh (1)
                    defer manager.wg.Done()
                    return manager.handle(peer)
                case return p2p.DiscQuitting
                }
            },
            ...
        })
    }
    ...
}

이 함수는 간접적으로 ProtocolManager를 호출합니다.handle(peer)>>ProtocolManager.handleMsg()
주의: 통신 과정은 두 개의 피어와 관련된다.go 파일, ethereum/go-ethereum/p2p/peer에 있습니다.go, 구조체는 Peer(대문자 P);또 다른 geth-pbft/eth/peer.go, 구조체는peer;

좋은 웹페이지 즐겨찾기