diff --git a/crates/kona-providers/src/blob_provider.rs b/crates/kona-providers/src/blob_provider.rs index 27cea28..98788e7 100644 --- a/crates/kona-providers/src/blob_provider.rs +++ b/crates/kona-providers/src/blob_provider.rs @@ -18,6 +18,14 @@ use reth::primitives::BlobTransactionSidecar; use tracing::warn; use url::Url; +/// A blob provider that first attempts to fetch blobs from a primary beacon client and +/// falls back to a secondary blob archiver if the primary fails. +/// +/// Any blob archiver just needs to implement the beacon +/// [`blob_sidecars` API](https://ethereum.github.io/beacon-APIs/#/Beacon/getBlobSidecars) +pub type DurableBlobProvider = + OnlineBlobProviderWithFallback; + /// Layered [BlobProvider] for the Kona derivation pipeline. /// /// This provider wraps different blob sources in an ordered manner: @@ -35,13 +43,9 @@ pub struct LayeredBlobProvider { /// This is used primarily during sync when archived blobs /// aren't provided by reth since they'll be too old. /// - /// The `WithFallback` setup allows to specify two different + /// The `Durable` setup allows to specify two different /// endpoints for a primary and a fallback blob provider. - online: OnlineBlobProviderWithFallback< - OnlineBeaconClient, - OnlineBeaconClient, - SimpleSlotDerivation, - >, + online: DurableBlobProvider, } /// A blob provider that hold blobs in memory. diff --git a/crates/rollup/src/cli.rs b/crates/rollup/src/cli.rs index 2119932..7b56af2 100644 --- a/crates/rollup/src/cli.rs +++ b/crates/rollup/src/cli.rs @@ -8,6 +8,9 @@ use url::Url; /// The default L2 chain ID to use. This corresponds to OP Mainnet. pub const DEFAULT_L2_CHAIN_ID: u64 = 10; +/// The default L1 RPC URL to use. +pub const DEFAULT_L1_RPC_URL: &str = "https://eth.llamarpc.com/"; + /// The default L2 RPC URL to use. pub const DEFAULT_L2_RPC_URL: &str = "https://optimism.llamarpc.com/"; @@ -30,6 +33,11 @@ pub struct HeraArgsExt { #[clap(long = "hera.l2-rpc-url", default_value = DEFAULT_L2_RPC_URL)] pub l2_rpc_url: Url, + /// RPC URL of an L1 execution client + /// (This is only needed when running in Standalone mode) + #[clap(long = "hera.l1-rpc-url", default_value = DEFAULT_L1_RPC_URL)] + pub l1_rpc_url: Url, + /// URL of an L1 beacon client to fetch blobs #[clap(long = "hera.l1-beacon-client-url", default_value = DEFAULT_L1_BEACON_CLIENT_URL)] pub l1_beacon_client_url: Url, diff --git a/crates/rollup/src/driver.rs b/crates/rollup/src/driver.rs index ad3402d..219763c 100644 --- a/crates/rollup/src/driver.rs +++ b/crates/rollup/src/driver.rs @@ -5,11 +5,13 @@ use std::{fmt::Debug, sync::Arc}; use async_trait::async_trait; use eyre::{bail, Result}; use kona_derive::{ - online::AlloyL2ChainProvider, + online::{AlloyChainProvider, AlloyL2ChainProvider, OnlineBlobProviderBuilder}, traits::{BlobProvider, ChainProvider, L2ChainProvider}, }; use kona_primitives::BlockInfo; -use kona_providers::{InMemoryChainProvider, LayeredBlobProvider}; +use kona_providers::{ + blob_provider::DurableBlobProvider, InMemoryChainProvider, LayeredBlobProvider, +}; use reth_exex::{ExExContext, ExExEvent, ExExNotification}; use reth_node_api::FullNodeComponents; use superchain_registry::RollupConfig; @@ -25,17 +27,6 @@ pub trait DriverContext { fn send_event(&mut self, event: ExExEvent) -> Result<(), SendError>; } -#[async_trait] -impl DriverContext for ExExContext { - async fn recv_notification(&mut self) -> Option { - self.notifications.recv().await - } - - fn send_event(&mut self, event: ExExEvent) -> Result<(), SendError> { - self.events.send(event) - } -} - /// The Rollup Driver entrypoint. #[derive(Debug)] pub struct Driver { @@ -51,6 +42,36 @@ pub struct Driver { l2_chain_provider: L2CP, } +#[async_trait] +impl DriverContext for ExExContext { + async fn recv_notification(&mut self) -> Option { + self.notifications.recv().await + } + + fn send_event(&mut self, event: ExExEvent) -> Result<(), SendError> { + self.events.send(event) + } +} + +#[derive(Debug)] +pub struct StandaloneContext; + +#[async_trait] +impl DriverContext for StandaloneContext { + async fn recv_notification(&mut self) -> Option { + // Where should we get notifications from? + // We could use the L1 chain provider, but it's already in the Driver struct + // and it doesn't work well with the ExExNotification abstraction IMO. + todo!() + } + + fn send_event(&mut self, _event: ExExEvent) -> Result<(), SendError> { + // Sending events is a no-op for standalone mode for now, + // really not sure if we'll need it here? + Ok(()) + } +} + impl Driver, InMemoryChainProvider, LayeredBlobProvider, AlloyL2ChainProvider> where N: FullNodeComponents, @@ -65,6 +86,20 @@ where } } +impl Driver { + /// Create a new standalone Hera Driver + pub async fn std(ctx: StandaloneContext, args: HeraArgsExt, cfg: Arc) -> Self { + let cp = AlloyChainProvider::new_http(args.l1_rpc_url); + let l2_cp = AlloyL2ChainProvider::new_http(args.l2_rpc_url, cfg.clone()); + let bp = OnlineBlobProviderBuilder::new() + .with_primary(args.l1_beacon_client_url.to_string()) + .with_fallback(args.l1_blob_archiver_url.map(|url| url.to_string())) + .build(); + + Self { cfg, ctx, chain_provider: cp, blob_provider: bp, l2_chain_provider: l2_cp } + } +} + #[allow(unused)] impl Driver where