1#![allow(non_camel_case_types)]
15
16use crate::internals::construct_params;
17use crate::rpc_types::ethereum_types::{
18 EthBlock, EthCallRequest, EthFilter, EthLog, EthReceipt, EthRpcTransaction,
19 EthTransactionRequest,
20};
21use crate::rpc_types::{
22 Block, BlockNumber, Boolean, CallRequest, CallResult, CensorAddrs, Data, Data20, Data32,
23 Filter, FilterChanges, Id, Integer, LicenseInfo, Log, MetaData, OneItemTupleTrick, PeersInfo,
24 PoolTxNum, Quantity, Receipt, RpcTransaction, SoftwareVersion, TxResponse, Version,
25};
26use serde_json;
28
29pub type Logs = Vec<Log>;
30pub type EthLogs = Vec<EthLog>;
31pub type Accounts = Vec<Data20>;
32
33#[derive(Debug, Clone, PartialEq)]
34pub struct RequestInfo {
35 pub jsonrpc: Option<Version>,
36 pub id: Id,
37}
38
39impl RequestInfo {
40 pub fn new(jsonrpc: Option<Version>, id: Id) -> Self {
41 RequestInfo { jsonrpc, id }
42 }
43 pub fn null() -> Self {
44 RequestInfo {
45 jsonrpc: None,
46 id: Id::Null,
47 }
48 }
49}
50
51impl Default for RequestInfo {
52 fn default() -> Self {
53 RequestInfo::new(Some(Version::default()), Id::default())
54 }
55}
56
57#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
59pub struct Request {
60 #[serde(default, skip_serializing_if = "Option::is_none")]
61 pub jsonrpc: Option<Version>,
62 #[serde(default, skip_serializing_if = "Id::is_null")]
63 pub id: Id,
64 #[serde(flatten)]
66 pub call: Call,
67}
68
69impl Request {
70 pub fn new(jsonrpc: Option<Version>, id: Id, call: Call) -> Self {
71 Request { jsonrpc, id, call }
72 }
73 pub fn get_method(&self) -> &str {
74 self.call.get_method()
75 }
76 pub fn get_info(&self) -> RequestInfo {
77 RequestInfo::new(self.jsonrpc.clone(), self.id.clone())
78 }
79}
80
81impl Into<String> for Request {
82 fn into(self) -> String {
83 serde_json::to_string(&self).unwrap()
84 }
85}
86
87#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
88pub struct PartialRequest {
89 pub jsonrpc: Option<Version>,
90 pub id: Id,
91 #[serde(flatten)]
93 pub call: Option<PartialCall>,
94}
95
96impl PartialRequest {
97 pub fn get_info(&self) -> RequestInfo {
98 RequestInfo::new(self.jsonrpc.clone(), self.id.clone())
99 }
100}
101
102macro_rules! define_call {
103 ($( ($enum_name:ident, $params_name:ident: $params_list:expr, $result_type:ident) ),+ ,) => {
104 define_call!($( ($enum_name, $params_name: $params_list, $result_type) ),+);
105 };
106 ($( ($enum_name:ident, $params_name:ident: $params_list:expr, $result_type:ident) ),+ ) => {
107
108 $(
109 construct_params!($params_name: $params_list, $result_type);
110 )+
111
112
113 #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
114 #[serde(untagged)]
115 #[allow(clippy::large_enum_variant)] pub enum ResponseResult {
117 #[serde(rename = "null")]
118 Null,
119 $(
120 $enum_name($result_type),
121 )+
122 }
123
124 impl Default for ResponseResult {
125 fn default() -> Self {
126 ResponseResult::Null
127 }
128 }
129
130 #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
131 #[serde(tag = "method", rename_all = "camelCase")]
132 pub enum Call {
133 $(
134 $enum_name { params: $params_name},
135 )+
136 }
137
138 #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
139 #[serde(tag = "method", rename_all = "camelCase")]
140 pub enum PartialCall {
141 $(
142 $enum_name {
143 params: Option<serde_json::Value>
144 },
145 )+
146 }
147
148 impl Call {
149 pub fn get_method(&self) -> &str {
150 match self {
151 $(
152 Call::$enum_name { ref params } => params.method_name(),
153 )+
154 }
155 }
156 pub fn into_request(self, id: u64) -> Request {
157 Request::new(
158 Some(Version::default()),
159 Id::Num(id),
160 self,
161 )
162 }
163 }
164
165 $(
166 impl Into<$params_name> for Call {
167 fn into(self) -> $params_name{
168 if let Call::$enum_name{ params } = self {
169 params
170 } else {
171 panic!("The method and params are one to one correspondence.")
175 }
176 }
177 }
178
179 impl From<$params_name> for Call {
180 fn from(params: $params_name) -> Call {
181 Call::$enum_name{ params }
182 }
183 }
184
185 impl $params_name {
186 pub fn into_request(self, id: u64) -> Request {
187 Request::new(
188 Some(Version::default()),
189 Id::Num(id),
190 self.into(),
191 )
192 }
193 }
194 )+
195 };
196}
197
198pub trait JsonRpcRequest {
199 type Response;
200 fn required_len() -> usize;
201 fn valid_len() -> usize;
202 fn method_name(&self) -> &'static str;
203 fn value_vec(self) -> Vec<serde_json::Value>;
204}
205
206#[macro_export]
225macro_rules! impl_for_each_jsonrpc_requests {
226 ($macro:ident) => {
227 $macro!(
228 (BlockNumber, BlockNumberParams: [], Quantity),
229 (PeerCount, PeerCountParams: [], Quantity),
230 (SendRawTransaction, SendRawTransactionParams: [Data], TxResponse),
231 (SendTransaction, SendTransactionParams: [Data], TxResponse),
232 (GetBlockByHash, GetBlockByHashParams: [Data32, Boolean], Block),
233 (GetBlockByNumber, GetBlockByNumberParams: [BlockNumber, Boolean], Block),
234 (GetTransactionReceipt, GetTransactionReceiptParams: [Data32], Receipt),
235 (GetLogs, GetLogsParams: [Filter], Logs),
236 (GetTransactionCount, GetTransactionCountParams: [Data20, BlockNumber], Quantity),
237 (GetCode, GetCodeParams: [Data20, BlockNumber], Data),
238 (GetAbi, GetAbiParams: [Data20, BlockNumber], Data),
239 (GetBalance, GetBalanceParams: [Data20, BlockNumber], Quantity),
240 (NewFilter, NewFilterParams: [Filter], Quantity),
241 (NewBlockFilter, NewBlockFilterParams: [], Quantity),
242 (UninstallFilter, UninstallFilterParams: [Quantity], Boolean),
243 (GetFilterChanges, GetFilterChangesParams: [Quantity], FilterChanges),
244 (GetFilterLogs, GetFilterLogsParams: [Quantity], Logs),
245 (GetTransactionProof, GetTransactionProofParams: [Data32], Data),
246 (GetMetaData, GetMetaDataParams: [BlockNumber], MetaData),
247 (GetStateProof, GetStateProofParams: [Data20, Data32, BlockNumber], Data),
248 (GetBlockHeader, GetBlockHeaderParams: [BlockNumber], Data),
249 (GetStorageAt, GetStorageKeyParams: [Data20, Data32, BlockNumber], Data),
250 (GetVersion, GetVersionParams: [], SoftwareVersion),
251 (EstimateQuota, EstimateQuotaParams: [CallRequest, BlockNumber], Quantity),
252 (LicenseInfo, LicenseInfoParams: [], LicenseInfo),
253 (GetPoolTxNum, GetPoolTxNumParams: [], PoolTxNum),
254 (OpCensoredAddress, OpCensoredAddressParams: [Integer, Data20], Boolean),
255 (PeersInfo, PeersInfoParams: [
256 #[serde(default)]
257 Boolean
258 ], PeersInfo),
259 (GetTransaction, GetTransactionParams: [
260 Data32,
261 #[serde(default)]
262 Boolean
263 ], RpcTransaction),
264 (Call, CallParams: [
265 CallRequest,
266 BlockNumber,
267 #[serde(default)]
268 Boolean
269 ], CallResult),
270 (GetCensoredAddrs, GetCensoredAddrsParams: [], CensorAddrs),
271 (eth_blockNumber, eth_blockNumberParams: [], Quantity),
273 (eth_chainId, eth_chainIdParams: [], Quantity),
274 (eth_getBlockByHash, eth_getBlockByHashParams: [Data32, Boolean], EthBlock),
275 (eth_getBlockByNumber, eth_getBlockByNumberParams: [BlockNumber, Boolean], EthBlock),
276 (eth_getTransactionByHash, eth_getTransactionByHashParams: [Data32], EthRpcTransaction),
277 (eth_getTransactionByBlockHashAndIndex, eth_getTransactionByBlockHashAndIndexParams: [Data32, Integer], EthRpcTransaction),
278 (eth_getTransactionByBlockNumberAndIndex, eth_getTransactionByBlockNumberAndIndexParams: [BlockNumber, Integer], EthRpcTransaction),
279 (eth_getBlockTransactionCountByHash, eth_getBlockTransactionCountByHashParams: [Data32], Integer),
280 (eth_getBlockTransactionCountByNumber, eth_getBlockTransactionCountByNumberParams: [BlockNumber], Integer),
281 (eth_getTransactionReceipt, eth_getTransactionReceiptParams: [Data32], EthReceipt),
282 (eth_getBalance, eth_getBalanceParams: [Data20, BlockNumber], Quantity),
283 (eth_syncing, eth_syncingParams: [], Boolean),
284 (eth_getStorageAt, eth_getStorageAtParams: [Data20, Quantity, BlockNumber], Data),
285 (eth_getCode, eth_getCodeParams: [Data20, BlockNumber], Data),
286 (eth_getTransactionCount, eth_getTransactionCountParams: [Data20, BlockNumber], Quantity),
287 (eth_getLogs, eth_getLogsParams: [EthFilter], EthLogs),
288 (eth_call, eth_callParams: [EthCallRequest, BlockNumber], Data),
289 (eth_estimateGas, eth_estimateGasParams: [
290 EthCallRequest,
291 #[serde(default)]
292 BlockNumber
293 ], Quantity),
294 (eth_gasPrice, eth_gasPriceParams: [], Quantity),
295 (eth_maxPriorityFeePerGas, eth_maxPriorityFeePerGasParams: [], Quantity),
296 (eth_sendTransaction, eth_sendTransactionParams: [EthTransactionRequest], Data32),
297 (eth_sendRawTransaction, eth_sendRawTransactionParams: [Data], Data32),
298 (eth_accounts, eth_accountsParams: [], Accounts),
299 (net_version, net_versionParams: [], Integer),
301 );
302 };
303}
304
305impl_for_each_jsonrpc_requests!(define_call);