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  }