Skip to content

Commit

Permalink
init L1 retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Feb 25, 2024
1 parent 1ca215b commit c0fe0e4
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
71 changes: 71 additions & 0 deletions crates/derive/src/stages/l1_retrieval.rs
Original file line number Diff line number Diff line change
@@ -1 +1,72 @@
//! Contains the [L1Retrieval] stage of the derivation pipeline.]
use super::L1Traversal;
use crate::{
traits::{ChainProvider, DataAvailabilityProvider, DataIter, ResettableStage},
types::{BlockInfo, SystemConfig},
};
use alloc::boxed::Box;
use alloy_primitives::Bytes;
use anyhow::{anyhow, Result};
use async_trait::async_trait;

/// The L1 retrieval stage of the derivation pipeline.
#[derive(Debug)]
pub struct L1Retrieval<T, DAP, CP>
where
DAP: DataAvailabilityProvider,
CP: ChainProvider,
{
/// The previous stage in the pipeline.
pub prev: L1Traversal<CP>,
/// The data availability provider to use for the L1 retrieval stage.
pub provider: DAP,
/// The current data iterator.
data: Option<DAP::DataIter<T>>,
}

impl<T, DAP, CP> L1Retrieval<T, DAP, CP>
where
T: Into<Bytes>,
DAP: DataAvailabilityProvider,
CP: ChainProvider,
{
/// Creates a new L1 retrieval stage with the given data availability provider and previous stage.
pub fn new(prev: L1Traversal<CP>, provider: DAP) -> Self {
Self {
prev,
provider,
data: None,
}
}

/// Returns the current L1 block in the traversal stage, if it exists.
pub fn origin(&self) -> Option<&BlockInfo> {
self.prev.origin()
}

/// Retrieves the next data item from the L1 retrieval stage.
/// If there is data, it pushes it into the next stage.
/// If there is no data, it returns an error.
pub async fn next_data(&mut self) -> Result<Bytes> {
if self.data.is_none() {
let next = self
.prev
.next_l1_block()
.ok_or_else(|| anyhow!("No block to retrieve data from"))?;
self.data = Some(
self.provider
.open_data(&next, self.prev.system_config.batch_sender)
.await?,
);
}

// Fetch next data item from the iterator.
let data = self
.data
.as_mut()
.and_then(|d| d.next())
.ok_or_else(|| anyhow!("No more data to retrieve"))?;
Ok(data.into())
}
}
9 changes: 7 additions & 2 deletions crates/derive/src/stages/l1_traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ pub struct L1Traversal<Provider: ChainProvider> {
/// Signals whether or not the traversal stage has been completed.
done: bool,
/// The system config
system_config: SystemConfig,
pub system_config: SystemConfig,
/// The rollup config
rollup_config: RollupConfig,
pub rollup_config: RollupConfig,
}

impl<F: ChainProvider> L1Traversal<F> {
Expand All @@ -44,6 +44,11 @@ impl<F: ChainProvider> L1Traversal<F> {
}
}

/// Returns the current L1 block in the traversal stage, if it exists.
pub fn origin(&self) -> Option<&BlockInfo> {
self.block.as_ref()
}

/// Advances the internal state of the [L1Traversal] stage to the next L1 block.
pub async fn advance_l1_block(&mut self) -> Result<()> {
let block = self.block.ok_or(anyhow!("No block to advance from"))?;
Expand Down
23 changes: 22 additions & 1 deletion crates/derive/src/traits/data_sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// use alloy_rpc_types::Block;
use crate::types::{BlockInfo, Receipt};
use alloc::{boxed::Box, vec::Vec};
use alloy_primitives::B256;
use alloy_primitives::{Address, B256};
use anyhow::Result;
use async_trait::async_trait;

Expand All @@ -17,3 +17,24 @@ pub trait ChainProvider {
/// source.
async fn receipts_by_hash(&self, hash: B256) -> Result<Vec<Receipt>>;
}

/// Describes the functionality of a data source that can provide data availability information.
#[async_trait]
pub trait DataAvailabilityProvider {
/// A data iterator for the data source to return.
type DataIter<T>: DataIter<T>;

/// Returns the data availability for the block with the given hash, or an error if the block does not exist in the
/// data source.
async fn open_data<T>(
&self,
block_ref: &BlockInfo,
batcher_address: Address,
) -> Result<Self::DataIter<T>>;
}

/// Describes the behavior of a data iterator.
pub trait DataIter<T> {
/// Returns the next item in the iterator, or `None` if the iterator is exhausted.
fn next(&self) -> Option<T>;
}
2 changes: 1 addition & 1 deletion crates/derive/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! This module contains all of the traits describing functionality of portions of the derivation pipeline.
mod data_sources;
pub use data_sources::ChainProvider;
pub use data_sources::{ChainProvider, DataAvailabilityProvider, DataIter};

mod stages;
pub use stages::ResettableStage;
3 changes: 1 addition & 2 deletions crates/derive/src/traits/stages.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
//! This module contains common traits for stages within the derivation pipeline.
use anyhow::Result;

use crate::types::{BlockInfo, SystemConfig};
use anyhow::Result;

/// Describes the functionality fo a resettable stage within the derivation pipeline.
pub trait ResettableStage {
Expand Down

0 comments on commit c0fe0e4

Please sign in to comment.