diff --git a/Cargo.toml b/Cargo.toml index 0e43dc5b..338167d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ tokio = { version = "1.18.0", features = ["full"] } parking_lot = "0.12.0" regex = "1.5.5" reqwest = { version = "0.11.10", features = ["json", "rustls"] } -serde = "1.0.136" +serde = { version = "1.0.136", features = [] } serde_json = { version = "1.0.79", default-features = false, features = ["alloc"] } tracing = "0.1.34" tracing-subscriber = "0.3.11" diff --git a/src/main.rs b/src/main.rs index d09d0228..be3ae6dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,9 @@ use futures::future; use futures::stream::FuturesUnordered; use futures::StreamExt; use governor::clock::{Clock, QuantaClock}; +use serde::{Deserialize, Serialize}; use serde_json::json; +use serde_json::value::RawValue; use std::collections::HashMap; use std::fmt; use std::sync::Arc; @@ -27,6 +29,21 @@ static APP_USER_AGENT: &str = concat!( env!("CARGO_PKG_VERSION"), ); +#[derive(Clone, Deserialize)] +struct JsonRpcRequest { + jsonrpc: Box, + id: Box, + method: String, + params: Box, +} + +#[derive(Clone, Serialize)] +struct JsonRpcForwardedResponse { + jsonrpc: Box, + id: Box, + result: Box, +} + /// The application // TODO: this debug impl is way too verbose. make something smaller struct Web3ProxyApp { @@ -175,13 +192,9 @@ impl Web3ProxyApp { /// TODO: dry this up async fn proxy_web3_rpc( self: Arc, - json_body: serde_json::Value, + json_body: JsonRpcRequest, ) -> anyhow::Result { - let eth_send_raw_transaction = - serde_json::Value::String("eth_sendRawTransaction".to_string()); - - if self.private_rpcs.is_some() && json_body.get("method") == Some(ð_send_raw_transaction) - { + if self.private_rpcs.is_some() && json_body.method == "eth_sendRawTransaction" { let private_rpcs = self.private_rpcs.clone().unwrap(); // there are private rpcs configured and the request is eth_sendSignedTransaction. send to all private rpcs @@ -199,7 +212,7 @@ impl Web3ProxyApp { let connections = private_rpcs.clone_connections(); // check incoming_id before sending any requests - let incoming_id = json_body.as_object().unwrap().get("id").unwrap(); + let incoming_id = &*json_body.id; tokio::spawn(async move { clone @@ -253,7 +266,7 @@ impl Web3ProxyApp { let mut earliest_not_until = None; // check incoming_id before sending any requests - let incoming_id = json_body.as_object().unwrap().get("id").unwrap(); + let incoming_id = &*json_body.id; for balanced_rpcs in self.balanced_rpc_tiers.iter() { // TODO: what allowed lag? @@ -358,20 +371,13 @@ impl Web3ProxyApp { &self, rpc_servers: Vec, connections: Arc, - json_request_body: serde_json::Value, + json_request_body: JsonRpcRequest, // TODO: better type for this tx: mpsc::UnboundedSender>, ) -> anyhow::Result<()> { // {"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1} - let method = json_request_body - .get("method") - .and_then(|x| x.as_str()) - .ok_or_else(|| anyhow::anyhow!("bad id"))? - .to_string(); - let params = json_request_body - .get("params") - .ok_or_else(|| anyhow::anyhow!("no params"))? - .to_owned(); + let method = json_request_body.method.clone(); + let params = json_request_body.params; if rpc_servers.len() == 1 { let rpc = rpc_servers.first().unwrap(); diff --git a/src/provider.rs b/src/provider.rs index e0a9953e..a39d6c01 100644 --- a/src/provider.rs +++ b/src/provider.rs @@ -39,7 +39,7 @@ impl Web3Provider { pub async fn request( &self, method: &str, - params: serde_json::Value, + params: Box, ) -> Result { match self { Self::Http(provider) => provider.request(method, params).await,