Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(providers): adding the Aurora native mainnet and testnet RPC #469

Merged
merged 1 commit into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/env/aurora.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use {
super::ProviderConfig,
crate::providers::{Priority, Weight},
std::collections::HashMap,
};

#[derive(Debug)]
pub struct AuroraConfig {
pub supported_chains: HashMap<String, (String, Weight)>,
}

impl Default for AuroraConfig {
fn default() -> Self {
Self {
supported_chains: default_supported_chains(),
}
}
}

impl ProviderConfig for AuroraConfig {
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::Aurora
}
}

fn default_supported_chains() -> HashMap<String, (String, Weight)> {
// Keep in-sync with SUPPORTED_CHAINS.md

HashMap::from([
// Aurora Mainnet
(
"eip155:1313161554".into(),
(
"https://mainnet.aurora.dev".into(),
Weight::new(Priority::High).unwrap(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the priority HIGH by default for the native endpoint.

),
),
// Aurora Testnet
(
"eip155:1313161555".into(),
(
"https://testnet.aurora.dev".into(),
Weight::new(Priority::High).unwrap(),
),
),
])
}
2 changes: 2 additions & 0 deletions src/env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use {
std::{collections::HashMap, fmt::Display},
};
pub use {
aurora::*,
base::*,
binance::*,
infura::*,
Expand All @@ -21,6 +22,7 @@ pub use {
zksync::*,
zora::*,
};
mod aurora;
mod base;
mod binance;
mod infura;
Expand Down
99 changes: 99 additions & 0 deletions src/providers/aurora.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use {
super::{Provider, ProviderKind, RateLimited, RpcProvider, RpcProviderFactory},
crate::{
env::AuroraConfig,
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::info,
};

#[derive(Debug)]
pub struct AuroraProvider {
pub client: Client<HttpsConnector<HttpConnector>>,
pub supported_chains: HashMap<String, String>,
}

impl Provider for AuroraProvider {
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::Aurora
}
}

#[async_trait]
impl RateLimited for AuroraProvider {
async fn is_rate_limited(&self, response: &mut Response) -> bool
where
Self: Sized,
{
response.status() == http::StatusCode::TOO_MANY_REQUESTS
}
}

#[async_trait]
impl RpcProvider for AuroraProvider {
#[tracing::instrument(skip(self, body), fields(provider = %self.provider_kind()))]
async fn proxy(&self, chain_id: &str, body: hyper::body::Bytes) -> RpcResult<Response> {
let uri = self
.supported_chains
.get(chain_id)
.ok_or(RpcError::ChainNotFound)?;

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() {
info!(
"Strange: provider returned JSON RPC error, but status {status} is success: \
Aurora: {response:?}"
);
}
}

let mut response = (status, body).into_response();
response
.headers_mut()
.insert("Content-Type", HeaderValue::from_static("application/json"));
Ok(response)
}
}

impl RpcProviderFactory<AuroraConfig> for AuroraProvider {
#[tracing::instrument]
fn new(provider_config: &AuroraConfig) -> 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();

AuroraProvider {
client: forward_proxy_client,
supported_chains,
}
}
}
4 changes: 4 additions & 0 deletions src/providers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use {
wc::metrics::TaskMetrics,
};

mod aurora;
mod base;
mod binance;
mod coinbase;
Expand Down Expand Up @@ -270,6 +271,7 @@ impl ProviderRepository {

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ProviderKind {
Aurora,
Infura,
Pokt,
Binance,
Expand All @@ -285,6 +287,7 @@ pub enum ProviderKind {
impl Display for ProviderKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", match self {
ProviderKind::Aurora => "Aurora",
ProviderKind::Infura => "Infura",
ProviderKind::Pokt => "Pokt",
ProviderKind::Binance => "Binance",
Expand All @@ -302,6 +305,7 @@ impl Display for ProviderKind {
impl ProviderKind {
pub fn from_str(s: &str) -> Option<Self> {
match s {
"Aurora" => Some(Self::Aurora),
"Infura" => Some(Self::Infura),
"Pokt" => Some(Self::Pokt),
"Binance" => Some(Self::Binance),
Expand Down
22 changes: 22 additions & 0 deletions tests/functional/http/aurora.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use {
super::check_if_rpc_is_responding_correctly_for_supported_chain,
crate::context::ServerContext,
test_context::test_context,
};

#[test_context(ServerContext)]
#[tokio::test]
#[ignore]
async fn aurora_provider(ctx: &mut ServerContext) {
// Aurora Mainnet
check_if_rpc_is_responding_correctly_for_supported_chain(
ctx,
"eip155:1313161554",
"0x4e454152",
)
.await;

// Aurora Testnet
check_if_rpc_is_responding_correctly_for_supported_chain(ctx, "eip155:1313161555", "0x4e454153")
.await
}
1 change: 1 addition & 0 deletions tests/functional/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use {
test_context::test_context,
};

pub(crate) mod aurora;
pub(crate) mod base;
pub(crate) mod binance;
pub(crate) mod infura;
Expand Down