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 }