github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/gossip/discovery/discovery.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package discovery 18 19 import ( 20 "fmt" 21 22 "github.com/inklabsfoundation/inkchain/gossip/common" 23 proto "github.com/inklabsfoundation/inkchain/protos/gossip" 24 ) 25 26 // CryptoService is an interface that the discovery expects to be implemented and passed on creation 27 type CryptoService interface { 28 // ValidateAliveMsg validates that an Alive message is authentic 29 ValidateAliveMsg(message *proto.SignedGossipMessage) bool 30 31 // SignMessage signs a message 32 SignMessage(m *proto.GossipMessage, internalEndpoint string) *proto.Envelope 33 } 34 35 // EnvelopeFilter may or may not remove part of the Envelope 36 // that the given SignedGossipMessage originates from. 37 type EnvelopeFilter func(message *proto.SignedGossipMessage) *proto.Envelope 38 39 // Sieve defines the messages that are allowed to be sent to some remote peer, 40 // based on some criteria. 41 // Returns whether the sieve permits sending a given message. 42 type Sieve func(message *proto.SignedGossipMessage) bool 43 44 // DisclosurePolicy defines which messages a given remote peer 45 // is eligible of knowing about, and also what is it eligible 46 // to know about out of a given SignedGossipMessage. 47 // Returns: 48 // 1) A Sieve for a given remote peer. 49 // The Sieve is applied for each peer in question and outputs 50 // whether the message should be disclosed to the remote peer. 51 // 2) A EnvelopeFilter for a given SignedGossipMessage, which may remove 52 // part of the Envelope the SignedGossipMessage originates from 53 type DisclosurePolicy func(remotePeer *NetworkMember) (Sieve, EnvelopeFilter) 54 55 // CommService is an interface that the discovery expects to be implemented and passed on creation 56 type CommService interface { 57 // Gossip gossips a message 58 Gossip(msg *proto.SignedGossipMessage) 59 60 // SendToPeer sends to a given peer a message. 61 // The nonce can be anything since the communication module handles the nonce itself 62 SendToPeer(peer *NetworkMember, msg *proto.SignedGossipMessage) 63 64 // Ping probes a remote peer and returns if it's responsive or not 65 Ping(peer *NetworkMember) bool 66 67 // Accept returns a read-only channel for membership messages sent from remote peers 68 Accept() <-chan *proto.SignedGossipMessage 69 70 // PresumedDead returns a read-only channel for peers that are presumed to be dead 71 PresumedDead() <-chan common.PKIidType 72 73 // CloseConn orders to close the connection with a certain peer 74 CloseConn(peer *NetworkMember) 75 } 76 77 // NetworkMember is a peer's representation 78 type NetworkMember struct { 79 Endpoint string 80 Metadata []byte 81 PKIid common.PKIidType 82 InternalEndpoint string 83 } 84 85 // String returns a string representation of the NetworkMember 86 func (n *NetworkMember) String() string { 87 return fmt.Sprintf("Endpoint: %s, InternalEndpoint: %s, PKI-ID: %v, Metadata: %v", n.Endpoint, n.InternalEndpoint, n.PKIid, n.Metadata) 88 } 89 90 // PreferredEndpoint computes the endpoint to connect to, 91 // while preferring internal endpoint over the standard 92 // endpoint 93 func (n NetworkMember) PreferredEndpoint() string { 94 if n.InternalEndpoint != "" { 95 return n.InternalEndpoint 96 } 97 return n.Endpoint 98 } 99 100 // PeerIdentification encompasses a remote peer's 101 // PKI-ID and whether its in the same org as the current 102 // peer or not 103 type PeerIdentification struct { 104 ID common.PKIidType 105 SelfOrg bool 106 } 107 108 type identifier func() (*PeerIdentification, error) 109 110 // Discovery is the interface that represents a discovery module 111 type Discovery interface { 112 113 // Lookup returns a network member, or nil if not found 114 Lookup(PKIID common.PKIidType) *NetworkMember 115 116 // Self returns this instance's membership information 117 Self() NetworkMember 118 119 // UpdateMetadata updates this instance's metadata 120 UpdateMetadata([]byte) 121 122 // UpdateEndpoint updates this instance's endpoint 123 UpdateEndpoint(string) 124 125 // Stops this instance 126 Stop() 127 128 // GetMembership returns the alive members in the view 129 GetMembership() []NetworkMember 130 131 // InitiateSync makes the instance ask a given number of peers 132 // for their membership information 133 InitiateSync(peerNum int) 134 135 // Connect makes this instance to connect to a remote instance 136 // The identifier param is a function that can be used to identify 137 // the peer, and to assert its PKI-ID, whether its in the peer's org or not, 138 // and whether the action was successful or not 139 Connect(member NetworkMember, id identifier) 140 }