diff --git a/bin/host/src/cli/mod.rs b/bin/host/src/cli/mod.rs index 942fb49bd..b2ea32295 100644 --- a/bin/host/src/cli/mod.rs +++ b/bin/host/src/cli/mod.rs @@ -14,7 +14,7 @@ use clap::{ builder::styling::{AnsiColor, Color, Style}, ArgAction, Parser, }; -use kona_providers_alloy::{OnlineBeaconClient, OnlineBlobProvider, SimpleSlotDerivation}; +use kona_providers_alloy::{OnlineBeaconClient, OnlineBlobProvider}; use op_alloy_genesis::RollupConfig; use serde::Serialize; use std::{path::PathBuf, sync::Arc}; @@ -130,11 +130,7 @@ impl HostCli { /// - A [ReqwestProvider] for the L2 node. pub async fn create_providers( &self, - ) -> Result<( - ReqwestProvider, - OnlineBlobProvider, - ReqwestProvider, - )> { + ) -> Result<(ReqwestProvider, OnlineBlobProvider, ReqwestProvider)> { let beacon_client = OnlineBeaconClient::new_http( self.l1_beacon_address.clone().ok_or(anyhow!("Beacon API URL must be set"))?, ); diff --git a/bin/host/src/fetcher/mod.rs b/bin/host/src/fetcher/mod.rs index 5b2d07714..f366c30b5 100644 --- a/bin/host/src/fetcher/mod.rs +++ b/bin/host/src/fetcher/mod.rs @@ -14,7 +14,7 @@ use anyhow::{anyhow, Result}; use kona_client::HintType; use kona_preimage::{PreimageKey, PreimageKeyType}; use kona_primitives::IndexedBlobHash; -use kona_providers_alloy::{OnlineBeaconClient, OnlineBlobProvider, SimpleSlotDerivation}; +use kona_providers_alloy::{OnlineBeaconClient, OnlineBlobProvider}; use op_alloy_protocol::BlockInfo; use std::sync::Arc; use tokio::sync::RwLock; @@ -33,7 +33,7 @@ where /// L1 chain provider. l1_provider: ReqwestProvider, /// The blob provider - blob_provider: OnlineBlobProvider, + blob_provider: OnlineBlobProvider, /// L2 chain provider. /// TODO: OP provider, N = Optimism l2_provider: ReqwestProvider, @@ -51,7 +51,7 @@ where pub const fn new( kv_store: Arc>, l1_provider: ReqwestProvider, - blob_provider: OnlineBlobProvider, + blob_provider: OnlineBlobProvider, l2_provider: ReqwestProvider, l2_head: B256, ) -> Self { diff --git a/crates/providers-alloy/src/blob_provider.rs b/crates/providers-alloy/src/blob_provider.rs index 9587464ca..12dd73b70 100644 --- a/crates/providers-alloy/src/blob_provider.rs +++ b/crates/providers-alloy/src/blob_provider.rs @@ -2,7 +2,6 @@ use alloy_eips::eip4844::Blob; use async_trait::async_trait; -use core::marker::PhantomData; use kona_derive::{errors::BlobProviderError, traits::BlobProvider}; use kona_primitives::{APIBlobSidecar, BlobSidecar, IndexedBlobHash}; use op_alloy_protocol::BlockInfo; @@ -10,26 +9,18 @@ use tracing::warn; use crate::{BeaconClient, OnlineBeaconClient}; -/// Specifies the derivation of a slot from a timestamp. -pub trait SlotDerivation { - /// Converts a timestamp to a slot number. - fn slot(genesis: u64, slot_time: u64, timestamp: u64) -> Result; -} - /// An online implementation of the [BlobProvider] trait. #[derive(Debug, Clone)] -pub struct OnlineBlobProvider { +pub struct OnlineBlobProvider { /// The Beacon API client. beacon_client: B, /// Beacon Genesis time used for the time to slot conversion. pub genesis_time: Option, /// Slot interval used for the time to slot conversion. pub slot_interval: Option, - /// Phantom data for slot derivation. - _slot_derivation: PhantomData, } -impl OnlineBlobProvider { +impl OnlineBlobProvider { /// Creates a new instance of the [OnlineBlobProvider]. /// /// The `genesis_time` and `slot_interval` arguments are _optional_ and the @@ -40,7 +31,7 @@ impl OnlineBlobProvider { genesis_time: Option, slot_interval: Option, ) -> Self { - Self { beacon_client, genesis_time, slot_interval, _slot_derivation: PhantomData } + Self { beacon_client, genesis_time, slot_interval } } /// Loads the beacon genesis and config spec @@ -80,6 +71,12 @@ impl OnlineBlobProvider { .map_err(|e| BlobProviderError::Backend(e.to_string())) } + /// Computes the slot for the given timestamp. + pub fn slot(genesis: u64, slot_time: u64, timestamp: u64) -> Result { + crate::ensure!(timestamp >= genesis, BlobProviderError::SlotDerivation); + Ok((timestamp - genesis) / slot_time) + } + /// Fetches blob sidecars for the given block reference and blob hashes. pub async fn fetch_filtered_sidecars( &self, @@ -95,7 +92,7 @@ impl OnlineBlobProvider { let interval = self.slot_interval.expect("Config Spec Loaded"); // Calculate the slot for the given timestamp. - let slot = S::slot(genesis, interval, block_ref.timestamp)?; + let slot = Self::slot(genesis, interval, block_ref.timestamp)?; // Fetch blob sidecars for the slot using the given blob hashes. let sidecars = self.fetch_sidecars(slot, blob_hashes).await?; @@ -116,22 +113,10 @@ impl OnlineBlobProvider { } } -/// Minimal slot derivation implementation. -#[derive(Debug, Default, Clone)] -pub struct SimpleSlotDerivation; - -impl SlotDerivation for SimpleSlotDerivation { - fn slot(genesis: u64, slot_time: u64, timestamp: u64) -> Result { - crate::ensure!(timestamp >= genesis, BlobProviderError::SlotDerivation); - Ok((timestamp - genesis) / slot_time) - } -} - #[async_trait] -impl BlobProvider for OnlineBlobProvider +impl BlobProvider for OnlineBlobProvider where B: BeaconClient + Send + Sync, - S: SlotDerivation + Send + Sync, { type Error = BlobProviderError; @@ -233,23 +218,16 @@ impl BlobSidecarProvider for B { /// Blob storage APIs are expected to implement the [BlobSidecarProvider] trait. /// One example can be found at #[derive(Debug, Clone)] -pub struct OnlineBlobProviderWithFallback< - B: BeaconClient, - F: BlobSidecarProvider, - S: SlotDerivation, -> { - primary: OnlineBlobProvider, +pub struct OnlineBlobProviderWithFallback { + primary: OnlineBlobProvider, fallback: Option, - _slot_derivation: PhantomData, } -impl - OnlineBlobProviderWithFallback -{ +impl OnlineBlobProviderWithFallback { /// Creates a new instance of the [OnlineBlobProviderWithFallback] with the /// specified primary and fallback providers. - pub const fn new(primary: OnlineBlobProvider, fallback: Option) -> Self { - Self { primary, fallback, _slot_derivation: PhantomData } + pub const fn new(primary: OnlineBlobProvider, fallback: Option) -> Self { + Self { primary, fallback } } /// Attempts to fetch blob sidecars from the fallback provider, if configured. @@ -270,7 +248,7 @@ impl } // Extract the genesis timestamp and slot interval from the primary provider. - let slot = S::slot( + let slot = OnlineBlobProvider::::slot( self.primary.genesis_time.expect("Genesis Config Loaded"), self.primary.slot_interval.expect("Config Spec Loaded"), block_ref.timestamp, @@ -296,11 +274,10 @@ impl } #[async_trait] -impl BlobProvider for OnlineBlobProviderWithFallback +impl BlobProvider for OnlineBlobProviderWithFallback where B: BeaconClient + Send + Sync, F: BlobSidecarProvider + Send + Sync, - S: SlotDerivation + Send + Sync, { type Error = BlobProviderError; @@ -375,31 +352,20 @@ where /// - [Self::with_primary] for the primary beacon client. /// - [Self::with_fallback] for the fallback beacon client. #[derive(Debug, Clone)] -pub struct OnlineBlobProviderBuilder { +pub struct OnlineBlobProviderBuilder { beacon_client: Option, fallback: Option, genesis_time: Option, slot_interval: Option, - _slot_derivation: PhantomData, } -impl Default - for OnlineBlobProviderBuilder -{ +impl Default for OnlineBlobProviderBuilder { fn default() -> Self { - Self { - beacon_client: None, - fallback: None, - genesis_time: None, - slot_interval: None, - _slot_derivation: PhantomData, - } + Self { beacon_client: None, fallback: None, genesis_time: None, slot_interval: None } } } -impl - OnlineBlobProviderBuilder -{ +impl OnlineBlobProviderBuilder { /// Creates a new [OnlineBlobProviderBuilder]. pub fn new() -> Self { Self::default() @@ -430,14 +396,12 @@ impl } /// Builds the [OnlineBlobProviderWithFallback] instance. - pub fn build(self) -> OnlineBlobProviderWithFallback { + pub fn build(self) -> OnlineBlobProviderWithFallback { self.into() } } -impl - OnlineBlobProviderBuilder -{ +impl OnlineBlobProviderBuilder { /// Adds a primary [OnlineBeaconClient] to the builder using the specified HTTP URL. pub fn with_primary(mut self, url: String) -> Self { self.beacon_client = Some(OnlineBeaconClient::new_http(url)); @@ -445,9 +409,7 @@ impl } } -impl - OnlineBlobProviderBuilder -{ +impl OnlineBlobProviderBuilder { /// Adds a fallback [OnlineBeaconClient] to the builder using the specified HTTP URL. pub fn with_fallback(mut self, maybe_url: Option) -> Self { self.fallback = maybe_url.map(OnlineBeaconClient::new_http); @@ -455,10 +417,10 @@ impl } } -impl - From> for OnlineBlobProviderWithFallback +impl From> + for OnlineBlobProviderWithFallback { - fn from(builder: OnlineBlobProviderBuilder) -> Self { + fn from(builder: OnlineBlobProviderBuilder) -> Self { Self::new( OnlineBlobProvider::new( builder.beacon_client.expect("Primary beacon client must be set"), @@ -486,8 +448,7 @@ mod tests { config_spec: Some(APIConfigResponse::new(seconds_per_slot)), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let result = blob_provider.load_configs().await; assert!(result.is_ok()); assert_eq!(blob_provider.genesis_time, Some(genesis_time)); @@ -526,8 +487,7 @@ mod tests { blob_sidecars: Some(sidecars), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo { timestamp: 15, ..Default::default() }; let blobs = blob_provider.get_blobs(&block_ref, &blob_hashes).await.unwrap(); assert_eq!(blobs.len(), 5); @@ -540,8 +500,7 @@ mod tests { config_spec: Some(APIConfigResponse::new(12)), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo::default(); let blob_hashes = Vec::new(); let result = blob_provider.get_blobs(&block_ref, &blob_hashes).await; @@ -551,8 +510,7 @@ mod tests { #[tokio::test] async fn test_get_blobs_beacon_genesis_fetch_fails() { let beacon_client = MockBeaconClient::default(); - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo::default(); let blob_hashes = vec![IndexedBlobHash::default()]; let result = blob_provider.get_blobs(&block_ref, &blob_hashes).await; @@ -568,8 +526,7 @@ mod tests { beacon_genesis: Some(APIGenesisResponse::default()), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo::default(); let blob_hashes = vec![IndexedBlobHash::default()]; let result = blob_provider.get_blobs(&block_ref, &blob_hashes).await; @@ -586,8 +543,7 @@ mod tests { config_spec: Some(APIConfigResponse::new(12)), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo { timestamp: 5, ..Default::default() }; let blob_hashes = vec![IndexedBlobHash::default()]; let result = blob_provider.get_blobs(&block_ref, &blob_hashes).await; @@ -601,8 +557,7 @@ mod tests { config_spec: Some(APIConfigResponse::new(12)), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo { timestamp: 15, ..Default::default() }; let blob_hashes = vec![IndexedBlobHash::default()]; let result = blob_provider.get_blobs(&block_ref, &blob_hashes).await; @@ -622,8 +577,7 @@ mod tests { }), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo { timestamp: 15, ..Default::default() }; let blob_hashes = vec![IndexedBlobHash { index: 1, ..Default::default() }]; let result = blob_provider.get_blobs(&block_ref, &blob_hashes).await; @@ -662,8 +616,7 @@ mod tests { hash: b256!("01df1f9ae707f5847513c9c430b683182079edf2b1f94ee12e4daae7f3c8c309"), }, ]; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo { timestamp: 15, ..Default::default() }; let result = blob_provider.get_blobs(&block_ref, &blob_hashes).await; assert_eq!( @@ -685,8 +638,7 @@ mod tests { }), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo { timestamp: 15, ..Default::default() }; let blob_hashes = vec![IndexedBlobHash { hash: alloy_primitives::FixedBytes::from([1; 32]), @@ -706,8 +658,7 @@ mod tests { }), ..Default::default() }; - let mut blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let mut blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let block_ref = BlockInfo { timestamp: 15, ..Default::default() }; let blob_hashes = vec![IndexedBlobHash { hash: b256!("01b0761f87b081d5cf10757ccc89f12be355c70e2e29df288b65b30710dcbcd1"), @@ -734,11 +685,10 @@ mod tests { }; let fallback_client = MockBeaconClient { blob_sidecars: Some(sidecars), ..Default::default() }; - let mut blob_provider: OnlineBlobProviderWithFallback<_, _, SimpleSlotDerivation> = - OnlineBlobProviderWithFallback::new( - OnlineBlobProvider::new(beacon_client, None, None), - Some(fallback_client), - ); + let mut blob_provider = OnlineBlobProviderWithFallback::new( + OnlineBlobProvider::new(beacon_client, None, None), + Some(fallback_client), + ); let block_ref = BlockInfo { timestamp: 15, ..Default::default() }; let blob_hashes = vec![ IndexedBlobHash { @@ -784,11 +734,10 @@ mod tests { }; let fallback_client = MockBeaconClient { blob_sidecars: Some(all_sidecars), ..Default::default() }; - let mut blob_provider: OnlineBlobProviderWithFallback<_, _, SimpleSlotDerivation> = - OnlineBlobProviderWithFallback::new( - OnlineBlobProvider::new(beacon_client, None, None), - Some(fallback_client), - ); + let mut blob_provider = OnlineBlobProviderWithFallback::new( + OnlineBlobProvider::new(beacon_client, None, None), + Some(fallback_client), + ); let block_ref = BlockInfo { timestamp: 15, ..Default::default() }; let blob_hashes = vec![ IndexedBlobHash { diff --git a/crates/providers-alloy/src/lib.rs b/crates/providers-alloy/src/lib.rs index 3548de69a..405ca4047 100644 --- a/crates/providers-alloy/src/lib.rs +++ b/crates/providers-alloy/src/lib.rs @@ -25,7 +25,7 @@ pub mod prelude { beacon_client::{BeaconClient, OnlineBeaconClient}, blob_provider::{ BlobSidecarProvider, OnlineBlobProvider, OnlineBlobProviderBuilder, - OnlineBlobProviderWithFallback, SimpleSlotDerivation, SlotDerivation, + OnlineBlobProviderWithFallback, }, pipeline::{new_online_pipeline, OnlinePipeline}, }; @@ -44,5 +44,5 @@ pub use beacon_client::{BeaconClient, OnlineBeaconClient}; pub mod blob_provider; pub use blob_provider::{ BlobSidecarProvider, OnlineBlobProvider, OnlineBlobProviderBuilder, - OnlineBlobProviderWithFallback, SimpleSlotDerivation, SlotDerivation, + OnlineBlobProviderWithFallback, }; diff --git a/crates/providers-alloy/src/pipeline.rs b/crates/providers-alloy/src/pipeline.rs index cd04bf097..f60a9c728 100644 --- a/crates/providers-alloy/src/pipeline.rs +++ b/crates/providers-alloy/src/pipeline.rs @@ -15,7 +15,6 @@ use std::sync::Arc; use crate::{ AlloyChainProvider, AlloyL2ChainProvider, OnlineBeaconClient, OnlineBlobProviderWithFallback, - SimpleSlotDerivation, }; /// An online derivation pipeline. @@ -25,7 +24,7 @@ pub type OnlinePipeline = /// An `online` Ethereum data source. pub type OnlineDataProvider = EthereumDataSource< AlloyChainProvider, - OnlineBlobProviderWithFallback, + OnlineBlobProviderWithFallback, >; /// An `online` payload attributes builder for the `AttributesQueue` stage of the derivation @@ -83,8 +82,7 @@ mod tests { rollup_config.clone(), ); let beacon_client = OnlineBeaconClient::new_http("http://127.0.0.1:5555".into()); - let blob_provider: OnlineBlobProvider<_, SimpleSlotDerivation> = - OnlineBlobProvider::new(beacon_client, None, None); + let blob_provider = OnlineBlobProvider::new(beacon_client, None, None); let blob_provider = OnlineBlobProviderWithFallback::new(blob_provider, None); let dap_source = EthereumDataSource::new(chain_provider.clone(), blob_provider, &rollup_config);