Skip to content

Commit

Permalink
feat(bridge): add fallback providers (#1260)
Browse files Browse the repository at this point in the history
  • Loading branch information
njgheorghita authored Apr 18, 2024
1 parent 492f1d8 commit 8566cd4
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 229 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ reth-ipc = { tag = "v0.2.0-beta.5", git = "https://github.com/paradigmxyz/reth.g
rpc = { path = "rpc"}
serde_json = {version = "1.0.89", features = ["preserve_order"]}
sha3 = "0.9.1"
surf = { version = "2.3.2", default-features = false, features = ["h1-client-rustls", "middleware-logger", "encoding"] } # we use rustils because OpenSSL cause issues compiling on aarch64
surf = { version = "2.3.2", default-features = false, features = ["h1-client-rustls", "middleware-logger", "encoding"] } # we use rustls because OpenSSL cause issues compiling on aarch64
tempfile = "3.3.0"
tokio = { version = "1.14.0", features = ["full"] }
tracing = "0.1.36"
Expand Down
2 changes: 2 additions & 0 deletions ethportal-peertest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rpc = { path = "../rpc" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.89"
serde_yaml = "0.9"
surf = { version = "2.3.2", default-features = false, features = ["h1-client-rustls", "middleware-logger", "encoding"] } # we use rustls because OpenSSL cause issues compiling on aarch64
tempfile = "3.3.0"
tokio = {version = "1.14.0", features = ["full"]}
tracing = "0.1.36"
Expand All @@ -38,6 +39,7 @@ trin-state = { path = "../trin-state" }
trin-utils = { path = "../trin-utils" }
trin-validation = { path = "../trin-validation" }
ureq = { version = "2.5.0", features = ["json"] }
url = "2.3.1"

[target.'cfg(windows)'.dependencies]
uds_windows = "1.0.1"
10 changes: 7 additions & 3 deletions ethportal-peertest/src/scenarios/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,28 @@ use ethportal_api::{jsonrpsee::http_client::HttpClient, BeaconContentKey, Beacon
use portal_bridge::{
api::{consensus::ConsensusApi, execution::ExecutionApi},
bridge::{beacon::BeaconBridge, history::HistoryBridge},
cli::Provider,
constants::DEFAULT_GOSSIP_LIMIT,
types::mode::BridgeMode,
};
use serde_json::Value;
use std::sync::Arc;
use surf::{Client, Config};
use tokio::time::{sleep, Duration};
use trin_validation::{accumulator::MasterAccumulator, oracle::HeaderOracle};
use url::Url;

pub async fn test_history_bridge(peertest: &Peertest, target: &HttpClient) {
let master_acc = MasterAccumulator::default();
let header_oracle = HeaderOracle::new(master_acc);
let portal_clients = vec![target.clone()];
let epoch_acc_path = "validation_assets/epoch_acc.bin".into();
let mode = BridgeMode::Test("./test_assets/portalnet/bridge_data.json".into());
let execution_api = ExecutionApi::new(Provider::Test, mode.clone())
.await
let client: Client = Config::new()
// url doesn't matter, we're not making any requests
.set_base_url(Url::parse("http://www.null.com").unwrap())
.try_into()
.unwrap();
let execution_api = ExecutionApi::new(client.clone(), client).await.unwrap();
// Wait for bootnode to start
sleep(Duration::from_secs(1)).await;
let bridge = HistoryBridge::new(
Expand Down
2 changes: 1 addition & 1 deletion portal-bridge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ serde_json = "1.0.89"
serde_yaml = "0.9"
snap = "1.1.1"
ssz_types = { git = "https://github.com/KolbyML/ssz_types.git", rev = "2a5922de75f00746890bf4ea9ad663c9d5d58efe" }
surf = { version = "2.3.2", default-features = false, features = ["h1-client-rustls", "middleware-logger", "encoding"] } # we use rustils because OpenSSL cause issues compiling on aarch64
surf = { version = "2.3.2", default-features = false, features = ["h1-client-rustls", "middleware-logger", "encoding"] } # we use rustls because OpenSSL cause issues compiling on aarch64
tokio = { version = "1.14.0", features = ["full"] }
tracing = "0.1.36"
tracing-subscriber = "0.3.15"
Expand Down
74 changes: 34 additions & 40 deletions portal-bridge/src/api/consensus.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,40 @@
use std::fmt::Display;

use anyhow::anyhow;
use surf::{Client, Config};
use tracing::debug;
use url::Url;

use crate::{
cli::Provider, constants::HTTP_REQUEST_TIMEOUT, BASE_CL_ENDPOINT, PANDAOPS_CLIENT_ID,
PANDAOPS_CLIENT_SECRET,
};
use surf::Client;
use tracing::{debug, warn};

/// Implements endpoints from the Beacon API to access data from the consensus layer.
#[derive(Clone, Debug, Default)]
pub struct ConsensusApi {
client: Client,
fallback_client: Client,
}

impl ConsensusApi {
pub async fn new(provider: Provider) -> Result<Self, surf::Error> {
let client: Client = match provider {
Provider::PandaOps => {
let base_cl_endpoint = Url::parse(&BASE_CL_ENDPOINT)
.expect("to be able to parse static base cl endpoint url");
Config::new()
.add_header("CF-Access-Client-Id", PANDAOPS_CLIENT_ID.to_string())?
.add_header(
"CF-Access-Client-Secret",
PANDAOPS_CLIENT_SECRET.to_string(),
)?
.add_header("Content-Type", "application/json")?
.set_base_url(base_cl_endpoint)
.set_timeout(Some(HTTP_REQUEST_TIMEOUT))
.try_into()?
}
Provider::Url(url) => Config::new()
.add_header("Content-Type", "application/json")?
.set_base_url(url)
.set_timeout(Some(HTTP_REQUEST_TIMEOUT))
.try_into()?,
Provider::Test => {
return Err(surf::Error::from(anyhow!(
"Invalid provider, test mode is not supported for ConsensusApi"
)))
}
};
pub async fn new(client: Client, fallback_client: Client) -> Result<Self, surf::Error> {
debug!(
"Starting ConsensusApi with provider at url: {:?}",
client.config().base_url
"Starting ConsensusApi with primary provider: {} and fallback provider: {}",
client
.config()
.base_url
.as_ref()
.expect("to have base url set")
.as_str(),
fallback_client
.config()
.base_url
.as_ref()
.expect("to have base url set")
.as_str()
);
check_provider(&client)
.await
.map_err(|err| anyhow!("Check CL provider failed. Provider may be offline: {err:?}"))?;
Ok(Self { client })
Ok(Self {
client,
fallback_client,
})
}

/// Requests the `LightClientBootstrap` structure corresponding to a given post-Altair beacon
Expand Down Expand Up @@ -99,8 +82,19 @@ impl ConsensusApi {

/// Make a request to the cl provider.
async fn request(&self, endpoint: String) -> anyhow::Result<String> {
let result = self.client.get(endpoint).recv_string().await;
result.map_err(|err| anyhow!("Unable to request consensus data from provider: {err:?}"))
match self.client.get(&endpoint).recv_string().await {
Ok(response) => Ok(response),
Err(err) => {
warn!("Error requesting consensus data from provider, retrying with fallback provider: {err:?}");
self.fallback_client
.get(endpoint)
.recv_string()
.await
.map_err(|err| {
anyhow!("Unable to request consensus data from fallback provider: {err:?}")
})
}
}
}
}

Expand Down
Loading

0 comments on commit 8566cd4

Please sign in to comment.