github.com/celestiaorg/celestia-node@v0.15.0-beta.1/nodebuilder/p2p/p2p.go (about) 1 package p2p 2 3 import ( 4 "context" 5 "fmt" 6 "reflect" 7 8 pubsub "github.com/libp2p/go-libp2p-pubsub" 9 libhost "github.com/libp2p/go-libp2p/core/host" 10 "github.com/libp2p/go-libp2p/core/metrics" 11 "github.com/libp2p/go-libp2p/core/network" 12 "github.com/libp2p/go-libp2p/core/peer" 13 "github.com/libp2p/go-libp2p/core/protocol" 14 basichost "github.com/libp2p/go-libp2p/p2p/host/basic" 15 rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" 16 "github.com/libp2p/go-libp2p/p2p/net/conngater" 17 ) 18 19 var _ Module = (*API)(nil) 20 21 // Module represents all accessible methods related to the node's p2p 22 // host / operations. 23 // 24 //nolint:dupl 25 //go:generate mockgen -destination=mocks/api.go -package=mocks . Module 26 type Module interface { 27 // Info returns address information about the host. 28 Info(context.Context) (peer.AddrInfo, error) 29 // Peers returns connected peers. 30 Peers(context.Context) ([]peer.ID, error) 31 // PeerInfo returns a small slice of information Peerstore has on the 32 // given peer. 33 PeerInfo(ctx context.Context, id peer.ID) (peer.AddrInfo, error) 34 35 // Connect ensures there is a connection between this host and the peer with 36 // given peer. 37 Connect(ctx context.Context, pi peer.AddrInfo) error 38 // ClosePeer closes the connection to a given peer. 39 ClosePeer(ctx context.Context, id peer.ID) error 40 // Connectedness returns a state signaling connection capabilities. 41 Connectedness(ctx context.Context, id peer.ID) (network.Connectedness, error) 42 // NATStatus returns the current NAT status. 43 NATStatus(context.Context) (network.Reachability, error) 44 45 // BlockPeer adds a peer to the set of blocked peers. 46 BlockPeer(ctx context.Context, p peer.ID) error 47 // UnblockPeer removes a peer from the set of blocked peers. 48 UnblockPeer(ctx context.Context, p peer.ID) error 49 // ListBlockedPeers returns a list of blocked peers. 50 ListBlockedPeers(context.Context) ([]peer.ID, error) 51 // Protect adds a peer to the list of peers who have a bidirectional 52 // peering agreement that they are protected from being trimmed, dropped 53 // or negatively scored. 54 Protect(ctx context.Context, id peer.ID, tag string) error 55 // Unprotect removes a peer from the list of peers who have a bidirectional 56 // peering agreement that they are protected from being trimmed, dropped 57 // or negatively scored, returning a bool representing whether the given 58 // peer is protected or not. 59 Unprotect(ctx context.Context, id peer.ID, tag string) (bool, error) 60 // IsProtected returns whether the given peer is protected. 61 IsProtected(ctx context.Context, id peer.ID, tag string) (bool, error) 62 63 // BandwidthStats returns a Stats struct with bandwidth metrics for all 64 // data sent/received by the local peer, regardless of protocol or remote 65 // peer IDs. 66 BandwidthStats(context.Context) (metrics.Stats, error) 67 // BandwidthForPeer returns a Stats struct with bandwidth metrics associated with the given peer.ID. 68 // The metrics returned include all traffic sent / received for the peer, regardless of protocol. 69 BandwidthForPeer(ctx context.Context, id peer.ID) (metrics.Stats, error) 70 // BandwidthForProtocol returns a Stats struct with bandwidth metrics associated with the given 71 // protocol.ID. 72 BandwidthForProtocol(ctx context.Context, proto protocol.ID) (metrics.Stats, error) 73 74 // ResourceState returns the state of the resource manager. 75 ResourceState(context.Context) (rcmgr.ResourceManagerStat, error) 76 77 // PubSubPeers returns the peer IDs of the peers joined on 78 // the given topic. 79 PubSubPeers(ctx context.Context, topic string) ([]peer.ID, error) 80 } 81 82 // module contains all components necessary to access information and 83 // perform actions related to the node's p2p Host / operations. 84 type module struct { 85 host HostBase 86 ps *pubsub.PubSub 87 connGater *conngater.BasicConnectionGater 88 bw *metrics.BandwidthCounter 89 rm network.ResourceManager 90 } 91 92 func newModule( 93 host HostBase, 94 ps *pubsub.PubSub, 95 cg *conngater.BasicConnectionGater, 96 bw *metrics.BandwidthCounter, 97 rm network.ResourceManager, 98 ) Module { 99 return &module{ 100 host: host, 101 ps: ps, 102 connGater: cg, 103 bw: bw, 104 rm: rm, 105 } 106 } 107 108 func (m *module) Info(context.Context) (peer.AddrInfo, error) { 109 return *libhost.InfoFromHost(m.host), nil 110 } 111 112 func (m *module) Peers(context.Context) ([]peer.ID, error) { 113 return m.host.Network().Peers(), nil 114 } 115 116 func (m *module) PeerInfo(_ context.Context, id peer.ID) (peer.AddrInfo, error) { 117 return m.host.Peerstore().PeerInfo(id), nil 118 } 119 120 func (m *module) Connect(ctx context.Context, pi peer.AddrInfo) error { 121 return m.host.Connect(ctx, pi) 122 } 123 124 func (m *module) ClosePeer(_ context.Context, id peer.ID) error { 125 return m.host.Network().ClosePeer(id) 126 } 127 128 func (m *module) Connectedness(_ context.Context, id peer.ID) (network.Connectedness, error) { 129 return m.host.Network().Connectedness(id), nil 130 } 131 132 func (m *module) NATStatus(context.Context) (network.Reachability, error) { 133 basic, ok := m.host.(*basichost.BasicHost) 134 if !ok { 135 return 0, fmt.Errorf("unexpected implementation of host.Host, expected %s, got %T", 136 reflect.TypeOf(&basichost.BasicHost{}).String(), m.host) 137 } 138 return basic.GetAutoNat().Status(), nil 139 } 140 141 func (m *module) BlockPeer(_ context.Context, p peer.ID) error { 142 return m.connGater.BlockPeer(p) 143 } 144 145 func (m *module) UnblockPeer(_ context.Context, p peer.ID) error { 146 return m.connGater.UnblockPeer(p) 147 } 148 149 func (m *module) ListBlockedPeers(context.Context) ([]peer.ID, error) { 150 return m.connGater.ListBlockedPeers(), nil 151 } 152 153 func (m *module) Protect(_ context.Context, id peer.ID, tag string) error { 154 m.host.ConnManager().Protect(id, tag) 155 return nil 156 } 157 158 func (m *module) Unprotect(_ context.Context, id peer.ID, tag string) (bool, error) { 159 return m.host.ConnManager().Unprotect(id, tag), nil 160 } 161 162 func (m *module) IsProtected(_ context.Context, id peer.ID, tag string) (bool, error) { 163 return m.host.ConnManager().IsProtected(id, tag), nil 164 } 165 166 func (m *module) BandwidthStats(context.Context) (metrics.Stats, error) { 167 return m.bw.GetBandwidthTotals(), nil 168 } 169 170 func (m *module) BandwidthForPeer(_ context.Context, id peer.ID) (metrics.Stats, error) { 171 return m.bw.GetBandwidthForPeer(id), nil 172 } 173 174 func (m *module) BandwidthForProtocol(_ context.Context, proto protocol.ID) (metrics.Stats, error) { 175 return m.bw.GetBandwidthForProtocol(proto), nil 176 } 177 178 func (m *module) ResourceState(context.Context) (rcmgr.ResourceManagerStat, error) { 179 rms, ok := m.rm.(rcmgr.ResourceManagerState) 180 if !ok { 181 return rcmgr.ResourceManagerStat{}, fmt.Errorf("network.resourceManager does not implement " + 182 "rcmgr.ResourceManagerState") 183 } 184 return rms.Stat(), nil 185 } 186 187 func (m *module) PubSubPeers(_ context.Context, topic string) ([]peer.ID, error) { 188 return m.ps.ListPeers(topic), nil 189 } 190 191 // API is a wrapper around Module for the RPC. 192 // TODO(@distractedm1nd): These structs need to be autogenerated. 193 // 194 //nolint:dupl 195 type API struct { 196 Internal struct { 197 Info func(context.Context) (peer.AddrInfo, error) `perm:"admin"` 198 Peers func(context.Context) ([]peer.ID, error) `perm:"admin"` 199 PeerInfo func(ctx context.Context, id peer.ID) (peer.AddrInfo, error) `perm:"admin"` 200 Connect func(ctx context.Context, pi peer.AddrInfo) error `perm:"admin"` 201 ClosePeer func(ctx context.Context, id peer.ID) error `perm:"admin"` 202 Connectedness func(ctx context.Context, id peer.ID) (network.Connectedness, error) `perm:"admin"` 203 NATStatus func(context.Context) (network.Reachability, error) `perm:"admin"` 204 BlockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` 205 UnblockPeer func(ctx context.Context, p peer.ID) error `perm:"admin"` 206 ListBlockedPeers func(context.Context) ([]peer.ID, error) `perm:"admin"` 207 Protect func(ctx context.Context, id peer.ID, tag string) error `perm:"admin"` 208 Unprotect func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` 209 IsProtected func(ctx context.Context, id peer.ID, tag string) (bool, error) `perm:"admin"` 210 BandwidthStats func(context.Context) (metrics.Stats, error) `perm:"admin"` 211 BandwidthForPeer func(ctx context.Context, id peer.ID) (metrics.Stats, error) `perm:"admin"` 212 BandwidthForProtocol func(ctx context.Context, proto protocol.ID) (metrics.Stats, error) `perm:"admin"` 213 ResourceState func(context.Context) (rcmgr.ResourceManagerStat, error) `perm:"admin"` 214 PubSubPeers func(ctx context.Context, topic string) ([]peer.ID, error) `perm:"admin"` 215 } 216 } 217 218 func (api *API) Info(ctx context.Context) (peer.AddrInfo, error) { 219 return api.Internal.Info(ctx) 220 } 221 222 func (api *API) Peers(ctx context.Context) ([]peer.ID, error) { 223 return api.Internal.Peers(ctx) 224 } 225 226 func (api *API) PeerInfo(ctx context.Context, id peer.ID) (peer.AddrInfo, error) { 227 return api.Internal.PeerInfo(ctx, id) 228 } 229 230 func (api *API) Connect(ctx context.Context, pi peer.AddrInfo) error { 231 return api.Internal.Connect(ctx, pi) 232 } 233 234 func (api *API) ClosePeer(ctx context.Context, id peer.ID) error { 235 return api.Internal.ClosePeer(ctx, id) 236 } 237 238 func (api *API) Connectedness(ctx context.Context, id peer.ID) (network.Connectedness, error) { 239 return api.Internal.Connectedness(ctx, id) 240 } 241 242 func (api *API) NATStatus(ctx context.Context) (network.Reachability, error) { 243 return api.Internal.NATStatus(ctx) 244 } 245 246 func (api *API) BlockPeer(ctx context.Context, p peer.ID) error { 247 return api.Internal.BlockPeer(ctx, p) 248 } 249 250 func (api *API) UnblockPeer(ctx context.Context, p peer.ID) error { 251 return api.Internal.UnblockPeer(ctx, p) 252 } 253 254 func (api *API) ListBlockedPeers(ctx context.Context) ([]peer.ID, error) { 255 return api.Internal.ListBlockedPeers(ctx) 256 } 257 258 func (api *API) Protect(ctx context.Context, id peer.ID, tag string) error { 259 return api.Internal.Protect(ctx, id, tag) 260 } 261 262 func (api *API) Unprotect(ctx context.Context, id peer.ID, tag string) (bool, error) { 263 return api.Internal.Unprotect(ctx, id, tag) 264 } 265 266 func (api *API) IsProtected(ctx context.Context, id peer.ID, tag string) (bool, error) { 267 return api.Internal.IsProtected(ctx, id, tag) 268 } 269 270 func (api *API) BandwidthStats(ctx context.Context) (metrics.Stats, error) { 271 return api.Internal.BandwidthStats(ctx) 272 } 273 274 func (api *API) BandwidthForPeer(ctx context.Context, id peer.ID) (metrics.Stats, error) { 275 return api.Internal.BandwidthForPeer(ctx, id) 276 } 277 278 func (api *API) BandwidthForProtocol(ctx context.Context, proto protocol.ID) (metrics.Stats, error) { 279 return api.Internal.BandwidthForProtocol(ctx, proto) 280 } 281 282 func (api *API) ResourceState(ctx context.Context) (rcmgr.ResourceManagerStat, error) { 283 return api.Internal.ResourceState(ctx) 284 } 285 286 func (api *API) PubSubPeers(ctx context.Context, topic string) ([]peer.ID, error) { 287 return api.Internal.PubSubPeers(ctx, topic) 288 }