-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(providers): adding Allnodes RPC endpoint (#934)
* feat(providers): adding Allnodes RPC endpoint * feat: making tthe priority high
- Loading branch information
1 parent
56e42e3
commit 29534c5
Showing
11 changed files
with
190 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
use { | ||
super::ProviderConfig, | ||
crate::providers::{Priority, Weight}, | ||
std::collections::HashMap, | ||
}; | ||
|
||
#[derive(Debug)] | ||
pub struct AllnodesConfig { | ||
pub supported_chains: HashMap<String, (String, Weight)>, | ||
pub api_key: String, | ||
} | ||
|
||
impl AllnodesConfig { | ||
pub fn new(api_key: String) -> Self { | ||
Self { | ||
supported_chains: default_supported_chains(), | ||
api_key, | ||
} | ||
} | ||
} | ||
|
||
impl ProviderConfig for AllnodesConfig { | ||
fn supported_chains(self) -> HashMap<String, (String, Weight)> { | ||
self.supported_chains | ||
} | ||
|
||
fn supported_ws_chains(self) -> HashMap<String, (String, Weight)> { | ||
HashMap::new() | ||
} | ||
|
||
fn provider_kind(&self) -> crate::providers::ProviderKind { | ||
crate::providers::ProviderKind::Allnodes | ||
} | ||
} | ||
|
||
fn default_supported_chains() -> HashMap<String, (String, Weight)> { | ||
// Keep in-sync with SUPPORTED_CHAINS.md | ||
|
||
HashMap::from([ | ||
// Ethereum Mainnet | ||
( | ||
"eip155:1".into(), | ||
("eth30082".into(), Weight::new(Priority::High).unwrap()), | ||
), | ||
]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
use { | ||
super::{Provider, ProviderKind, RateLimited, RpcProvider, RpcProviderFactory}, | ||
crate::{ | ||
env::AllnodesConfig, | ||
error::{RpcError, RpcResult}, | ||
}, | ||
async_trait::async_trait, | ||
axum::{ | ||
http::HeaderValue, | ||
response::{IntoResponse, Response}, | ||
}, | ||
hyper::{client::HttpConnector, http, Client, Method}, | ||
hyper_tls::HttpsConnector, | ||
std::collections::HashMap, | ||
tracing::debug, | ||
}; | ||
|
||
#[derive(Debug)] | ||
pub struct AllnodesProvider { | ||
pub client: Client<HttpsConnector<HttpConnector>>, | ||
pub supported_chains: HashMap<String, String>, | ||
pub api_key: String, | ||
} | ||
|
||
impl Provider for AllnodesProvider { | ||
fn supports_caip_chainid(&self, chain_id: &str) -> bool { | ||
self.supported_chains.contains_key(chain_id) | ||
} | ||
|
||
fn supported_caip_chains(&self) -> Vec<String> { | ||
self.supported_chains.keys().cloned().collect() | ||
} | ||
|
||
fn provider_kind(&self) -> ProviderKind { | ||
ProviderKind::Allnodes | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl RateLimited for AllnodesProvider { | ||
async fn is_rate_limited(&self, response: &mut Response) -> bool { | ||
response.status() == http::StatusCode::TOO_MANY_REQUESTS | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl RpcProvider for AllnodesProvider { | ||
#[tracing::instrument(skip(self, body), fields(provider = %self.provider_kind()), level = "debug")] | ||
async fn proxy(&self, chain_id: &str, body: hyper::body::Bytes) -> RpcResult<Response> { | ||
let chain = &self | ||
.supported_chains | ||
.get(chain_id) | ||
.ok_or(RpcError::ChainNotFound)?; | ||
|
||
let uri = format!("https://{}.allnodes.me:8545/{}", chain, &self.api_key); | ||
|
||
let hyper_request = hyper::http::Request::builder() | ||
.method(Method::POST) | ||
.uri(uri) | ||
.header("Content-Type", "application/json") | ||
.body(hyper::body::Body::from(body))?; | ||
|
||
let response = self.client.request(hyper_request).await?; | ||
let status = response.status(); | ||
let body = hyper::body::to_bytes(response.into_body()).await?; | ||
|
||
if let Ok(response) = serde_json::from_slice::<jsonrpc::Response>(&body) { | ||
if response.error.is_some() && status.is_success() { | ||
debug!( | ||
"Strange: provider returned JSON RPC error, but status {status} is success: \ | ||
Allnodes: {response:?}" | ||
); | ||
} | ||
} | ||
|
||
let mut response = (status, body).into_response(); | ||
response | ||
.headers_mut() | ||
.insert("Content-Type", HeaderValue::from_static("application/json")); | ||
Ok(response) | ||
} | ||
} | ||
|
||
impl RpcProviderFactory<AllnodesConfig> for AllnodesProvider { | ||
#[tracing::instrument(level = "debug")] | ||
fn new(provider_config: &AllnodesConfig) -> Self { | ||
let forward_proxy_client = Client::builder().build::<_, hyper::Body>(HttpsConnector::new()); | ||
let supported_chains: HashMap<String, String> = provider_config | ||
.supported_chains | ||
.iter() | ||
.map(|(k, v)| (k.clone(), v.0.clone())) | ||
.collect(); | ||
|
||
AllnodesProvider { | ||
client: forward_proxy_client, | ||
supported_chains, | ||
api_key: provider_config.api_key.clone(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters