-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: init L1 traversal * More types * moar * port `alloy`
- Loading branch information
Showing
36 changed files
with
4,034 additions
and
11 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,90 @@ | ||
//! Contains the L1 traversal stage of the derivation pipeline. | ||
use crate::{ | ||
traits::{ChainProvider, ResettableStage}, | ||
types::{BlockInfo, RollupConfig, SystemConfig}, | ||
}; | ||
use anyhow::{anyhow, bail, Result}; | ||
|
||
/// The L1 traversal stage of the derivation pipeline. | ||
#[derive(Debug, Clone, Copy)] | ||
pub struct L1Traversal<F: ChainProvider> { | ||
/// The current block in the traversal stage. | ||
block: Option<BlockInfo>, | ||
/// The data source for the traversal stage. | ||
data_source: F, | ||
/// Signals whether or not the traversal stage has been completed. | ||
done: bool, | ||
/// The system config | ||
system_config: SystemConfig, | ||
/// The rollup config | ||
rollup_config: RollupConfig, | ||
} | ||
|
||
impl<F: ChainProvider> L1Traversal<F> { | ||
/// Creates a new [L1Traversal] instance. | ||
pub fn new(data_source: F, cfg: RollupConfig) -> Self { | ||
Self { | ||
block: None, | ||
data_source, | ||
done: false, | ||
system_config: SystemConfig::default(), | ||
rollup_config: cfg, | ||
} | ||
} | ||
|
||
/// Returns the next L1 block in the traversal stage, if the stage has not been completed. This function can only | ||
/// be called once, and will return `None` on subsequent calls unless the stage is reset. | ||
pub fn next_l1_block(&mut self) -> Option<BlockInfo> { | ||
if !self.done { | ||
self.done = true; | ||
self.block | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
/// 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"))?; | ||
let next_l1_origin = self | ||
.data_source | ||
.block_info_by_number(block.number + 1) | ||
.await?; | ||
|
||
// Check for reorgs | ||
if block.hash != next_l1_origin.parent_hash { | ||
bail!( | ||
"Detected L1 reorg from {} to {} with conflicting parent", | ||
block.hash, | ||
next_l1_origin.hash | ||
); | ||
} | ||
|
||
// Fetch receipts. | ||
let receipts = self | ||
.data_source | ||
.receipts_by_hash(next_l1_origin.hash) | ||
.await?; | ||
self.system_config.update_with_receipts( | ||
receipts.as_slice(), | ||
&self.rollup_config, | ||
next_l1_origin.timestamp, | ||
)?; | ||
|
||
self.block = Some(next_l1_origin); | ||
self.done = false; | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl<F: ChainProvider> ResettableStage for L1Traversal<F> { | ||
fn reset(&mut self, base: BlockInfo, cfg: SystemConfig) -> Result<()> { | ||
self.block = Some(base); | ||
self.done = false; | ||
self.system_config = cfg; | ||
|
||
// TODO: Do we want to return an error here w/ EOF? | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,19 @@ | ||
//! Contains traits that describe the functionality of various data sources used in the derivation pipeline's stages. | ||
// use alloy_rpc_types::Block; | ||
use crate::types::{BlockInfo, Receipt}; | ||
use alloc::{boxed::Box, vec::Vec}; | ||
use alloy_primitives::B256; | ||
use anyhow::Result; | ||
use async_trait::async_trait; | ||
|
||
/// Describes the functionality of a data source that can provide information from the blockchain. | ||
#[async_trait] | ||
pub trait ChainProvider { | ||
/// Returns the block at the given number, or an error if the block does not exist in the data source. | ||
async fn block_info_by_number(&self, number: u64) -> Result<BlockInfo>; | ||
|
||
/// Returns all receipts in the block with the given hash, or an error if the block does not exist in the data | ||
/// source. | ||
async fn receipts_by_hash(&self, hash: B256) -> Result<Vec<Receipt>>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
//! This module contains all of the traits describing functionality of portions of the derivation pipeline. | ||
pub mod data_sources; | ||
mod data_sources; | ||
pub use data_sources::ChainProvider; | ||
|
||
mod stages; | ||
pub use stages::ResettableStage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
//! This module contains common traits for stages within the derivation pipeline. | ||
use anyhow::Result; | ||
|
||
use crate::types::{BlockInfo, SystemConfig}; | ||
|
||
/// Describes the functionality fo a resettable stage within the derivation pipeline. | ||
pub trait ResettableStage { | ||
/// Resets the derivation stage to its initial state. | ||
fn reset(&mut self, base: BlockInfo, cfg: SystemConfig) -> Result<()>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
//! This module contains the various Block types. | ||
use alloy_primitives::{BlockHash, BlockNumber, B256}; | ||
|
||
#[cfg(feature = "serde")] | ||
use serde::{Deserialize, Serialize}; | ||
|
||
/// Block Header Info | ||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] | ||
pub struct BlockInfo { | ||
/// The block hash | ||
pub hash: B256, | ||
/// The block number | ||
pub number: u64, | ||
/// The parent block hash | ||
pub parent_hash: B256, | ||
/// The block timestamp | ||
pub timestamp: u64, | ||
} | ||
|
||
impl BlockInfo { | ||
/// Instantiates a new [BlockInfo]. | ||
pub fn new(hash: B256, number: u64, parent_hash: B256, timestamp: u64) -> Self { | ||
Self { | ||
hash, | ||
number, | ||
parent_hash, | ||
timestamp, | ||
} | ||
} | ||
} | ||
|
||
// impl TryFrom<BlockWithTransactions> for BlockInfo { | ||
// type Error = anyhow::Error; | ||
// | ||
// fn try_from(block: BlockWithTransactions) -> anyhow::Result<Self> { | ||
// Ok(BlockInfo { | ||
// number: block.number.unwrap_or_default().to::<u64>(), | ||
// hash: block.hash.unwrap_or_default(), | ||
// parent_hash: block.parent_hash, | ||
// timestamp: block.timestamp.to::<u64>(), | ||
// }) | ||
// } | ||
// } | ||
|
||
/// A Block Identifier | ||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||
#[derive(Debug, Clone, Copy, Eq, PartialEq)] | ||
pub enum BlockId { | ||
/// The block hash | ||
Hash(BlockHash), | ||
/// The block number | ||
Number(BlockNumber), | ||
/// The block kind | ||
Kind(BlockKind), | ||
} | ||
|
||
/// The Block Kind | ||
/// | ||
/// The block kinds are: | ||
/// - `Earliest`: The earliest known block. | ||
/// - `Latest`: The latest pending block. | ||
/// - `Finalized`: The latest finalized block. | ||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||
#[derive(Debug, Clone, Copy, Eq, PartialEq)] | ||
pub enum BlockKind { | ||
/// The earliest known block. | ||
Earliest, | ||
/// The latest pending block. | ||
Latest, | ||
/// The latest finalized block. | ||
Finalized, | ||
} | ||
|
||
// /// A Block with Transactions | ||
// #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||
// #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] | ||
// #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] | ||
// pub struct Block { | ||
// /// Header of the block. | ||
// #[serde(flatten)] | ||
// pub header: Header, | ||
// /// Uncles' hashes. | ||
// pub uncles: Vec<B256>, | ||
// /// Block Transactions. In the case of an uncle block, this field is not included in RPC | ||
// /// responses, and when deserialized, it will be set to [BlockTransactions::Uncle]. | ||
// #[serde( | ||
// skip_serializing_if = "BlockTransactions::is_uncle", | ||
// default = "BlockTransactions::uncle" | ||
// )] | ||
// pub transactions: BlockTransactions, | ||
// /// Integer the size of this block in bytes. | ||
// pub size: Option<U256>, | ||
// /// Withdrawals in the block. | ||
// #[serde(default, skip_serializing_if = "Option::is_none")] | ||
// pub withdrawals: Option<Vec<Withdrawal>>, | ||
// /// Support for arbitrary additional fields. | ||
// #[serde(flatten)] | ||
// pub other: OtherFields, | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use super::constants::{DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR, DEFAULT_ELASTICITY_MULTIPLIER}; | ||
|
||
/// BaseFeeParams contains the config parameters that control block base fee computation | ||
#[derive(Debug, Copy, Clone, PartialEq, Eq)] | ||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct BaseFeeParams { | ||
/// The base_fee_max_change_denominator from EIP-1559 | ||
pub max_change_denominator: u64, | ||
/// The elasticity multiplier from EIP-1559 | ||
pub elasticity_multiplier: u64, | ||
} | ||
|
||
impl BaseFeeParams { | ||
/// Get the base fee parameters for Ethereum mainnet | ||
pub const fn ethereum() -> BaseFeeParams { | ||
BaseFeeParams { | ||
max_change_denominator: DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR, | ||
elasticity_multiplier: DEFAULT_ELASTICITY_MULTIPLIER, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use alloy_primitives::U256; | ||
|
||
/// The default Ethereum block gas limit. | ||
/// | ||
/// TODO: This should be a chain spec parameter. | ||
/// See <https://github.com/paradigmxyz/reth/issues/3233>. | ||
pub const ETHEREUM_BLOCK_GAS_LIMIT: u64 = 30_000_000; | ||
|
||
/// The minimum tx fee below which the txpool will reject the transaction. | ||
/// | ||
/// Configured to `7` WEI which is the lowest possible value of base fee under mainnet EIP-1559 | ||
/// parameters. `BASE_FEE_MAX_CHANGE_DENOMINATOR` <https://eips.ethereum.org/EIPS/eip-1559> | ||
/// is `8`, or 12.5%. Once the base fee has dropped to `7` WEI it cannot decrease further because | ||
/// 12.5% of 7 is less than 1. | ||
/// | ||
/// Note that min base fee under different 1559 parameterizations may differ, but there's no | ||
/// signifant harm in leaving this setting as is. | ||
pub const MIN_PROTOCOL_BASE_FEE: u64 = 7; | ||
|
||
/// Same as [MIN_PROTOCOL_BASE_FEE] but as a U256. | ||
pub const MIN_PROTOCOL_BASE_FEE_U256: U256 = U256::from_limbs([7u64, 0, 0, 0]); | ||
|
||
/// Initial base fee as defined in [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) | ||
pub const INITIAL_BASE_FEE: u64 = 1_000_000_000; | ||
|
||
/// Base fee max change denominator as defined in [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) | ||
pub const DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8; | ||
|
||
/// Elasticity multiplier as defined in [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) | ||
pub const DEFAULT_ELASTICITY_MULTIPLIER: u64 = 2; |
Oops, something went wrong.