Line data Source code
1 : #ifndef HEADER_fd_src_app_shared_dev_rpc_client_fd_rpc_client_h 2 : #define HEADER_fd_src_app_shared_dev_rpc_client_fd_rpc_client_h 3 : 4 : #include "../../../util/fd_util.h" 5 : 6 : #include <poll.h> 7 : 8 : /* This is a poor RPC client implementation to retrieve information from 9 : the Agave validator. It is not a Firedancer RPC implementation 10 : and should not be used in that way. It is just here to provide code 11 : interoperability. It is not fuzzed or hardened, and should not be 12 : used in any code that matters. */ 13 : 14 12 : #define FD_RPC_CLIENT_SUCCESS (0) 15 6 : #define FD_RPC_CLIENT_PENDING (-1) 16 0 : #define FD_RPC_CLIENT_ERR_NOT_FOUND (-2) 17 0 : #define FD_RPC_CLIENT_ERR_TOO_LARGE (-3) 18 0 : #define FD_RPC_CLIENT_ERR_TOO_MANY (-4) 19 0 : #define FD_RPC_CLIENT_ERR_MALFORMED (-5) 20 0 : #define FD_RPC_CLIENT_ERR_NETWORK (-6) 21 : 22 3 : #define FD_RPC_CLIENT_ALIGN (8UL) 23 3 : #define FD_RPC_CLIENT_FOOTPRINT (273424UL) 24 : 25 390 : #define FD_RPC_CLIENT_STATE_NONE (0UL) 26 6 : #define FD_RPC_CLIENT_STATE_CONNECTED (1UL) 27 6 : #define FD_RPC_CLIENT_STATE_SENT (2UL) 28 : #define FD_RPC_CLIENT_STATE_RECEIVED (3UL) 29 6 : #define FD_RPC_CLIENT_STATE_FINISHED (4UL) 30 : 31 2724555 : #define FD_RPC_CLIENT_REQUEST_CNT (128UL) 32 : 33 6 : #define FD_RPC_CLIENT_METHOD_LATEST_BLOCK_HASH (0UL) 34 6 : #define FD_RPC_CLIENT_METHOD_TRANSACTION_COUNT (1UL) 35 : 36 : typedef struct { 37 : long request_id; 38 : ulong method; 39 : 40 : long status; 41 : 42 : union { 43 : struct { 44 : uchar block_hash[ 32 ]; 45 : } latest_block_hash; 46 : 47 : struct { 48 : ulong transaction_count; 49 : } transaction_count; 50 : } result; 51 : } fd_rpc_client_response_t; 52 : 53 : struct fd_rpc_client_private; 54 : typedef struct fd_rpc_client_private fd_rpc_client_t; 55 : 56 : FD_PROTOTYPES_BEGIN 57 : 58 : FD_FN_CONST static inline char const * 59 0 : fd_rpc_client_strerror( long err ) { 60 0 : switch( err ) { 61 0 : case FD_RPC_CLIENT_SUCCESS: return "Success"; 62 0 : case FD_RPC_CLIENT_PENDING: return "Pending"; 63 0 : case FD_RPC_CLIENT_ERR_NOT_FOUND: return "Not found"; 64 0 : case FD_RPC_CLIENT_ERR_TOO_LARGE: return "Request too large"; 65 0 : case FD_RPC_CLIENT_ERR_TOO_MANY: return "Too many requests in flight"; 66 0 : case FD_RPC_CLIENT_ERR_MALFORMED: return "Malformed response"; 67 0 : case FD_RPC_CLIENT_ERR_NETWORK: return "Network error"; 68 0 : default: return "Unknown error"; 69 0 : } 70 0 : } 71 : 72 3 : FD_FN_CONST static inline ulong fd_rpc_client_align ( void ) { return FD_RPC_CLIENT_ALIGN; } 73 3 : FD_FN_CONST static inline ulong fd_rpc_client_footprint( void ) { return FD_RPC_CLIENT_FOOTPRINT; } 74 : 75 : void * 76 : fd_rpc_client_new( void * mem, 77 : uint rpc_addr, 78 : ushort rpc_port ); 79 : 80 3 : static inline fd_rpc_client_t * fd_rpc_client_join ( void * _rpc ) { return (fd_rpc_client_t *)_rpc; } 81 3 : static inline void * fd_rpc_client_leave ( fd_rpc_client_t * rpc ) { return (void *) rpc; } 82 3 : static inline void * fd_rpc_client_delete( void * _rpc ) { return (void *)_rpc; } 83 : 84 : /* Wait until the RPC server is ready to receive requests. This is a 85 : blocking call. If timeout_ns is -1 it will wait forever, otherwise 86 : it will wait at most this amount of nanoseconds before returning 87 : FD_RPC_CLIENT_ERR_NETWORK. 88 : 89 : Returns FD_RPC_CLIENT_SUCCESS once the server is ready. */ 90 : 91 : long 92 : fd_rpc_client_wait_ready( fd_rpc_client_t * rpc, 93 : long timeout_ns ); 94 : 95 : /* Make an RPC request to get the latest block hash. 96 : 97 : On success returns a non-negative request ID. On failure, returns a 98 : negative value, one of FD_RPC_ERR_*. In particular, if there are too 99 : many requests in flight already FD_RPC_ERR_TOO_MANY is returned. */ 100 : 101 : long 102 : fd_rpc_client_request_latest_block_hash( fd_rpc_client_t * rpc ); 103 : 104 : /* Make an RPC request to the current transaction count. 105 : 106 : On success returns a non-negative request ID. On failure, returns a 107 : negative value, one of FD_RPC_ERR_*. In particular, if there are too 108 : many requests in flight already FD_RPC_ERR_TOO_MANY is returned. */ 109 : 110 : long 111 : fd_rpc_client_request_transaction_count( fd_rpc_client_t * rpc ); 112 : 113 : /* Service all the RPC connections. This sends, receives, parses and 114 : otherwise does all the work required to poll and make forward 115 : progress on receiving responses for RPC requests that have been made. 116 : 117 : This is non-blocking and will always return immediately after sending 118 : and receiving data. To operate in blocking mode, where the function 119 : will not return unless some forward progress has been made, set wait 120 : to true. The function may still return without a response available 121 : when wait is true. 122 : 123 : Returns 1 if the RPC client did any work to progress a connection, 124 : otherwise returns 0. */ 125 : 126 : int 127 : fd_rpc_client_service( fd_rpc_client_t * rpc, 128 : int wait ); 129 : 130 : /* Get the response of the RPC request with a given ID. If the response 131 : is not yet available, the status will be FD_RPC_PENDING, otherwise it 132 : is one of FD_RPC_SUCCESS or FD_RPC_ERR_*. 133 : 134 : If wait is true, the function will block until an error occurs or the 135 : response is available, and it will not return FD_RPC_PENDING. 136 : 137 : If the request_id does not exist or has already been closed, 138 : NULL is returned. */ 139 : 140 : fd_rpc_client_response_t * 141 : fd_rpc_client_status( fd_rpc_client_t * rpc, 142 : long request_id, 143 : int wait ); 144 : 145 : /* Close the request with the given ID. If the request is still pending, 146 : it will be abandoned. If the request has already been closed or does 147 : not exist the function will silently return. 148 : 149 : All RPC requests need to be closed once you are done inspecting the 150 : results, otherwise the RPC client will run out of resources and 151 : subsequent requests will fail with FD_RPC_ERR_TOO_MANY. */ 152 : 153 : void 154 : fd_rpc_client_close( fd_rpc_client_t * rpc, 155 : long request_id ); 156 : 157 : FD_PROTOTYPES_END 158 : 159 : #endif /* HEADER_fd_src_app_shared_dev_rpc_client_fd_rpc_client_h */