Skip to content

Commit

Permalink
Merge branch 'main' into refcell/pipeline-builder
Browse files Browse the repository at this point in the history
  • Loading branch information
refcell authored Apr 19, 2024
2 parents 1f7fb9e + 7289697 commit b6346b2
Show file tree
Hide file tree
Showing 14 changed files with 346 additions and 131 deletions.
21 changes: 20 additions & 1 deletion crates/derive/src/online/alloy_providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

use crate::{
traits::{ChainProvider, L2ChainProvider},
types::{Block, BlockInfo, L2BlockInfo, L2ExecutionPayloadEnvelope, OpBlock, RollupConfig},
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 Down Expand Up @@ -165,6 +168,8 @@ pub struct AlloyL2ChainProvider<T: Provider<Http<reqwest::Client>>> {
payload_by_number_cache: LruCache<u64, L2ExecutionPayloadEnvelope>,
/// `l2_block_info_by_number` LRU cache.
l2_block_info_by_number_cache: LruCache<u64, L2BlockInfo>,
/// `system_config_by_l2_hash` LRU cache.
system_config_by_number_cache: LruCache<u64, SystemConfig>,
}

impl<T: Provider<Http<reqwest::Client>>> AlloyL2ChainProvider<T> {
Expand All @@ -175,6 +180,7 @@ impl<T: Provider<Http<reqwest::Client>>> AlloyL2ChainProvider<T> {
rollup_config,
payload_by_number_cache: LruCache::new(NonZeroUsize::new(CACHE_SIZE).unwrap()),
l2_block_info_by_number_cache: LruCache::new(NonZeroUsize::new(CACHE_SIZE).unwrap()),
system_config_by_number_cache: LruCache::new(NonZeroUsize::new(CACHE_SIZE).unwrap()),
}
}
}
Expand Down Expand Up @@ -209,4 +215,17 @@ impl<T: Provider<Http<reqwest::Client>>> L2ChainProvider for AlloyL2ChainProvide
self.payload_by_number_cache.put(number, payload_envelope.clone());
Ok(payload_envelope)
}

async fn system_config_by_number(
&mut self,
number: u64,
rollup_config: Arc<RollupConfig>,
) -> Result<SystemConfig> {
if let Some(system_config) = self.system_config_by_number_cache.get(&number) {
return Ok(*system_config);
}

let envelope = self.payload_by_number(number).await?;
envelope.to_system_config(&rollup_config)
}
}
2 changes: 1 addition & 1 deletion crates/derive/src/sources/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ where
blob_provider: blobs,
ecotone_timestamp: cfg.ecotone_time,
plasma_enabled: cfg.is_plasma_enabled(),
signer: cfg.l1_signer_address(),
signer: cfg.genesis.system_config.batcher_addr,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/derive/src/stages/attributes_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mod deposits;
pub(crate) use deposits::derive_deposits;

mod builder;
pub use builder::{AttributesBuilder, StatefulAttributesBuilder, SystemConfigL2Fetcher};
pub use builder::{AttributesBuilder, StatefulAttributesBuilder};

/// [AttributesProvider] is a trait abstraction that generalizes the [BatchQueue] stage.
///
Expand Down
125 changes: 68 additions & 57 deletions crates/derive/src/stages/attributes_queue/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
use super::derive_deposits;
use crate::{
params::SEQUENCER_FEE_VAULT_ADDRESS,
traits::ChainProvider,
traits::{ChainProvider, L2ChainProvider},
types::{
BlockID, BuilderError, EcotoneTransactionBuilder, L1BlockInfoTx, L2BlockInfo,
L2PayloadAttributes, RawTransaction, RollupConfig, SystemConfig,
L2PayloadAttributes, RawTransaction, RollupConfig,
},
};
use alloc::{boxed::Box, fmt::Debug, sync::Arc, vec, vec::Vec};
use alloy_primitives::B256;
use alloy_rlp::Encodable;
use async_trait::async_trait;

Expand All @@ -32,43 +31,37 @@ pub trait AttributesBuilder {
) -> Result<L2PayloadAttributes, BuilderError>;
}

/// The [SystemConfigL2Fetcher] fetches the system config by L2 hash.
pub trait SystemConfigL2Fetcher {
/// Fetch the system config by L2 hash.
fn system_config_by_l2_hash(&self, hash: B256) -> anyhow::Result<SystemConfig>;
}

/// A stateful implementation of the [AttributesBuilder].
#[derive(Debug, Default)]
pub struct StatefulAttributesBuilder<S, R>
pub struct StatefulAttributesBuilder<L1P, L2P>
where
S: SystemConfigL2Fetcher + Debug,
R: ChainProvider + Debug,
L1P: ChainProvider + Debug,
L2P: L2ChainProvider + Debug,
{
/// The rollup config.
rollup_cfg: Arc<RollupConfig>,
/// The system config fetcher.
config_fetcher: S,
config_fetcher: L2P,
/// The L1 receipts fetcher.
receipts_fetcher: R,
receipts_fetcher: L1P,
}

impl<S, R> StatefulAttributesBuilder<S, R>
impl<L1P, L2P> StatefulAttributesBuilder<L1P, L2P>
where
S: SystemConfigL2Fetcher + Debug,
R: ChainProvider + Debug,
L1P: ChainProvider + Debug,
L2P: L2ChainProvider + Debug,
{
/// Create a new [StatefulAttributesBuilder] with the given epoch.
pub fn new(rcfg: Arc<RollupConfig>, cfg: S, receipts: R) -> Self {
Self { rollup_cfg: rcfg, config_fetcher: cfg, receipts_fetcher: receipts }
pub fn new(rcfg: Arc<RollupConfig>, sys_cfg_fetcher: L2P, receipts: L1P) -> Self {
Self { rollup_cfg: rcfg, config_fetcher: sys_cfg_fetcher, receipts_fetcher: receipts }
}
}

#[async_trait]
impl<S, R> AttributesBuilder for StatefulAttributesBuilder<S, R>
impl<L1P, L2P> AttributesBuilder for StatefulAttributesBuilder<L1P, L2P>
where
S: SystemConfigL2Fetcher + Send + Debug,
R: ChainProvider + Send + Debug,
L1P: ChainProvider + Debug + Send,
L2P: L2ChainProvider + Debug + Send,
{
async fn prepare_payload_attributes(
&mut self,
Expand All @@ -77,8 +70,10 @@ where
) -> Result<L2PayloadAttributes, BuilderError> {
let l1_header;
let deposit_transactions: Vec<RawTransaction>;
let mut sys_config =
self.config_fetcher.system_config_by_l2_hash(l2_parent.block_info.hash)?;
let mut sys_config = self
.config_fetcher
.system_config_by_number(l2_parent.block_info.number, self.rollup_cfg.clone())
.await?;

// If the L1 origin changed in this block, then we are in the first block of the epoch.
// In this case we need to fetch all transaction receipts from the L1 origin block so
Expand Down Expand Up @@ -177,27 +172,28 @@ where
mod tests {
use super::*;
use crate::{
stages::test_utils::MockSystemConfigL2Fetcher, traits::test_utils::TestChainProvider,
types::BlockInfo,
stages::test_utils::MockSystemConfigL2Fetcher,
traits::test_utils::TestChainProvider,
types::{BlockInfo, SystemConfig},
};
use alloy_consensus::Header;
use alloy_primitives::b256;
use alloy_primitives::B256;

#[tokio::test]
async fn test_prepare_payload_block_mismatch_epoch_reset() {
let cfg = Arc::new(RollupConfig::default());
let l2_hash = b256!("0000000000000000000000000000000000000000000000000000000000000002");
let l2_number = 1;
let mut fetcher = MockSystemConfigL2Fetcher::default();
fetcher.insert(l2_hash, SystemConfig::default());
fetcher.insert(l2_number, SystemConfig::default());
let mut provider = TestChainProvider::default();
let header = Header::default();
let hash = header.hash_slow();
provider.insert_header(hash, header);
let mut builder = StatefulAttributesBuilder::new(cfg, fetcher, provider);
let epoch = BlockID { hash, number: 1 };
let epoch = BlockID { hash, number: l2_number };
let l2_parent = L2BlockInfo {
block_info: BlockInfo { hash: l2_hash, number: 1, ..Default::default() },
l1_origin: BlockID { hash: l2_hash, number: 2 },
block_info: BlockInfo { hash: B256::ZERO, number: l2_number, ..Default::default() },
l1_origin: BlockID { hash: B256::left_padding_from(&[0xFF]), number: 2 },
seq_num: 0,
};
// This should error because the l2 parent's l1_origin.hash should equal the epoch header
Expand All @@ -211,18 +207,18 @@ mod tests {
#[tokio::test]
async fn test_prepare_payload_block_mismatch() {
let cfg = Arc::new(RollupConfig::default());
let l2_hash = b256!("0000000000000000000000000000000000000000000000000000000000000002");
let l2_number = 1;
let mut fetcher = MockSystemConfigL2Fetcher::default();
fetcher.insert(l2_hash, SystemConfig::default());
fetcher.insert(l2_number, SystemConfig::default());
let mut provider = TestChainProvider::default();
let header = Header::default();
let hash = header.hash_slow();
provider.insert_header(hash, header);
let mut builder = StatefulAttributesBuilder::new(cfg, fetcher, provider);
let epoch = BlockID { hash, number: 1 };
let epoch = BlockID { hash, number: l2_number };
let l2_parent = L2BlockInfo {
block_info: BlockInfo { hash: l2_hash, number: 1, ..Default::default() },
l1_origin: BlockID { hash: l2_hash, number: 1 },
block_info: BlockInfo { hash: B256::ZERO, number: l2_number, ..Default::default() },
l1_origin: BlockID { hash: B256::ZERO, number: l2_number },
seq_num: 0,
};
// This should error because the l2 parent's l1_origin.hash should equal the epoch hash
Expand All @@ -237,18 +233,18 @@ mod tests {
let block_time = 10;
let timestamp = 100;
let cfg = Arc::new(RollupConfig { block_time, ..Default::default() });
let l2_hash = b256!("0000000000000000000000000000000000000000000000000000000000000002");
let l2_number = 1;
let mut fetcher = MockSystemConfigL2Fetcher::default();
fetcher.insert(l2_hash, SystemConfig::default());
fetcher.insert(l2_number, SystemConfig::default());
let mut provider = TestChainProvider::default();
let header = Header { timestamp, ..Default::default() };
let hash = header.hash_slow();
provider.insert_header(hash, header);
let mut builder = StatefulAttributesBuilder::new(cfg, fetcher, provider);
let epoch = BlockID { hash, number: 1 };
let epoch = BlockID { hash, number: l2_number };
let l2_parent = L2BlockInfo {
block_info: BlockInfo { hash: l2_hash, number: 1, ..Default::default() },
l1_origin: BlockID { hash, number: 1 },
block_info: BlockInfo { hash: B256::ZERO, number: l2_number, ..Default::default() },
l1_origin: BlockID { hash, number: l2_number },
seq_num: 0,
};
let next_l2_time = l2_parent.block_info.timestamp + block_time;
Expand All @@ -268,19 +264,24 @@ mod tests {
let block_time = 10;
let timestamp = 100;
let cfg = Arc::new(RollupConfig { block_time, ..Default::default() });
let l2_hash = b256!("0000000000000000000000000000000000000000000000000000000000000002");
let l2_number = 1;
let mut fetcher = MockSystemConfigL2Fetcher::default();
fetcher.insert(l2_hash, SystemConfig::default());
fetcher.insert(l2_number, SystemConfig::default());
let mut provider = TestChainProvider::default();
let header = Header { timestamp, ..Default::default() };
let prev_randao = header.mix_hash;
let hash = header.hash_slow();
provider.insert_header(hash, header);
let mut builder = StatefulAttributesBuilder::new(cfg, fetcher, provider);
let epoch = BlockID { hash, number: 1 };
let epoch = BlockID { hash, number: l2_number };
let l2_parent = L2BlockInfo {
block_info: BlockInfo { hash: l2_hash, number: 1, timestamp, parent_hash: hash },
l1_origin: BlockID { hash, number: 1 },
block_info: BlockInfo {
hash: B256::ZERO,
number: l2_number,
timestamp,
parent_hash: hash,
},
l1_origin: BlockID { hash, number: l2_number },
seq_num: 0,
};
let next_l2_time = l2_parent.block_info.timestamp + block_time;
Expand All @@ -306,19 +307,24 @@ mod tests {
let block_time = 10;
let timestamp = 100;
let cfg = Arc::new(RollupConfig { block_time, canyon_time: Some(0), ..Default::default() });
let l2_hash = b256!("0000000000000000000000000000000000000000000000000000000000000002");
let l2_number = 1;
let mut fetcher = MockSystemConfigL2Fetcher::default();
fetcher.insert(l2_hash, SystemConfig::default());
fetcher.insert(l2_number, SystemConfig::default());
let mut provider = TestChainProvider::default();
let header = Header { timestamp, ..Default::default() };
let prev_randao = header.mix_hash;
let hash = header.hash_slow();
provider.insert_header(hash, header);
let mut builder = StatefulAttributesBuilder::new(cfg, fetcher, provider);
let epoch = BlockID { hash, number: 1 };
let epoch = BlockID { hash, number: l2_number };
let l2_parent = L2BlockInfo {
block_info: BlockInfo { hash: l2_hash, number: 1, timestamp, parent_hash: hash },
l1_origin: BlockID { hash, number: 1 },
block_info: BlockInfo {
hash: B256::ZERO,
number: l2_number,
timestamp,
parent_hash: hash,
},
l1_origin: BlockID { hash, number: l2_number },
seq_num: 0,
};
let next_l2_time = l2_parent.block_info.timestamp + block_time;
Expand All @@ -345,20 +351,25 @@ mod tests {
let timestamp = 100;
let cfg =
Arc::new(RollupConfig { block_time, ecotone_time: Some(0), ..Default::default() });
let l2_hash = b256!("0000000000000000000000000000000000000000000000000000000000000002");
let l2_number = 1;
let mut fetcher = MockSystemConfigL2Fetcher::default();
fetcher.insert(l2_hash, SystemConfig::default());
fetcher.insert(l2_number, SystemConfig::default());
let mut provider = TestChainProvider::default();
let header = Header { timestamp, ..Default::default() };
let parent_beacon_block_root = Some(header.parent_beacon_block_root.unwrap_or_default());
let prev_randao = header.mix_hash;
let hash = header.hash_slow();
provider.insert_header(hash, header);
let mut builder = StatefulAttributesBuilder::new(cfg, fetcher, provider);
let epoch = BlockID { hash, number: 1 };
let epoch = BlockID { hash, number: l2_number };
let l2_parent = L2BlockInfo {
block_info: BlockInfo { hash: l2_hash, number: 1, timestamp, parent_hash: hash },
l1_origin: BlockID { hash, number: 1 },
block_info: BlockInfo {
hash: B256::ZERO,
number: l2_number,
timestamp,
parent_hash: hash,
},
l1_origin: BlockID { hash, number: l2_number },
seq_num: 0,
};
let next_l2_time = l2_parent.block_info.timestamp + block_time;
Expand Down
2 changes: 1 addition & 1 deletion crates/derive/src/stages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub use batch_queue::{BatchQueue, BatchQueueProvider};
mod attributes_queue;
pub use attributes_queue::{
AttributesBuilder, AttributesProvider, AttributesQueue, NextAttributes,
StatefulAttributesBuilder, SystemConfigL2Fetcher,
StatefulAttributesBuilder,
};

#[cfg(test)]
Expand Down
40 changes: 29 additions & 11 deletions crates/derive/src/stages/test_utils/sys_config_fetcher.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
//! Implements a mock [L2SystemConfigFetcher] for testing.

use crate::{stages::attributes_queue::SystemConfigL2Fetcher, types::SystemConfig};
use alloy_primitives::B256;
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;

/// A mock implementation of the [`SystemConfigL2Fetcher`] for testing.
#[derive(Debug, Default)]
pub struct MockSystemConfigL2Fetcher {
/// A map from [B256] block hash to a [SystemConfig].
pub system_configs: HashMap<B256, SystemConfig>,
/// A map from [u64] block number to a [SystemConfig].
pub system_configs: HashMap<u64, SystemConfig>,
}

impl MockSystemConfigL2Fetcher {
/// Inserts a new system config into the mock fetcher with the given hash.
pub fn insert(&mut self, hash: B256, config: SystemConfig) {
self.system_configs.insert(hash, config);
/// Inserts a new system config into the mock fetcher with the given block number.
pub fn insert(&mut self, number: u64, config: SystemConfig) {
self.system_configs.insert(number, config);
}

/// Clears all system configs from the mock fetcher.
Expand All @@ -23,11 +28,24 @@ impl MockSystemConfigL2Fetcher {
}
}

impl SystemConfigL2Fetcher for MockSystemConfigL2Fetcher {
fn system_config_by_l2_hash(&self, hash: B256) -> anyhow::Result<SystemConfig> {
#[async_trait]
impl L2ChainProvider for MockSystemConfigL2Fetcher {
async fn system_config_by_number(
&mut self,
number: u64,
_: Arc<RollupConfig>,
) -> Result<SystemConfig> {
self.system_configs
.get(&hash)
.get(&number)
.cloned()
.ok_or_else(|| anyhow::anyhow!("system config not found"))
.ok_or_else(|| anyhow::anyhow!("system config not found: {number}"))
}

async fn l2_block_info_by_number(&mut self, _: u64) -> Result<L2BlockInfo> {
unimplemented!()
}

async fn payload_by_number(&mut self, _: u64) -> Result<L2ExecutionPayloadEnvelope> {
unimplemented!()
}
}
Loading

0 comments on commit b6346b2

Please sign in to comment.