filecoin 기술 구조 분석의 6: filecoin 소스 코드 분석의 협의 층 hello 악수 프로 토 콜
8093 단어 filecoin
전편: filecoin 기술 구조 분석의 5: filecoin 개발 네트워크 사용 다음 편: filecoin 기술 구조 분석의 7: filecoin 소스 코드 분석의 프로 토 콜 층 저장 프로 토 콜
목차
6.1 목적
6.2 소스 정보
6.3 소스 코드 분석
6.3.1 데이터 구조
// Protocol is the libp2p protocol identifier for the hello protocol.
const protocol = "/fil/hello/1.0.0"
// 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)
type getTipSetFunc func() types.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")
// New peer connection notifications
type helloNotify Handler
//
const helloTimeout = time.Second * 10
6.3.2 방법
6.3.2.1 Handler 방법
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)
}
}
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
}
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 방법
func (hn *helloNotify) hello() *Handler {
return (*Handler)(hn)
}
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 함수
// 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 실례 화 및 업무 논리
type Node struct {
......
HelloSvc *hello.Handler
......
}
// 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 소스 코드 분석의 프로 토 콜 층 저장 프로 토 콜
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
filecoin 기술 구조 분석의 6: filecoin 소스 코드 분석의 협의 층 hello 악수 프로 토 콜6 filecoin 소스 코드 프로 토 콜 층 분석의 hello 악수 프로 토 콜 노드 가 출시 된 후의 블록 동기 화 악 수 를 처리 합 니 다. hello protocol/hello hello 프로 토 콜 메시지...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.