github.com/defanghe/fabric@v2.1.1+incompatible/gossip/comm/comm.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package comm 8 9 import ( 10 "encoding/json" 11 "fmt" 12 "time" 13 14 "github.com/hyperledger/fabric/gossip/api" 15 "github.com/hyperledger/fabric/gossip/common" 16 "github.com/hyperledger/fabric/gossip/protoext" 17 ) 18 19 // Comm is an object that enables to communicate with other peers 20 // that also embed a CommModule. 21 type Comm interface { 22 23 // GetPKIid returns this instance's PKI id 24 GetPKIid() common.PKIidType 25 26 // Send sends a message to remote peers asynchronously 27 Send(msg *protoext.SignedGossipMessage, peers ...*RemotePeer) 28 29 // SendWithAck sends a message to remote peers, waiting for acknowledgement from minAck of them, or until a certain timeout expires 30 SendWithAck(msg *protoext.SignedGossipMessage, timeout time.Duration, minAck int, peers ...*RemotePeer) AggregatedSendResult 31 32 // Probe probes a remote node and returns nil if its responsive, 33 // and an error if it's not. 34 Probe(peer *RemotePeer) error 35 36 // Handshake authenticates a remote peer and returns 37 // (its identity, nil) on success and (nil, error) 38 Handshake(peer *RemotePeer) (api.PeerIdentityType, error) 39 40 // Accept returns a dedicated read-only channel for messages sent by other nodes that match a certain predicate. 41 // Each message from the channel can be used to send a reply back to the sender 42 Accept(common.MessageAcceptor) <-chan protoext.ReceivedMessage 43 44 // PresumedDead returns a read-only channel for node endpoints that are suspected to be offline 45 PresumedDead() <-chan common.PKIidType 46 47 // IdentitySwitch returns a read-only channel about identity change events 48 IdentitySwitch() <-chan common.PKIidType 49 50 // CloseConn closes a connection to a certain endpoint 51 CloseConn(peer *RemotePeer) 52 53 // Stop stops the module 54 Stop() 55 } 56 57 // RemotePeer defines a peer's endpoint and its PKIid 58 type RemotePeer struct { 59 Endpoint string 60 PKIID common.PKIidType 61 } 62 63 // SendResult defines a result of a send to a remote peer 64 type SendResult struct { 65 error 66 RemotePeer 67 } 68 69 // Error returns the error of the SendResult, or an empty string 70 // if an error hasn't occurred 71 func (sr SendResult) Error() string { 72 if sr.error != nil { 73 return sr.error.Error() 74 } 75 return "" 76 } 77 78 // AggregatedSendResult represents a slice of SendResults 79 type AggregatedSendResult []SendResult 80 81 // AckCount returns the number of successful acknowledgements 82 func (ar AggregatedSendResult) AckCount() int { 83 c := 0 84 for _, ack := range ar { 85 if ack.error == nil { 86 c++ 87 } 88 } 89 return c 90 } 91 92 // NackCount returns the number of unsuccessful acknowledgements 93 func (ar AggregatedSendResult) NackCount() int { 94 return len(ar) - ar.AckCount() 95 } 96 97 // String returns a JSONed string representation 98 // of the AggregatedSendResult 99 func (ar AggregatedSendResult) String() string { 100 errMap := map[string]int{} 101 for _, ack := range ar { 102 if ack.error == nil { 103 continue 104 } 105 errMap[ack.Error()]++ 106 } 107 108 ackCount := ar.AckCount() 109 output := map[string]interface{}{} 110 if ackCount > 0 { 111 output["successes"] = ackCount 112 } 113 if ackCount < len(ar) { 114 output["failures"] = errMap 115 } 116 b, _ := json.Marshal(output) 117 return string(b) 118 } 119 120 // String converts a RemotePeer to a string 121 func (p *RemotePeer) String() string { 122 return fmt.Sprintf("%s, PKIid:%v", p.Endpoint, p.PKIID) 123 }