github.com/amazechain/amc@v0.1.3/internal/p2p/peers/peerdata/store.go (about)

     1  package peerdata
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"github.com/amazechain/amc/api/protocol/msg_proto"
     7  	"github.com/amazechain/amc/api/protocol/sync_pb"
     8  	"github.com/amazechain/amc/internal/p2p/enr"
     9  	"github.com/amazechain/amc/utils"
    10  	"github.com/holiman/uint256"
    11  	"github.com/libp2p/go-libp2p/core/network"
    12  	"github.com/libp2p/go-libp2p/core/peer"
    13  	ma "github.com/multiformats/go-multiaddr"
    14  	"sync"
    15  	"time"
    16  )
    17  
    18  var (
    19  	// ErrPeerUnknown is returned when there is an attempt to obtain data from a peer that is not known.
    20  	ErrPeerUnknown = errors.New("peer unknown")
    21  	// ErrNoPeerStatus is returned when there is a map entry for a given peer but there is no chain
    22  	// status for that peer. This should happen in rare circumstances only, but is a very possible
    23  	// scenario in a chaotic and adversarial network.
    24  	ErrNoPeerStatus = errors.New("no chain status for peer")
    25  )
    26  
    27  // PeerConnectionState is the state of the connection.
    28  type PeerConnectionState int
    29  
    30  // StoreConfig holds peer store parameters.
    31  type StoreConfig struct {
    32  	MaxPeers int
    33  }
    34  
    35  func (c PeerConnectionState) String() string {
    36  	str := [...]string{"PeerDisconnected", "PeerDisconnecting", "PeerConnected", "PeerConnecting"}
    37  	if c < 0 || int(c) >= len(str) {
    38  		return "(unrecognized)"
    39  	}
    40  	return str[c]
    41  }
    42  
    43  // Store is a container for various peer related data (both protocol and app level).
    44  // Container implements RWMutex, so data access can be restricted on the container level. This allows
    45  // different components rely on the very same peer map container.
    46  // Note: access to data is controlled by clients i.e. client code is responsible for locking/unlocking
    47  // the mutex when accessing data.
    48  type Store struct {
    49  	sync.RWMutex
    50  	ctx    context.Context
    51  	config *StoreConfig
    52  	peers  map[peer.ID]*PeerData
    53  }
    54  
    55  // PeerData aggregates protocol and application level info about a single peer.
    56  type PeerData struct {
    57  	// Network related data.
    58  	Address       ma.Multiaddr
    59  	Direction     network.Direction
    60  	ConnState     PeerConnectionState
    61  	Enr           *enr.Record
    62  	NextValidTime time.Time
    63  	// Chain related data.
    64  	Ping                      *sync_pb.Ping
    65  	ChainState                *sync_pb.Status
    66  	ChainStateLastUpdated     time.Time
    67  	ChainStateValidationError error
    68  	// Scorers internal data.
    69  	BadResponses         int
    70  	ProcessedBlocks      uint64
    71  	BlockProviderUpdated time.Time
    72  	// Gossip Scoring data.
    73  	TopicScores      map[string]*msg_proto.TopicScoreSnapshot
    74  	GossipScore      float64
    75  	BehaviourPenalty float64
    76  }
    77  
    78  // todo
    79  func (s *PeerData) CurrentHeight() *uint256.Int {
    80  	return utils.ConvertH256ToUint256Int(s.ChainState.CurrentHeight)
    81  }
    82  
    83  // NewStore creates new peer data store.
    84  func NewStore(ctx context.Context, config *StoreConfig) *Store {
    85  	return &Store{
    86  		ctx:    ctx,
    87  		config: config,
    88  		peers:  make(map[peer.ID]*PeerData),
    89  	}
    90  }
    91  
    92  // PeerData returns data associated with a given peer, if any.
    93  // Important: it is assumed that store mutex is locked when calling this method.
    94  func (s *Store) PeerData(pid peer.ID) (*PeerData, bool) {
    95  	peerData, ok := s.peers[pid]
    96  	return peerData, ok
    97  }
    98  
    99  // PeerDataGetOrCreate returns data associated with a given peer.
   100  // If no data has been associated yet, newly created and associated data object is returned.
   101  // Important: it is assumed that store mutex is locked when calling this method.
   102  func (s *Store) PeerDataGetOrCreate(pid peer.ID) *PeerData {
   103  	if peerData, ok := s.peers[pid]; ok {
   104  		return peerData
   105  	}
   106  	s.peers[pid] = &PeerData{}
   107  	return s.peers[pid]
   108  }
   109  
   110  // SetPeerData updates data associated with a given peer.
   111  // Important: it is assumed that store mutex is locked when calling this method.
   112  func (s *Store) SetPeerData(pid peer.ID, data *PeerData) {
   113  	s.peers[pid] = data
   114  }
   115  
   116  // DeletePeerData removes data associated with a given peer.
   117  // Important: it is assumed that store mutex is locked when calling this method.
   118  func (s *Store) DeletePeerData(pid peer.ID) {
   119  	delete(s.peers, pid)
   120  }
   121  
   122  // Peers returns map of peer data objects.
   123  // Important: it is assumed that store mutex is locked when calling this method.
   124  func (s *Store) Peers() map[peer.ID]*PeerData {
   125  	return s.peers
   126  }
   127  
   128  // Config exposes store configuration params.
   129  func (s *Store) Config() *StoreConfig {
   130  	return s.config
   131  }