Blockchain tutorial Fabric1.0 source code analysis rumor algorithm Gossip server 1

Keywords: Go Blockchain

In the second half of 2018, the blockchain industry is gradually fading away from the impetuosity and rationality at the beginning of development. On the surface, the demand and value of relevant talents seem to be falling. But in fact, it is the gradual decline of the initial bubble that gives people more attention to the real technology of the block chain.

Gossip (rumor algorithm) of Fabric 1.0 source code Notes: GossipServer (GossipServer)

1. Overview of GossipServer

The relevant codes of the GossipServer are distributed in the PROTOS / gossips and gossips / comm directories. The directory structure is as follows:

  • PROTOS / Mission Directory:

message.pb.go, GossipClient interface definition and implementation, and GossipServer interface definition.

  • Mission / comm Directory:

comm.go, comm interface definition.
* conn.go, connFactory interface definition, connectionStore structure and method.
Comm? Comm? Impl.go, commImpl structure and method (implement the GossipServer interface / comm interface / connFactory interface at the same time).
* demux.go, ChannelDeMultiplexer structure and method.

2. Definition and implementation of GossipClient interface

2.1 definition of GossipClient interface

type GossipClient interface {
    // GossipStream is the gRPC stream used for sending and receiving messages
    GossipStream(ctx context.Context, opts ...grpc.CallOption) (Gossip_GossipStreamClient, error)
    // Ping is used to probe a remote peer's aliveness
    Ping(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
}
//The code is in PROTOS / mission / message.pb.go

2.2 implementation of GossipClient interface

type gossipClient struct {
    cc *grpc.ClientConn
}

func NewGossipClient(cc *grpc.ClientConn) GossipClient {
    return &gossipClient{cc}
}

func (c *gossipClient) GossipStream(ctx context.Context, opts ...grpc.CallOption) (Gossip_GossipStreamClient, error) {
    stream, err := grpc.NewClientStream(ctx, &_Gossip_serviceDesc.Streams[0], c.cc, "/gossip.Gossip/GossipStream", opts...)
    if err != nil {
        return nil, err
    }
    x := &gossipGossipStreamClient{stream}
    return x, nil
}

func (c *gossipClient) Ping(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) {
    out := new(Empty)
    err := grpc.Invoke(ctx, "/gossip.Gossip/Ping", in, out, c.cc, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
//The code is in PROTOS / mission / message.pb.go

2.3 definition and implementation of gossipstreamclient interface

type Gossip_GossipStreamClient interface {
    Send(*Envelope) error
    Recv() (*Envelope, error)
    grpc.ClientStream
}

type gossipGossipStreamClient struct {
    grpc.ClientStream
}

func (x *gossipGossipStreamClient) Send(m *Envelope) error {
    return x.ClientStream.SendMsg(m)
}

func (x *gossipGossipStreamClient) Recv() (*Envelope, error) {
    m := new(Envelope)
    if err := x.ClientStream.RecvMsg(m); err != nil {
        return nil, err
    }
    return m, nil
}
//The code is in PROTOS / mission / message.pb.go

3. Definition of GossipServer interface

3.1 definition of GossipServer interface

type GossipServer interface {
    // GossipStream is the gRPC stream used for sending and receiving messages
    GossipStream(Gossip_GossipStreamServer) error
    // Ping is used to probe a remote peer's aliveness
    Ping(context.Context, *Empty) (*Empty, error)
}

func RegisterGossipServer(s *grpc.Server, srv GossipServer) {
    s.RegisterService(&_Gossip_serviceDesc, srv)
}

func _Gossip_GossipStream_Handler(srv interface{}, stream grpc.ServerStream) error {
    return srv.(GossipServer).GossipStream(&gossipGossipStreamServer{stream})
}

func _Gossip_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(Empty)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(GossipServer).Ping(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/gossip.Gossip/Ping",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(GossipServer).Ping(ctx, req.(*Empty))
    }
    return interceptor(ctx, in, info, handler)
}

var _Gossip_serviceDesc = grpc.ServiceDesc{
    ServiceName: "gossip.Gossip",
    HandlerType: (*GossipServer)(nil),
    Methods: []grpc.MethodDesc{
        {
            MethodName: "Ping",
            Handler:    _Gossip_Ping_Handler,
        },
    },
    Streams: []grpc.StreamDesc{
        {
            StreamName:    "GossipStream",
            Handler:       _Gossip_GossipStream_Handler,
            ServerStreams: true,
            ClientStreams: true,
        },
    },
    Metadata: "gossip/message.proto",
}
//The code is in PROTOS / mission / message.pb.go

3.2 definition and implementation of gossipstreamserver interface

type Gossip_GossipStreamServer interface {
    Send(*Envelope) error
    Recv() (*Envelope, error)
    grpc.ServerStream
}

type gossipGossipStreamServer struct {
    grpc.ServerStream
}

func (x *gossipGossipStreamServer) Send(m *Envelope) error {
    return x.ServerStream.SendMsg(m)
}

func (x *gossipGossipStreamServer) Recv() (*Envelope, error) {
    m := new(Envelope)
    if err := x.ServerStream.RecvMsg(m); err != nil {
        return nil, err
    }
    return m, nil
}
//The code is in PROTOS / mission / message.pb.go

4. Definition of Comm interface / connFactory interface

4.1 definition of Comm interface

type Comm interface {
    //Returns the PKI id of this instance
    GetPKIid() common.PKIidType
    //Send message to node
    Send(msg *proto.SignedGossipMessage, peers ...*RemotePeer)
    //Detect whether the remote node responds
    Probe(peer *RemotePeer) error
    //Handshake authentication remote node
    Handshake(peer *RemotePeer) (api.PeerIdentityType, error)
    Accept(common.MessageAcceptor) <-chan proto.ReceivedMessage
    //Get read-only channel of suspected offline node
    PresumedDead() <-chan common.PKIidType
    //Close connection to a node
    CloseConn(peer *RemotePeer)
    //Close
    Stop()
}
//The code is in visit / comm / comm.go

4.2. connFactory interface definition

type connFactory interface {
    createConnection(endpoint string, pkiID common.PKIidType) (*connection, error)
}
//The code is in visit / comm / conn.go

5. commImpl structure and method (realize the GossipServer interface / Comm interface / connFactory interface at the same time)

5.1 definition of commImpl structure

type commImpl struct {
    selfCertHash   []byte
    peerIdentity   api.PeerIdentityType
    idMapper       identity.Mapper
    logger         *logging.Logger
    opts           []grpc.DialOption
    secureDialOpts func() []grpc.DialOption
    connStore      *connectionStore
    PKIID          []byte
    deadEndpoints  chan common.PKIidType
    msgPublisher   *ChannelDeMultiplexer
    lock           *sync.RWMutex
    lsnr           net.Listener
    gSrv           *grpc.Server
    exitChan       chan struct{}
    stopWG         sync.WaitGroup
    subscriptions  []chan proto.ReceivedMessage
    port           int
    stopping       int32
}
//The code is in gossip/comm/comm_impl.go

To be continued, please continue to follow the brotherhood blockchain tutorial sharing!

Posted by Paavero on Thu, 12 Dec 2019 11:08:03 -0800