Hyperledger Fabric handles source parsing of communication between peer and peer

Source: Internet
Author: User
Tags bool constructor error handling key string rand touch valid hyperledger fabric

1. During the network initialization process, the node is connected to the other peer as the client during the creation of the node engine during the execution of the following

Peerserver, err = Peer. Newpeerwithengine (Sechelperfunc, Helper.) Getengine)
2. Returns a peer using the provided handler factory function to create a new handler handle on a new chat service call
Func Newpeerwithengine (Sechelperfunc func () crypto.

    Peer, Engfactory enginefactory) (Peer *impl, err error) {peer = new (Impl) Peernodes: = Peer.initdiscovery () Peer.handlermap = &handlermap{m:make (MAP[PB. Peerid]messagehandler)} Peer.isvalidator = validatorenabled () Peer.sechelper = Sechelperfunc ()//for peer installation security Like if securityenabled () {if Peer.sechelper = = Nil {return nil, fmt. Errorf ("Security Helper not provided")}}//Initialize the ledger before the engine because the consensus may want to start asking the ledger ledgerptr immediately, err: = Ledger. Getledger () if err! = Nil {return nil, fmt. Errorf ("Error Constructing Newpeerwithhandler:%s", err)} Peer.ledgerwrapper = &ledgerwrapper{ledger:ledgerp TR} peer.engine, err = engfactory (PEER) if err! = Nil {return nil, err} peer.handlerfactory = P Eer.engine.GetHandlerFactory () if peer.handlerfactory = = Nil {return nil, errors.

  New ("Cannot supply nil handler factory")}  Peer.chatwithsomepeers (Peernodes) return peer, nil}
 
2.1.NewPeerWithHandler Returns a peer that uses the provided handler factory function to create a new handlers handle on a new chat service call,
Func Newpeerwithhandler (Sechelperfunc func () crypto. Peer, Handlerfact handlerfactory) (*impl, error) {
    Peer: = new (Impl)
    peernodes: = Peer.initdiscovery ()

    if Handlerfact = = Nil {
        return nil, errors. New ("Cannot supply nil handler factory")
    }
    peer.handlerfactory = handlerfact
    Peer.handlermap = & Handlermap{m:make (MAP[PB. Peerid]messagehandler)}

    peer.sechelper = Sechelperfunc ()

    //Install security object for peer
    if securityenabled () {
        if Peer.sechelper = = Nil {
            return nil, FMT. Errorf ("Security Helper not provided")
        }
    }

    ledgerptr, err: = Ledger. Getledger ()
    if err! = Nil {
        return nil, FMT. Errorf ("Error Constructing Newpeerwithhandler:%s", err)
    }
    peer.ledgerwrapper = &ledgerwrapper{ledger: LEDGERPTR}

    peer.chatwithsomepeers (peernodes)
    return peer, nil
}
2.2.Discovery is the merge boot Peer member selection and the VP node selection interface for the NVP node
Type Discovery Interface {AddNode (string) bool//Add an address to Discovery list RemoveNode (string) bool// Remove an address from the Discovery List getallnodes () []string//Return all addresses maintained by this node getrandomnodes (n int) []string//return this peer connection with the Machine address FindNode (STRING) bool//Find a node in the Discovery List}//Discoveryimpl is a discovery implementation type Discoveryimpl struct {Sync. Rwmutex nodes map[string]bool seq []string random *rand. Rand}//Newdiscoveryimpl is a discovery implemented constructor func Newdiscoveryimpl () *discoveryimpl {di: = discoveryimpl{} DI.N Odes = Make (map[string]bool) Di.random = rand. New (Rand. Newsource (time. Now (). Unix ())) return &di}//AddNode Add an address to Discovery list func (di *discoveryimpl) AddNode (address string) bool {di . Lock () defer di. Unlock () If _, OK: = di.nodes[address];!ok {di.seq = append (di.seq, address) di.nodes[address] = Tru e} return di.nodes[address]}//Removenode Remove an address from the Discovery list func (di *dIscoveryimpl) RemoveNode (address string) bool {di. Lock () defer di. Unlock () If _, OK: = di.nodes[address]; OK {Di.nodes[address] = False return True} return false}//Getallnodes returns all addresses maintained by this node func (di *discoveryimpl) getallnodes () []string {di. Rlock () defer di.  Runlock () var addresses []string for address, valid: = Range Di.nodes {If valid {addresses = Append (addresses, address)//TODO expensive, don ' t quite like it}} return addresses}//Getrandomnod ES returns n Random node func (di *discoveryimpl) getrandomnodes (n int) []string {var pick string randomnodes: = Make ([]string , N) di. Rlock () defer di. Runlock () for I: = 0; I < n; i++ {for {pick = DI.SEQ[DI.RANDOM.INTN (len (di.nodes))] if Di.nodes[pick] &&!ina Rray (pick, randomnodes) {break}} Randomnodes[i] = pick} return ran
Domnodes}
FindNode If the address is stored in the Discovery list, it returns true Func (Di *discoveryimpl) FindNode (address string) bool {di. Rlock () defer di. Runlock () _, OK: = di.nodes[address] return OK} func InArray (element string, array []string) bool {for _, V
 Al: = Range Array {if val = = element {return true}} return False}
2.3.Peer is an entity capable of validating transactions
Type Peer interface {
    Node

    ///GetID Returns the authentication identifier of a peer
    GetID () []byte

    //Getenrollmentid returns the registration ID of this peer
    Getenrollmentid () string

    //sign If there is no error with this authenticator signing key signing message and signing everywhere sign
    (msg []byte) ([]byte, error)

    // Verify checks if the signature is a valid signature for the message under the Vkid authentication key/
    /If the check succeeds, Verify return null means that no error occurred
    //If the Vkid is empty, then verify the signature against the authenticator's authentication key.
    Verify (Vkid, signature, message []byte) error
}
3. Save to disk before loading addresses from discovery list and add them to the current discovery list
Func (P *impl) initdiscovery () []string {
    p.dischelper = discovery. Newdiscoveryimpl ()
    p.discpersist = viper. Getbool ("Peer.discovery.persist")
    if!p.discpersist {
        peerlogger.warning ("Discovery list would not be Persisted to disk ")
    }
    //Load some pre-saved address
    addresses, err: = P.loaddiscoverylist ()
    if err! = Nil {
        Peerlogger.errorf ("%s", err)
    }
    for _, Address: = Range addresses {//Add them to the current discovery list
  
   _ = P.dischelper.addnode (address)
    }
    PEERLOGGER.DEBUGF ("Retrieved Discovery list from disk:%v", addresses) c14/>//parsing configuration files, env flags, and so on.
    Rootnodes: = Strings. Split (Viper. GetString ("Peer.discovery.rootnode"), ",")
    if! ( Len (rootnodes) = = 1 && strings. Compare (Rootnodes[0], "") = = 0) {
        addresses = append (Rootnodes, P.dischelper.getallnodes () ...)
    }
    return addresses
}

  
4.NewDiscoveryImpl is an implementation of a discovery constructor
Func Newdiscoveryimpl () *discoveryimpl {
    di: = discoveryimpl{}
    di.nodes = Make (Map[string]bool)
    di.random = Rand. New (Rand. Newsource (time. Now (). Unix ()))
    return &di
}
4.1. Related structures.
Type Discoveryimpl struct {
    sync. Rwmutex
    nodes  map[string]bool
    seq    []string
    random *rand. Rand
}
5. Load some pre-saved addresses, loaddiscoverylist a peer from the database to the Discovery list
Func (P *impl) loaddiscoverylist ([]string, error) {
    var err error
    packed, err: = P.load ("discovery")
    If Err ! = Nil {
        err = fmt. Errorf ("Unable to load discovery list from DB:%s", err)
        peerlogger.error (err)
        return nil, err
    }
    Addresses: = &PB. peersaddresses{}
    Err = Proto. Unmarshal (packed, addresses)
    if err! = Nil {
        err = fmt. Errorf ("Could not unmarshal Discovery List message:%s", err)
        peerlogger.error (err)
    }
    return addresses. Addresses, Err
}
5.1.PeersAddresses Definition
Type peersaddresses struct {
    Addresses []string ' protobuf: ' bytes,1,rep,name=addresses ' json: ' Addresses, Omitempty "'
}
5.2 Unmarshaler is an interface that represents an object that can be solved by the group itself. The method should reset the receiver before decoding begins. The parameter points to the data that may be overwritten, so the implementation should not keep a reference to the buffer.
Type Unmarshaler Interface {
    unmarshal ([]byte) Error
}
6.Load enables a peer to read a value corresponding to a given database key
Func (P *impl) Load (key String) ([]byte, error) {
    db: = db. Getdbhandle ()
    return db. Get (db. PERSISTCF, []byte (key)
}
7.AddNode add address to Discovery list
Func (di *discoveryimpl) AddNode (address string) bool {
    di. Lock ()
    defer di. Unlock ()
    If _, OK: = di.nodes[address];!ok {
        di.seq = append (di.seq, address)
        di.nodes[address] = True
    }
    return di.nodes[address]
}
8.ValidatorEnabled Returns whether peer.validator.enabled is available
Func validatorenabled () bool {
    If!configurationcached {
        cacheconfiguration ()
    }
    return Validatorenabled
}
9.SecurityEnabled return safe available performance from configuration
Func securityenabled () bool {
    If!configurationcached {
        cacheconfiguration ()
    }
    return SecurityEnabled
}
the 10.Engine interface is responsible for managing peer communication (handlers) and trading processes, Gethandlerfactory returns a handler handle to receive chat streams
Type Engine interface {
    transactionproccesor
    gethandlerfactory () handlerfactory
}
11.chatWithSomePeers initiates a chat node with 1 or all peers based on whether the node is being validated
Func (P *impl) chatwithsomepeers (addresses []string) {
    p.reconnectonce.do (func () {
        go p.ensureconnected ()
    })
    If Len (addresses) = = 0 {
        peerlogger.debug ("Starting up the first peer of a new network")
        return//Nothing to do
    }< C13/>for _, Address: = Range addresses {
        If PE, err: = Getpeerendpoint (); err = = Nil
            {if address = = PE. Address {
                PEERLOGGER.DEBUGF ("Skipping own address:%v", address)
                continue
            }
        } else {
            Peerlogger.errorf ("Failed to obtain peer endpoint,%v", err)
            return
        }
        go P.chatwithpeer (address)
    }
}
12. Make sure that the nodes are connected properly
Func (P *impl) ensureconnected () {touchperiod: = viper. Getduration ("Peer.discovery.touchPeriod") Touchmaxnodes: = Viper. GetInt ("Peer.discovery.touchMaxNodes") Tickchan: = time. Newticker (Touchperiod).
        C PEERLOGGER.DEBUGF ("Starting Peer Reconnect Service (touch service), with period =%s", touchperiod) for { Simple loop and check if you need to reconnect <-tickchan peersmsg, err: = P.getpeers () if err! = Nil {Peerl Ogger. Errorf ("Error in touch Service:%s", err.)
        Error ())} Allnodes: = P.dischelper.getallnodes ()///These always is returned in random order If Len (peersmsg.peers) < Len (allnodes) {peerlogger.warning ("Touch service indicates dropped connections, Attempting to reconnect ... ") Delta: = util. Findmissingelements (Allnodes, getpeeraddresses (peersmsg)) If Len (delta) > touchmaxnodes {D Elta = Delta[:touchmaxnodes]} p.chatwithsomepeers (dELTA)} else {peerlogger.debug ("Touch service indicates no dropped connections")} PE ERLOGGER.DEBUGF ("Connected to:%v", Getpeeraddresses (peersmsg)) PEERLOGGER.DEBUGF ("Discovery knows on:%v", all
 Nodes)}}
13.GetPeerEndpoint returning Peerendpoint from the cache configuration
Func getpeerendpoint () (*PB. Peerendpoint, error) {
    If!configurationcached {
        cacheconfiguration ()
    }
    return Peerendpoint, Peerendpointerror
}
communication processing between 14.Peer nodes
Func (P *impl) chatwithpeer (address string) error {
    PEERLOGGER.DEBUGF ("initiating Chat with peer address:%s", address )
    conn, err: = newpeerclientconnectionwithaddress (address)
    if err! = Nil {
        Peerlogger.errorf ("Error Creating connection to peer address%s:%s ", address, Err)
        return err
    }
    serverclient: = PB. Newpeerclient (conn)
    CTX: = context. Background ()
    stream, Err: = Serverclient.chat (CTX)
    if err! = Nil {
        Peerlogger.errorf ("Error establishing Chat with peer address%s:%s ", address, Err)
        return err
    }
    PEERLOGGER.DEBUGF (" Established chat with peer ad Dress:%s ", address)
    err = P.handlechat (CTX, Stream, true)
    stream. Closesend ()
    if err! = Nil {
        Peerlogger.errorf ("Ending Chat with peer address%s due to error:%s", address, err)
        return err
    }
    return Nil
}
15. Return to the currently registered Peerendpoints
Func (P *impl) getpeers () (*PB. Peersmessage, error) {
    p.handlermap.rlock ()
    defer p.handlermap.runlock ()
    peers: = []*PB. peerendpoint{}
    for _, Msghandler: = Range p.handlermap.m {
        Peerendpoint, err: = Msghandler.to ()
        if err! = Nil {
            return nil, FMT. Errorf ("Error Getting peers:%s", err)
        }
        peers = append (peers, &peerendpoint)
    }
    peersmessage: = & AMP;PB. Peersmessage{peers:peers}
    return peersmessage, nil
}
15.1. Standard interface for handling open-chain messages
Type MessageHandler interface {
    remoteledger
    handlemessage (msg *pb. Message) Error
    SendMessage (msg *pb. Message) error to
    () (PB. Peerendpoint, error)
    Stop () error
}
16.GetAllNodes Returns an array of all addresses stored in the discovery list
Func (di *discoveryimpl) getallnodes () []string {
    di. Rlock ()
    defer di. Runlock ()
    var addresses []string
    for address, valid: = Range Di.nodes {
        If valid {
            addresses = append (addr Esses, address)//TODO expensive, don ' t quite like it
        }
    }
    return addresses
}
17.FindMissingElements identifies an element in the first slice that does not exist in the second slice, and the second slice is expected to be a subset of the first slice
Func findmissingelements (all []string, some []string] (Delta []string) {All
:
    for _, V1: = Range All {for
        _, V2: = range Some {
            if strings. Compare (v1, v2) = = 0 {
                continue all
            }
        }
        delta = append (Delta, v1)
    }
    return
}
Newpeerclientconnectionwithaddress Returns a new grpc.clientconn to configure the local peer
Func newpeerclientconnectionwithaddress (peeraddress string) (*grpc. Clientconn, error) {
    if comm. Tlsenabled () {
        return comm. Newclientconnectionwithaddress (Peeraddress, True, True, Comm. Inittlsforpeer ())
    }
    return comm. Newclientconnectionwithaddress (Peeraddress, True, false, nil)
}
19. Accept a stream message during the chat session while receiving other messages (for example, from another peer)
Type Peerclient Interface {
    //accepts a stream message during the chat session while receiving other messages (such as from another peer)
    Chat (CTX context. Context, opts ... grpc. Calloption) (peer_chatclient, error)
    //Handles transaction processtransaction from the remote source
    (CTX context. Context, in *transaction, opts ... grpc. Calloption) (*response, error)
}
Handlechat The execution process, the message loop is established, and here the handler. Handlemessage. This handler is the engine's message response handle, which is handled from the consensus module
Func (P *impl) handlechat (CTX context. Context, Stream chatstream, initiatedstream bool) error {
    deadline, OK: = ctx. Deadline ()
    PEERLOGGER.DEBUGF ("current Context Deadline =%s, OK =%v", Deadline, OK)
    handler, err: = P.handlerfact Ory (P, Stream, Initiatedstream)
    if err! = Nil {
        return FMT. Errorf ("Error creating handler during Handlechat Initiation:%s", err)
    }
    defer handler. Stop ()
    for {
        in, err: = stream. RECV ()
        If err = = Io. EOF {
            peerlogger.debug ("Received eof, ending Chat")
            return nil
        }
        if err! = Nil {
            e: = fmt. Errorf ("Error during Chat, stopping handler:%s", err)
            Peerlogger.error (E.error ())
            return e
        }
        err = handler. Handlemessage (in)
        if err! = Nil {
            Peerlogger.errorf ("Error Handling message:%s", err)
            //return err
        }
    }
}
21.Impl is the implementation of peer services
Type Impl struct {
    handlerfactory handlerfactory
    handlermap     *handlermap
    ledgerwrapper  * Ledgerwrapper
    sechelper      Crypto. Peer
    engine         engine
    isvalidator    bool
    reconnectonce  sync. Once
    dischelper     discovery. Discovery
    discpersist    bool
}
22.MessageHandler standard interface for processing open-chain messages
Type MessageHandler interface {
    remoteledger
    handlemessage (msg *pb. Message) Error
    SendMessage (msg *pb. Message) error to
    () (PB. Peerendpoint, error)
    Stop () error
}
23.ChatStream two peer stream support interface
Type Chatstream Interface {
    Send (*PB. Message) Error
    Recv () (*PB. Message, error)
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.