filecoin 기술 구조 분석의 6: filecoin 소스 코드 분석의 협의 층 hello 악수 프로 토 콜

8093 단어 filecoin
본문 저자: 선 하 시스템 양 위;오리지널 작품, 전재 출처 를 밝 혀 주 십시오.
전편: filecoin 기술 구조 분석의 5: filecoin 개발 네트워크 사용 다음 편: filecoin 기술 구조 분석의 7: filecoin 소스 코드 분석의 프로 토 콜 층 저장 프로 토 콜
목차
  • 6 filecoin 소스 코드 프로 토 콜 층 분석의 hello 악수 프로 토 콜
  • 6.1 목적
  • 6.2 소스 정보
  • 6.3 소스 코드 분석
  • 6.3.1 데이터 구조
  • 6.3.2 방법
  • 6.3.3 함수
  • 6.3.4 실례 화 및 업무 논리


  • 6.1 목적
  • 노드 가 출시 된 후의 블록 동기 화 악 수 를 처리 합 니 다.

  • 6.2 소스 정보
  • version
  • master 분기 619 b0eb 1 (2019 년 3 월 2 일)
  • package
  • hello

  • location
  • protocol/hello
  • node/node.go


  • 6.3 소스 코드 분석
    6.3.1 데이터 구조
  • 프로 토 콜 이름 정의
  • // Protocol is the libp2p protocol identifier for the hello protocol.
    const protocol = "/fil/hello/1.0.0"
    
  • hello 프로 토 콜 메시지 구조 정의
  • TipSet 절편
  • TipSet 높이
  • 창세 블록 cid
  • // Message is the data structure of a single message in the hello protocol.
    type Message struct {
    	HeaviestTipSetCids   []cid.Cid
    	HeaviestTipSetHeight uint64
    	GenesisHash          cid.Cid
    }
    
  • 동기 반전 함수 형식 정의
  • type syncCallback func(from peer.ID, cids []cid.Cid, height uint64)
    
  • Tipstet 함수 형식 정의 가 져 오기
  • type getTipSetFunc func() types.TipSet
    
  • Handler 구조 체 는 다른 노드 에 연 결 될 때 하 나 는 본 노드 정 보 를 포함 한 hello 메 시 지 를 엔 드 노드 에 보 냅 니 다.둘째, 엔 드 에 도 엔 드 노드 정 보 를 포함 한 메시지 체 를 답장 합 니 다.
  • host 대응 libp2p 호스트
  • 창세 블록 cid
  • 블록 동기 반전 함수
  • TipSet 함수 가 져 오기
  • // Handler implements the 'Hello' protocol handler. Upon connecting to a new
    // node, we send them a message containing some information about the state of
    // our chain, and receive the same information from them. This is used to
    // initiate a chainsync and detect connections to forks.
    type Handler struct {
    	host host.Host
    
    	genesis cid.Cid
    
    	// chainSyncCB is called when new peers tell us about their chain
    	chainSyncCB syncCallback
    
    	// getHeaviestTipSet is used to retrieve the current heaviest tipset
    	// for filling out our hello messages.
    	getHeaviestTipSet getTipSetFunc
    }
    
  • 잘못된 창세 블록
  • // ErrBadGenesis is the error returned when a missmatch in genesis blocks happens.
    var ErrBadGenesis = fmt.Errorf("bad genesis block")
    
  • 이상 은 기본적으로 hello 클 라 이언 트 로 서 의 정의 이 고 다음은 hello 서버 로 서 의 정의
  • // New peer connection notifications
    type helloNotify Handler
    
    //       
    const helloTimeout = time.Second * 10
    

    6.3.2 방법
    6.3.2.1 Handler 방법
  • 흐름 함수 처리, 원 격 노드 의 hello 메시지 수신
  • func (h *Handler) handleNewStream(s net.Stream) {
    	defer s.Close() // nolint: errcheck
    
        //        
    	from := s.Conn().RemotePeer()
    
    	var hello Message
        //       hello    
    	if err := cbu.NewMsgReader(s).ReadMsg(&hello); err != nil {
    		log.Warningf("bad hello message from peer %s: %s", from, err)
    		return
    	}
    
        //   processHelloMessage             
    	switch err := h.processHelloMessage(from, &hello); err {
        //          ,       ,    
    	case ErrBadGenesis:
    		log.Warningf("genesis cid: %s does not match: %s, disconnecting from peer: %s", &hello.GenesisHash, h.genesis, from)
    		s.Conn().Close() // nolint: errcheck
    		return
    	case nil: // ok, noop
    	default:
    		log.Error(err)
    	}
    }
    
  • hello 메시지 처리
  • func (h *Handler) processHelloMessage(from peer.ID, msg *Message) error {
        //          ,  
    	if !msg.GenesisHash.Equals(h.genesis) {
    		return ErrBadGenesis
    	}
    
        //         
        //        node    hello         
    	h.chainSyncCB(from, msg.HeaviestTipSetCids, msg.HeaviestTipSetHeight)
    	return nil
    }
    
  • 원 격 노드 의 연결 에 응답 하고 hello 메시지 체
  • 에 답장 합 니 다.
    func (h *Handler) getOurHelloMessage() *Message {
    	heaviest := h.getHeaviestTipSet()
    	height, err := heaviest.Height()
    	if err != nil {
    		panic("somehow heaviest tipset is empty")
    	}
    
    	return &Message{
    		GenesisHash:          h.genesis,
    		HeaviestTipSetCids:   heaviest.ToSortedCidSet().ToSlice(),
    		HeaviestTipSetHeight: height,
    	}
    }
    
    func (h *Handler) sayHello(ctx context.Context, p peer.ID) error {
    	s, err := h.host.NewStream(ctx, p, protocol)
    	if err != nil {
    		return err
    	}
    	defer s.Close() // nolint: errcheck
    
        //      hello   
    	msg := h.getOurHelloMessage()
    
        //          
    	return cbu.NewMsgWriter(s).WriteMsg(&msg)
    }
    

    6.3.2.2 hello Notify 방법
  • hello 방법, handler 인 스 턴 스
  • 를 되 돌려 줍 니 다.
    func (hn *helloNotify) hello() *Handler {
    	return (*Handler)(hn)
    }
    
  • hello Notify 는 libp2p - net / interface. go 의 Notifie 인터페이스
  • 를 실현 했다.
    func (hn *helloNotify) Connected(n net.Network, c net.Conn) {
    	go func() {
    		ctx, cancel := context.WithTimeout(context.Background(), helloTimeout)
    		defer cancel()
    		p := c.RemotePeer()
            //             sayHello,  hello   
    		if err := hn.hello().sayHello(ctx, p); err != nil {
    			log.Warningf("failed to send hello handshake to peer %s: %s", p, err)
    		}
    	}()
    }
    
    func (hn *helloNotify) Listen(n net.Network, a ma.Multiaddr)      {}
    func (hn *helloNotify) ListenClose(n net.Network, a ma.Multiaddr) {}
    func (hn *helloNotify) Disconnected(n net.Network, c net.Conn)    {}
    func (hn *helloNotify) OpenedStream(n net.Network, s net.Stream)  {}
    func (hn *helloNotify) ClosedStream(n net.Network, s net.Stream)  {}
    

    6.3.3 함수
  • hello 인 스 턴 스 생 성
  • // New creates a new instance of the hello protocol and registers it to
    // the given host, with the provided callbacks.
    func New(h host.Host, gen cid.Cid, syncCallback syncCallback, getHeaviestTipSet getTipSetFunc) *Handler {
    	hello := &Handler{
    		host:              h,
    		genesis:           gen,
    		chainSyncCB:       syncCallback,
    		getHeaviestTipSet: getHeaviestTipSet,
    	}
    
        //         
    	h.SetStreamHandler(protocol, hello.handleNewStream)
    
        //              
    	// register for connection notifications
    	h.Network().Notify((*helloNotify)(hello))
    
    	return hello
    }
    
    
    
    //    helloNotify    libp2p-net/interface.go  Notifiee  
    // Notifiee is an interface for an object wishing to receive
    // notifications from a Network.
    type Notifiee interface {
    	Listen(Network, ma.Multiaddr)      // called when network starts listening on an addr
    	ListenClose(Network, ma.Multiaddr) // called when network stops listening on an addr
    	Connected(Network, Conn)           // called when a connection opened
    	Disconnected(Network, Conn)        // called when a connection closed
    	OpenedStream(Network, Stream)      // called when a stream opened
    	ClosedStream(Network, Stream)      // called when a stream closed
    
    	// TODO
    	// PeerConnected(Network, peer.ID)    // called when a peer connected
    	// PeerDisconnected(Network, peer.ID) // called when a peer disconnected
    }
    

    6.3.4 실례 화 및 업무 논리
  • location: node/node.go
  • Node 노드 에서 hello 서비스
  • 를 정의 했다.
    type Node struct {
        ......
    
    	HelloSvc     *hello.Handler
        ......
    }
    
  • hello 서비스 시작
  • // Start boots up the node.
    func (node *Node) Start(ctx context.Context) error {
        ......
    
    	// Start up 'hello' handshake service
        //            
    	syncCallBack := func(pid libp2ppeer.ID, cids []cid.Cid, height uint64) {
    		// TODO it is possible the syncer interface should be modified to
    		// make use of the additional context not used here (from addr + height).
    		// To keep things simple for now this info is not used.
            //               
    		err := node.Syncer.HandleNewBlocks(context.Background(), cids)
    		if err != nil {
    			log.Infof("error handling blocks: %s", types.NewSortedCidSet(cids...).String())
    		}
    	}
        //   hello  
    	node.HelloSvc = hello.New(node.Host(), node.ChainReader.GenesisCid(), syncCallBack, node.ChainReader.Head)
    
        ......
    }
    

    전편: filecoin 기술 구조 분석의 5: filecoin 개발 네트워크 사용 다음 편: filecoin 기술 구조 분석의 7: filecoin 소스 코드 분석의 프로 토 콜 층 저장 프로 토 콜

    좋은 웹페이지 즐겨찾기