diff --git a/Cargo.lock b/Cargo.lock index 832cc30b64..e6139bf4cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1556,9 +1556,7 @@ dependencies = [ "async-trait", "c-kzg", "hashbrown", - "kona-plasma", "kona-primitives", - "kona-providers", "lru", "miniz_oxide", "op-alloy-consensus", @@ -1614,10 +1612,11 @@ dependencies = [ "alloy-primitives", "anyhow", "async-trait", + "kona-derive", "kona-primitives", - "kona-providers", "serde", "serde_json", + "tokio", "tracing", "tracing-subscriber", ] @@ -1649,26 +1648,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "kona-providers" -version = "0.0.1" -dependencies = [ - "alloy-consensus 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=e3f2f07)", - "alloy-primitives", - "alloy-rlp", - "alloy-sol-types", - "anyhow", - "async-trait", - "hashbrown", - "kona-primitives", - "op-alloy-consensus", - "serde", - "serde_json", - "tokio", - "tracing", - "tracing-subscriber", -] - [[package]] name = "lazy_static" version = "1.4.0" diff --git a/crates/derive/Cargo.toml b/crates/derive/Cargo.toml index 703bcbf912..667233eb05 100644 --- a/crates/derive/Cargo.toml +++ b/crates/derive/Cargo.toml @@ -18,8 +18,6 @@ alloy-rlp = { workspace = true, features = ["derive"] } # Local kona-primitives = { path = "../primitives", version = "0.0.1" } -kona-plasma = { path = "../plasma", version = "0.0.1" } -kona-providers = { path = "../providers", version = "0.0.1" } # External alloy-sol-types = { version = "0.7.1", default-features = false } @@ -43,8 +41,12 @@ alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", o alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", optional = true } reqwest = { version = "0.12", default-features = false, optional = true } +# `test-utils` feature dependencies +alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", default-features = false, optional = true } +tracing-subscriber = { version = "0.3.18", optional = true } +alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", default-features = false, optional = true } + [dev-dependencies] -kona-plasma = { path = "../plasma", version = "0.0.1", features = ["default", "test-utils"] } tokio = { version = "1.37", features = ["full"] } proptest = "1.4.0" tracing-subscriber = "0.3.18" @@ -54,7 +56,13 @@ serde_json = { version = "1.0.116", default-features = false } [features] default = ["serde", "k256"] -serde = ["dep:serde", "kona-plasma/serde", "kona-providers/serde", "kona-primitives/serde", "alloy-primitives/serde", "alloy-consensus/serde", "op-alloy-consensus/serde"] +serde = [ + "dep:serde", + "kona-primitives/serde", + "alloy-primitives/serde", + "alloy-consensus/serde", + "op-alloy-consensus/serde" +] k256 = ["alloy-primitives/k256", "alloy-consensus/k256", "op-alloy-consensus/k256"] online = [ "dep:revm-primitives", @@ -69,4 +77,4 @@ online = [ "revm-primitives/serde", "revm-primitives/c-kzg", ] -test-utils = [ "kona-providers/test-utils", "kona-plasma/test-utils" ] +test-utils = ["dep:alloy-node-bindings", "dep:tracing-subscriber", "dep:alloy-rpc-client"] diff --git a/crates/derive/src/lib.rs b/crates/derive/src/lib.rs index b638217830..2a861af607 100644 --- a/crates/derive/src/lib.rs +++ b/crates/derive/src/lib.rs @@ -22,9 +22,6 @@ pub mod traits; pub mod types; #[cfg(feature = "online")] -mod online; +pub mod online; #[cfg(feature = "online")] -pub use online::{ - new_online_stack, AlloyChainProvider, AlloyL2ChainProvider, BeaconClient, OnlineBeaconClient, - OnlineBlobProvider, SimpleSlotDerivation, -}; +pub use online::new_online_stack; diff --git a/crates/derive/src/online/alloy_providers.rs b/crates/derive/src/online/alloy_providers.rs index a30a0bb59b..c4c7e1c833 100644 --- a/crates/derive/src/online/alloy_providers.rs +++ b/crates/derive/src/online/alloy_providers.rs @@ -1,8 +1,12 @@ //! This module contains concrete implementations of the data provider traits, using an alloy //! provider on the backend. -use crate::types::{ - Block, BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, OpBlock, RollupConfig, SystemConfig, +use crate::{ + traits::{ChainProvider, L2ChainProvider}, + types::{ + Block, BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, OpBlock, RollupConfig, + SystemConfig, + }, }; use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloy_consensus::{Header, Receipt, ReceiptWithBloom, TxEnvelope, TxType}; @@ -13,7 +17,6 @@ use alloy_transport_http::Http; use anyhow::{anyhow, Result}; use async_trait::async_trait; use core::num::NonZeroUsize; -use kona_providers::{ChainProvider, L2ChainProvider}; use lru::LruCache; const CACHE_SIZE: usize = 16; diff --git a/crates/derive/src/online/blob_provider.rs b/crates/derive/src/online/blob_provider.rs index 3eefc6e06e..bd0336d407 100644 --- a/crates/derive/src/online/blob_provider.rs +++ b/crates/derive/src/online/blob_provider.rs @@ -76,7 +76,7 @@ impl>, B: BeaconClient, S: SlotDerivation> OnlineBlobPr /// Creates a new instance of the [OnlineBlobProvider]. /// /// The `genesis_time` and `slot_interval` arguments are _optional_ and the - /// [OnlineBlockProvider] will attempt to load them dynamically at runtime if they are not + /// [OnlineBlobProvider] will attempt to load them dynamically at runtime if they are not /// provided. pub fn new( _inner: T, diff --git a/crates/derive/src/online/mod.rs b/crates/derive/src/online/mod.rs index 399336fb20..5c4fdc90c4 100644 --- a/crates/derive/src/online/mod.rs +++ b/crates/derive/src/online/mod.rs @@ -1,38 +1,32 @@ //! Contains "online" implementations for providers. use crate::{ - sources::DataSourceFactory, stages::{ AttributesQueue, BatchQueue, ChannelBank, ChannelReader, FrameQueue, L1Retrieval, L1Traversal, NextAttributes, StatefulAttributesBuilder, }, - traits::ResettableStage, + traits::{DataAvailabilityProvider, ResettableStage}, types::RollupConfig, }; - use alloc::sync::Arc; use alloy_provider::ReqwestProvider; use core::fmt::Debug; -/// Creates a new [OnlineStageStack]. +/// Creates a new online stack. #[cfg(feature = "online")] -pub fn new_online_stack( +pub fn new_online_stack( rollup_config: Arc, chain_provider: AlloyChainProvider, - dap_source: DataSourceFactory< - AlloyChainProvider, - OnlineBlobProvider< - ReqwestProvider, - OnlineBeaconClient, - SimpleSlotDerivation, - >, - >, + dap_source: DAP, fetcher: AlloyL2ChainProvider, builder: StatefulAttributesBuilder< AlloyChainProvider, AlloyL2ChainProvider, >, -) -> impl NextAttributes + ResettableStage + Debug + Send { +) -> impl NextAttributes + ResettableStage + Debug + Send +where + DAP: DataAvailabilityProvider + Debug + Send, +{ let l1_traversal = L1Traversal::new(chain_provider, rollup_config.clone()); let l1_retrieval = L1Retrieval::new(l1_traversal, dap_source); let frame_queue = FrameQueue::new(l1_retrieval); @@ -42,8 +36,7 @@ pub fn new_online_stack( AttributesQueue::new(*rollup_config, batch_queue, builder) } -#[cfg(test)] -#[allow(unreachable_pub)] +#[cfg(any(test, feature = "test-utils"))] pub mod test_utils; mod beacon_client; diff --git a/crates/derive/src/online/test_utils.rs b/crates/derive/src/online/test_utils.rs index 23b7040818..414e695b83 100644 --- a/crates/derive/src/online/test_utils.rs +++ b/crates/derive/src/online/test_utils.rs @@ -12,16 +12,19 @@ use alloy_transport_http::Http; use async_trait::async_trait; use reqwest::Client; -pub(crate) fn spawn_anvil() -> (ReqwestProvider, AnvilInstance) { +/// Spawns an Anvil instance and returns a provider and the instance. +pub fn spawn_anvil() -> (ReqwestProvider, AnvilInstance) { let anvil = Anvil::new().try_spawn().expect("could not spawn anvil"); (anvil_http_provider(&anvil), anvil) } -pub(crate) fn anvil_http_provider(anvil: &AnvilInstance) -> ReqwestProvider { +/// Returns an Anvil HTTP provider wrapping the given [AnvilInstance]. +pub fn anvil_http_provider(anvil: &AnvilInstance) -> ReqwestProvider { http_provider(&anvil.endpoint()) } -pub(crate) fn http_provider(url: &str) -> ReqwestProvider { +/// Returns an HTTP provider for the given URL. +pub fn http_provider(url: &str) -> ReqwestProvider { let url = url.parse().unwrap(); let http = Http::::new(url); ReqwestProvider::new(RpcClient::new(http, true)) diff --git a/crates/derive/src/sources/blobs.rs b/crates/derive/src/sources/blobs.rs index c9fd534add..245168dff9 100644 --- a/crates/derive/src/sources/blobs.rs +++ b/crates/derive/src/sources/blobs.rs @@ -1,7 +1,7 @@ //! Blob Data Source use crate::{ - traits::{AsyncIterator, BlobProvider, SignedRecoverable}, + traits::{AsyncIterator, BlobProvider, ChainProvider, SignedRecoverable}, types::{BlobData, BlockInfo, IndexedBlobHash, StageError, StageResult}, }; use alloc::{boxed::Box, vec::Vec}; @@ -9,7 +9,6 @@ use alloy_consensus::{Transaction, TxEip4844Variant, TxEnvelope, TxType}; use alloy_primitives::{Address, Bytes, TxKind}; use anyhow::Result; use async_trait::async_trait; -use kona_providers::ChainProvider; use tracing::warn; /// A data iterator that reads from a blob. diff --git a/crates/derive/src/sources/calldata.rs b/crates/derive/src/sources/calldata.rs index 1099ecd050..f9a4000e58 100644 --- a/crates/derive/src/sources/calldata.rs +++ b/crates/derive/src/sources/calldata.rs @@ -1,14 +1,13 @@ //! CallData Source use crate::{ - traits::{AsyncIterator, SignedRecoverable}, + traits::{AsyncIterator, ChainProvider, SignedRecoverable}, types::{BlockInfo, StageError, StageResult}, }; use alloc::{boxed::Box, collections::VecDeque}; use alloy_consensus::{Transaction, TxEnvelope}; use alloy_primitives::{Address, Bytes, TxKind}; use async_trait::async_trait; -use kona_providers::ChainProvider; /// A data iterator that reads from calldata. #[derive(Debug, Clone)] diff --git a/crates/derive/src/sources/factory.rs b/crates/derive/src/sources/ethereum.rs similarity index 51% rename from crates/derive/src/sources/factory.rs rename to crates/derive/src/sources/ethereum.rs index d313eb9562..8055d568dd 100644 --- a/crates/derive/src/sources/factory.rs +++ b/crates/derive/src/sources/ethereum.rs @@ -1,73 +1,57 @@ -//! Contains a Factory for creating a calldata and blob provider. +//! Contains the [EthereumDataSource], which is a concrete implementation of the +//! [DataAvailabilityProvider] trait for the Ethereum protocol. use crate::{ - sources::{BlobSource, CalldataSource, DataSource, PlasmaSource}, - traits::{BlobProvider, DataAvailabilityProvider}, - types::{BlockID, BlockInfo, RollupConfig}, + sources::{BlobSource, CalldataSource, EthereumDataSourceVariant}, + traits::{BlobProvider, ChainProvider, DataAvailabilityProvider}, + types::{BlockInfo, RollupConfig}, }; use alloc::{boxed::Box, fmt::Debug}; use alloy_primitives::{Address, Bytes}; use anyhow::{anyhow, Result}; use async_trait::async_trait; -use kona_plasma::traits::PlasmaInputFetcher; -use kona_providers::ChainProvider; -/// A factory for creating a calldata and blob provider. +/// A factory for creating an Ethereum data source provider. #[derive(Debug, Clone, Copy)] -pub struct DataSourceFactory +pub struct EthereumDataSource where C: ChainProvider + Send + Clone, B: BlobProvider + Clone, - PIF: PlasmaInputFetcher + Clone, - I: Iterator + Send + Clone, { /// The chain provider to use for the factory. pub chain_provider: C, - /// The plasma iterator. - pub plasma_source: I, /// The blob provider pub blob_provider: B, - /// The plasma input fetcher. - pub plasma_input_fetcher: PIF, /// The ecotone timestamp. pub ecotone_timestamp: Option, - /// Whether or not plasma is enabled. - pub plasma_enabled: bool, /// The L1 Signer. pub signer: Address, } -impl DataSourceFactory +impl EthereumDataSource where C: ChainProvider + Send + Clone + Debug, B: BlobProvider + Clone + Debug, - PIF: PlasmaInputFetcher + Clone + Debug, - I: Iterator + Send + Clone, { /// Creates a new factory. - pub fn new(provider: C, blobs: B, pif: PIF, s: I, cfg: &RollupConfig) -> Self { + pub fn new(provider: C, blobs: B, cfg: &RollupConfig) -> Self { Self { chain_provider: provider, - plasma_source: s, blob_provider: blobs, - plasma_input_fetcher: pif, ecotone_timestamp: cfg.ecotone_time, - plasma_enabled: cfg.is_plasma_enabled(), signer: cfg.genesis.system_config.batcher_addr, } } } #[async_trait] -impl DataAvailabilityProvider for DataSourceFactory +impl DataAvailabilityProvider for EthereumDataSource where C: ChainProvider + Send + Sync + Clone + Debug, B: BlobProvider + Send + Sync + Clone + Debug, - PIF: PlasmaInputFetcher + Send + Sync + Clone + Debug, - I: Iterator + Send + Sync + Clone + Debug, { type Item = Bytes; - type DataIter = DataSource; + type DataIter = EthereumDataSourceVariant; async fn open_data( &self, @@ -77,7 +61,7 @@ where if let Some(ecotone) = self.ecotone_timestamp { let source = (block_ref.timestamp >= ecotone) .then(|| { - DataSource::Blob(BlobSource::new( + EthereumDataSourceVariant::Blob(BlobSource::new( self.chain_provider.clone(), self.blob_provider.clone(), batcher_address, @@ -86,7 +70,7 @@ where )) }) .unwrap_or_else(|| { - DataSource::Calldata(CalldataSource::new( + EthereumDataSourceVariant::Calldata(CalldataSource::new( self.chain_provider.clone(), batcher_address, *block_ref, @@ -94,14 +78,6 @@ where )) }); Ok(source) - } else if self.plasma_enabled { - let id = BlockID { hash: block_ref.hash, number: block_ref.number }; - Ok(DataSource::Plasma(PlasmaSource::new( - self.chain_provider.clone(), - self.plasma_input_fetcher.clone(), - self.plasma_source.clone(), - id, - ))) } else { Err(anyhow!("No data source available")) } diff --git a/crates/derive/src/sources/mod.rs b/crates/derive/src/sources/mod.rs index b999db5638..253b65268d 100644 --- a/crates/derive/src/sources/mod.rs +++ b/crates/derive/src/sources/mod.rs @@ -1,7 +1,7 @@ //! This module contains data source impelmentations. -mod factory; -pub use factory::DataSourceFactory; +mod ethereum; +pub use ethereum::EthereumDataSource; mod blobs; pub use blobs::BlobSource; @@ -9,8 +9,5 @@ pub use blobs::BlobSource; mod calldata; pub use calldata::CalldataSource; -mod plasma; -pub use plasma::PlasmaSource; - -mod source; -pub use source::DataSource; +mod variant; +pub use variant::EthereumDataSourceVariant; diff --git a/crates/derive/src/sources/source.rs b/crates/derive/src/sources/source.rs deleted file mode 100644 index 49dfb06834..0000000000 --- a/crates/derive/src/sources/source.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! Data source - -use crate::{ - sources::{BlobSource, CalldataSource, PlasmaSource}, - traits::{AsyncIterator, BlobProvider}, - types::StageResult, -}; -use alloc::boxed::Box; -use alloy_primitives::Bytes; -use async_trait::async_trait; -use kona_plasma::traits::PlasmaInputFetcher; -use kona_providers::ChainProvider; - -/// An enum over the various data sources. -#[derive(Debug, Clone)] -pub enum DataSource -where - CP: ChainProvider + Send, - B: BlobProvider + Send, - PIF: PlasmaInputFetcher + Send, - I: Iterator + Send, -{ - /// A calldata source. - Calldata(CalldataSource), - /// A blob source. - Blob(BlobSource), - /// A plasma source. - Plasma(PlasmaSource), -} - -#[async_trait] -impl AsyncIterator for DataSource -where - CP: ChainProvider + Send, - B: BlobProvider + Send, - PIF: PlasmaInputFetcher + Send, - I: Iterator + Send, -{ - type Item = Bytes; - - async fn next(&mut self) -> Option> { - match self { - DataSource::Calldata(c) => c.next().await, - DataSource::Blob(b) => b.next().await, - DataSource::Plasma(p) => p.next().await, - } - } -} diff --git a/crates/derive/src/sources/variant.rs b/crates/derive/src/sources/variant.rs new file mode 100644 index 0000000000..d02db69d5d --- /dev/null +++ b/crates/derive/src/sources/variant.rs @@ -0,0 +1,39 @@ +//! Data source + +use crate::{ + sources::{BlobSource, CalldataSource}, + traits::{AsyncIterator, BlobProvider, ChainProvider}, + types::StageResult, +}; +use alloc::boxed::Box; +use alloy_primitives::Bytes; +use async_trait::async_trait; + +/// An enum over the various data sources. +#[derive(Debug, Clone)] +pub enum EthereumDataSourceVariant +where + CP: ChainProvider + Send, + B: BlobProvider + Send, +{ + /// A calldata source. + Calldata(CalldataSource), + /// A blob source. + Blob(BlobSource), +} + +#[async_trait] +impl AsyncIterator for EthereumDataSourceVariant +where + CP: ChainProvider + Send, + B: BlobProvider + Send, +{ + type Item = Bytes; + + async fn next(&mut self) -> Option> { + match self { + EthereumDataSourceVariant::Calldata(c) => c.next().await, + EthereumDataSourceVariant::Blob(b) => b.next().await, + } + } +} diff --git a/crates/derive/src/stages/attributes_queue/builder.rs b/crates/derive/src/stages/attributes_queue/builder.rs index f24778441f..4282671da7 100644 --- a/crates/derive/src/stages/attributes_queue/builder.rs +++ b/crates/derive/src/stages/attributes_queue/builder.rs @@ -3,6 +3,7 @@ use super::derive_deposits; use crate::{ params::SEQUENCER_FEE_VAULT_ADDRESS, + traits::{ChainProvider, L2ChainProvider}, types::{ BlockID, BuilderError, EcotoneTransactionBuilder, L1BlockInfoTx, L2BlockInfo, L2PayloadAttributes, RawTransaction, RollupConfig, @@ -11,7 +12,6 @@ use crate::{ use alloc::{boxed::Box, fmt::Debug, sync::Arc, vec, vec::Vec}; use alloy_rlp::Encodable; use async_trait::async_trait; -use kona_providers::{ChainProvider, L2ChainProvider}; /// The [AttributesBuilder] is responsible for preparing [L2PayloadAttributes] /// that can be used to construct an L2 Block containing only deposits. @@ -173,11 +173,11 @@ mod tests { use super::*; use crate::{ stages::test_utils::MockSystemConfigL2Fetcher, + traits::test_utils::TestChainProvider, types::{BlockInfo, SystemConfig}, }; use alloy_consensus::Header; use alloy_primitives::B256; - use kona_providers::test_utils::TestChainProvider; #[tokio::test] async fn test_prepare_payload_block_mismatch_epoch_reset() { diff --git a/crates/derive/src/stages/batch_queue.rs b/crates/derive/src/stages/batch_queue.rs index 47931c5498..200cd2697c 100644 --- a/crates/derive/src/stages/batch_queue.rs +++ b/crates/derive/src/stages/batch_queue.rs @@ -2,7 +2,7 @@ use crate::{ stages::attributes_queue::AttributesProvider, - traits::{OriginAdvancer, OriginProvider, PreviousStage, ResettableStage}, + traits::{L2ChainProvider, OriginAdvancer, OriginProvider, PreviousStage, ResettableStage}, types::{ Batch, BatchValidity, BatchWithInclusionBlock, BlockInfo, L2BlockInfo, RollupConfig, SingleBatch, StageError, StageResult, SystemConfig, @@ -12,7 +12,6 @@ use alloc::{boxed::Box, sync::Arc, vec::Vec}; use anyhow::anyhow; use async_trait::async_trait; use core::fmt::Debug; -use kona_providers::L2ChainProvider; use tracing::{error, info, warn}; /// Provides [Batch]es for the [BatchQueue] stage. @@ -435,6 +434,7 @@ mod tests { channel_reader::BatchReader, test_utils::{CollectingLayer, MockBatchQueueProvider, TraceStorage}, }, + traits::test_utils::TestL2ChainProvider, types::{ BatchType, BlockID, Genesis, L1BlockInfoBedrock, L1BlockInfoTx, L2ExecutionPayload, L2ExecutionPayloadEnvelope, @@ -443,7 +443,6 @@ mod tests { use alloc::vec; use alloy_primitives::{address, b256, Address, Bytes, TxKind, B256, U256}; use alloy_rlp::{BytesMut, Encodable}; - use kona_providers::test_utils::TestL2ChainProvider; use miniz_oxide::deflate::compress_to_vec_zlib; use op_alloy_consensus::{OpTxType, TxDeposit}; use tracing::Level; diff --git a/crates/derive/src/stages/l1_traversal.rs b/crates/derive/src/stages/l1_traversal.rs index 532b72457a..65c9751084 100644 --- a/crates/derive/src/stages/l1_traversal.rs +++ b/crates/derive/src/stages/l1_traversal.rs @@ -2,13 +2,12 @@ use crate::{ stages::L1RetrievalProvider, - traits::{OriginAdvancer, OriginProvider, PreviousStage, ResettableStage}, + traits::{ChainProvider, OriginAdvancer, OriginProvider, PreviousStage, ResettableStage}, types::{BlockInfo, RollupConfig, StageError, StageResult, SystemConfig}, }; use alloc::{boxed::Box, sync::Arc}; use alloy_primitives::Address; use async_trait::async_trait; -use kona_providers::ChainProvider; use tracing::warn; /// The [L1Traversal] stage of the derivation pipeline. @@ -136,11 +135,13 @@ impl ResettableStage for L1Traversal { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::params::{CONFIG_UPDATE_EVENT_VERSION_0, CONFIG_UPDATE_TOPIC}; + use crate::{ + params::{CONFIG_UPDATE_EVENT_VERSION_0, CONFIG_UPDATE_TOPIC}, + traits::test_utils::TestChainProvider, + }; use alloc::vec; use alloy_consensus::Receipt; use alloy_primitives::{address, b256, hex, Bytes, Log, LogData, B256}; - use kona_providers::test_utils::TestChainProvider; const L1_SYS_CONFIG_ADDR: Address = address!("1337000000000000000000000000000000000000"); diff --git a/crates/derive/src/stages/mod.rs b/crates/derive/src/stages/mod.rs index 2034cf5d76..58329e03b2 100644 --- a/crates/derive/src/stages/mod.rs +++ b/crates/derive/src/stages/mod.rs @@ -37,5 +37,5 @@ pub use attributes_queue::{ StatefulAttributesBuilder, }; -#[cfg(test)] +#[cfg(any(test, feature = "test-utils"))] pub mod test_utils; diff --git a/crates/derive/src/stages/test_utils/sys_config_fetcher.rs b/crates/derive/src/stages/test_utils/sys_config_fetcher.rs index 2ef05326dd..53489faa9d 100644 --- a/crates/derive/src/stages/test_utils/sys_config_fetcher.rs +++ b/crates/derive/src/stages/test_utils/sys_config_fetcher.rs @@ -1,11 +1,13 @@ //! Implements a mock [L2SystemConfigFetcher] for testing. -use crate::types::{L2BlockInfo, L2ExecutionPayloadEnvelope, RollupConfig, SystemConfig}; +use crate::{ + traits::L2ChainProvider, + types::{L2BlockInfo, L2ExecutionPayloadEnvelope, RollupConfig, SystemConfig}, +}; use alloc::{boxed::Box, sync::Arc}; use anyhow::Result; use async_trait::async_trait; use hashbrown::HashMap; -use kona_providers::L2ChainProvider; /// A mock implementation of the [`SystemConfigL2Fetcher`] for testing. #[derive(Debug, Default)] diff --git a/crates/derive/src/stages/test_utils/tracing.rs b/crates/derive/src/stages/test_utils/tracing.rs index eb065c203b..6b59e3b747 100644 --- a/crates/derive/src/stages/test_utils/tracing.rs +++ b/crates/derive/src/stages/test_utils/tracing.rs @@ -31,12 +31,15 @@ impl TraceStorage { } } +/// A subscriber layer that collects traces and their log levels. #[derive(Debug, Default)] pub struct CollectingLayer { + /// The storage for the collected traces. pub storage: TraceStorage, } impl CollectingLayer { + /// Creates a new collecting layer with the specified storage. pub fn new(storage: TraceStorage) -> Self { Self { storage } } diff --git a/crates/derive/src/traits/data_sources.rs b/crates/derive/src/traits/data_sources.rs index 10640a4ccd..6c1e2b0a24 100644 --- a/crates/derive/src/traits/data_sources.rs +++ b/crates/derive/src/traits/data_sources.rs @@ -18,15 +18,6 @@ pub trait BlobProvider { ) -> Result>; } -/// The PlasmaProvider trait specifies the functionality of a data source that can fetch plasma -/// inputs. -#[async_trait] -#[allow(dead_code)] -pub(crate) trait PlasmaProvider { - /// Fetches the plasma input for the given commitment at the given block number. - async fn get_input(&self, commitment: &[u8], block_number: u64) -> Result; -} - /// Describes the functionality of a data source that can provide data availability information. #[async_trait] pub trait DataAvailabilityProvider { diff --git a/crates/derive/src/traits/mod.rs b/crates/derive/src/traits/mod.rs index f3ff4f5473..89f5ff9249 100644 --- a/crates/derive/src/traits/mod.rs +++ b/crates/derive/src/traits/mod.rs @@ -4,11 +4,14 @@ mod data_sources; pub use data_sources::*; +mod providers; +pub use providers::{ChainProvider, L2ChainProvider}; + mod stages; pub use stages::{OriginAdvancer, OriginProvider, PreviousStage, ResettableStage}; mod ecrecover; pub use ecrecover::SignedRecoverable; -#[cfg(test)] +#[cfg(any(test, feature = "test-utils"))] pub mod test_utils; diff --git a/crates/providers/src/chain_provider.rs b/crates/derive/src/traits/providers.rs similarity index 54% rename from crates/providers/src/chain_provider.rs rename to crates/derive/src/traits/providers.rs index 18e667d9fb..0b27f86e06 100644 --- a/crates/providers/src/chain_provider.rs +++ b/crates/derive/src/traits/providers.rs @@ -1,11 +1,11 @@ -//! This module defines the [ChainProvider] trait. - -use alloc::{boxed::Box, vec::Vec}; +use alloc::{boxed::Box, sync::Arc, vec::Vec}; use alloy_consensus::{Header, Receipt, TxEnvelope}; use alloy_primitives::B256; use anyhow::Result; use async_trait::async_trait; -use kona_primitives::block::BlockInfo; +use kona_primitives::{ + BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, RollupConfig, SystemConfig, +}; /// Describes the functionality of a data source that can provide information from the blockchain. #[async_trait] @@ -27,3 +27,22 @@ pub trait ChainProvider { hash: B256, ) -> Result<(BlockInfo, Vec)>; } + +/// Describes the functionality of a data source that fetches safe blocks. +#[async_trait] +pub trait L2ChainProvider { + /// Returns the L2 block info given a block number. + /// Errors if the block does not exist. + async fn l2_block_info_by_number(&mut self, number: u64) -> Result; + + /// Returns an execution payload for a given number. + /// Errors if the execution payload does not exist. + async fn payload_by_number(&mut self, number: u64) -> Result; + + /// Returns the [SystemConfig] by L2 number. + async fn system_config_by_number( + &mut self, + number: u64, + rollup_config: Arc, + ) -> Result; +} diff --git a/crates/derive/src/traits/test_utils.rs b/crates/derive/src/traits/test_utils.rs index 6ee6205cce..ffc3d44653 100644 --- a/crates/derive/src/traits/test_utils.rs +++ b/crates/derive/src/traits/test_utils.rs @@ -1,14 +1,19 @@ //! Test Utilities for derive traits use crate::{ - traits::{AsyncIterator, DataAvailabilityProvider}, - types::{BlockInfo, StageError, StageResult}, + traits::{AsyncIterator, ChainProvider, DataAvailabilityProvider, L2ChainProvider}, + types::{StageError, StageResult}, }; -use alloc::{boxed::Box, vec, vec::Vec}; -use alloy_primitives::{Address, Bytes}; +use alloc::{boxed::Box, sync::Arc, vec, vec::Vec}; +use alloy_consensus::{Header, Receipt, TxEnvelope}; +use alloy_primitives::{Address, Bytes, B256}; use anyhow::Result; use async_trait::async_trait; use core::fmt::Debug; +use hashbrown::HashMap; +use kona_primitives::{ + BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, RollupConfig, SystemConfig, +}; /// Mock data iterator #[derive(Debug, Default, PartialEq)] @@ -57,3 +62,150 @@ impl DataAvailabilityProvider for TestDAP { Ok(TestIter { open_data_calls: vec![(*block_ref, batcher_address)], results }) } } + +/// A mock chain provider for testing. +#[derive(Debug, Clone, Default)] +pub struct TestChainProvider { + /// Maps block numbers to block information using a tuple list. + pub blocks: Vec<(u64, BlockInfo)>, + /// Maps block hashes to header information using a tuple list. + pub headers: Vec<(B256, Header)>, + /// Maps block hashes to receipts using a tuple list. + pub receipts: Vec<(B256, Vec)>, +} + +impl TestChainProvider { + /// Insert a block into the mock chain provider. + pub fn insert_block(&mut self, number: u64, block: BlockInfo) { + self.blocks.push((number, block)); + } + + /// Insert receipts into the mock chain provider. + pub fn insert_receipts(&mut self, hash: B256, receipts: Vec) { + self.receipts.push((hash, receipts)); + } + + /// Insert a header into the mock chain provider. + pub fn insert_header(&mut self, hash: B256, header: Header) { + self.headers.push((hash, header)); + } + + /// Clears headers from the mock chain provider. + pub fn clear_headers(&mut self) { + self.headers.clear(); + } + + /// Clears blocks from the mock chain provider. + pub fn clear_blocks(&mut self) { + self.blocks.clear(); + } + + /// Clears receipts from the mock chain provider. + pub fn clear_receipts(&mut self) { + self.receipts.clear(); + } + + /// Clears all blocks and receipts from the mock chain provider. + pub fn clear(&mut self) { + self.clear_blocks(); + self.clear_receipts(); + self.clear_headers(); + } +} + +#[async_trait] +impl ChainProvider for TestChainProvider { + async fn header_by_hash(&mut self, hash: B256) -> Result
{ + if let Some((_, header)) = self.headers.iter().find(|(_, b)| b.hash_slow() == hash) { + Ok(header.clone()) + } else { + Err(anyhow::anyhow!("Header not found")) + } + } + + async fn block_info_by_number(&mut self, _number: u64) -> Result { + if let Some((_, block)) = self.blocks.iter().find(|(n, _)| *n == _number) { + Ok(*block) + } else { + Err(anyhow::anyhow!("Block not found")) + } + } + + async fn receipts_by_hash(&mut self, _hash: B256) -> Result> { + if let Some((_, receipts)) = self.receipts.iter().find(|(h, _)| *h == _hash) { + Ok(receipts.clone()) + } else { + Err(anyhow::anyhow!("Receipts not found")) + } + } + + async fn block_info_and_transactions_by_hash( + &mut self, + hash: B256, + ) -> Result<(BlockInfo, Vec)> { + let block = self + .blocks + .iter() + .find(|(_, b)| b.hash == hash) + .map(|(_, b)| *b) + .ok_or_else(|| anyhow::anyhow!("Block not found"))?; + Ok((block, Vec::new())) + } +} + +/// An [L2ChainProvider] implementation for testing. +#[derive(Debug, Default)] +pub struct TestL2ChainProvider { + /// Blocks + pub blocks: Vec, + /// Short circuit the block return to be the first block. + pub short_circuit: bool, + /// Payloads + pub payloads: Vec, + /// System configs + pub system_configs: HashMap, +} + +impl TestL2ChainProvider { + /// Creates a new [MockBlockFetcher] with the given origin and batches. + pub fn new( + blocks: Vec, + payloads: Vec, + system_configs: HashMap, + ) -> Self { + Self { blocks, short_circuit: false, payloads, system_configs } + } +} + +#[async_trait] +impl L2ChainProvider for TestL2ChainProvider { + async fn l2_block_info_by_number(&mut self, number: u64) -> Result { + if self.short_circuit { + return self.blocks.first().copied().ok_or_else(|| anyhow::anyhow!("Block not found")); + } + self.blocks + .iter() + .find(|b| b.block_info.number == number) + .cloned() + .ok_or_else(|| anyhow::anyhow!("Block not found")) + } + + async fn payload_by_number(&mut self, number: u64) -> Result { + self.payloads + .iter() + .find(|p| p.execution_payload.block_number == number) + .cloned() + .ok_or_else(|| anyhow::anyhow!("Payload not found")) + } + + async fn system_config_by_number( + &mut self, + number: u64, + _: Arc, + ) -> Result { + self.system_configs + .get(&number) + .ok_or_else(|| anyhow::anyhow!("System config not found")) + .cloned() + } +} diff --git a/crates/derive/src/types/batch/mod.rs b/crates/derive/src/types/batch/mod.rs index 66407630e4..58541377fb 100644 --- a/crates/derive/src/types/batch/mod.rs +++ b/crates/derive/src/types/batch/mod.rs @@ -2,9 +2,11 @@ //! [SingleBatch]. use super::DecodeError; -use crate::types::{BlockInfo, L2BlockInfo, RollupConfig}; +use crate::{ + traits::L2ChainProvider, + types::{BlockInfo, L2BlockInfo, RollupConfig}, +}; use alloy_rlp::{Buf, Decodable}; -use kona_providers::L2ChainProvider; mod batch_type; pub use batch_type::BatchType; diff --git a/crates/derive/src/types/batch/span_batch/batch.rs b/crates/derive/src/types/batch/span_batch/batch.rs index 9037d89bb1..63e3a7fee9 100644 --- a/crates/derive/src/types/batch/span_batch/batch.rs +++ b/crates/derive/src/types/batch/span_batch/batch.rs @@ -1,13 +1,15 @@ //! The Span Batch Type use super::{SpanBatchError, SpanBatchTransactions}; -use crate::types::{ - BatchValidity, BlockInfo, L2BlockInfo, RollupConfig, SingleBatch, SpanBatchBits, - SpanBatchElement, +use crate::{ + traits::L2ChainProvider, + types::{ + BatchValidity, BlockInfo, L2BlockInfo, RollupConfig, SingleBatch, SpanBatchBits, + SpanBatchElement, + }, }; use alloc::vec::Vec; use alloy_primitives::FixedBytes; -use kona_providers::L2ChainProvider; use op_alloy_consensus::OpTxType; use tracing::{info, warn}; @@ -412,11 +414,11 @@ mod tests { use super::*; use crate::{ stages::test_utils::{CollectingLayer, TraceStorage}, + traits::test_utils::TestL2ChainProvider, types::{BlockID, Genesis, L2ExecutionPayload, L2ExecutionPayloadEnvelope, RawTransaction}, }; use alloc::vec; use alloy_primitives::{b256, Bytes, B256}; - use kona_providers::test_utils::TestL2ChainProvider; use op_alloy_consensus::OpTxType; use tracing::Level; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; diff --git a/crates/derive/src/types/errors.rs b/crates/derive/src/types/errors.rs index f7a41c0d75..afed20ff37 100644 --- a/crates/derive/src/types/errors.rs +++ b/crates/derive/src/types/errors.rs @@ -5,7 +5,6 @@ use crate::types::{BlockID, Frame}; use alloc::vec::Vec; use alloy_primitives::{Bytes, B256}; use core::fmt::Display; -use kona_plasma::types::PlasmaError; /// A result type for the derivation pipeline stages. pub type StageResult = Result; @@ -19,8 +18,6 @@ pub enum StageError { Temporary(anyhow::Error), /// A critical error. Critical(anyhow::Error), - /// Plasma data source error. - Plasma(PlasmaError), /// There is not enough data progress, but if we wait, the stage will eventually return data /// or produce an EOF error. NotEnoughData, @@ -70,7 +67,6 @@ impl PartialEq for StageError { (StageError::Eof, StageError::Eof) | (StageError::Temporary(_), StageError::Temporary(_)) | (StageError::Critical(_), StageError::Critical(_)) | - (StageError::Plasma(_), StageError::Plasma(_)) | (StageError::NotEnoughData, StageError::NotEnoughData) | (StageError::NoChannelsAvailable, StageError::NoChannelsAvailable) | (StageError::NoChannel, StageError::NoChannel) | @@ -105,7 +101,6 @@ impl Display for StageError { StageError::Eof => write!(f, "End of file"), StageError::Temporary(e) => write!(f, "Temporary error: {}", e), StageError::Critical(e) => write!(f, "Critical error: {}", e), - StageError::Plasma(e) => write!(f, "Plasma error: {:?}", e), StageError::NotEnoughData => write!(f, "Not enough data"), StageError::BlockFetch(hash) => { write!(f, "Failed to fetch block info and transactions by hash: {}", hash) diff --git a/crates/plasma/Cargo.toml b/crates/plasma/Cargo.toml index ef9f73d4b9..8b5fd8cb77 100644 --- a/crates/plasma/Cargo.toml +++ b/crates/plasma/Cargo.toml @@ -15,7 +15,7 @@ tracing.workspace = true # Local kona-primitives = { path = "../primitives" } -kona-providers = { path = "../providers" } +kona-derive = { path = "../derive" } # External alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", default-features = false } @@ -26,10 +26,11 @@ async-trait = "0.1.77" serde = { version = "1.0.197", default-features = false, features = ["derive"], optional = true } [dev-dependencies] +kona-derive = { path = "../derive", features = ["test-utils"] } tracing-subscriber = "0.3.18" serde_json = { version = "1.0.68", default-features = false } +tokio = { version = "1.37", features = ["full"] } [features] -default = [ "serde" ] -serde = [ "dep:serde", "kona-providers/serde", "kona-primitives/serde" ] -test-utils = [ "kona-providers/test-utils" ] +default = ["serde"] +serde = ["dep:serde", "kona-primitives/serde"] diff --git a/crates/plasma/src/lib.rs b/crates/plasma/src/lib.rs index 8f46bbff3f..4fec9fa224 100644 --- a/crates/plasma/src/lib.rs +++ b/crates/plasma/src/lib.rs @@ -6,14 +6,10 @@ extern crate alloc; -// Re-export kona primitives. -pub use kona_primitives::*; - +pub mod plasma; +pub mod source; pub mod traits; -pub use traits::PlasmaInputFetcher; - pub mod types; -pub use types::{FinalizedHeadSignal, Keccak256Commitment, PlasmaError, SystemConfig}; -#[cfg(any(test, feature = "test-utils"))] +#[cfg(test)] pub mod test_utils; diff --git a/crates/plasma/src/plasma.rs b/crates/plasma/src/plasma.rs new file mode 100644 index 0000000000..f29b04765d --- /dev/null +++ b/crates/plasma/src/plasma.rs @@ -0,0 +1,72 @@ +//! Contains the [PlasmaDataSource], which is a concrete implementation of the +//! [DataAvailabilityProvider] trait for the Plasma protocol. Used as an adapter to the +//! [kona_derive] crate's derivation pipeline construction. +//! +//! [DataAvailabilityProvider]: kona_derive::traits::DataAvailabilityProvider + +use crate::{source::PlasmaSource, traits::PlasmaInputFetcher}; +use alloc::{boxed::Box, fmt::Debug}; +use alloy_primitives::{Address, Bytes}; +use anyhow::Result; +use async_trait::async_trait; +use kona_derive::{ + traits::{ChainProvider, DataAvailabilityProvider}, + types::{BlockInfo, RollupConfig}, +}; +use kona_primitives::BlockID; + +/// A factory for creating an Ethereum data source provider. +#[derive(Debug, Clone, Copy)] +pub struct PlasmaDataSource +where + C: ChainProvider + Send + Clone, + PIF: PlasmaInputFetcher + Clone, + I: Iterator + Send + Clone, +{ + /// The chain provider to use for the factory. + pub chain_provider: C, + /// The plasma iterator. + pub plasma_source: I, + /// The plasma input fetcher. + pub plasma_input_fetcher: PIF, + /// The L1 Signer. + pub signer: Address, +} + +impl PlasmaDataSource +where + C: ChainProvider + Send + Clone + Debug, + PIF: PlasmaInputFetcher + Clone, + I: Iterator + Send + Clone, +{ + /// Creates a new factory. + pub fn new(provider: C, pif: PIF, s: I, cfg: &RollupConfig) -> Self { + Self { + chain_provider: provider, + plasma_source: s, + plasma_input_fetcher: pif, + signer: cfg.genesis.system_config.batcher_addr, + } + } +} + +#[async_trait] +impl DataAvailabilityProvider for PlasmaDataSource +where + C: ChainProvider + Send + Clone + Debug + Sync, + PIF: PlasmaInputFetcher + Clone + Debug + Send + Sync, + I: Iterator + Send + Clone + Debug + Sync, +{ + type Item = Bytes; + type DataIter = PlasmaSource; + + async fn open_data(&self, block_ref: &BlockInfo, _: Address) -> Result { + let id = BlockID { hash: block_ref.hash, number: block_ref.number }; + Ok(PlasmaSource::new( + self.chain_provider.clone(), + self.plasma_input_fetcher.clone(), + self.plasma_source.clone(), + id, + )) + } +} diff --git a/crates/derive/src/sources/plasma.rs b/crates/plasma/src/source.rs similarity index 94% rename from crates/derive/src/sources/plasma.rs rename to crates/plasma/src/source.rs index 4c222fb148..d08c01f5b1 100644 --- a/crates/derive/src/sources/plasma.rs +++ b/crates/plasma/src/source.rs @@ -1,20 +1,20 @@ //! Plasma Data Source use crate::{ - traits::AsyncIterator, - types::{ResetError, StageError, StageResult}, -}; -use alloc::boxed::Box; -use alloy_primitives::Bytes; -use async_trait::async_trait; -use kona_plasma::{ traits::PlasmaInputFetcher, types::{ decode_keccak256, Keccak256Commitment, PlasmaError, MAX_INPUT_SIZE, TX_DATA_VERSION_1, }, }; +use alloc::boxed::Box; +use alloy_primitives::Bytes; +use anyhow::anyhow; +use async_trait::async_trait; +use kona_derive::{ + traits::{AsyncIterator, ChainProvider}, + types::{ResetError, StageError, StageResult}, +}; use kona_primitives::block::BlockID; -use kona_providers::ChainProvider; /// A plasma data iterator. #[derive(Debug, Clone)] @@ -89,14 +89,14 @@ where Ok(d) => d, Err(e) => { tracing::warn!("failed to pull next data from the plasma source iterator"); - return Some(Err(StageError::Plasma(e))); + return Some(Err(StageError::Custom(anyhow!(e)))); } }; // If the data is empty, if data.is_empty() { tracing::warn!("empty data from plasma source"); - return Some(Err(StageError::Plasma(PlasmaError::NotEnoughData))); + return Some(Err(StageError::Custom(anyhow!(PlasmaError::NotEnoughData)))); } // If the tx data type is not plasma, we forward it downstream to let the next @@ -138,7 +138,7 @@ where tracing::warn!("challenge expired, skipping batch"); self.commitment = None; // Skip the input. - return self.next().await + return self.next().await; } Some(Err(PlasmaError::MissingPastWindow)) => { tracing::warn!("missing past window, skipping batch"); @@ -187,10 +187,12 @@ where #[cfg(test)] mod tests { use super::*; - use crate::stages::test_utils::{CollectingLayer, TraceStorage}; + use crate::test_utils::TestPlasmaInputFetcher; use alloc::vec; - use kona_plasma::test_utils::TestPlasmaInputFetcher; - use kona_providers::test_utils::TestChainProvider; + use kona_derive::{ + stages::test_utils::{CollectingLayer, TraceStorage}, + traits::test_utils::TestChainProvider, + }; use tracing::Level; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; @@ -236,7 +238,7 @@ mod tests { let mut plasma_source = PlasmaSource::new(chain_provider, input_fetcher, source, id); let err = plasma_source.next().await.unwrap().unwrap_err(); - assert_eq!(err, StageError::Plasma(PlasmaError::NotEnoughData)); + assert_eq!(err, StageError::Custom(anyhow!(PlasmaError::NotEnoughData))); } #[tokio::test] @@ -253,7 +255,7 @@ mod tests { let mut plasma_source = PlasmaSource::new(chain_provider, input_fetcher, source, id); let err = plasma_source.next().await.unwrap().unwrap_err(); - assert_eq!(err, StageError::Plasma(PlasmaError::NotEnoughData)); + assert_eq!(err, StageError::Custom(anyhow!(PlasmaError::NotEnoughData))); let logs = trace_store.get_by_level(Level::WARN); assert_eq!(logs.len(), 1); diff --git a/crates/plasma/src/test_utils.rs b/crates/plasma/src/test_utils.rs index 31d7f4ca8a..415129abef 100644 --- a/crates/plasma/src/test_utils.rs +++ b/crates/plasma/src/test_utils.rs @@ -1,4 +1,4 @@ -//! Test utilities for the Plasma crate. +//! Test utilities for the `kona-plasma` crate. use crate::{ traits::PlasmaInputFetcher, @@ -6,13 +6,9 @@ use crate::{ }; use alloc::{boxed::Box, vec::Vec}; use alloy_primitives::Bytes; -use anyhow::Result; use async_trait::async_trait; -use kona_primitives::{ - block::{BlockID, BlockInfo}, - system_config::SystemConfig, -}; -use kona_providers::test_utils::TestChainProvider; +use kona_derive::traits::test_utils::TestChainProvider; +use kona_primitives::{BlockID, BlockInfo, SystemConfig}; /// A mock plasma input fetcher for testing. #[derive(Debug, Clone, Default)] diff --git a/crates/plasma/src/traits.rs b/crates/plasma/src/traits.rs index f4960bdf89..6529623cc3 100644 --- a/crates/plasma/src/traits.rs +++ b/crates/plasma/src/traits.rs @@ -1,14 +1,11 @@ -//! Traits for plasma sources and internal components. +//! This module contains traits for the plasma extension of the derivation pipeline. use crate::types::{FinalizedHeadSignal, PlasmaError}; use alloc::boxed::Box; use alloy_primitives::Bytes; use async_trait::async_trait; -use kona_primitives::{ - block::{BlockID, BlockInfo}, - system_config::SystemConfig, -}; -use kona_providers::ChainProvider; +use kona_derive::traits::ChainProvider; +use kona_primitives::{BlockID, BlockInfo, SystemConfig}; /// A plasma input fetcher. #[async_trait] diff --git a/crates/plasma/src/types.rs b/crates/plasma/src/types.rs index fe449d0c10..e158296caf 100644 --- a/crates/plasma/src/types.rs +++ b/crates/plasma/src/types.rs @@ -1,9 +1,9 @@ -//! Types for the Kona Plasma crate. +//! Types for the `kona-plasma` crate. use alloc::boxed::Box; -use alloy_primitives::{Address, Bytes, U256}; +use alloy_primitives::Bytes; use core::fmt::Display; -use kona_primitives::block::BlockInfo; +use kona_primitives::BlockInfo; /// A plasma error. #[derive(Debug, Clone, Copy, Eq, PartialEq)] @@ -32,6 +32,9 @@ impl Display for PlasmaError { } } +/// A callback method for the finalized head signal. +pub type FinalizedHeadSignal = Box; + /// Max input size ensures the canonical chain cannot include input batches too large to /// challenge in the Data Availability Challenge contract. Value in number of bytes. /// This value can only be changed in a hard fork. @@ -42,12 +45,12 @@ pub const MAX_INPUT_SIZE: usize = 130672; /// used downstream when parsing the frames. pub const TX_DATA_VERSION_1: u8 = 1; -/// The default commitment type. -pub type Keccak256Commitment = Bytes; - /// The default commitment type for the DA storage. pub const KECCAK_256_COMMITMENT_TYPE: u8 = 0; +/// The default commitment type. +pub type Keccak256Commitment = Bytes; + /// DecodeKeccak256 validates and casts the commitment into a Keccak256Commitment. pub fn decode_keccak256(commitment: &[u8]) -> Result { if commitment.is_empty() { @@ -62,23 +65,3 @@ pub fn decode_keccak256(commitment: &[u8]) -> Result; - -/// Optimism system config contract values -#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -pub struct SystemConfig { - /// Batch sender address - pub batcher_addr: Address, - /// L2 gas limit - pub gas_limit: U256, - /// Fee overhead - #[cfg_attr(feature = "serde", serde(rename = "overhead"))] - pub l1_fee_overhead: U256, - /// Fee scalar - #[cfg_attr(feature = "serde", serde(rename = "scalar"))] - pub l1_fee_scalar: U256, -} diff --git a/crates/providers/Cargo.toml b/crates/providers/Cargo.toml deleted file mode 100644 index 4df33b1c77..0000000000 --- a/crates/providers/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "kona-providers" -description = "Provider traits and implementations for kona crates" -version = "0.0.1" -edition.workspace = true -authors.workspace = true -license.workspace = true -repository.workspace = true -homepage.workspace = true - -[dependencies] -anyhow.workspace = true -tracing.workspace = true -alloy-rlp = { workspace = true, features = ["derive"] } -alloy-primitives = { workspace = true, features = ["rlp"] } - -# Local -kona-primitives = { path = "../primitives", version = "0.0.1" } - -# External -async-trait = "0.1.77" -hashbrown = { version = "0.14.3", optional = true } - -# Alloy Types -alloy-sol-types = { version = "0.7.1", default-features = false } -alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", default-features = false } -op-alloy-consensus = { git = "https://github.com/clabby/op-alloy", branch = "refcell/consensus-port", default-features = false } - -# `serde` feature dependencies -serde = { version = "1.0.197", default-features = false, features = ["derive"], optional = true } - -[dev-dependencies] -hashbrown = "0.14.3" -tokio = { version = "1.37", features = ["full"] } -tracing-subscriber = "0.3.18" -serde_json = { version = "1.0.68", default-features = false } - -[features] -default = ["serde"] -serde = ["dep:serde"] -test-utils = [ "dep:hashbrown" ] diff --git a/crates/providers/README.md b/crates/providers/README.md deleted file mode 100644 index 9a5df05c31..0000000000 --- a/crates/providers/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# `kona-providers` - -Providers traits and implementations for kona crates. diff --git a/crates/providers/src/l2_chain_provider.rs b/crates/providers/src/l2_chain_provider.rs deleted file mode 100644 index 6167f33425..0000000000 --- a/crates/providers/src/l2_chain_provider.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! This module defines the [L2ChainProvider] trait. - -use alloc::{boxed::Box, sync::Arc}; -use anyhow::Result; -use async_trait::async_trait; -use kona_primitives::{ - block::L2BlockInfo, payload::L2ExecutionPayloadEnvelope, rollup_config::RollupConfig, - system_config::SystemConfig, -}; - -/// Describes the functionality of a data source that fetches safe blocks. -#[async_trait] -pub trait L2ChainProvider { - /// Returns the L2 block info given a block number. - /// Errors if the block does not exist. - async fn l2_block_info_by_number(&mut self, number: u64) -> Result; - - /// Returns an execution payload for a given number. - /// Errors if the execution payload does not exist. - async fn payload_by_number(&mut self, number: u64) -> Result; - - /// Returns the [SystemConfig] by L2 number. - async fn system_config_by_number( - &mut self, - number: u64, - rollup_config: Arc, - ) -> Result; -} diff --git a/crates/providers/src/lib.rs b/crates/providers/src/lib.rs deleted file mode 100644 index 5d13137bdb..0000000000 --- a/crates/providers/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![doc = include_str!("../README.md")] -#![warn(missing_debug_implementations, missing_docs, unreachable_pub, rustdoc::all)] -#![deny(unused_must_use, rust_2018_idioms)] -#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -#![no_std] - -extern crate alloc; - -pub mod chain_provider; -pub use chain_provider::ChainProvider; - -pub mod l2_chain_provider; -pub use l2_chain_provider::L2ChainProvider; - -#[cfg(any(test, feature = "test-utils"))] -pub mod test_utils; diff --git a/crates/providers/src/test_utils.rs b/crates/providers/src/test_utils.rs deleted file mode 100644 index 3576413292..0000000000 --- a/crates/providers/src/test_utils.rs +++ /dev/null @@ -1,159 +0,0 @@ -//! Test utilities for kona providers. - -use crate::{ChainProvider, L2ChainProvider}; -use alloc::{boxed::Box, sync::Arc, vec::Vec}; -use alloy_consensus::{Header, Receipt, TxEnvelope}; -use alloy_primitives::B256; -use anyhow::Result; -use async_trait::async_trait; -use hashbrown::HashMap; -use kona_primitives::{ - BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, RollupConfig, SystemConfig, -}; - -/// A mock chain provider for testing. -#[derive(Debug, Clone, Default)] -pub struct TestChainProvider { - /// Maps block numbers to block information using a tuple list. - pub blocks: Vec<(u64, BlockInfo)>, - /// Maps block hashes to header information using a tuple list. - pub headers: Vec<(B256, Header)>, - /// Maps block hashes to receipts using a tuple list. - pub receipts: Vec<(B256, Vec)>, -} - -impl TestChainProvider { - /// Insert a block into the mock chain provider. - pub fn insert_block(&mut self, number: u64, block: BlockInfo) { - self.blocks.push((number, block)); - } - - /// Insert receipts into the mock chain provider. - pub fn insert_receipts(&mut self, hash: B256, receipts: Vec) { - self.receipts.push((hash, receipts)); - } - - /// Insert a header into the mock chain provider. - pub fn insert_header(&mut self, hash: B256, header: Header) { - self.headers.push((hash, header)); - } - - /// Clears headers from the mock chain provider. - pub fn clear_headers(&mut self) { - self.headers.clear(); - } - - /// Clears blocks from the mock chain provider. - pub fn clear_blocks(&mut self) { - self.blocks.clear(); - } - - /// Clears receipts from the mock chain provider. - pub fn clear_receipts(&mut self) { - self.receipts.clear(); - } - - /// Clears all blocks and receipts from the mock chain provider. - pub fn clear(&mut self) { - self.clear_blocks(); - self.clear_receipts(); - self.clear_headers(); - } -} - -#[async_trait] -impl ChainProvider for TestChainProvider { - async fn header_by_hash(&mut self, hash: B256) -> Result
{ - if let Some((_, header)) = self.headers.iter().find(|(_, b)| b.hash_slow() == hash) { - Ok(header.clone()) - } else { - Err(anyhow::anyhow!("Header not found")) - } - } - - async fn block_info_by_number(&mut self, _number: u64) -> Result { - if let Some((_, block)) = self.blocks.iter().find(|(n, _)| *n == _number) { - Ok(*block) - } else { - Err(anyhow::anyhow!("Block not found")) - } - } - - async fn receipts_by_hash(&mut self, _hash: B256) -> Result> { - if let Some((_, receipts)) = self.receipts.iter().find(|(h, _)| *h == _hash) { - Ok(receipts.clone()) - } else { - Err(anyhow::anyhow!("Receipts not found")) - } - } - - async fn block_info_and_transactions_by_hash( - &mut self, - hash: B256, - ) -> Result<(BlockInfo, Vec)> { - let block = self - .blocks - .iter() - .find(|(_, b)| b.hash == hash) - .map(|(_, b)| *b) - .ok_or_else(|| anyhow::anyhow!("Block not found"))?; - Ok((block, Vec::new())) - } -} - -/// An [L2ChainProvider] implementation for testing. -#[derive(Debug, Default)] -pub struct TestL2ChainProvider { - /// Blocks - pub blocks: Vec, - /// Short circuit the block return to be the first block. - pub short_circuit: bool, - /// Payloads - pub payloads: Vec, - /// System configs - pub system_configs: HashMap, -} - -impl TestL2ChainProvider { - /// Creates a new [MockBlockFetcher] with the given origin and batches. - pub fn new( - blocks: Vec, - payloads: Vec, - system_configs: HashMap, - ) -> Self { - Self { blocks, short_circuit: false, payloads, system_configs } - } -} - -#[async_trait] -impl L2ChainProvider for TestL2ChainProvider { - async fn l2_block_info_by_number(&mut self, number: u64) -> Result { - if self.short_circuit { - return self.blocks.first().copied().ok_or_else(|| anyhow::anyhow!("Block not found")); - } - self.blocks - .iter() - .find(|b| b.block_info.number == number) - .cloned() - .ok_or_else(|| anyhow::anyhow!("Block not found")) - } - - async fn payload_by_number(&mut self, number: u64) -> Result { - self.payloads - .iter() - .find(|p| p.execution_payload.block_number == number) - .cloned() - .ok_or_else(|| anyhow::anyhow!("Payload not found")) - } - - async fn system_config_by_number( - &mut self, - number: u64, - _: Arc, - ) -> Result { - self.system_configs - .get(&number) - .ok_or_else(|| anyhow::anyhow!("System config not found")) - .cloned() - } -} diff --git a/justfile b/justfile index a50ffd70bc..e25dbbf5cd 100644 --- a/justfile +++ b/justfile @@ -9,7 +9,7 @@ tests: test test-online test-docs # Test for the native target test *args='': - cargo nextest run --workspace --all $@ + cargo nextest run --workspace --all --all-features $@ # Run online tests test-online: