diff --git a/bedrock_client/Cargo.toml b/bedrock_client/Cargo.toml deleted file mode 100644 index 2137cb74..00000000 --- a/bedrock_client/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "bedrock_client" -version = "0.1.0" -edition = "2024" -license = { workspace = true } - -[lints] -workspace = true - -[dependencies] -common.workspace = true - -reqwest.workspace = true -anyhow.workspace = true -tokio-retry.workspace = true -futures.workspace = true -log.workspace = true -serde.workspace = true -humantime-serde.workspace = true -logos-blockchain-common-http-client.workspace = true -logos-blockchain-core.workspace = true -logos-blockchain-chain-broadcast-service.workspace = true -logos-blockchain-chain-service.workspace = true diff --git a/bedrock_client/src/lib.rs b/bedrock_client/src/lib.rs deleted file mode 100644 index 4e9bfffd..00000000 --- a/bedrock_client/src/lib.rs +++ /dev/null @@ -1,121 +0,0 @@ -use std::time::Duration; - -use anyhow::{Context as _, Result}; -use common::config::BasicAuth; -use futures::{Stream, TryFutureExt as _}; -#[expect(clippy::single_component_path_imports, reason = "Satisfy machete")] -use humantime_serde; -use log::{info, warn}; -pub use logos_blockchain_chain_broadcast_service::BlockInfo; -use logos_blockchain_chain_service::CryptarchiaInfo; -pub use logos_blockchain_common_http_client::{CommonHttpClient, Error}; -pub use logos_blockchain_core::{block::Block, header::HeaderId, mantle::SignedMantleTx}; -use reqwest::{Client, Url}; -use serde::{Deserialize, Serialize}; -use tokio_retry::Retry; - -/// Fibonacci backoff retry strategy configuration. -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] -pub struct BackoffConfig { - #[serde(with = "humantime_serde")] - pub start_delay: Duration, - pub max_retries: usize, -} - -impl Default for BackoffConfig { - fn default() -> Self { - Self { - start_delay: Duration::from_millis(100), - max_retries: 5, - } - } -} - -/// Simple wrapper -/// maybe extend in the future for our purposes -/// `Clone` is cheap because `CommonHttpClient` is internally reference counted (`Arc`). -#[derive(Clone)] -pub struct BedrockClient { - http_client: CommonHttpClient, - node_url: Url, - backoff: BackoffConfig, -} - -impl BedrockClient { - pub fn new(backoff: BackoffConfig, node_url: Url, auth: Option) -> Result { - info!("Creating Bedrock client with node URL {node_url}"); - let client = Client::builder() - //Add more fields if needed - .timeout(std::time::Duration::from_mins(1)) - .build() - .context("Failed to build HTTP client")?; - - let auth = auth.map(|a| { - logos_blockchain_common_http_client::BasicAuthCredentials::new(a.username, a.password) - }); - - let http_client = CommonHttpClient::new_with_client(client, auth); - Ok(Self { - http_client, - node_url, - backoff, - }) - } - - pub async fn post_transaction(&self, tx: SignedMantleTx) -> Result, Error> { - Retry::spawn(self.backoff_strategy(), || async { - match self - .http_client - .post_transaction(self.node_url.clone(), tx.clone()) - .await - { - Ok(()) => Ok(Ok(())), - Err(err) => match err { - // Retry arm. - // Retrying only reqwest errors: mainly connected to http. - Error::Request(_) => Err(err), - // Returning non-retryable error - Error::Server(_) | Error::Client(_) | Error::Url(_) => Ok(Err(err)), - }, - } - }) - .await - } - - pub async fn get_lib_stream(&self) -> Result, Error> { - self.http_client.get_lib_stream(self.node_url.clone()).await - } - - pub async fn get_block_by_id( - &self, - header_id: HeaderId, - ) -> Result>, Error> { - Retry::spawn(self.backoff_strategy(), || { - self.http_client - .get_block_by_id(self.node_url.clone(), header_id) - .inspect_err(|err| warn!("Block fetching failed with error: {err:#}")) - }) - .await - } - - pub async fn get_consensus_info(&self) -> Result { - Retry::spawn(self.backoff_strategy(), || { - self.http_client - .consensus_info(self.node_url.clone()) - .inspect_err(|err| warn!("Block fetching failed with error: {err:#}")) - }) - .await - } - - fn backoff_strategy(&self) -> impl Iterator { - let start_delay_millis = self - .backoff - .start_delay - .as_millis() - .try_into() - .expect("Start delay must be less than u64::MAX milliseconds"); - - tokio_retry::strategy::FibonacciBackoff::from_millis(start_delay_millis) - .take(self.backoff.max_retries) - } -}