Skip to content

Commit

Permalink
feat(derive): Abstract Alt DA out of kona-derive (#156)
Browse files Browse the repository at this point in the history
* chore(workspace): Simplify, fix CI

* feat: Re-add `kona-plasma`

* feat(derive): Abstract away alternative DA layers

* feat(plasma): Add `PlasmaDataSource`

* chore(plasma): Standard `test_utils` mod name

fmt
  • Loading branch information
clabby authored Apr 28, 2024
1 parent af80e7b commit f3a961b
Show file tree
Hide file tree
Showing 39 changed files with 422 additions and 508 deletions.
25 changes: 2 additions & 23 deletions Cargo.lock

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

18 changes: 13 additions & 5 deletions crates/derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -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"
Expand All @@ -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",
Expand All @@ -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"]
7 changes: 2 additions & 5 deletions crates/derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
9 changes: 6 additions & 3 deletions crates/derive/src/online/alloy_providers.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion crates/derive/src/online/blob_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<T: Provider<Http<Client>>, 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,
Expand Down
25 changes: 9 additions & 16 deletions crates/derive/src/online/mod.rs
Original file line number Diff line number Diff line change
@@ -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<DAP>(
rollup_config: Arc<RollupConfig>,
chain_provider: AlloyChainProvider<ReqwestProvider>,
dap_source: DataSourceFactory<
AlloyChainProvider<ReqwestProvider>,
OnlineBlobProvider<
ReqwestProvider,
OnlineBeaconClient<ReqwestProvider>,
SimpleSlotDerivation,
>,
>,
dap_source: DAP,
fetcher: AlloyL2ChainProvider<ReqwestProvider>,
builder: StatefulAttributesBuilder<
AlloyChainProvider<ReqwestProvider>,
AlloyL2ChainProvider<ReqwestProvider>,
>,
) -> 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);
Expand All @@ -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;
Expand Down
9 changes: 6 additions & 3 deletions crates/derive/src/online/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@ use alloy_transport_http::Http;
use async_trait::async_trait;
use reqwest::Client;

pub(crate) fn spawn_anvil() -> (ReqwestProvider<Ethereum>, AnvilInstance) {
/// Spawns an Anvil instance and returns a provider and the instance.
pub fn spawn_anvil() -> (ReqwestProvider<Ethereum>, 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<Ethereum> {
/// Returns an Anvil HTTP provider wrapping the given [AnvilInstance].
pub fn anvil_http_provider(anvil: &AnvilInstance) -> ReqwestProvider<Ethereum> {
http_provider(&anvil.endpoint())
}

pub(crate) fn http_provider(url: &str) -> ReqwestProvider<Ethereum> {
/// Returns an HTTP provider for the given URL.
pub fn http_provider(url: &str) -> ReqwestProvider<Ethereum> {
let url = url.parse().unwrap();
let http = Http::<Client>::new(url);
ReqwestProvider::new(RpcClient::new(http, true))
Expand Down
3 changes: 1 addition & 2 deletions crates/derive/src/sources/blobs.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
//! 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};
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.
Expand Down
3 changes: 1 addition & 2 deletions crates/derive/src/sources/calldata.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down
Original file line number Diff line number Diff line change
@@ -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<C, B, PIF, I>
pub struct EthereumDataSource<C, B>
where
C: ChainProvider + Send + Clone,
B: BlobProvider + Clone,
PIF: PlasmaInputFetcher<C> + Clone,
I: Iterator<Item = Bytes> + 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<u64>,
/// Whether or not plasma is enabled.
pub plasma_enabled: bool,
/// The L1 Signer.
pub signer: Address,
}

impl<C, B, PIF, I> DataSourceFactory<C, B, PIF, I>
impl<C, B> EthereumDataSource<C, B>
where
C: ChainProvider + Send + Clone + Debug,
B: BlobProvider + Clone + Debug,
PIF: PlasmaInputFetcher<C> + Clone + Debug,
I: Iterator<Item = Bytes> + 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<C, B, PIF, I> DataAvailabilityProvider for DataSourceFactory<C, B, PIF, I>
impl<C, B> DataAvailabilityProvider for EthereumDataSource<C, B>
where
C: ChainProvider + Send + Sync + Clone + Debug,
B: BlobProvider + Send + Sync + Clone + Debug,
PIF: PlasmaInputFetcher<C> + Send + Sync + Clone + Debug,
I: Iterator<Item = Bytes> + Send + Sync + Clone + Debug,
{
type Item = Bytes;
type DataIter = DataSource<C, B, PIF, I>;
type DataIter = EthereumDataSourceVariant<C, B>;

async fn open_data(
&self,
Expand All @@ -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,
Expand All @@ -86,22 +70,14 @@ where
))
})
.unwrap_or_else(|| {
DataSource::Calldata(CalldataSource::new(
EthereumDataSourceVariant::Calldata(CalldataSource::new(
self.chain_provider.clone(),
batcher_address,
*block_ref,
self.signer,
))
});
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"))
}
Expand Down
11 changes: 4 additions & 7 deletions crates/derive/src/sources/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
//! This module contains data source impelmentations.

mod factory;
pub use factory::DataSourceFactory;
mod ethereum;
pub use ethereum::EthereumDataSource;

mod blobs;
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;
Loading

0 comments on commit f3a961b

Please sign in to comment.