Skip to content

refactor(l2): refactor privileged transactions #3365

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

Merged
merged 24 commits into from
Jul 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
87df762
Drop tx hash from deposit log, index from instead of amount
iovoid Jun 27, 2025
cac4301
rename deposits to privileged transactions
iovoid Jun 27, 2025
800c00d
rename more instances of deposit
iovoid Jun 27, 2025
5617528
rename more instances of deposit
iovoid Jun 27, 2025
4dbb6d6
rename instances of deposit in based
iovoid Jun 27, 2025
557d06d
rename more instances of deposit
iovoid Jun 27, 2025
9c0abae
resolve merge
iovoid Jun 30, 2025
f7e6cae
Merge branch 'main' into refactor/simplify-privileged
iovoid Jun 30, 2025
f11b253
Merge branch 'main' into refactor/simplify-privileged
jrchatruc Jun 30, 2025
d0dd59a
rename amount->value, reorder fields in l2TxHash
iovoid Jul 1, 2025
1eb1cb2
fix constant
iovoid Jul 1, 2025
3ac28c7
fix duplicate lastVerifiedBatch setting
iovoid Jul 1, 2025
25927a6
fix unclear comment
iovoid Jul 1, 2025
38c151b
Merge branch 'main' into refactor/simplify-privileged
iovoid Jul 1, 2025
2d328fa
fix
iovoid Jul 1, 2025
5ee9929
Merge branch 'main' into refactor/simplify-privileged
iovoid Jul 2, 2025
cba999f
fmt
iovoid Jul 2, 2025
3b5b8e2
Merge branch 'main' into refactor/simplify-privileged
MegaRedHand Jul 2, 2025
b29dd4b
improve variable naming
iovoid Jul 2, 2025
d842b61
update state diff docs
iovoid Jul 2, 2025
8c7b55d
Fix typo
iovoid Jul 2, 2025
6ed285b
remove getPendingTransactionHashes
iovoid Jul 2, 2025
fff3b0d
Merge branch 'main' into refactor/simplify-privileged
iovoid Jul 2, 2025
f3b47b3
Revert "remove getPendingTransactionHashes"
iovoid Jul 2, 2025
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 cmd/ethrex/l2/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ impl Command {
first_block: first_block_number,
last_block: new_block.number,
state_root: new_block.state_root,
deposit_logs_hash: H256::zero(),
privileged_transactions_hash: H256::zero(),
message_hashes,
blobs_bundle: BlobsBundle::empty(),
commit_tx: None,
Expand Down
4 changes: 2 additions & 2 deletions crates/blockchain/metrics/l2/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ pub enum MetricsBlockType {
}

pub enum MetricsOperationType {
Deposits,
PrivilegedTransactions,
L1Messages,
}

Expand All @@ -146,7 +146,7 @@ impl MetricsBlockType {
impl MetricsOperationType {
fn to_str(&self) -> &str {
match self {
MetricsOperationType::Deposits => "processedDeposits",
MetricsOperationType::PrivilegedTransactions => "processedPrivilegedTransactions",
MetricsOperationType::L1Messages => "processedMessages",
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/common/types/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct Batch {
pub first_block: u64,
pub last_block: u64,
pub state_root: H256,
pub deposit_logs_hash: H256,
pub privileged_transactions_hash: H256,
pub message_hashes: Vec<H256>,
#[serde(skip_serializing)]
pub blobs_bundle: BlobsBundle,
Expand Down
16 changes: 8 additions & 8 deletions crates/common/types/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ impl Transaction {

pub fn compute_hash(&self) -> H256 {
if let Transaction::PrivilegedL2Transaction(tx) = self {
return tx.get_deposit_hash().unwrap_or_default();
return tx.get_privileged_hash().unwrap_or_default();
}
keccak_hash::keccak(self.encode_canonical_to_vec())
}
Expand Down Expand Up @@ -1354,10 +1354,10 @@ impl TxType {
}

impl PrivilegedL2Transaction {
/// Returns the formatted hash of the deposit transaction,
/// or None if the transaction is not a deposit.
/// The hash is computed as keccak256(to || value || deposit_id == nonce || from || gas_limit || keccak256(calldata))
pub fn get_deposit_hash(&self) -> Option<H256> {
/// Returns the formatted hash of the privileged transaction,
/// or None if the transaction is not a privileged transaction.
/// The hash is computed as keccak256(from || to || transaction_id || value || gas_limit || keccak256(calldata))
pub fn get_privileged_hash(&self) -> Option<H256> {
// Should this function be changed?
let to = match self.to {
TxKind::Call(to) => to,
Expand All @@ -1367,16 +1367,16 @@ impl PrivilegedL2Transaction {
let value = self.value.to_big_endian();

// The nonce should be a U256,
// in solidity the depositId is a U256.
// in solidity the transactionId is a U256.
let u256_nonce = U256::from(self.nonce);
let nonce = u256_nonce.to_big_endian();

Some(keccak_hash::keccak(
[
self.from.as_bytes(),
to.as_bytes(),
&value,
&nonce,
self.from.as_bytes(),
&value,
&U256::from(self.gas_limit).to_big_endian(),
keccak(&self.data).as_bytes(),
]
Expand Down
26 changes: 14 additions & 12 deletions crates/l2/based/block_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use ethrex_common::{
},
};
use ethrex_l2_common::{
deposits::compute_deposit_logs_hash,
l1_messages::{L1Message, get_block_l1_messages, get_l1_message_hash},
privileged_transactions::compute_privileged_transactions_hash,
state_diff::prepare_state_diff,
};
use ethrex_rlp::decode::RLPDecode;
Expand Down Expand Up @@ -52,8 +52,10 @@ pub enum BlockFetcherError {
EvmError(#[from] ethrex_vm::EvmError),
#[error("Failed to produce the blob bundle")]
BlobBundleError,
#[error("Failed to compute deposit logs hash: {0}")]
DepositError(#[from] ethrex_l2_common::deposits::DepositError),
#[error("Failed to compute privileged transactions hash: {0}")]
PrivilegedTransactionError(
#[from] ethrex_l2_common::privileged_transactions::PrivilegedTransactionError,
),
#[error("Spawned GenServer Error")]
GenServerError(spawned_concurrency::GenServerError),
}
Expand Down Expand Up @@ -343,7 +345,7 @@ fn decode_batch_from_calldata(calldata: &[u8]) -> Result<Vec<Block>, BlockFetche
// bytes32 newStateRoot,
// bytes32 stateDiffKZGVersionedHash,
// bytes32 messagesLogsMerkleRoot,
// bytes32 processedDepositLogsRollingHash,
// bytes32 processedPrivilegedTransactionsRollingHash,
// bytes[] calldata _rlpEncodedBlocks
// ) external;

Expand All @@ -352,7 +354,7 @@ fn decode_batch_from_calldata(calldata: &[u8]) -> Result<Vec<Block>, BlockFetche
// || 32 bytes (new state root) 36..68
// || 32 bytes (state diff KZG versioned hash) 68..100
// || 32 bytes (messages logs merkle root) 100..132
// || 32 bytes (processed deposit logs rolling hash) 132..164
// || 32 bytes (processed privileged transactions rolling hash) 132..164

let batch_length_in_blocks = U256::from_big_endian(calldata.get(196..228).ok_or(
BlockFetcherError::WrongBatchCalldata("Couldn't get batch length bytes".to_owned()),
Expand Down Expand Up @@ -489,29 +491,29 @@ async fn get_batch(
batch_number: U256,
commit_tx: H256,
) -> Result<Batch, BlockFetcherError> {
let deposits: Vec<PrivilegedL2Transaction> = batch
let privileged_transactions: Vec<PrivilegedL2Transaction> = batch
.iter()
.flat_map(|block| {
block.body.transactions.iter().filter_map(|tx| {
if let Transaction::PrivilegedL2Transaction(tx) = tx {
Some(tx.clone())
// tx.get_deposit_hash()
} else {
None
}
})
})
.collect();
let deposit_log_hashes = deposits
let privileged_transaction_hashes = privileged_transactions
.iter()
.filter_map(|tx| tx.get_deposit_hash())
.filter_map(|tx| tx.get_privileged_hash())
.collect();
let mut messages = Vec::new();
for block in batch {
let block_messages = extract_block_messages(state, block.header.number).await?;
messages.extend(block_messages);
}
let deposit_logs_hash = compute_deposit_logs_hash(deposit_log_hashes)?;
let privileged_transactions_hash =
compute_privileged_transactions_hash(privileged_transaction_hashes)?;

let first_block = batch.first().ok_or(BlockFetcherError::InternalError(
"Batch is empty. This shouldn't happen.".to_owned(),
Expand Down Expand Up @@ -558,7 +560,7 @@ async fn get_batch(
last_block.header.clone(),
&parent_db,
&messages,
&deposits,
&privileged_transactions,
acc_account_updates.into_values().collect(),
)
.map_err(|_| BlockFetcherError::BlobBundleError)?;
Expand All @@ -571,7 +573,7 @@ async fn get_batch(
first_block: first_block.header.number,
last_block: last_block.header.number,
state_root: new_state_root,
deposit_logs_hash,
privileged_transactions_hash,
message_hashes: get_batch_message_hashes(state, batch).await?,
blobs_bundle,
commit_tx: Some(commit_tx),
Expand Down
2 changes: 1 addition & 1 deletion crates/l2/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub mod calldata;
pub mod deposits;
pub mod l1_messages;
pub mod merkle_tree;
pub mod privileged_transactions;
pub mod prover;
pub mod state_diff;
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ use keccak_hash::keccak;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct DepositLog {
pub struct PrivilegedTransactionLog {
pub address: Address,
pub amount: U256,
pub nonce: u64,
}

impl DepositLog {
impl PrivilegedTransactionLog {
pub fn encode(&self) -> Vec<u8> {
let mut encoded = Vec::new();
encoded.extend(self.address.0);
Expand All @@ -20,14 +20,14 @@ impl DepositLog {
}

#[derive(Debug, thiserror::Error)]
pub enum DepositError {
#[error("Failed to decode deposit hash")]
pub enum PrivilegedTransactionError {
#[error("Failed to decode transaction hash")]
FailedToDecodeHash,
#[error("Length does not fit in u16")]
LengthTooLarge(#[from] std::num::TryFromIntError),
}

pub fn get_block_deposits(txs: &[Transaction]) -> Vec<PrivilegedL2Transaction> {
pub fn get_block_privileged_transactions(txs: &[Transaction]) -> Vec<PrivilegedL2Transaction> {
txs.iter()
.filter_map(|tx| match tx {
Transaction::PrivilegedL2Transaction(tx) => Some(tx.clone()),
Expand All @@ -36,26 +36,28 @@ pub fn get_block_deposits(txs: &[Transaction]) -> Vec<PrivilegedL2Transaction> {
.collect()
}

pub fn compute_deposit_logs_hash(deposit_log_hashes: Vec<H256>) -> Result<H256, DepositError> {
if deposit_log_hashes.is_empty() {
pub fn compute_privileged_transactions_hash(
privileged_transaction_hashes: Vec<H256>,
) -> Result<H256, PrivilegedTransactionError> {
if privileged_transaction_hashes.is_empty() {
return Ok(H256::zero());
}

let deposit_hashes_len: u16 = deposit_log_hashes.len().try_into()?;
let privileged_transaction_hashes_len: u16 = privileged_transaction_hashes.len().try_into()?;

Ok(H256::from_slice(
[
&deposit_hashes_len.to_be_bytes(),
&privileged_transaction_hashes_len.to_be_bytes(),
keccak(
deposit_log_hashes
privileged_transaction_hashes
.iter()
.map(H256::as_bytes)
.collect::<Vec<&[u8]>>()
.concat(),
)
.as_bytes()
.get(2..32)
.ok_or(DepositError::FailedToDecodeHash)?,
.ok_or(PrivilegedTransactionError::FailedToDecodeHash)?,
]
.concat()
.as_slice(),
Expand Down
36 changes: 18 additions & 18 deletions crates/l2/common/src/state_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ use serde::{Deserialize, Serialize};

use lazy_static::lazy_static;

use crate::{deposits::DepositLog, l1_messages::L1Message};
use crate::{l1_messages::L1Message, privileged_transactions::PrivilegedTransactionLog};

lazy_static! {
/// The serialized length of a default l1message log
pub static ref L1MESSAGE_LOG_LEN: usize = L1Message::default().encode().len();

/// The serialized length of a default deposit log
pub static ref DEPOSITS_LOG_LEN: usize = DepositLog::default().encode().len();
/// The serialized length of a default privileged transaction log
pub static ref PRIVILEGED_TX_LOG_LEN: usize = PrivilegedTransactionLog::default().encode().len();

/// The serialized lenght of a default block header
pub static ref BLOCK_HEADER_LEN: usize = encode_block_header(&BlockHeader::default()).len();
Expand Down Expand Up @@ -83,7 +83,7 @@ pub struct StateDiff {
pub last_header: BlockHeader,
pub modified_accounts: BTreeMap<Address, AccountStateDiff>,
pub l1_messages: Vec<L1Message>,
pub deposit_logs: Vec<DepositLog>,
pub privileged_transactions: Vec<PrivilegedTransactionLog>,
}

impl TryFrom<u8> for AccountStateDiffType {
Expand Down Expand Up @@ -127,7 +127,7 @@ impl Default for StateDiff {
last_header: BlockHeader::default(),
modified_accounts: BTreeMap::new(),
l1_messages: Vec::new(),
deposit_logs: Vec::new(),
privileged_transactions: Vec::new(),
}
}
}
Expand Down Expand Up @@ -177,11 +177,11 @@ impl StateDiff {
encoded.extend(message_encoded);
}

let deposits_len: u16 = self.deposit_logs.len().try_into()?;
encoded.extend(deposits_len.to_be_bytes());
for deposit in self.deposit_logs.iter() {
let deposit_encoded = deposit.encode();
encoded.extend(deposit_encoded);
let privileged_tx_len: u16 = self.privileged_transactions.len().try_into()?;
encoded.extend(privileged_tx_len.to_be_bytes());
for privileged_tx in self.privileged_transactions.iter() {
let privileged_tx_encoded = privileged_tx.encode();
encoded.extend(privileged_tx_encoded);
}

Ok(Bytes::from(encoded))
Expand Down Expand Up @@ -238,14 +238,14 @@ impl StateDiff {
});
}

let deposit_logs_len = decoder.get_u16()?;
let privileged_transactions_len = decoder.get_u16()?;

let mut deposit_logs = Vec::with_capacity(deposit_logs_len.into());
for _ in 0..deposit_logs_len {
let mut privileged_transactions = Vec::with_capacity(privileged_transactions_len.into());
for _ in 0..privileged_transactions_len {
let address = decoder.get_address()?;
let amount = decoder.get_u256()?;

deposit_logs.push(DepositLog {
privileged_transactions.push(PrivilegedTransactionLog {
address,
amount,
nonce: Default::default(),
Expand All @@ -257,7 +257,7 @@ impl StateDiff {
last_header,
modified_accounts,
l1_messages: l1messages,
deposit_logs,
privileged_transactions,
})
}

Expand Down Expand Up @@ -575,7 +575,7 @@ pub fn prepare_state_diff(
last_header: BlockHeader,
db: &impl VmDatabase,
l1messages: &[L1Message],
deposits: &[PrivilegedL2Transaction],
privileged_transactions: &[PrivilegedL2Transaction],
account_updates: Vec<AccountUpdate>,
) -> Result<StateDiff, StateDiffError> {
let mut modified_accounts = BTreeMap::new();
Expand All @@ -599,9 +599,9 @@ pub fn prepare_state_diff(
version: StateDiff::default().version,
last_header,
l1_messages: l1messages.to_vec(),
deposit_logs: deposits
privileged_transactions: privileged_transactions
.iter()
.map(|tx| DepositLog {
.map(|tx| PrivilegedTransactionLog {
address: match tx.to {
TxKind::Call(address) => address,
TxKind::Create => Address::zero(),
Expand Down
Loading
Loading