github.com/dim4egster/coreth@v0.10.2/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/dim4egster/qmallgo/ids"
    10  
    11  	"github.com/dim4egster/qmallgo/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  	// RequestAny synchronously sends request to a randomly chosen 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  	RequestAny(minVersion *version.Application, request []byte) ([]byte, ids.NodeID, error)
    27  
    28  	// Request synchronously sends request to the selected nodeID
    29  	// Returns response bytes, and ErrRequestFailed if the request should be retried.
    30  	Request(nodeID ids.NodeID, request []byte) ([]byte, error)
    31  
    32  	// Gossip sends given gossip message to peers
    33  	Gossip(gossip []byte) error
    34  
    35  	// TrackBandwidth should be called for each valid request with the bandwidth
    36  	// (length of response divided by request time), and with 0 if the response is invalid.
    37  	TrackBandwidth(nodeID ids.NodeID, bandwidth float64)
    38  }
    39  
    40  // client implements NetworkClient interface
    41  // provides ability to send request / responses through the Network and wait for a response
    42  // so that the caller gets the result synchronously.
    43  type client struct {
    44  	network Network
    45  }
    46  
    47  // NewNetworkClient returns Client for a given network
    48  func NewNetworkClient(network Network) NetworkClient {
    49  	return &client{
    50  		network: network,
    51  	}
    52  }
    53  
    54  // RequestAny synchronously sends request to a randomly chosen peer with a
    55  // node version greater than or equal to minVersion.
    56  // Returns response bytes, the ID of the chosen peer, and ErrRequestFailed if
    57  // the request should be retried.
    58  func (c *client) RequestAny(minVersion *version.Application, request []byte) ([]byte, ids.NodeID, error) {
    59  	waitingHandler := newWaitingResponseHandler()
    60  	nodeID, err := c.network.RequestAny(minVersion, request, waitingHandler)
    61  	if err != nil {
    62  		return nil, nodeID, err
    63  	}
    64  	response := <-waitingHandler.responseChan
    65  	if waitingHandler.failed {
    66  		return nil, nodeID, ErrRequestFailed
    67  	}
    68  	return response, nodeID, nil
    69  }
    70  
    71  // Request synchronously sends request to the specified nodeID
    72  // Returns response bytes and ErrRequestFailed if the request should be retried.
    73  func (c *client) Request(nodeID ids.NodeID, request []byte) ([]byte, error) {
    74  	waitingHandler := newWaitingResponseHandler()
    75  	if err := c.network.Request(nodeID, request, waitingHandler); err != nil {
    76  		return nil, err
    77  	}
    78  	response := <-waitingHandler.responseChan
    79  	if waitingHandler.failed {
    80  		return nil, ErrRequestFailed
    81  	}
    82  	return response, nil
    83  }
    84  
    85  func (c *client) Gossip(gossip []byte) error {
    86  	return c.network.Gossip(gossip)
    87  }
    88  
    89  func (c *client) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) {
    90  	c.network.TrackBandwidth(nodeID, bandwidth)
    91  }