github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/registry/registry.go (about)

     1  // Copyright Monax Industries Limited
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package registry
     5  
     6  import (
     7  	"fmt"
     8  	"net"
     9  
    10  	"github.com/hyperledger/burrow/crypto"
    11  )
    12  
    13  type NodeStats struct {
    14  	Addresses map[string]map[crypto.Address]struct{}
    15  }
    16  
    17  func NewNodeStats() NodeStats {
    18  	return NodeStats{
    19  		Addresses: make(map[string]map[crypto.Address]struct{}),
    20  	}
    21  }
    22  
    23  func (ns *NodeStats) GetAddresses(net string) []crypto.Address {
    24  	nodes := ns.Addresses[net]
    25  	addrs := make([]crypto.Address, 0, len(nodes))
    26  	for id := range nodes {
    27  		addrs = append(addrs, id)
    28  	}
    29  	return addrs
    30  }
    31  
    32  func (ns *NodeStats) Insert(net string, id crypto.Address) {
    33  	_, ok := ns.Addresses[net]
    34  	if !ok {
    35  		ns.Addresses[net] = make(map[crypto.Address]struct{})
    36  	}
    37  	ns.Addresses[net][id] = struct{}{}
    38  }
    39  
    40  func (ns *NodeStats) Remove(node *NodeIdentity) bool {
    41  	_, ok := ns.Addresses[node.GetNetworkAddress()]
    42  	if !ok {
    43  		return false
    44  	}
    45  	_, ok = ns.Addresses[node.GetNetworkAddress()][node.TendermintNodeID]
    46  	if ok {
    47  		delete(ns.Addresses[node.GetNetworkAddress()], node.TendermintNodeID)
    48  		return true
    49  	}
    50  	return false
    51  }
    52  
    53  type NodeFilter struct {
    54  	state IterableReader
    55  }
    56  
    57  func NewNodeFilter(state IterableReader) *NodeFilter {
    58  	return &NodeFilter{
    59  		state: state,
    60  	}
    61  }
    62  
    63  func (nf *NodeFilter) QueryPeerByID(id string) bool {
    64  	addr, err := crypto.AddressFromHexString(id)
    65  	if err != nil {
    66  		return false
    67  	}
    68  
    69  	node, err := nf.state.GetNodeByID(addr)
    70  	if err != nil || node == nil {
    71  		return false
    72  	}
    73  	return true
    74  }
    75  
    76  func (nf *NodeFilter) findByAddress(addr string) bool {
    77  	nodes, err := nf.state.GetNodeIDsByAddress(addr)
    78  	if err != nil {
    79  		panic(err)
    80  	} else if len(nodes) == 0 {
    81  		return false
    82  	}
    83  	return true
    84  }
    85  
    86  func (nf *NodeFilter) QueryPeerByAddress(addr string) bool {
    87  	// may have different outbound port in address, so fallback to host
    88  	ok := nf.findByAddress(addr)
    89  	if ok {
    90  		return ok
    91  	}
    92  	host, _, _ := net.SplitHostPort(addr)
    93  	return nf.findByAddress(host)
    94  }
    95  
    96  func (nf *NodeFilter) NumPeers() int {
    97  	return nf.state.GetNumPeers()
    98  }
    99  
   100  func (rn *NodeIdentity) String() string {
   101  	return fmt.Sprintf("RegisterNode{%v -> %v @ %v}", rn.ValidatorPublicKey, rn.TendermintNodeID, rn.NetworkAddress)
   102  }
   103  
   104  type Reader interface {
   105  	GetNodeByID(crypto.Address) (*NodeIdentity, error)
   106  	GetNodeIDsByAddress(net string) ([]crypto.Address, error)
   107  	GetNumPeers() int
   108  }
   109  
   110  type Writer interface {
   111  	// Updates the node, creating it if it does not exist
   112  	UpdateNode(crypto.Address, *NodeIdentity) error
   113  	// Remove the node by address
   114  	RemoveNode(crypto.Address) error
   115  }
   116  
   117  type ReaderWriter interface {
   118  	Reader
   119  	Writer
   120  }
   121  
   122  type Iterable interface {
   123  	IterateNodes(consumer func(crypto.Address, *NodeIdentity) error) (err error)
   124  }
   125  
   126  type IterableReader interface {
   127  	Iterable
   128  	Reader
   129  }
   130  
   131  type IterableReaderWriter interface {
   132  	Iterable
   133  	ReaderWriter
   134  }