Skip to content

Commit

Permalink
feat(range-finder): setup
Browse files Browse the repository at this point in the history
  • Loading branch information
refcell committed Jul 31, 2024
1 parent e95b88a commit 9780288
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 7 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
members = ["crates/*", "bin/opt8n", "bin/opd8n"]
default-members = ["bin/opt8n", "bin/opd8n"]
members = ["crates/*", "bin/*"]
default-members = ["bin/opt8n", "bin/opd8n", "bin/range-finder"]
resolver = "2"

[workspace.package]
Expand Down
190 changes: 186 additions & 4 deletions bin/range-finder/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
//! CLI for the range-finder.

use alloy_primitives::B256;
use clap::{ArgAction, Parser};
use color_eyre::eyre::Result;
use std::path::PathBuf;
use color_eyre::eyre::{eyre, Result};
use kona_derive::{
online::*,
types::{L2BlockInfo, StageError},
};
use reqwest::Url;
use std::sync::Arc;
use superchain_registry::ROLLUP_CONFIGS;
use tracing::{debug, error, trace, warn};

const LOG_TARGET: &str = "range_finder";

/// Range Finder Cli
///
Expand Down Expand Up @@ -45,6 +53,180 @@ impl Cli {

/// Parse the CLI arguments and run the command
pub async fn run(&self) -> Result<()> {
unimplemented!()
// Build the pipeline
let cfg = Arc::new(self.rollup_config().await?);
let mut l1_provider = self.l1_provider()?;
let mut l2_provider = self.l2_provider(cfg.clone())?;
let attributes = self.attributes(cfg.clone(), &l2_provider, &l1_provider);
let blob_provider = self.blob_provider();
let dap = self.dap(l1_provider.clone(), blob_provider, &cfg);
let mut l2_cursor = self.cursor().await?;
let l1_tip = l1_provider
.block_info_by_number(l2_cursor.l1_origin.number)
.await
.expect("Failed to fetch genesis L1 block info for pipeline tip");
let mut pipeline = new_online_pipeline(
cfg,
l1_provider.clone(),
dap,
l2_provider.clone(),
attributes,
l1_tip,
);

// Run the pipeline
loop {
// If the cursor is beyond the end block, break the loop.
if l2_cursor.block_info.number > self.end_block {
trace!(target: "loop", "Cursor is beyond the end block, breaking loop");
break;
}

// Step on the pipeline.
match pipeline.step(l2_cursor).await {
StepResult::PreparedAttributes => trace!(target: "loop", "Prepared attributes"),
StepResult::AdvancedOrigin => trace!(target: "loop", "Advanced origin"),
StepResult::OriginAdvanceErr(e) => {
warn!(target: "loop", "Could not advance origin: {:?}", e)
}
StepResult::StepFailed(e) => match e {
StageError::NotEnoughData => {
debug!(target: "loop", "Not enough data to step derivation pipeline");
}
_ => {
error!(target: "loop", "Error stepping derivation pipeline: {:?}", e);
}
},
}

// Get the attributes if there are some available.
let attributes = if let Some(attributes) = pipeline.next() {
attributes
} else {
continue;
};

// Print the L1 range for this L2 Block.
let derived = attributes.parent.block_info.number as i64 + 1;
let l2_block_info = l2_provider
.l2_block_info_by_number(derived as u64)
.await
.expect("Failed to fetch L2 block info for pipeline cursor");
let origin = pipeline.origin().expect("Failed to get pipeline l1 origin");
println!(
"L2 Block [{}] L1 Range: [{}, {}]",
derived, l2_block_info.l1_origin.number, origin.number
);

// Keep trying to advance the cursor in case the fetch fails.
loop {
match l2_provider
.l2_block_info_by_number(l2_cursor.block_info.number + 1)
.await
{
Ok(bi) => {
l2_cursor = bi;
break;
}
Err(e) => {
error!(target: LOG_TARGET, "Failed to fetch next pending l2 safe head: {}, err: {:?}", l2_cursor.block_info.number + 1, e);
// Don't step on the pipeline if we failed to fetch the next l2 safe head.
continue;
}
}
}
}

Ok(())
}

/// Gets the L2 starting block number.
/// Returns the genesis L2 block number if the start block is less than the genesis block number.
pub fn start_block(&self, cfg: &RollupConfig) -> u64 {
if self.start_block < cfg.genesis.l2.number {
cfg.genesis.l2.number
} else {
self.start_block
}
}

/// Returns an [L2BlockInfo] cursor for the pipeline.
pub async fn cursor(&self) -> Result<L2BlockInfo> {
let cfg = self.rollup_config().await?;
let mut l2_provider = self.l2_provider(Arc::new(cfg))?;
let cursor = l2_provider
.l2_block_info_by_number(self.start_block)
.await
.map_err(|_| eyre!("Failed to fetch genesis L2 block info for pipeline cursor"))?;
Ok(cursor)
}

/// Returns a new [AlloyChainProvider] using the l1 rpc url.
pub fn l1_provider(&self) -> Result<AlloyChainProvider> {
Ok(AlloyChainProvider::new_http(self.l1_rpc_url()?))
}

/// Returns a new [AlloyL2ChainProvider] using the l2 rpc url.
pub fn l2_provider(&self, cfg: Arc<RollupConfig>) -> Result<AlloyL2ChainProvider> {
Ok(AlloyL2ChainProvider::new_http(self.l2_rpc_url()?, cfg))
}

/// Returns a new [StatefulAttributesBuilder] using the l1 and l2 providers.
pub fn attributes(
&self,
cfg: Arc<RollupConfig>,
l2_provider: &AlloyL2ChainProvider,
l1_provider: &AlloyChainProvider,
) -> StatefulAttributesBuilder<AlloyChainProvider, AlloyL2ChainProvider> {
StatefulAttributesBuilder::new(cfg, l2_provider.clone(), l1_provider.clone())
}

/// Returns a new [OnlineBlobProvider] using the beacon url.
pub fn blob_provider(&self) -> OnlineBlobProvider<OnlineBeaconClient, SimpleSlotDerivation> {
OnlineBlobProvider::new(
OnlineBeaconClient::new_http(self.beacon_url.clone()),
None,
None,
)
}

/// Returns a new [EthereumDataSource] using the l1 provider and blob provider.
pub fn dap(
&self,
l1_provider: AlloyChainProvider,
blob_provider: OnlineBlobProvider<OnlineBeaconClient, SimpleSlotDerivation>,
cfg: &RollupConfig,
) -> EthereumDataSource<
AlloyChainProvider,
OnlineBlobProvider<OnlineBeaconClient, SimpleSlotDerivation>,
> {
EthereumDataSource::new(l1_provider, blob_provider, cfg)
}

/// Gets the rollup config from the l2 rpc url.
pub async fn rollup_config(&self) -> Result<RollupConfig> {
let mut l2_provider =
AlloyL2ChainProvider::new_http(self.l2_rpc_url()?, Arc::new(Default::default()));
let l2_chain_id = l2_provider.chain_id().await.map_err(|e| eyre!(e))?;
let cfg = ROLLUP_CONFIGS
.get(&l2_chain_id)
.cloned()
.ok_or_else(|| eyre!("No rollup config found for L2 chain ID: {}", l2_chain_id))?;
Ok(cfg)
}

/// Returns the l1 rpc url from CLI or environment variable.
pub fn l1_rpc_url(&self) -> Result<Url> {
Url::parse(&self.l1_rpc_url).map_err(|e| eyre!(e))
}

/// Returns the l2 rpc url from CLI or environment variable.
pub fn l2_rpc_url(&self) -> Result<Url> {
Url::parse(&self.l2_rpc_url).map_err(|e| eyre!(e))
}

/// Returns the beacon url from CLI or environment variable.
pub fn beacon_url(&self) -> String {
self.beacon_url.clone()
}
}
6 changes: 6 additions & 0 deletions bin/range-finder/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use clap::Parser;

#[tokio::main]
async fn main() -> color_eyre::Result<()> {
range_finder::Cli::parse().init_telemetry()?.run().await
}
2 changes: 1 addition & 1 deletion bin/range-finder/src/verbosity.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Module to configure the verbosity level for logging and telemetry.

use tracing::Level;
use color_eyre::eyre::{eyre, Result};
use tracing::Level;

/// Initializes tracing verbosity.
pub fn init_tracing(verbosity_level: u8) -> Result<()> {
Expand Down

0 comments on commit 9780288

Please sign in to comment.