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  }