Skip to content

Commit

Permalink
Merge pull request #128 from anton-rs/rf/provider-refactor
Browse files Browse the repository at this point in the history
chore: provider refactor
  • Loading branch information
refcell authored Nov 25, 2024
2 parents e38e954 + d92c496 commit c4c7bcc
Show file tree
Hide file tree
Showing 25 changed files with 903 additions and 155 deletions.
57 changes: 49 additions & 8 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ hilo-net = { version = "0.11.0", path = "crates/net", default-features = false }
hilo-node = { version = "0.11.0", path = "crates/node", default-features = false }
hilo-driver = { version = "0.11.0", path = "crates/driver", default-features = false }
hilo-engine = { version = "0.11.0", path = "crates/engine", default-features = false }
hilo-providers-local = { version = "0.11.0", path = "crates/providers-local", default-features = false }
hilo-providers-alloy = { version = "0.11.0", path = "crates/providers-alloy", default-features = false }

# Kona
kona-derive = { version = "0.1.0", default-features = false }
Expand Down
20 changes: 10 additions & 10 deletions crates/driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,46 @@ repository.workspace = true
rust-version.workspace = true

[dependencies]
# Local
hilo-providers-local.workspace = true
hilo-providers-alloy.workspace = true

# Kona
kona-derive.workspace = true
kona-driver.workspace = true

# Alloy
alloy-eips.workspace = true
alloy-serde.workspace = true
alloy-network.workspace = true
alloy-transport.workspace = true
alloy-consensus.workspace = true
alloy-rpc-types-eth.workspace = true
alloy-rpc-types-beacon.workspace = true
alloy-provider = { workspace = true, features = ["ipc", "ws", "reqwest"] }
alloy-rpc-types = { workspace = true, features = ["ssz"] }
alloy-primitives = { workspace = true, features = ["map"] }

# Op Alloy
op-alloy-genesis.workspace = true
op-alloy-protocol.workspace = true
op-alloy-consensus.workspace = true
op-alloy-rpc-types-engine.workspace = true

# Reth
reth-provider.workspace = true
reth-primitives.workspace = true
reth-execution-types.workspace = true
reth-exex = { workspace = true, features = ["serde"] }

# Misc
url.workspace = true
eyre.workspace = true
serde.workspace = true
tokio.workspace = true
serde.workspace = true
tracing.workspace = true
futures.workspace = true
thiserror.workspace = true
async-trait.workspace = true
parking_lot.workspace = true
reqwest = { workspace = true, features = ["json"] }
derive_more = { workspace = true, features = ["full"] }
url = { workspace = true, features = ["serde"] }

[dev-dependencies]
reqwest.workspace = true
eyre.workspace = true

[features]
default = []
127 changes: 127 additions & 0 deletions crates/driver/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//! Configuration for the Hilo Driver.

use kona_derive::traits::ChainProvider;
use kona_driver::PipelineCursor;
use op_alloy_genesis::RollupConfig;
use op_alloy_protocol::{BatchValidationProvider, BlockInfo, L2BlockInfo};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use url::Url;

use hilo_providers_alloy::{
AlloyChainProvider, AlloyL2ChainProvider, BeaconClient, OnlineBeaconClient, OnlineBlobProvider,
OnlineBlobProviderWithFallback,
};

/// An error thrown by a [Config] operation.
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
/// An error thrown by the beacon client.
#[error("beacon client error: {0}")]
Beacon(String),
/// An L2 chain provider error.
#[error("L2 chain provider error: {0}")]
L2ChainProvider(String),
/// An L1 chain provider error.
#[error("L1 chain provider error: {0}")]
ChainProvider(String),
}

/// The global node configuration.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Config {
/// The L2 Chain ID.
pub l2_chain_id: u64,
/// The L1 chain RPC URL
pub l1_rpc_url: Url,
/// The base chain beacon client RPC URL
pub l1_beacon_url: Url,
/// An optional blob archiver URL used in the fallback provider.
pub blob_archiver_url: Option<Url>,
/// The L2 chain RPC URL
pub l2_rpc_url: Url,
/// The L2 engine API URL
pub l2_engine_url: Url,
/// The rollup config
pub rollup_config: RollupConfig,
/// The hilo-node RPC server
pub rpc_url: Option<Url>,
/// The cache size for in-memory providers.
pub cache_size: usize,
}

impl Config {
/// Construct an [OnlineBlobProviderWithFallback] from the [Config].
pub async fn blob_provider(
&self,
) -> Result<OnlineBlobProviderWithFallback<OnlineBeaconClient, OnlineBeaconClient>, ConfigError>
{
let beacon_client = OnlineBeaconClient::new_http(String::from(self.l1_beacon_url.clone()));
let genesis = Some(self.rollup_config.genesis.l1.number);
let slot_interval = beacon_client
.config_spec()
.await
.map_err(|e| ConfigError::Beacon(e.to_string()))?
.data
.seconds_per_slot;
let blob = OnlineBlobProvider::new(beacon_client, genesis, Some(slot_interval));
Ok(OnlineBlobProviderWithFallback::new(blob, None))
}

/// Returns an [AlloyChainProvider] from the configured provider endpoints.
pub fn l1_chain_provider(&self) -> AlloyChainProvider {
AlloyChainProvider::new_http(self.l1_rpc_url.clone())
}

/// Returns the L2 provider.
pub fn l2_provider(&self) -> AlloyL2ChainProvider {
AlloyL2ChainProvider::new_http(
self.l2_rpc_url.clone(),
Arc::new(self.rollup_config.clone()),
)
}

/// Returns the safe head tip.
/// The chain tip includes the safe L1 block info and the L2 block info.
pub async fn safe_tip(&self) -> Result<(BlockInfo, L2BlockInfo), ConfigError> {
let mut l2_provider = self.l2_provider();
let latest_block_number = l2_provider
.latest_block_number()
.await
.map_err(|e| ConfigError::L2ChainProvider(e.to_string()))?;
let l2_block_info = l2_provider
.l2_block_info_by_number(latest_block_number)
.await
.map_err(|e| ConfigError::L2ChainProvider(e.to_string()))?;

let mut l1_provider = self.l1_chain_provider();
let l1_block_info = l1_provider
.block_info_by_number(l2_block_info.l1_origin.number)
.await
.map_err(|e| ConfigError::ChainProvider(e.to_string()))?;

Ok((l1_block_info, l2_block_info))
}

/// Constructs a [PipelineCursor] from the origin.
pub async fn tip_cursor(&self) -> Result<PipelineCursor, ConfigError> {
// Load the safe head info.
let (origin, safe_head_info) = self.safe_tip().await?;

// Calculate the channel timeout
let channel_timeout =
self.rollup_config.channel_timeout(safe_head_info.block_info.timestamp);
let mut l1_origin_number = origin.number.saturating_sub(channel_timeout);
if l1_origin_number < self.rollup_config.genesis.l1.number {
l1_origin_number = self.rollup_config.genesis.l1.number;
}

// Create the pipeline cursor from the origin
let mut l1_provider = self.l1_chain_provider();
let l1_origin = l1_provider
.block_info_by_number(l1_origin_number)
.await
.map_err(|e| ConfigError::ChainProvider(e.to_string()))?;
Ok(PipelineCursor::new(channel_timeout, l1_origin))
}
}
Loading

0 comments on commit c4c7bcc

Please sign in to comment.