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!