github.com/mavryk-network/mvgo@v1.19.9/rpc/network.go (about) 1 // Copyright (c) 2018 ECAD Labs Inc. MIT License 2 // Copyright (c) 2020-2021 Blockwatch Data Inc. 3 // Author: alex@blockwatch.cc 4 5 package rpc 6 7 import ( 8 "context" 9 "fmt" 10 "net/url" 11 "time" 12 ) 13 14 // NetworkStats models global network bandwidth totals and usage in B/s. 15 type NetworkStats struct { 16 TotalBytesSent int64 `json:"total_sent,string"` 17 TotalBytesRecv int64 `json:"total_recv,string"` 18 CurrentInflow int64 `json:"current_inflow"` 19 CurrentOutflow int64 `json:"current_outflow"` 20 } 21 22 // NetworkConnection models detailed information for one network connection. 23 type NetworkConnection struct { 24 Incoming bool `json:"incoming"` 25 PeerID string `json:"peer_id"` 26 IDPoint NetworkAddress `json:"id_point"` 27 RemoteSocketPort uint16 `json:"remote_socket_port"` 28 Versions []*ConnVersion `json:"versions"` 29 Private bool `json:"private"` 30 LocalMetadata NetworkMetadata `json:"local_metadata"` 31 RemoteMetadata NetworkMetadata `json:"remote_metadata"` 32 } 33 34 // NetworkAddress models a point's address and port. 35 type NetworkAddress struct { 36 Addr string `json:"addr"` 37 Port uint16 `json:"port"` 38 } 39 40 // ConnVersion models a network-layer version of a node. 41 type ConnVersion struct { 42 Name string `json:"name"` 43 Major uint16 `json:"major"` 44 Minor uint16 `json:"minor"` 45 } 46 47 // NetworkMetadata models metadata of a node. 48 type NetworkMetadata struct { 49 DisableMempool bool `json:"disable_mempool"` 50 PrivateNode bool `json:"private_node"` 51 } 52 53 // NetworkConnectionTimestamp represents peer address with timestamp added 54 type NetworkConnectionTimestamp struct { 55 NetworkAddress 56 Timestamp time.Time 57 } 58 59 // UnmarshalJSON implements json.Unmarshaler 60 func (n *NetworkConnectionTimestamp) UnmarshalJSON(data []byte) error { 61 return unmarshalMultiTypeJSONArray(data, &n.NetworkAddress, &n.Timestamp) 62 } 63 64 // NetworkPeer represents peer info 65 type NetworkPeer struct { 66 PeerID string `json:"-"` 67 Score int64 `json:"score"` 68 Trusted bool `json:"trusted"` 69 ConnMetadata *NetworkMetadata `json:"conn_metadata"` 70 State string `json:"state"` 71 ReachableAt *NetworkAddress `json:"reachable_at"` 72 Stat NetworkStats `json:"stat"` 73 LastEstablishedConnection *NetworkConnectionTimestamp `json:"last_established_connection"` 74 LastSeen *NetworkConnectionTimestamp `json:"last_seen"` 75 LastFailedConnection *NetworkConnectionTimestamp `json:"last_failed_connection"` 76 LastRejectedConnection *NetworkConnectionTimestamp `json:"last_rejected_connection"` 77 LastDisconnection *NetworkConnectionTimestamp `json:"last_disconnection"` 78 LastMiss *NetworkConnectionTimestamp `json:"last_miss"` 79 } 80 81 // networkPeerWithID is a heterogeneously encoded NetworkPeer with ID as a first array member 82 // See OperationAlt for details 83 type networkPeerWithID NetworkPeer 84 85 func (n *networkPeerWithID) UnmarshalJSON(data []byte) error { 86 return unmarshalMultiTypeJSONArray(data, &n.PeerID, (*NetworkPeer)(n)) 87 } 88 89 // NetworkPoint represents network point info 90 type NetworkPoint struct { 91 Address string `json:"-"` 92 Trusted bool `json:"trusted"` 93 GreylistedUntil time.Time `json:"greylisted_until"` 94 State NetworkPointState `json:"state"` 95 P2PPeerID string `json:"p2p_peer_id"` 96 LastFailedConnection time.Time `json:"last_failed_connection"` 97 LastRejectedConnection *IDTimestamp `json:"last_rejected_connection"` 98 LastEstablishedConnection *IDTimestamp `json:"last_established_connection"` 99 LastDisconnection *IDTimestamp `json:"last_disconnection"` 100 LastSeen *IDTimestamp `json:"last_seen"` 101 LastMiss time.Time `json:"last_miss"` 102 } 103 104 // networkPointAlt is a heterogeneously encoded NetworkPoint with address as a first array member 105 // See OperationAlt for details 106 type networkPointAlt NetworkPoint 107 108 func (n *networkPointAlt) UnmarshalJSON(data []byte) error { 109 return unmarshalMultiTypeJSONArray(data, &n.Address, (*NetworkPoint)(n)) 110 } 111 112 // NetworkPointState represents point state 113 type NetworkPointState struct { 114 EventKind string `json:"event_kind"` 115 P2PPeerID string `json:"p2p_peer_id"` 116 } 117 118 // IDTimestamp represents peer id with timestamp 119 type IDTimestamp struct { 120 ID string 121 Timestamp time.Time 122 } 123 124 // UnmarshalJSON implements json.Unmarshaler 125 func (i *IDTimestamp) UnmarshalJSON(data []byte) error { 126 return unmarshalMultiTypeJSONArray(data, &i.ID, &i.Timestamp) 127 } 128 129 // GetNetworkStats returns current network stats https://protocol.mavryk.org/betanet/api/rpc.html#get-network-stat 130 func (c *Client) GetNetworkStats(ctx context.Context) (*NetworkStats, error) { 131 var stats NetworkStats 132 if err := c.Get(ctx, "network/stat", &stats); err != nil { 133 return nil, err 134 } 135 return &stats, nil 136 } 137 138 // GetNetworkConnections returns all network connections http://protocol.mavryk.org/mainnet/api/rpc.html#get-network-connections 139 func (c *Client) GetNetworkConnections(ctx context.Context) ([]*NetworkConnection, error) { 140 var conns []*NetworkConnection 141 if err := c.Get(ctx, "network/connections", &conns); err != nil { 142 return nil, err 143 } 144 return conns, nil 145 } 146 147 // GetNetworkPeers returns the list the peers the node ever met. 148 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-peers 149 func (c *Client) GetNetworkPeers(ctx context.Context, filter string) ([]*NetworkPeer, error) { 150 u := url.URL{ 151 Path: "network/peers", 152 } 153 154 if filter != "" { 155 q := url.Values{ 156 "filter": []string{filter}, 157 } 158 u.RawQuery = q.Encode() 159 } 160 161 var peers []*networkPeerWithID 162 if err := c.Get(ctx, u.String(), &peers); err != nil { 163 return nil, err 164 } 165 166 ret := make([]*NetworkPeer, len(peers)) 167 for i, p := range peers { 168 ret[i] = (*NetworkPeer)(p) 169 } 170 171 return ret, nil 172 } 173 174 // GetNetworkPeer returns details about a given peer. 175 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-peers-peer-id 176 func (c *Client) GetNetworkPeer(ctx context.Context, peerID string) (*NetworkPeer, error) { 177 var peer NetworkPeer 178 if err := c.Get(ctx, "network/peers/"+peerID, &peer); err != nil { 179 return nil, err 180 } 181 peer.PeerID = peerID 182 183 return &peer, nil 184 } 185 186 // BanNetworkPeer blacklists the given peer. 187 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-peers-peer-id-ban 188 func (c *Client) BanNetworkPeer(ctx context.Context, peerID string) error { 189 return c.Get(ctx, "network/peers/"+peerID+"/ban", nil) 190 } 191 192 // TrustNetworkPeer used to trust a given peer permanently: the peer cannot be blocked (but its host IP still can). 193 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-peers-peer-id-trust 194 func (c *Client) TrustNetworkPeer(ctx context.Context, peerID string) error { 195 return c.Get(ctx, "network/peers/"+peerID+"/trust", nil) 196 } 197 198 // GetNetworkPeerBanned checks if a given peer is blacklisted or greylisted. 199 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-peers-peer-id-banned 200 func (c *Client) GetNetworkPeerBanned(ctx context.Context, peerID string) (bool, error) { 201 var banned bool 202 if err := c.Get(ctx, "network/peers/"+peerID+"/banned", &banned); err != nil { 203 return false, err 204 } 205 return banned, nil 206 } 207 208 // GetNetworkPeerLog monitors network events related to a given peer. 209 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-peers-peer-id-log 210 func (c *Client) GetNetworkPeerLog(ctx context.Context, peerID string) ([]*NetworkPeerLogEntry, error) { 211 var log []*NetworkPeerLogEntry 212 if err := c.Get(ctx, "network/peers/"+peerID+"/log", &log); err != nil { 213 return nil, err 214 } 215 return log, nil 216 } 217 218 // GetNetworkPoints returns list the pool of known `IP:port` used for establishing P2P connections. 219 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-points 220 func (c *Client) GetNetworkPoints(ctx context.Context, filter string) ([]*NetworkPoint, error) { 221 u := url.URL{ 222 Path: "network/points", 223 } 224 225 if filter != "" { 226 q := url.Values{ 227 "filter": []string{filter}, 228 } 229 u.RawQuery = q.Encode() 230 } 231 232 var points []*networkPointAlt 233 if err := c.Get(ctx, u.String(), &points); err != nil { 234 return nil, err 235 } 236 237 ret := make([]*NetworkPoint, len(points)) 238 for i, p := range points { 239 ret[i] = (*NetworkPoint)(p) 240 } 241 242 return ret, nil 243 } 244 245 // GetNetworkPoint returns details about a given `IP:addr`. 246 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-points-point 247 func (c *Client) GetNetworkPoint(ctx context.Context, address string) (*NetworkPoint, error) { 248 var point NetworkPoint 249 if err := c.Get(ctx, "network/points/"+address, &point); err != nil { 250 return nil, err 251 } 252 point.Address = address 253 return &point, nil 254 } 255 256 // ConnectToNetworkPoint used to connect to a peer. 257 // https://protocol.mavryk.org/mainnet/api/rpc.html#put-network-points-point 258 func (c *Client) ConnectToNetworkPoint(ctx context.Context, address string, timeout time.Duration) error { 259 u := url.URL{ 260 Path: "network/points/" + address, 261 } 262 263 if timeout > 0 { 264 q := url.Values{ 265 "timeout": []string{fmt.Sprintf("%f", float64(timeout)/float64(time.Second))}, 266 } 267 u.RawQuery = q.Encode() 268 } 269 270 return c.Put(ctx, u.String(), &struct{}{}, nil) 271 } 272 273 // BanNetworkPoint blacklists the given address. 274 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-points-point-ban 275 func (c *Client) BanNetworkPoint(ctx context.Context, address string) error { 276 return c.Get(ctx, "network/points/"+address+"/ban", nil) 277 } 278 279 // TrustNetworkPoint used to trust a given address permanently. Connections from this address can still be closed on authentication if the peer is blacklisted or greylisted. 280 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-points-point-trust 281 func (c *Client) TrustNetworkPoint(ctx context.Context, address string) error { 282 return c.Get(ctx, "network/points/"+address+"/trust", nil) 283 } 284 285 // GetNetworkPointBanned check is a given address is blacklisted or greylisted. 286 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-points-point-banned 287 func (c *Client) GetNetworkPointBanned(ctx context.Context, address string) (bool, error) { 288 var banned bool 289 if err := c.Get(ctx, "network/points/"+address+"/banned", &banned); err != nil { 290 return false, err 291 } 292 return banned, nil 293 } 294 295 // GetNetworkPointLog monitors network events related to an `IP:addr`. 296 // https://protocol.mavryk.org/mainnet/api/rpc.html#get-network-peers-peer-id-log 297 func (c *Client) GetNetworkPointLog(ctx context.Context, address string) ([]*NetworkPointLogEntry, error) { 298 var log []*NetworkPointLogEntry 299 if err := c.Get(ctx, "network/points/"+address+"/log", &log); err != nil { 300 return nil, err 301 } 302 return log, nil 303 }