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 }