From ce40bb97d2e90983da322fb8b79e23dbd2291b8e Mon Sep 17 00:00:00 2001 From: clabby Date: Sat, 27 Apr 2024 22:25:57 -0400 Subject: [PATCH 1/5] chore(workspace): Simplify, fix CI --- Cargo.lock | 38 ---- crates/derive/Cargo.toml | 14 +- crates/derive/src/online/alloy_providers.rs | 9 +- crates/derive/src/online/blob_provider.rs | 2 +- crates/derive/src/online/mod.rs | 15 +- crates/derive/src/sources/blobs.rs | 3 +- crates/derive/src/sources/calldata.rs | 3 +- crates/derive/src/sources/factory.rs | 6 +- crates/derive/src/sources/plasma.rs | 23 +- crates/derive/src/sources/source.rs | 4 +- .../src/stages/attributes_queue/builder.rs | 4 +- crates/derive/src/stages/batch_queue.rs | 5 +- crates/derive/src/stages/l1_traversal.rs | 9 +- .../stages/test_utils/sys_config_fetcher.rs | 6 +- crates/derive/src/traits/mod.rs | 6 + crates/derive/src/traits/plasma.rs | 84 +++++++ .../src/traits/providers.rs} | 27 ++- crates/derive/src/traits/test_utils.rs | 207 +++++++++++++++++- crates/derive/src/types/batch/mod.rs | 6 +- .../src/types/batch/span_batch/batch.rs | 12 +- crates/derive/src/types/errors.rs | 3 +- crates/derive/src/types/mod.rs | 3 + .../types.rs => derive/src/types/plasma.rs} | 35 +-- crates/plasma/Cargo.toml | 35 --- crates/plasma/README.md | 27 --- crates/plasma/src/lib.rs | 19 -- crates/plasma/src/test_utils.rs | 60 ----- crates/plasma/src/traits.rs | 44 ---- crates/providers/Cargo.toml | 41 ---- crates/providers/README.md | 3 - crates/providers/src/l2_chain_provider.rs | 28 --- crates/providers/src/lib.rs | 16 -- crates/providers/src/test_utils.rs | 159 -------------- 33 files changed, 391 insertions(+), 565 deletions(-) create mode 100644 crates/derive/src/traits/plasma.rs rename crates/{providers/src/chain_provider.rs => derive/src/traits/providers.rs} (54%) rename crates/{plasma/src/types.rs => derive/src/types/plasma.rs} (75%) delete mode 100644 crates/plasma/Cargo.toml delete mode 100644 crates/plasma/README.md delete mode 100644 crates/plasma/src/lib.rs delete mode 100644 crates/plasma/src/test_utils.rs delete mode 100644 crates/plasma/src/traits.rs delete mode 100644 crates/providers/Cargo.toml delete mode 100644 crates/providers/README.md delete mode 100644 crates/providers/src/l2_chain_provider.rs delete mode 100644 crates/providers/src/lib.rs delete mode 100644 crates/providers/src/test_utils.rs diff --git a/Cargo.lock b/Cargo.lock index 832cc30b64..5c5cf35f18 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", @@ -1606,22 +1604,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "kona-plasma" -version = "0.0.1" -dependencies = [ - "alloy-consensus 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=e3f2f07)", - "alloy-primitives", - "anyhow", - "async-trait", - "kona-primitives", - "kona-providers", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - [[package]] name = "kona-preimage" version = "0.0.1" @@ -1649,26 +1631,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..e616fdd5bb 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 } @@ -44,7 +42,6 @@ alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f reqwest = { version = "0.12", 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" @@ -53,8 +50,14 @@ alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", 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"] +default = ["serde", "k256", "online"] +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 +72,3 @@ online = [ "revm-primitives/serde", "revm-primitives/c-kzg", ] -test-utils = [ "kona-providers/test-utils", "kona-plasma/test-utils" ] 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..7b8ab6140e 100644 --- a/crates/derive/src/online/mod.rs +++ b/crates/derive/src/online/mod.rs @@ -9,23 +9,24 @@ use crate::{ traits::ResettableStage, types::RollupConfig, }; - use alloc::sync::Arc; +use alloy_primitives::Bytes; use alloy_provider::ReqwestProvider; use core::fmt::Debug; -/// Creates a new [OnlineStageStack]. +type BlobProvider = + OnlineBlobProvider, SimpleSlotDerivation>; + +/// Creates a new online stack. #[cfg(feature = "online")] pub fn new_online_stack( rollup_config: Arc, chain_provider: AlloyChainProvider, dap_source: DataSourceFactory< AlloyChainProvider, - OnlineBlobProvider< - ReqwestProvider, - OnlineBeaconClient, - SimpleSlotDerivation, - >, + BlobProvider, + (), + alloc::collections::vec_deque::IntoIter, >, fetcher: AlloyL2ChainProvider, builder: StatefulAttributesBuilder< 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/factory.rs index d313eb9562..ac719ca5ae 100644 --- a/crates/derive/src/sources/factory.rs +++ b/crates/derive/src/sources/factory.rs @@ -2,17 +2,17 @@ use crate::{ sources::{BlobSource, CalldataSource, DataSource, PlasmaSource}, - traits::{BlobProvider, DataAvailabilityProvider}, + traits::{BlobProvider, ChainProvider, DataAvailabilityProvider, PlasmaInputFetcher}, types::{BlockID, 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. +/// +/// TODO: Delete this, very leaky. #[derive(Debug, Clone, Copy)] pub struct DataSourceFactory where diff --git a/crates/derive/src/sources/plasma.rs b/crates/derive/src/sources/plasma.rs index 4c222fb148..d0e410d335 100644 --- a/crates/derive/src/sources/plasma.rs +++ b/crates/derive/src/sources/plasma.rs @@ -1,20 +1,16 @@ //! Plasma Data Source use crate::{ - traits::AsyncIterator, - types::{ResetError, StageError, StageResult}, + traits::{AsyncIterator, ChainProvider, PlasmaInputFetcher}, + types::{ + decode_keccak256, Keccak256Commitment, PlasmaError, ResetError, StageError, StageResult, + MAX_INPUT_SIZE, TX_DATA_VERSION_1, + }, }; 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 kona_primitives::block::BlockID; -use kona_providers::ChainProvider; /// A plasma data iterator. #[derive(Debug, Clone)] @@ -138,7 +134,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 +183,11 @@ where #[cfg(test)] mod tests { use super::*; - use crate::stages::test_utils::{CollectingLayer, TraceStorage}; + use crate::{ + stages::test_utils::{CollectingLayer, TraceStorage}, + traits::test_utils::{TestChainProvider, TestPlasmaInputFetcher}, + }; use alloc::vec; - use kona_plasma::test_utils::TestPlasmaInputFetcher; - use kona_providers::test_utils::TestChainProvider; use tracing::Level; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; diff --git a/crates/derive/src/sources/source.rs b/crates/derive/src/sources/source.rs index 49dfb06834..7217a95ef8 100644 --- a/crates/derive/src/sources/source.rs +++ b/crates/derive/src/sources/source.rs @@ -2,14 +2,12 @@ use crate::{ sources::{BlobSource, CalldataSource, PlasmaSource}, - traits::{AsyncIterator, BlobProvider}, + traits::{AsyncIterator, BlobProvider, ChainProvider, PlasmaInputFetcher}, 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)] 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/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/traits/mod.rs b/crates/derive/src/traits/mod.rs index f3ff4f5473..717c9d0138 100644 --- a/crates/derive/src/traits/mod.rs +++ b/crates/derive/src/traits/mod.rs @@ -4,6 +4,12 @@ mod data_sources; pub use data_sources::*; +mod providers; +pub use providers::{ChainProvider, L2ChainProvider}; + +mod plasma; +pub use plasma::PlasmaInputFetcher; + mod stages; pub use stages::{OriginAdvancer, OriginProvider, PreviousStage, ResettableStage}; diff --git a/crates/derive/src/traits/plasma.rs b/crates/derive/src/traits/plasma.rs new file mode 100644 index 0000000000..0bfb5e25ea --- /dev/null +++ b/crates/derive/src/traits/plasma.rs @@ -0,0 +1,84 @@ +//! This module contains traits for the plasma extension of the derivation pipeline. + +use crate::types::{FinalizedHeadSignal, PlasmaError}; + +use super::ChainProvider; +use alloc::boxed::Box; +use alloy_primitives::Bytes; +use async_trait::async_trait; +use kona_primitives::{BlockID, BlockInfo, SystemConfig}; + +/// A plasma input fetcher. +#[async_trait] +pub trait PlasmaInputFetcher { + /// Get the input for the given commitment at the given block number from the DA storage + /// service. + async fn get_input( + &mut self, + fetcher: &CP, + commitment: Bytes, + block: BlockID, + ) -> Option>; + + /// Advance the L1 origin to the given block number, syncing the DA challenge events. + async fn advance_l1_origin( + &mut self, + fetcher: &CP, + block: BlockID, + ) -> Option>; + + /// Reset the challenge origin in case of L1 reorg. + async fn reset( + &mut self, + block_number: BlockInfo, + cfg: SystemConfig, + ) -> Option>; + + /// Notify L1 finalized head so plasma finality is always behind L1. + async fn finalize(&mut self, block_number: BlockInfo) -> Option>; + + /// Set the engine finalization signal callback. + fn on_finalized_head_signal(&mut self, callback: FinalizedHeadSignal); +} + +#[async_trait] +impl PlasmaInputFetcher for () { + /// Get the input for the given commitment at the given block number from the DA storage + /// service. + async fn get_input( + &mut self, + _fetcher: &CP, + _commitment: Bytes, + _block: BlockID, + ) -> Option> { + unimplemented!() + } + + /// Advance the L1 origin to the given block number, syncing the DA challenge events. + async fn advance_l1_origin( + &mut self, + _fetcher: &CP, + _block: BlockID, + ) -> Option> { + unimplemented!() + } + + /// Reset the challenge origin in case of L1 reorg. + async fn reset( + &mut self, + _block_number: BlockInfo, + _cfg: SystemConfig, + ) -> Option> { + unimplemented!() + } + + /// Notify L1 finalized head so plasma finality is always behind L1. + async fn finalize(&mut self, _block_number: BlockInfo) -> Option> { + unimplemented!() + } + + /// Set the engine finalization signal callback. + fn on_finalized_head_signal(&mut self, _callback: FinalizedHeadSignal) { + unimplemented!() + } +} 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..293342287f 100644 --- a/crates/derive/src/traits/test_utils.rs +++ b/crates/derive/src/traits/test_utils.rs @@ -1,14 +1,21 @@ //! Test Utilities for derive traits use crate::{ - traits::{AsyncIterator, DataAvailabilityProvider}, - types::{BlockInfo, StageError, StageResult}, + traits::{AsyncIterator, ChainProvider, DataAvailabilityProvider, L2ChainProvider}, + types::{FinalizedHeadSignal, PlasmaError, 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::{ + BlockID, BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, RollupConfig, SystemConfig, +}; + +use super::PlasmaInputFetcher; /// Mock data iterator #[derive(Debug, Default, PartialEq)] @@ -57,3 +64,195 @@ 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() + } +} + +/// A mock plasma input fetcher for testing. +#[derive(Debug, Clone, Default)] +pub struct TestPlasmaInputFetcher { + /// Inputs to return. + pub inputs: Vec>, + /// Advance L1 origin results. + pub advances: Vec>, + /// Reset results. + pub resets: Vec>, +} + +#[async_trait] +impl PlasmaInputFetcher for TestPlasmaInputFetcher { + async fn get_input( + &mut self, + _fetcher: &TestChainProvider, + _commitment: Bytes, + _block: BlockID, + ) -> Option> { + self.inputs.pop() + } + + async fn advance_l1_origin( + &mut self, + _fetcher: &TestChainProvider, + _block: BlockID, + ) -> Option> { + self.advances.pop() + } + + async fn reset( + &mut self, + _block_number: BlockInfo, + _cfg: SystemConfig, + ) -> Option> { + self.resets.pop() + } + + async fn finalize(&mut self, _block_number: BlockInfo) -> Option> { + None + } + + fn on_finalized_head_signal(&mut self, _block_number: FinalizedHeadSignal) {} +} 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..5b340fb35d 100644 --- a/crates/derive/src/types/errors.rs +++ b/crates/derive/src/types/errors.rs @@ -1,11 +1,10 @@ //! This module contains derivation errors thrown within the pipeline. use super::SpanBatchError; -use crate::types::{BlockID, Frame}; +use crate::types::{BlockID, Frame, PlasmaError}; 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; diff --git a/crates/derive/src/types/mod.rs b/crates/derive/src/types/mod.rs index 35a1977fe7..aa976698af 100644 --- a/crates/derive/src/types/mod.rs +++ b/crates/derive/src/types/mod.rs @@ -34,5 +34,8 @@ pub use frame::Frame; mod channel; pub use channel::Channel; +mod plasma; +pub use plasma::*; + mod errors; pub use errors::*; diff --git a/crates/plasma/src/types.rs b/crates/derive/src/types/plasma.rs similarity index 75% rename from crates/plasma/src/types.rs rename to crates/derive/src/types/plasma.rs index fe449d0c10..0fdb91d0c9 100644 --- a/crates/plasma/src/types.rs +++ b/crates/derive/src/types/plasma.rs @@ -1,9 +1,7 @@ -//! 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 +30,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 +43,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 +63,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/plasma/Cargo.toml b/crates/plasma/Cargo.toml deleted file mode 100644 index ef9f73d4b9..0000000000 --- a/crates/plasma/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "kona-plasma" -description = "Plasma Data Availability Adapter" -version = "0.0.1" -edition.workspace = true -authors.workspace = true -license.workspace = true -repository.workspace = true -homepage.workspace = true - -[dependencies] -# Workspace -anyhow.workspace = true -tracing.workspace = true - -# Local -kona-primitives = { path = "../primitives" } -kona-providers = { path = "../providers" } - -# External -alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", default-features = false } -alloy-primitives = { workspace = true, features = ["rlp"] } -async-trait = "0.1.77" - -# `serde` feature dependencies -serde = { version = "1.0.197", default-features = false, features = ["derive"], optional = true } - -[dev-dependencies] -tracing-subscriber = "0.3.18" -serde_json = { version = "1.0.68", default-features = false } - -[features] -default = [ "serde" ] -serde = [ "dep:serde", "kona-providers/serde", "kona-primitives/serde" ] -test-utils = [ "kona-providers/test-utils" ] diff --git a/crates/plasma/README.md b/crates/plasma/README.md deleted file mode 100644 index 4eadf2ea96..0000000000 --- a/crates/plasma/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# `kona-plasma` - -Plasma Data Availability Adapter for `kona-derive`. - -[plasma]: https://specs.optimism.io/experimental/plasma.html - -`kona-plasma` is an implementation of the [Plasma][plasma] OP Stack Specification in rust. - -## Usage - -Add `kona-plasma` to your `Cargo.toml`. - -```ignore -[dependencies] -kona-plasma = "0.0.1" - -# Serde is enabled by default and can be disabled by toggling default-features off -# kona-plasma = { version = "0.0.1", default-features = false } -``` - -## Features - -### Serde - -[`serde`] serialization and deserialization support for `kona-plasma` types. - -By default, the `serde` feature is enabled on `kona-plasma`. diff --git a/crates/plasma/src/lib.rs b/crates/plasma/src/lib.rs deleted file mode 100644 index 8f46bbff3f..0000000000 --- a/crates/plasma/src/lib.rs +++ /dev/null @@ -1,19 +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; - -// Re-export kona primitives. -pub use kona_primitives::*; - -pub mod traits; -pub use traits::PlasmaInputFetcher; - -pub mod types; -pub use types::{FinalizedHeadSignal, Keccak256Commitment, PlasmaError, SystemConfig}; - -#[cfg(any(test, feature = "test-utils"))] -pub mod test_utils; diff --git a/crates/plasma/src/test_utils.rs b/crates/plasma/src/test_utils.rs deleted file mode 100644 index 31d7f4ca8a..0000000000 --- a/crates/plasma/src/test_utils.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! Test utilities for the Plasma crate. - -use crate::{ - traits::PlasmaInputFetcher, - types::{FinalizedHeadSignal, PlasmaError}, -}; -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; - -/// A mock plasma input fetcher for testing. -#[derive(Debug, Clone, Default)] -pub struct TestPlasmaInputFetcher { - /// Inputs to return. - pub inputs: Vec>, - /// Advance L1 origin results. - pub advances: Vec>, - /// Reset results. - pub resets: Vec>, -} - -#[async_trait] -impl PlasmaInputFetcher for TestPlasmaInputFetcher { - async fn get_input( - &mut self, - _fetcher: &TestChainProvider, - _commitment: Bytes, - _block: BlockID, - ) -> Option> { - self.inputs.pop() - } - - async fn advance_l1_origin( - &mut self, - _fetcher: &TestChainProvider, - _block: BlockID, - ) -> Option> { - self.advances.pop() - } - - async fn reset( - &mut self, - _block_number: BlockInfo, - _cfg: SystemConfig, - ) -> Option> { - self.resets.pop() - } - - async fn finalize(&mut self, _block_number: BlockInfo) -> Option> { - None - } - - fn on_finalized_head_signal(&mut self, _block_number: FinalizedHeadSignal) {} -} diff --git a/crates/plasma/src/traits.rs b/crates/plasma/src/traits.rs deleted file mode 100644 index f4960bdf89..0000000000 --- a/crates/plasma/src/traits.rs +++ /dev/null @@ -1,44 +0,0 @@ -//! Traits for plasma sources and internal components. - -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; - -/// A plasma input fetcher. -#[async_trait] -pub trait PlasmaInputFetcher { - /// Get the input for the given commitment at the given block number from the DA storage - /// service. - async fn get_input( - &mut self, - fetcher: &CP, - commitment: Bytes, - block: BlockID, - ) -> Option>; - - /// Advance the L1 origin to the given block number, syncing the DA challenge events. - async fn advance_l1_origin( - &mut self, - fetcher: &CP, - block: BlockID, - ) -> Option>; - - /// Reset the challenge origin in case of L1 reorg. - async fn reset( - &mut self, - block_number: BlockInfo, - cfg: SystemConfig, - ) -> Option>; - - /// Notify L1 finalized head so plasma finality is always behind L1. - async fn finalize(&mut self, block_number: BlockInfo) -> Option>; - - /// Set the engine finalization signal callback. - fn on_finalized_head_signal(&mut self, callback: FinalizedHeadSignal); -} 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() - } -} From eb4f7473c6a5e589d0afa3bbbcafca761bc93a9d Mon Sep 17 00:00:00 2001 From: clabby Date: Sat, 27 Apr 2024 22:34:15 -0400 Subject: [PATCH 2/5] feat: Re-add `kona-plasma` --- crates/plasma/Cargo.toml | 35 +++++++++++++++++++++++++++++++++++ crates/plasma/README.md | 27 +++++++++++++++++++++++++++ crates/plasma/src/lib.rs | 8 ++++++++ 3 files changed, 70 insertions(+) create mode 100644 crates/plasma/Cargo.toml create mode 100644 crates/plasma/README.md create mode 100644 crates/plasma/src/lib.rs diff --git a/crates/plasma/Cargo.toml b/crates/plasma/Cargo.toml new file mode 100644 index 0000000000..e68d4a7373 --- /dev/null +++ b/crates/plasma/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "kona-plasma" +description = "Plasma Data Availability Adapter" +version = "0.0.1" +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true + +[dependencies] +# Workspace +anyhow.workspace = true +tracing.workspace = true + +# Local +kona-primitives = { path = "../primitives" } +kona-derive = { path = "../derive" } + +# External +alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", default-features = false } +alloy-primitives = { workspace = true, features = ["rlp"] } +async-trait = "0.1.77" + +# `serde` feature dependencies +serde = { version = "1.0.197", default-features = false, features = ["derive"], optional = true } + +[dev-dependencies] +tracing-subscriber = "0.3.18" +serde_json = { version = "1.0.68", default-features = false } + +[features] +default = [ "serde" ] +serde = [ "dep:serde", "kona-providers/serde", "kona-primitives/serde" ] +test-utils = [ "kona-providers/test-utils" ] diff --git a/crates/plasma/README.md b/crates/plasma/README.md new file mode 100644 index 0000000000..4eadf2ea96 --- /dev/null +++ b/crates/plasma/README.md @@ -0,0 +1,27 @@ +# `kona-plasma` + +Plasma Data Availability Adapter for `kona-derive`. + +[plasma]: https://specs.optimism.io/experimental/plasma.html + +`kona-plasma` is an implementation of the [Plasma][plasma] OP Stack Specification in rust. + +## Usage + +Add `kona-plasma` to your `Cargo.toml`. + +```ignore +[dependencies] +kona-plasma = "0.0.1" + +# Serde is enabled by default and can be disabled by toggling default-features off +# kona-plasma = { version = "0.0.1", default-features = false } +``` + +## Features + +### Serde + +[`serde`] serialization and deserialization support for `kona-plasma` types. + +By default, the `serde` feature is enabled on `kona-plasma`. diff --git a/crates/plasma/src/lib.rs b/crates/plasma/src/lib.rs new file mode 100644 index 0000000000..2ac731df7b --- /dev/null +++ b/crates/plasma/src/lib.rs @@ -0,0 +1,8 @@ +#![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; + From cd0102081eda1410642086b83853347ad7aa4f40 Mon Sep 17 00:00:00 2001 From: clabby Date: Sat, 27 Apr 2024 23:30:01 -0400 Subject: [PATCH 3/5] feat(derive): Abstract away alternative DA layers --- Cargo.lock | 17 ++++++ crates/derive/Cargo.toml | 8 ++- crates/derive/src/lib.rs | 7 +-- crates/derive/src/online/mod.rs | 24 +++----- crates/derive/src/online/test_utils.rs | 9 ++- .../src/sources/{factory.rs => ethereum.rs} | 47 ++++------------ crates/derive/src/sources/mod.rs | 9 +-- crates/derive/src/sources/source.rs | 19 ++----- crates/derive/src/stages/mod.rs | 2 +- .../derive/src/stages/test_utils/tracing.rs | 3 + crates/derive/src/traits/mod.rs | 5 +- crates/derive/src/traits/test_utils.rs | 51 +---------------- crates/derive/src/types/errors.rs | 6 +- crates/derive/src/types/mod.rs | 3 - crates/plasma/Cargo.toml | 7 ++- crates/plasma/src/lib.rs | 6 ++ .../plasma.rs => plasma/src/source.rs} | 30 ++++++---- crates/plasma/src/test_util.rs | 56 +++++++++++++++++++ .../traits/plasma.rs => plasma/src/traits.rs} | 3 +- .../types/plasma.rs => plasma/src/types.rs} | 2 + justfile | 2 +- 21 files changed, 158 insertions(+), 158 deletions(-) rename crates/derive/src/sources/{factory.rs => ethereum.rs} (55%) rename crates/{derive/src/sources/plasma.rs => plasma/src/source.rs} (92%) create mode 100644 crates/plasma/src/test_util.rs rename crates/{derive/src/traits/plasma.rs => plasma/src/traits.rs} (98%) rename crates/{derive/src/types/plasma.rs => plasma/src/types.rs} (98%) diff --git a/Cargo.lock b/Cargo.lock index 5c5cf35f18..e6139bf4cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1604,6 +1604,23 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "kona-plasma" +version = "0.0.1" +dependencies = [ + "alloy-consensus 0.1.0 (git+https://github.com/alloy-rs/alloy?rev=e3f2f07)", + "alloy-primitives", + "anyhow", + "async-trait", + "kona-derive", + "kona-primitives", + "serde", + "serde_json", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "kona-preimage" version = "0.0.1" diff --git a/crates/derive/Cargo.toml b/crates/derive/Cargo.toml index e616fdd5bb..667233eb05 100644 --- a/crates/derive/Cargo.toml +++ b/crates/derive/Cargo.toml @@ -41,6 +41,11 @@ 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] tokio = { version = "1.37", features = ["full"] } proptest = "1.4.0" @@ -50,7 +55,7 @@ alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "e3f2f07", serde_json = { version = "1.0.116", default-features = false } [features] -default = ["serde", "k256", "online"] +default = ["serde", "k256"] serde = [ "dep:serde", "kona-primitives/serde", @@ -72,3 +77,4 @@ online = [ "revm-primitives/serde", "revm-primitives/c-kzg", ] +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/mod.rs b/crates/derive/src/online/mod.rs index 7b8ab6140e..5c4fdc90c4 100644 --- a/crates/derive/src/online/mod.rs +++ b/crates/derive/src/online/mod.rs @@ -1,39 +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_primitives::Bytes; use alloy_provider::ReqwestProvider; use core::fmt::Debug; -type BlobProvider = - OnlineBlobProvider, SimpleSlotDerivation>; - /// 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, - BlobProvider, - (), - alloc::collections::vec_deque::IntoIter, - >, + 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); @@ -43,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/factory.rs b/crates/derive/src/sources/ethereum.rs similarity index 55% rename from crates/derive/src/sources/factory.rs rename to crates/derive/src/sources/ethereum.rs index ac719ca5ae..f8f04403cf 100644 --- a/crates/derive/src/sources/factory.rs +++ b/crates/derive/src/sources/ethereum.rs @@ -1,73 +1,56 @@ //! Contains a Factory for creating a calldata and blob provider. use crate::{ - sources::{BlobSource, CalldataSource, DataSource, PlasmaSource}, - traits::{BlobProvider, ChainProvider, DataAvailabilityProvider, PlasmaInputFetcher}, - 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; -/// A factory for creating a calldata and blob provider. -/// -/// TODO: Delete this, very leaky. +/// 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 +60,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 +69,7 @@ where )) }) .unwrap_or_else(|| { - DataSource::Calldata(CalldataSource::new( + EthereumDataSourceVariant::Calldata(CalldataSource::new( self.chain_provider.clone(), batcher_address, *block_ref, @@ -94,14 +77,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..58b9f4fb05 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; +pub use source::EthereumDataSourceVariant; diff --git a/crates/derive/src/sources/source.rs b/crates/derive/src/sources/source.rs index 7217a95ef8..d02db69d5d 100644 --- a/crates/derive/src/sources/source.rs +++ b/crates/derive/src/sources/source.rs @@ -1,8 +1,8 @@ //! Data source use crate::{ - sources::{BlobSource, CalldataSource, PlasmaSource}, - traits::{AsyncIterator, BlobProvider, ChainProvider, PlasmaInputFetcher}, + sources::{BlobSource, CalldataSource}, + traits::{AsyncIterator, BlobProvider, ChainProvider}, types::StageResult, }; use alloc::boxed::Box; @@ -11,36 +11,29 @@ use async_trait::async_trait; /// An enum over the various data sources. #[derive(Debug, Clone)] -pub enum DataSource +pub enum EthereumDataSourceVariant 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 +impl AsyncIterator for EthereumDataSourceVariant 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, + EthereumDataSourceVariant::Calldata(c) => c.next().await, + EthereumDataSourceVariant::Blob(b) => b.next().await, } } } 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/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/mod.rs b/crates/derive/src/traits/mod.rs index 717c9d0138..89f5ff9249 100644 --- a/crates/derive/src/traits/mod.rs +++ b/crates/derive/src/traits/mod.rs @@ -7,14 +7,11 @@ pub use data_sources::*; mod providers; pub use providers::{ChainProvider, L2ChainProvider}; -mod plasma; -pub use plasma::PlasmaInputFetcher; - 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/derive/src/traits/test_utils.rs b/crates/derive/src/traits/test_utils.rs index 293342287f..ffc3d44653 100644 --- a/crates/derive/src/traits/test_utils.rs +++ b/crates/derive/src/traits/test_utils.rs @@ -2,7 +2,7 @@ use crate::{ traits::{AsyncIterator, ChainProvider, DataAvailabilityProvider, L2ChainProvider}, - types::{FinalizedHeadSignal, PlasmaError, StageError, StageResult}, + types::{StageError, StageResult}, }; use alloc::{boxed::Box, sync::Arc, vec, vec::Vec}; use alloy_consensus::{Header, Receipt, TxEnvelope}; @@ -12,11 +12,9 @@ use async_trait::async_trait; use core::fmt::Debug; use hashbrown::HashMap; use kona_primitives::{ - BlockID, BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, RollupConfig, SystemConfig, + BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, RollupConfig, SystemConfig, }; -use super::PlasmaInputFetcher; - /// Mock data iterator #[derive(Debug, Default, PartialEq)] pub struct TestIter { @@ -211,48 +209,3 @@ impl L2ChainProvider for TestL2ChainProvider { .cloned() } } - -/// A mock plasma input fetcher for testing. -#[derive(Debug, Clone, Default)] -pub struct TestPlasmaInputFetcher { - /// Inputs to return. - pub inputs: Vec>, - /// Advance L1 origin results. - pub advances: Vec>, - /// Reset results. - pub resets: Vec>, -} - -#[async_trait] -impl PlasmaInputFetcher for TestPlasmaInputFetcher { - async fn get_input( - &mut self, - _fetcher: &TestChainProvider, - _commitment: Bytes, - _block: BlockID, - ) -> Option> { - self.inputs.pop() - } - - async fn advance_l1_origin( - &mut self, - _fetcher: &TestChainProvider, - _block: BlockID, - ) -> Option> { - self.advances.pop() - } - - async fn reset( - &mut self, - _block_number: BlockInfo, - _cfg: SystemConfig, - ) -> Option> { - self.resets.pop() - } - - async fn finalize(&mut self, _block_number: BlockInfo) -> Option> { - None - } - - fn on_finalized_head_signal(&mut self, _block_number: FinalizedHeadSignal) {} -} diff --git a/crates/derive/src/types/errors.rs b/crates/derive/src/types/errors.rs index 5b340fb35d..afed20ff37 100644 --- a/crates/derive/src/types/errors.rs +++ b/crates/derive/src/types/errors.rs @@ -1,7 +1,7 @@ //! This module contains derivation errors thrown within the pipeline. use super::SpanBatchError; -use crate::types::{BlockID, Frame, PlasmaError}; +use crate::types::{BlockID, Frame}; use alloc::vec::Vec; use alloy_primitives::{Bytes, B256}; use core::fmt::Display; @@ -18,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, @@ -69,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) | @@ -104,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/derive/src/types/mod.rs b/crates/derive/src/types/mod.rs index aa976698af..35a1977fe7 100644 --- a/crates/derive/src/types/mod.rs +++ b/crates/derive/src/types/mod.rs @@ -34,8 +34,5 @@ pub use frame::Frame; mod channel; pub use channel::Channel; -mod plasma; -pub use plasma::*; - mod errors; pub use errors::*; diff --git a/crates/plasma/Cargo.toml b/crates/plasma/Cargo.toml index e68d4a7373..8b5fd8cb77 100644 --- a/crates/plasma/Cargo.toml +++ b/crates/plasma/Cargo.toml @@ -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 2ac731df7b..d153f84de6 100644 --- a/crates/plasma/src/lib.rs +++ b/crates/plasma/src/lib.rs @@ -6,3 +6,9 @@ extern crate alloc; +pub mod source; +pub mod traits; +pub mod types; + +#[cfg(test)] +pub mod test_util; diff --git a/crates/derive/src/sources/plasma.rs b/crates/plasma/src/source.rs similarity index 92% rename from crates/derive/src/sources/plasma.rs rename to crates/plasma/src/source.rs index d0e410d335..93288e8d8b 100644 --- a/crates/derive/src/sources/plasma.rs +++ b/crates/plasma/src/source.rs @@ -1,15 +1,19 @@ //! Plasma Data Source use crate::{ - traits::{AsyncIterator, ChainProvider, PlasmaInputFetcher}, + traits::PlasmaInputFetcher, types::{ - decode_keccak256, Keccak256Commitment, PlasmaError, ResetError, StageError, StageResult, - MAX_INPUT_SIZE, TX_DATA_VERSION_1, + 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; /// A plasma data iterator. @@ -85,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 @@ -182,12 +186,18 @@ where #[cfg(test)] mod tests { + use crate::test_util::TestPlasmaInputFetcher; + use super::*; - use crate::{ + // use crate::{ + // stages::test_utils::{CollectingLayer, TraceStorage}, + // traits::test_utils::{TestChainProvider, TestPlasmaInputFetcher}, + // }; + use alloc::vec; + use kona_derive::{ stages::test_utils::{CollectingLayer, TraceStorage}, - traits::test_utils::{TestChainProvider, TestPlasmaInputFetcher}, + traits::test_utils::TestChainProvider, }; - use alloc::vec; use tracing::Level; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; @@ -233,7 +243,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] @@ -250,7 +260,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_util.rs b/crates/plasma/src/test_util.rs new file mode 100644 index 0000000000..415129abef --- /dev/null +++ b/crates/plasma/src/test_util.rs @@ -0,0 +1,56 @@ +//! Test utilities for the `kona-plasma` crate. + +use crate::{ + traits::PlasmaInputFetcher, + types::{FinalizedHeadSignal, PlasmaError}, +}; +use alloc::{boxed::Box, vec::Vec}; +use alloy_primitives::Bytes; +use async_trait::async_trait; +use kona_derive::traits::test_utils::TestChainProvider; +use kona_primitives::{BlockID, BlockInfo, SystemConfig}; + +/// A mock plasma input fetcher for testing. +#[derive(Debug, Clone, Default)] +pub struct TestPlasmaInputFetcher { + /// Inputs to return. + pub inputs: Vec>, + /// Advance L1 origin results. + pub advances: Vec>, + /// Reset results. + pub resets: Vec>, +} + +#[async_trait] +impl PlasmaInputFetcher for TestPlasmaInputFetcher { + async fn get_input( + &mut self, + _fetcher: &TestChainProvider, + _commitment: Bytes, + _block: BlockID, + ) -> Option> { + self.inputs.pop() + } + + async fn advance_l1_origin( + &mut self, + _fetcher: &TestChainProvider, + _block: BlockID, + ) -> Option> { + self.advances.pop() + } + + async fn reset( + &mut self, + _block_number: BlockInfo, + _cfg: SystemConfig, + ) -> Option> { + self.resets.pop() + } + + async fn finalize(&mut self, _block_number: BlockInfo) -> Option> { + None + } + + fn on_finalized_head_signal(&mut self, _block_number: FinalizedHeadSignal) {} +} diff --git a/crates/derive/src/traits/plasma.rs b/crates/plasma/src/traits.rs similarity index 98% rename from crates/derive/src/traits/plasma.rs rename to crates/plasma/src/traits.rs index 0bfb5e25ea..d29f529c8e 100644 --- a/crates/derive/src/traits/plasma.rs +++ b/crates/plasma/src/traits.rs @@ -1,11 +1,10 @@ //! This module contains traits for the plasma extension of the derivation pipeline. use crate::types::{FinalizedHeadSignal, PlasmaError}; - -use super::ChainProvider; use alloc::boxed::Box; use alloy_primitives::Bytes; use async_trait::async_trait; +use kona_derive::traits::ChainProvider; use kona_primitives::{BlockID, BlockInfo, SystemConfig}; /// A plasma input fetcher. diff --git a/crates/derive/src/types/plasma.rs b/crates/plasma/src/types.rs similarity index 98% rename from crates/derive/src/types/plasma.rs rename to crates/plasma/src/types.rs index 0fdb91d0c9..e158296caf 100644 --- a/crates/derive/src/types/plasma.rs +++ b/crates/plasma/src/types.rs @@ -1,3 +1,5 @@ +//! Types for the `kona-plasma` crate. + use alloc::boxed::Box; use alloy_primitives::Bytes; use core::fmt::Display; 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: From 87999c5201dda74ca2a8bebb60c565629fe41471 Mon Sep 17 00:00:00 2001 From: clabby Date: Sat, 27 Apr 2024 23:40:57 -0400 Subject: [PATCH 4/5] feat(plasma): Add `PlasmaDataSource` --- crates/derive/src/sources/ethereum.rs | 3 +- crates/derive/src/sources/mod.rs | 4 +- .../src/sources/{source.rs => variant.rs} | 0 crates/derive/src/traits/data_sources.rs | 9 --- crates/plasma/src/lib.rs | 1 + crates/plasma/src/plasma.rs | 72 +++++++++++++++++++ crates/plasma/src/traits.rs | 42 ----------- 7 files changed, 77 insertions(+), 54 deletions(-) rename crates/derive/src/sources/{source.rs => variant.rs} (100%) create mode 100644 crates/plasma/src/plasma.rs diff --git a/crates/derive/src/sources/ethereum.rs b/crates/derive/src/sources/ethereum.rs index f8f04403cf..8055d568dd 100644 --- a/crates/derive/src/sources/ethereum.rs +++ b/crates/derive/src/sources/ethereum.rs @@ -1,4 +1,5 @@ -//! 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, EthereumDataSourceVariant}, diff --git a/crates/derive/src/sources/mod.rs b/crates/derive/src/sources/mod.rs index 58b9f4fb05..253b65268d 100644 --- a/crates/derive/src/sources/mod.rs +++ b/crates/derive/src/sources/mod.rs @@ -9,5 +9,5 @@ pub use blobs::BlobSource; mod calldata; pub use calldata::CalldataSource; -mod source; -pub use source::EthereumDataSourceVariant; +mod variant; +pub use variant::EthereumDataSourceVariant; diff --git a/crates/derive/src/sources/source.rs b/crates/derive/src/sources/variant.rs similarity index 100% rename from crates/derive/src/sources/source.rs rename to crates/derive/src/sources/variant.rs 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/plasma/src/lib.rs b/crates/plasma/src/lib.rs index d153f84de6..acd39ab094 100644 --- a/crates/plasma/src/lib.rs +++ b/crates/plasma/src/lib.rs @@ -6,6 +6,7 @@ extern crate alloc; +pub mod plasma; pub mod source; pub mod traits; pub mod types; 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/plasma/src/traits.rs b/crates/plasma/src/traits.rs index d29f529c8e..6529623cc3 100644 --- a/crates/plasma/src/traits.rs +++ b/crates/plasma/src/traits.rs @@ -39,45 +39,3 @@ pub trait PlasmaInputFetcher { /// Set the engine finalization signal callback. fn on_finalized_head_signal(&mut self, callback: FinalizedHeadSignal); } - -#[async_trait] -impl PlasmaInputFetcher for () { - /// Get the input for the given commitment at the given block number from the DA storage - /// service. - async fn get_input( - &mut self, - _fetcher: &CP, - _commitment: Bytes, - _block: BlockID, - ) -> Option> { - unimplemented!() - } - - /// Advance the L1 origin to the given block number, syncing the DA challenge events. - async fn advance_l1_origin( - &mut self, - _fetcher: &CP, - _block: BlockID, - ) -> Option> { - unimplemented!() - } - - /// Reset the challenge origin in case of L1 reorg. - async fn reset( - &mut self, - _block_number: BlockInfo, - _cfg: SystemConfig, - ) -> Option> { - unimplemented!() - } - - /// Notify L1 finalized head so plasma finality is always behind L1. - async fn finalize(&mut self, _block_number: BlockInfo) -> Option> { - unimplemented!() - } - - /// Set the engine finalization signal callback. - fn on_finalized_head_signal(&mut self, _callback: FinalizedHeadSignal) { - unimplemented!() - } -} From 8a85a2f4cbf96a085234a2261c8e271235ade474 Mon Sep 17 00:00:00 2001 From: clabby Date: Sun, 28 Apr 2024 12:07:49 -0400 Subject: [PATCH 5/5] chore(plasma): Standard `test_utils` mod name fmt --- crates/plasma/src/lib.rs | 2 +- crates/plasma/src/source.rs | 7 +------ crates/plasma/src/{test_util.rs => test_utils.rs} | 0 3 files changed, 2 insertions(+), 7 deletions(-) rename crates/plasma/src/{test_util.rs => test_utils.rs} (100%) diff --git a/crates/plasma/src/lib.rs b/crates/plasma/src/lib.rs index acd39ab094..4fec9fa224 100644 --- a/crates/plasma/src/lib.rs +++ b/crates/plasma/src/lib.rs @@ -12,4 +12,4 @@ pub mod traits; pub mod types; #[cfg(test)] -pub mod test_util; +pub mod test_utils; diff --git a/crates/plasma/src/source.rs b/crates/plasma/src/source.rs index 93288e8d8b..d08c01f5b1 100644 --- a/crates/plasma/src/source.rs +++ b/crates/plasma/src/source.rs @@ -186,13 +186,8 @@ where #[cfg(test)] mod tests { - use crate::test_util::TestPlasmaInputFetcher; - use super::*; - // use crate::{ - // stages::test_utils::{CollectingLayer, TraceStorage}, - // traits::test_utils::{TestChainProvider, TestPlasmaInputFetcher}, - // }; + use crate::test_utils::TestPlasmaInputFetcher; use alloc::vec; use kona_derive::{ stages::test_utils::{CollectingLayer, TraceStorage}, diff --git a/crates/plasma/src/test_util.rs b/crates/plasma/src/test_utils.rs similarity index 100% rename from crates/plasma/src/test_util.rs rename to crates/plasma/src/test_utils.rs