github.com/MetalBlockchain/subnet-evm@v0.4.9/peer/client.go (about)

     1  // (c) 2019-2022, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package peer
     5  
     6  import (
     7  	"errors"
     8  
     9  	"github.com/MetalBlockchain/metalgo/ids"
    10  
    11  	"github.com/MetalBlockchain/metalgo/version"
    12  )
    13  
    14  var (
    15  	_ NetworkClient = &client{}
    16  
    17  	ErrRequestFailed = errors.New("request failed")
    18  )
    19  
    20  // NetworkClient defines ability to send request / response through the Network
    21  type NetworkClient interface {
    22  	// SendAppRequestAny synchronously sends request to an arbitrary peer with a
    23  	// node version greater than or equal to minVersion.
    24  	// Returns response bytes, the ID of the chosen peer, and ErrRequestFailed if
    25  	// the request should be retried.
    26  	SendAppRequestAny(minVersion *version.Application, request []byte) ([]byte, ids.NodeID, error)
    27  
    28  	// SendAppRequest synchronously sends request to the selected nodeID
    29  	// Returns response bytes, and ErrRequestFailed if the request should be retried.
    30  	SendAppRequest(nodeID ids.NodeID, request []byte) ([]byte, error)
    31  
    32  	// SendCrossChainRequest sends a request to a specific blockchain running on this node.
    33  	// Returns response bytes, and ErrRequestFailed if the request failed.
    34  	SendCrossChainRequest(chainID ids.ID, request []byte) ([]byte, error)
    35  
    36  	// Gossip sends given gossip message to peers
    37  	Gossip(gossip []byte) error
    38  
    39  	// TrackBandwidth should be called for each valid request with the bandwidth
    40  	// (length of response divided by request time), and with 0 if the response is invalid.
    41  	TrackBandwidth(nodeID ids.NodeID, bandwidth float64)
    42  }
    43  
    44  // client implements NetworkClient interface
    45  // provides ability to send request / responses through the Network and wait for a response
    46  // so that the caller gets the result synchronously.
    47  type client struct {
    48  	network Network
    49  }
    50  
    51  // NewNetworkClient returns Client for a given network
    52  func NewNetworkClient(network Network) NetworkClient {
    53  	return &client{
    54  		network: network,
    55  	}
    56  }
    57  
    58  // SendAppRequestAny synchronously sends request to an arbitrary peer with a
    59  // node version greater than or equal to minVersion.
    60  // Returns response bytes, the ID of the chosen peer, and ErrRequestFailed if
    61  // the request should be retried.
    62  func (c *client) SendAppRequestAny(minVersion *version.Application, request []byte) ([]byte, ids.NodeID, error) {
    63  	waitingHandler := newWaitingResponseHandler()
    64  	nodeID, err := c.network.SendAppRequestAny(minVersion, request, waitingHandler)
    65  	if err != nil {
    66  		return nil, nodeID, err
    67  	}
    68  	response := <-waitingHandler.responseChan
    69  	if waitingHandler.failed {
    70  		return nil, nodeID, ErrRequestFailed
    71  	}
    72  	return response, nodeID, nil
    73  }
    74  
    75  // SendAppRequest synchronously sends request to the specified nodeID
    76  // Returns response bytes and ErrRequestFailed if the request should be retried.
    77  func (c *client) SendAppRequest(nodeID ids.NodeID, request []byte) ([]byte, error) {
    78  	waitingHandler := newWaitingResponseHandler()
    79  	if err := c.network.SendAppRequest(nodeID, request, waitingHandler); err != nil {
    80  		return nil, err
    81  	}
    82  	response := <-waitingHandler.responseChan
    83  	if waitingHandler.failed {
    84  		return nil, ErrRequestFailed
    85  	}
    86  	return response, nil
    87  }
    88  
    89  // SendCrossChainRequest synchronously sends request to the specified chainID
    90  // Returns response bytes and ErrRequestFailed if the request should be retried.
    91  func (c *client) SendCrossChainRequest(chainID ids.ID, request []byte) ([]byte, error) {
    92  	waitingHandler := newWaitingResponseHandler()
    93  	if err := c.network.SendCrossChainRequest(chainID, request, waitingHandler); err != nil {
    94  		return nil, err
    95  	}
    96  	response := <-waitingHandler.responseChan
    97  	if waitingHandler.failed {
    98  		return nil, ErrRequestFailed
    99  	}
   100  	return response, nil
   101  }
   102  
   103  func (c *client) Gossip(gossip []byte) error {
   104  	return c.network.Gossip(gossip)
   105  }
   106  
   107  func (c *client) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) {
   108  	c.network.TrackBandwidth(nodeID, bandwidth)
   109  }