Skip to content

Commit

Permalink
feat(derive): Build L1BlockInfoTx in payload builder (#102)
Browse files Browse the repository at this point in the history
rebase
  • Loading branch information
clabby authored Apr 14, 2024
1 parent d5ded03 commit 77dfe7c
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 24 deletions.
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 @@ -80,7 +80,7 @@ where
self.batch.as_ref().cloned().ok_or(StageError::Eof)
}

/// Returns the next [AttributesWithParent] from the current batch.
/// Returns the next [L2AttributesWithParent] from the current batch.
pub async fn next_attributes(
&mut self,
parent: L2BlockInfo,
Expand Down
31 changes: 19 additions & 12 deletions crates/derive/src/stages/attributes_queue/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ use crate::{
params::SEQUENCER_FEE_VAULT_ADDRESS,
traits::ChainProvider,
types::{
BlockID, BuilderError, EcotoneTransactionBuilder, L2BlockInfo, L2PayloadAttributes,
RawTransaction, RollupConfig, SystemConfig,
BlockID, BuilderError, EcotoneTransactionBuilder, L1BlockInfoTx, L2BlockInfo,
L2PayloadAttributes, RawTransaction, RollupConfig, SystemConfig,
},
};
use alloc::{boxed::Box, fmt::Debug, sync::Arc, vec, vec::Vec};
use alloy_primitives::B256;
use alloy_rlp::Encodable;
use async_trait::async_trait;

/// The [AttributesBuilder] is responsible for preparing [PayloadAttributes]
/// The [AttributesBuilder] is responsible for preparing [L2PayloadAttributes]
/// that can be used to construct an L2 Block containing only deposits.
#[async_trait]
pub trait AttributesBuilder {
Expand Down Expand Up @@ -76,14 +77,13 @@ where
) -> Result<L2PayloadAttributes, BuilderError> {
let l1_header;
let deposit_transactions: Vec<RawTransaction>;
// let mut sequence_number = 0u64;
let mut sys_config =
self.config_fetcher.system_config_by_l2_hash(l2_parent.block_info.hash)?;

// 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
// we can scan for user deposits.
if l2_parent.l1_origin.number != epoch.number {
let sequence_number = if l2_parent.l1_origin.number != epoch.number {
let header = self.receipts_fetcher.header_by_hash(epoch.hash).await?;
if l2_parent.l1_origin.hash != header.parent_hash {
return Err(BuilderError::BlockMismatchEpochReset(
Expand All @@ -99,7 +99,7 @@ where
.await?;
l1_header = header;
deposit_transactions = deposits;
// sequence_number = 0;
0
} else {
#[allow(clippy::collapsible_else_if)]
if l2_parent.l1_origin.hash != epoch.hash {
Expand All @@ -109,8 +109,8 @@ where
let header = self.receipts_fetcher.header_by_hash(epoch.hash).await?;
l1_header = header;
deposit_transactions = vec![];
// sequence_number = l2_parent.seq_num + 1;
}
l2_parent.seq_num + 1
};

// Sanity check the L1 origin was correctly selected to maintain the time invariant
// between L1 and L2.
Expand All @@ -130,13 +130,20 @@ where
EcotoneTransactionBuilder::build_txs().map_err(BuilderError::Custom)?;
}

// TODO(clabby): `L1BlockInfo` parsing from calldata.
// let l1_info_tx = l1_info_deposit_bytes(self.rollup_cfg, sys_config, sequence_number,
// l1_info, next_l2_time)?;
// Build and encode the L1 info transaction for the current payload.
let (_, l1_info_tx_envelope) = L1BlockInfoTx::try_new_with_deposit_tx(
&self.rollup_cfg,
&sys_config,
sequence_number,
&l1_header,
next_l2_time,
)?;
let mut encoded_l1_info_tx = Vec::with_capacity(l1_info_tx_envelope.length());
l1_info_tx_envelope.encode(&mut encoded_l1_info_tx);

let mut txs =
Vec::with_capacity(1 + deposit_transactions.len() + upgrade_transactions.len());
// txs.push(l1_info_tx);
txs.push(encoded_l1_info_tx.into());
txs.extend(deposit_transactions);
txs.extend(upgrade_transactions);

Expand Down
2 changes: 1 addition & 1 deletion crates/derive/src/types/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub struct L2AttributesWithParent {
}

impl L2AttributesWithParent {
/// Create a new [AttributesWithParent] instance.
/// Create a new [L2AttributesWithParent] instance.
pub fn new(
attributes: L2PayloadAttributes,
parent: L2BlockInfo,
Expand Down
4 changes: 3 additions & 1 deletion crates/derive/src/types/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ pub enum StageError {
ChannelNotFound,
/// Missing L1 origin.
MissingOrigin,
/// Failed to build the [super::PayloadAttributes] for the next batch.
/// Failed to build the [L2PayloadAttributes] for the next batch.
///
/// [L2PayloadAttributes]: super::L2PayloadAttributes
AttributesBuild(BuilderError),
/// Reset the pipeline.
Reset(ResetError),
Expand Down
14 changes: 7 additions & 7 deletions crates/derive/src/types/l1_block_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use alloc::vec::Vec;
use alloy_consensus::Header;
use alloy_primitives::{address, Address, Bytes, TxKind, B256, U256};
use anyhow::{anyhow, Result};
use op_alloy_consensus::TxDeposit;
use op_alloy_consensus::{OpTxEnvelope, TxDeposit};

/// The system transaction gas limit post-Regolith
const REGOLITH_SYSTEM_TX_GAS: u128 = 1_000_000;
Expand Down Expand Up @@ -117,7 +117,7 @@ impl L1BlockInfoTx {
rollup_config: &RollupConfig,
system_config: &SystemConfig,
sequence_number: u64,
l1_header: Header,
l1_header: &Header,
l2_block_time: u64,
) -> Result<Self> {
// In the first block of Ecotone, the L1Block contract has not been upgraded yet due to the
Expand Down Expand Up @@ -173,9 +173,9 @@ impl L1BlockInfoTx {
rollup_config: &RollupConfig,
system_config: &SystemConfig,
sequence_number: u64,
l1_header: Header,
l1_header: &Header,
l2_block_time: u64,
) -> Result<(L1BlockInfoTx, TxDeposit)> {
) -> Result<(L1BlockInfoTx, OpTxEnvelope)> {
let l1_info =
Self::try_new(rollup_config, system_config, sequence_number, l1_header, l2_block_time)?;
let l1_block_hash = match l1_info {
Expand Down Expand Up @@ -206,7 +206,7 @@ impl L1BlockInfoTx {
deposit_tx.gas_limit = REGOLITH_SYSTEM_TX_GAS;
}

Ok((l1_info, deposit_tx))
Ok((l1_info, OpTxEnvelope::Deposit(deposit_tx)))
}

/// Decodes the [L1BlockInfoEcotone] object from ethereum transaction calldata.
Expand Down Expand Up @@ -442,7 +442,7 @@ mod test {
&rollup_config,
&system_config,
sequence_number,
l1_header.clone(),
&l1_header,
l2_block_time,
)
.unwrap();
Expand Down Expand Up @@ -473,7 +473,7 @@ mod test {
&rollup_config,
&system_config,
sequence_number,
l1_header.clone(),
&l1_header,
l2_block_time,
)
.unwrap();
Expand Down
4 changes: 2 additions & 2 deletions crates/derive/src/types/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use alloy_rlp::{Decodable, Encodable};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// Envelope wrapping the [ExecutionPayload].
/// Envelope wrapping the [L2ExecutionPayload].
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct L2ExecutionPayloadEnvelope {
Expand Down Expand Up @@ -112,7 +112,7 @@ pub struct L2ExecutionPayload {
}

impl L2ExecutionPayloadEnvelope {
/// Converts the [ExecutionPayloadEnvelope] to an [L2BlockInfo], by checking against the L1
/// Converts the [L2ExecutionPayloadEnvelope] to an [L2BlockInfo], by checking against the L1
/// information transaction or the genesis block.
pub fn to_l2_block_ref(&self, rollup_config: &RollupConfig) -> Result<L2BlockInfo> {
let L2ExecutionPayloadEnvelope { execution_payload, .. } = self;
Expand Down

0 comments on commit 77dfe7c

Please sign in to comment.