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 }