Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(derive): Build L1BlockInfoTx in payload builder #102

Merged
merged 1 commit into from
Apr 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading