From 7d96a91ecb1c4c8a7aafed29baf56dcbedb8fb82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Thu, 4 Dec 2025 22:49:04 +0100 Subject: [PATCH 1/4] Etherlink+Tezlink/Kernel: add Transaction type in ChainConfigTrait --- etherlink/kernel_latest/kernel/src/chains.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/etherlink/kernel_latest/kernel/src/chains.rs b/etherlink/kernel_latest/kernel/src/chains.rs index 9e2d148f156f..d398a09570ca 100644 --- a/etherlink/kernel_latest/kernel/src/chains.rs +++ b/etherlink/kernel_latest/kernel/src/chains.rs @@ -311,6 +311,8 @@ impl ChainHeaderTrait for crate::blueprint_storage::TezBlockHeader { } pub trait ChainConfigTrait: Debug { + type Transaction: Encodable + Decodable + Debug; + type Transactions: TransactionsTrait + Encodable + Decodable + Debug; type BlockInProgress: BlockInProgressTrait; @@ -369,6 +371,8 @@ pub trait ChainConfigTrait: Debug { } impl ChainConfigTrait for EvmChainConfig { + type Transaction = crate::transaction::Transaction; + type Transactions = crate::transaction::Transactions; type BlockInProgress = crate::block_in_progress::EthBlockInProgress; @@ -500,6 +504,7 @@ const TEZLINK_SIMULATION_RESULT_PATH: RefPath = RefPath::assert_from(b"/tezlink/simulation_result"); impl ChainConfigTrait for MichelsonChainConfig { + type Transaction = TezlinkOperation; type Transactions = TezTransactions; type BlockInProgress = TezBlockInProgress; type ChainHeader = TezBlockHeader; -- GitLab From fcd231eebddac589aa13c435828cd025c537c72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Fri, 5 Dec 2025 09:05:12 +0100 Subject: [PATCH 2/4] Etherlink+Tezlink/Kernel: use Vec instead of Transactions --- etherlink/kernel_latest/kernel/src/block.rs | 19 +++-- .../kernel/src/block_in_progress.rs | 8 +- .../kernel_latest/kernel/src/blueprint.rs | 23 +++--- .../kernel/src/blueprint_storage.rs | 54 ++++++------- etherlink/kernel_latest/kernel/src/chains.rs | 81 ++++++------------- etherlink/kernel_latest/kernel/src/inbox.rs | 18 ++--- .../kernel/src/sequencer_blueprint.rs | 3 +- .../kernel_latest/kernel/src/stage_one.rs | 19 ++--- .../kernel_latest/kernel/src/transaction.rs | 8 -- 9 files changed, 93 insertions(+), 140 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/block.rs b/etherlink/kernel_latest/kernel/src/block.rs index 8ef514f4a261..609f62ef29e4 100644 --- a/etherlink/kernel_latest/kernel/src/block.rs +++ b/etherlink/kernel_latest/kernel/src/block.rs @@ -22,7 +22,7 @@ use crate::error::Error; use crate::event::Event; use crate::l2block::L2Block; use crate::storage; -use crate::transaction::{Transaction, Transactions}; +use crate::transaction::Transaction; use crate::upgrade; use crate::upgrade::KernelUpgrade; use crate::Configuration; @@ -230,7 +230,7 @@ pub fn eth_bip_from_blueprint( tick_counter: &TickCounter, next_bip_number: U256, header: EVMBlockHeader, - blueprint: Blueprint, + blueprint: Blueprint, ) -> EthBlockInProgress { let gas_price = crate::gas_price::base_fee_per_gas( host, @@ -593,7 +593,7 @@ mod tests { use crate::chains::TezlinkContent; use crate::chains::TezlinkOperation; use crate::chains::{ - EvmChainConfig, ExperimentalFeatures, MichelsonChainConfig, TezTransactions, + EvmChainConfig, ExperimentalFeatures, MichelsonChainConfig, TEZLINK_SAFE_STORAGE_ROOT_PATH, }; use crate::fees::DA_FEE_PER_BYTE; @@ -604,7 +604,6 @@ mod tests { use crate::transaction::TransactionContent; use crate::transaction::TransactionContent::Ethereum; use crate::transaction::TransactionContent::EthereumDelayed; - use crate::transaction::Transactions; use crate::{retrieve_block_fees, retrieve_chain_id}; use primitive_types::{H160, U256}; use revm_etherlink::helpers::legacy::{alloy_to_u256, h160_to_alloy, u256_to_alloy}; @@ -791,9 +790,9 @@ mod tests { ) } - fn blueprint(transactions: Vec) -> Blueprint { + fn blueprint(transactions: Vec) -> Blueprint { Blueprint { - transactions: Transactions::EthTxs(transactions), + transactions, timestamp: Timestamp::from(0i64), } } @@ -801,7 +800,7 @@ mod tests { fn tezlink_blueprint( operations: Vec, timestamp: Timestamp, - ) -> Blueprint { + ) -> Blueprint { let operations = operations .into_iter() .map(|op| { @@ -811,7 +810,7 @@ mod tests { }) .collect(); Blueprint { - transactions: TezTransactions(operations), + transactions: operations, timestamp, } } @@ -981,7 +980,7 @@ mod tests { fn store_blueprints( host: &mut Host, - blueprints: Vec>, + blueprints: Vec>, ) { for (i, blueprint) in blueprints.into_iter().enumerate() { store_inbox_blueprint_by_number(host, blueprint, U256::from(i)) @@ -1830,7 +1829,7 @@ mod tests { } /// A blueprint that should produce 1 block with an invalid transaction - fn almost_empty_blueprint() -> Blueprint { + fn almost_empty_blueprint() -> Blueprint { let tx_hash = [0; TRANSACTION_HASH_SIZE]; // transaction should be invalid diff --git a/etherlink/kernel_latest/kernel/src/block_in_progress.rs b/etherlink/kernel_latest/kernel/src/block_in_progress.rs index 072256438eef..0f307a415b3b 100644 --- a/etherlink/kernel_latest/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_latest/kernel/src/block_in_progress.rs @@ -13,7 +13,7 @@ use crate::error::TransferError::CumulativeGasUsedOverflow; use crate::gas_price::base_fee_per_gas; use crate::l2block::L2Block; use crate::tick_model; -use crate::transaction::{Transaction, Transactions, Transactions::EthTxs}; +use crate::transaction::Transaction; use alloy_consensus::proofs::ordered_trie_root_with_encoder; use alloy_consensus::EMPTY_ROOT_HASH; use anyhow::Context; @@ -323,16 +323,14 @@ impl EthBlockInProgress { } pub fn from_blueprint( - blueprint: crate::blueprint::Blueprint, + blueprint: crate::blueprint::Blueprint, number: U256, parent_hash: H256, tick_counter: u64, base_fee_per_gas: U256, ) -> EthBlockInProgress { // blueprint is turn into a ring to allow popping from the front - let ring = match blueprint.transactions { - EthTxs(transactions) => transactions.into(), - }; + let ring = blueprint.transactions.into(); EthBlockInProgress::new_with_ticks( number, parent_hash, diff --git a/etherlink/kernel_latest/kernel/src/blueprint.rs b/etherlink/kernel_latest/kernel/src/blueprint.rs index 4d750575c75a..14bb43ddc9b9 100644 --- a/etherlink/kernel_latest/kernel/src/blueprint.rs +++ b/etherlink/kernel_latest/kernel/src/blueprint.rs @@ -6,28 +6,26 @@ // SPDX-License-Identifier: MIT use rlp::{Decodable, DecoderError, Encodable}; -use tezos_ethereum::rlp_helpers::{ - self, append_timestamp, decode_field, decode_timestamp, -}; +use tezos_ethereum::rlp_helpers::{self, append_timestamp, decode_timestamp}; use tezos_smart_rollup_encoding::timestamp::Timestamp; /// The blueprint of a block is a list of transactions. #[derive(PartialEq, Debug, Clone)] -pub struct Blueprint { - pub transactions: Txs, +pub struct Blueprint { + pub transactions: Vec, pub timestamp: Timestamp, } -impl Encodable for Blueprint { +impl Encodable for Blueprint { fn rlp_append(&self, stream: &mut rlp::RlpStream) { stream.begin_list(2); - stream.append(&self.transactions); + stream.append_list(&self.transactions); append_timestamp(stream, self.timestamp); } } -impl Decodable for Blueprint { +impl Decodable for Blueprint { fn decode(decoder: &rlp::Rlp) -> Result { if !decoder.is_list() { return Err(DecoderError::RlpExpectedToBeList); @@ -37,7 +35,8 @@ impl Decodable for Blueprint { } let mut it = decoder.iter(); - let transactions = decode_field(&rlp_helpers::next(&mut it)?, "transactions")?; + let transactions = + rlp_helpers::decode_list(&rlp_helpers::next(&mut it)?, "transactions")?; let timestamp = decode_timestamp(&rlp_helpers::next(&mut it)?)?; Ok(Blueprint { @@ -51,9 +50,7 @@ impl Decodable for Blueprint { mod tests { use super::*; - use crate::transaction::{ - Transaction, TransactionContent::Ethereum, Transactions::EthTxs, - }; + use crate::transaction::{Transaction, TransactionContent::Ethereum}; use primitive_types::{H160, U256}; use rlp::Rlp; use tezos_ethereum::{ @@ -91,7 +88,7 @@ mod tests { #[test] fn test_encode_blueprint() { let proposal = Blueprint { - transactions: EthTxs(vec![dummy_transaction(0), dummy_transaction(1)]), + transactions: vec![dummy_transaction(0), dummy_transaction(1)], timestamp: Timestamp::from(0i64), }; let encoded = proposal.rlp_bytes(); diff --git a/etherlink/kernel_latest/kernel/src/blueprint_storage.rs b/etherlink/kernel_latest/kernel/src/blueprint_storage.rs index 3b4c49a565b2..d2cbc62f10a5 100644 --- a/etherlink/kernel_latest/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_latest/kernel/src/blueprint_storage.rs @@ -4,7 +4,7 @@ // SPDX-License-Identifier: MIT use crate::blueprint::Blueprint; -use crate::chains::{ChainConfigTrait, ChainHeaderTrait, TransactionsTrait}; +use crate::chains::{ChainConfigTrait, ChainHeaderTrait}; use crate::configuration::{Configuration, ConfigurationMode}; use crate::error::{Error, StorageError}; use crate::l2block::L2Block; @@ -13,7 +13,7 @@ use crate::sequencer_blueprint::{ BlueprintWithDelayedHashes, UnsignedSequencerBlueprint, }; use crate::storage::read_last_info_per_level_timestamp; -use crate::transaction::{Transaction, TransactionContent, Transactions}; +use crate::transaction::{Transaction, TransactionContent}; use crate::{delayed_inbox, DelayedInbox}; use primitive_types::{H256, U256}; use rlp::{Decodable, DecoderError, Encodable}; @@ -55,15 +55,15 @@ const EVM_CURRENT_BLOCK_HEADER: RefPath = /// inbox messages. Note that the latter are only to be /// used when the kernel isn't running with a sequencer. #[derive(PartialEq, Debug, Clone)] -enum StoreBlueprint { +enum StoreBlueprint { SequencerChunk(Vec), - InboxBlueprint(Blueprint), + InboxBlueprint(Blueprint), } const SEQUENCER_CHUNK_TAG: u8 = 0; const INBOX_BLUEPRINT_TAG: u8 = 1; -impl Encodable for StoreBlueprint { +impl Encodable for StoreBlueprint { fn rlp_append(&self, stream: &mut rlp::RlpStream) { stream.begin_list(2); match &self { @@ -79,7 +79,7 @@ impl Encodable for StoreBlueprint { } } -impl Decodable for StoreBlueprint { +impl Decodable for StoreBlueprint { fn decode(decoder: &rlp::Rlp) -> Result { if !decoder.is_list() { return Err(DecoderError::RlpExpectedToBeList); @@ -313,9 +313,9 @@ pub fn store_sequencer_blueprint( store_rlp(&store_blueprint, host, &blueprint_chunk_path).map_err(Error::from) } -pub fn store_inbox_blueprint_by_number( +pub fn store_inbox_blueprint_by_number( host: &mut Host, - blueprint: Blueprint, + blueprint: Blueprint, number: U256, ) -> Result<(), Error> { let blueprint_path = blueprint_path(number)?; @@ -327,9 +327,9 @@ pub fn store_inbox_blueprint_by_number( store_rlp(&store_blueprint, host, &chunk_path).map_err(Error::from) } -pub fn store_inbox_blueprint( +pub fn store_inbox_blueprint( host: &mut Host, - blueprint: Blueprint, + blueprint: Blueprint, ) -> anyhow::Result<()> { let number = read_next_blueprint_number(host)?; Ok(store_inbox_blueprint_by_number(host, blueprint, number)?) @@ -347,9 +347,9 @@ pub fn read_next_blueprint_number(host: &Host) -> Result( +pub fn store_forced_blueprint( host: &mut Host, - blueprint: Blueprint, + blueprint: Blueprint, number: U256, ) -> Result<(), Error> { let blueprint_path = blueprint_path(number)?; @@ -488,8 +488,8 @@ const MAXIMUM_SIZE_OF_DELAYED_TRANSACTION: usize = MAX_INPUT_MESSAGE_SIZE; /// Only used for test, as all errors are handled in the same way #[cfg_attr(feature = "benchmark", allow(dead_code))] #[derive(Debug, PartialEq)] -pub enum BlueprintValidity { - Valid(Blueprint), +pub enum BlueprintValidity { + Valid(Blueprint), InvalidParentHash, TimestampFromPast, TimestampFromFuture, @@ -514,7 +514,7 @@ pub fn fetch_hashes_from_delayed_inbox( delayed_hashes: Vec, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, -) -> anyhow::Result<(DelayedTransactionFetchingResult, usize)> { +) -> anyhow::Result<(DelayedTransactionFetchingResult>, usize)> { let mut delayed_txs = vec![]; let mut total_size = current_blueprint_size; for tx_hash in delayed_hashes { @@ -540,7 +540,7 @@ pub fn fetch_hashes_from_delayed_inbox( } } Ok(( - DelayedTransactionFetchingResult::Ok(Transactions::EthTxs(delayed_txs)), + DelayedTransactionFetchingResult::Ok(delayed_txs), total_size, )) } @@ -567,7 +567,7 @@ pub fn fetch_delayed_txs( blueprint_with_hashes: BlueprintWithDelayedHashes, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, -) -> anyhow::Result<(BlueprintValidity, usize)> { +) -> anyhow::Result<(BlueprintValidity, usize)> { let (mut delayed_txs, total_size) = match ChainConfig::fetch_hashes_from_delayed_inbox( host, @@ -616,7 +616,7 @@ fn parse_and_validate_blueprint( max_blueprint_lookahead_in_seconds: i64, parent_chain_header: &ChainConfig::ChainHeader, head_timestamp: Timestamp, -) -> anyhow::Result<(BlueprintValidity, usize)> { +) -> anyhow::Result<(BlueprintValidity, usize)> { // Decode match rlp::decode::(bytes) { Err(e) => Ok((BlueprintValidity::DecoderError(e), bytes.len())), @@ -678,10 +678,10 @@ fn parse_and_validate_blueprint( } } -fn invalidate_blueprint( +fn invalidate_blueprint( host: &mut Host, blueprint_path: &OwnedPath, - error: &BlueprintValidity, + error: &BlueprintValidity, ) -> Result<(), Error> { log!( host, @@ -701,11 +701,11 @@ fn read_all_chunks_and_validate( config: &mut Configuration, previous_chain_header: &ChainConfig::ChainHeader, previous_timestamp: Timestamp, -) -> anyhow::Result<(Option>, usize)> { +) -> anyhow::Result<(Option>, usize)> { let mut chunks = vec![]; let mut size = 0; if nb_chunks > MAXIMUM_NUMBER_OF_CHUNKS { - invalidate_blueprint::<_, ChainConfig::Transactions>( + invalidate_blueprint::<_, ChainConfig::Transaction>( host, blueprint_path, &BlueprintValidity::BlueprintTooLarge, @@ -741,7 +741,7 @@ fn read_all_chunks_and_validate( max_blueprint_lookahead_in_seconds, .. } => { - let validity: (BlueprintValidity, usize) = + let validity: (BlueprintValidity, usize) = parse_and_validate_blueprint::<_, ChainConfig>( host, chunks.concat().as_slice(), @@ -759,7 +759,7 @@ fn read_all_chunks_and_validate( host, Benchmarking, "Number of transactions in blueprint: {}", - blueprint.transactions.number_of_txs() + blueprint.transactions.len() ); Ok((Some(blueprint), size_with_delayed_transactions)) } else { @@ -776,7 +776,7 @@ pub fn read_blueprint( number: U256, previous_timestamp: Timestamp, previous_chain_header: &ChainConfig::ChainHeader, -) -> anyhow::Result<(Option>, usize)> { +) -> anyhow::Result<(Option>, usize)> { let blueprint_path = blueprint_path(number)?; let exists = blueprint_exists(host, &blueprint_path)?; if exists { @@ -789,7 +789,7 @@ pub fn read_blueprint( invalidate_blueprint( host, &blueprint_path, - &BlueprintValidity::::StaleBlueprint, + &BlueprintValidity::>::StaleBlueprint, )?; return Ok((None, 0)); } @@ -825,7 +825,7 @@ pub fn read_blueprint( pub fn read_next_blueprint( host: &mut Host, config: &mut Configuration, -) -> anyhow::Result<(Option>, usize)> { +) -> anyhow::Result<(Option>, usize)> { let (number, previous_timestamp, block_header) = match read_current_block_header::<_, EVMBlockHeader>(host) { Ok(BlockHeader { diff --git a/etherlink/kernel_latest/kernel/src/chains.rs b/etherlink/kernel_latest/kernel/src/chains.rs index d398a09570ca..d7d0297704d6 100644 --- a/etherlink/kernel_latest/kernel/src/chains.rs +++ b/etherlink/kernel_latest/kernel/src/chains.rs @@ -17,7 +17,7 @@ use crate::{ l2block::L2Block, simulation::start_simulation_mode, tick_model::constants::MAXIMUM_GAS_LIMIT, - transaction::{TransactionContent, Transactions::EthTxs}, + transaction::TransactionContent, CHAIN_ID, }; use anyhow::Context; @@ -141,23 +141,6 @@ pub enum ChainConfig { Michelson(MichelsonChainConfig), } -pub trait TransactionsTrait { - fn extend(&mut self, other: Self); - fn number_of_txs(&self) -> usize; -} - -impl TransactionsTrait for crate::transaction::Transactions { - fn extend(&mut self, other: Self) { - let EthTxs(ref mut txs) = self; - let EthTxs(other) = other; - txs.extend(other) - } - fn number_of_txs(&self) -> usize { - let EthTxs(txs) = self; - txs.len() - } -} - const TEZOS_OP_TAG: u8 = 1; const DEPOSIT_OP_TAG: u8 = 2; @@ -243,19 +226,6 @@ impl Decodable for TezlinkContent { #[derive(Debug)] pub struct TezTransactions(pub Vec); -impl TransactionsTrait for TezTransactions { - fn extend(&mut self, other: Self) { - let TezTransactions(ref mut ops) = self; - let TezTransactions(other) = other; - ops.extend(other) - } - - fn number_of_txs(&self) -> usize { - let TezTransactions(operations) = self; - operations.len() - } -} - impl Encodable for TezTransactions { fn rlp_append(&self, stream: &mut rlp::RlpStream) { let Self(operations) = self; @@ -313,8 +283,6 @@ impl ChainHeaderTrait for crate::blueprint_storage::TezBlockHeader { pub trait ChainConfigTrait: Debug { type Transaction: Encodable + Decodable + Debug; - type Transactions: TransactionsTrait + Encodable + Decodable + Debug; - type BlockInProgress: BlockInProgressTrait; type ChainHeader: ChainHeaderTrait + Decodable; @@ -335,10 +303,14 @@ pub trait ChainConfigTrait: Debug { delayed_hashes: Vec, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, - ) -> anyhow::Result<(DelayedTransactionFetchingResult, usize)>; + ) -> anyhow::Result<( + DelayedTransactionFetchingResult>, + usize, + )>; - fn transactions_from_bytes(bytes: Vec>) - -> anyhow::Result; + fn transactions_from_bytes( + bytes: Vec>, + ) -> anyhow::Result>; fn block_in_progress_from_blueprint( &self, @@ -346,7 +318,7 @@ pub trait ChainConfigTrait: Debug { tick_counter: &crate::block::TickCounter, current_block_number: U256, previous_chain_header: Self::ChainHeader, - blueprint: Blueprint, + blueprint: Blueprint, ) -> anyhow::Result; fn read_block_in_progress( @@ -373,8 +345,6 @@ pub trait ChainConfigTrait: Debug { impl ChainConfigTrait for EvmChainConfig { type Transaction = crate::transaction::Transaction; - type Transactions = crate::transaction::Transactions; - type BlockInProgress = crate::block_in_progress::EthBlockInProgress; type ChainHeader = crate::blueprint_storage::EVMBlockHeader; @@ -393,7 +363,7 @@ impl ChainConfigTrait for EvmChainConfig { tick_counter: &crate::block::TickCounter, current_block_number: U256, header: Self::ChainHeader, - blueprint: Blueprint, + blueprint: Blueprint, ) -> anyhow::Result { Ok(eth_bip_from_blueprint( host, @@ -407,10 +377,8 @@ impl ChainConfigTrait for EvmChainConfig { fn transactions_from_bytes( bytes: Vec>, - ) -> anyhow::Result { - Ok(EthTxs(crate::blueprint_storage::transactions_from_bytes( - bytes, - )?)) + ) -> anyhow::Result> { + crate::blueprint_storage::transactions_from_bytes(bytes) } fn fetch_hashes_from_delayed_inbox( @@ -418,8 +386,10 @@ impl ChainConfigTrait for EvmChainConfig { delayed_hashes: Vec, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, - ) -> anyhow::Result<(DelayedTransactionFetchingResult, usize)> - { + ) -> anyhow::Result<( + DelayedTransactionFetchingResult>, + usize, + )> { crate::blueprint_storage::fetch_hashes_from_delayed_inbox( host, delayed_hashes, @@ -505,7 +475,6 @@ const TEZLINK_SIMULATION_RESULT_PATH: RefPath = impl ChainConfigTrait for MichelsonChainConfig { type Transaction = TezlinkOperation; - type Transactions = TezTransactions; type BlockInProgress = TezBlockInProgress; type ChainHeader = TezBlockHeader; @@ -523,9 +492,9 @@ impl ChainConfigTrait for MichelsonChainConfig { _tick_counter: &crate::block::TickCounter, current_block_number: U256, header: Self::ChainHeader, - blueprint: Blueprint, + blueprint: Blueprint, ) -> anyhow::Result { - let TezTransactions(operations) = blueprint.transactions; + let operations = blueprint.transactions; let current_block_number: BlockNumber = current_block_number.try_into()?; Ok(TezBlockInProgress { number: current_block_number, @@ -541,8 +510,10 @@ impl ChainConfigTrait for MichelsonChainConfig { delayed_hashes: Vec, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, - ) -> anyhow::Result<(DelayedTransactionFetchingResult, usize)> - { + ) -> anyhow::Result<( + DelayedTransactionFetchingResult>, + usize, + )> { // By reusing 'fetch_hashes_from_delayed_inbox', Tezlink don't have to implement // the logic to retrieve delayed_inbox items. // @@ -556,7 +527,7 @@ impl ChainConfigTrait for MichelsonChainConfig { )?; Ok(( match delayed { - DelayedTransactionFetchingResult::Ok(EthTxs(txs)) => { + DelayedTransactionFetchingResult::Ok(txs) => { let mut ops = vec![]; for tx in txs.into_iter() { if let TransactionContent::Deposit(deposit) = tx.content { @@ -567,7 +538,7 @@ impl ChainConfigTrait for MichelsonChainConfig { ops.push(operation) } } - DelayedTransactionFetchingResult::Ok(TezTransactions(ops)) + DelayedTransactionFetchingResult::Ok(ops) } DelayedTransactionFetchingResult::BlueprintTooLarge => { DelayedTransactionFetchingResult::BlueprintTooLarge @@ -582,7 +553,7 @@ impl ChainConfigTrait for MichelsonChainConfig { fn transactions_from_bytes( bytes: Vec>, - ) -> anyhow::Result { + ) -> anyhow::Result> { let operations = bytes .iter() .map(|bytes| { @@ -597,7 +568,7 @@ impl ChainConfigTrait for MichelsonChainConfig { }) }) .collect::, error::Error>>()?; - Ok(TezTransactions(operations)) + Ok(operations) } fn read_block_in_progress( diff --git a/etherlink/kernel_latest/kernel/src/inbox.rs b/etherlink/kernel_latest/kernel/src/inbox.rs index 4be490436a3e..97e14248bcd8 100644 --- a/etherlink/kernel_latest/kernel/src/inbox.rs +++ b/etherlink/kernel_latest/kernel/src/inbox.rs @@ -26,7 +26,7 @@ use crate::storage::{ }; use crate::tick_model::constants::TICKS_FOR_BLUEPRINT_INTERCEPT; use crate::tick_model::maximum_ticks_for_sequencer_chunk; -use crate::transaction::{Transaction, TransactionContent, Transactions}; +use crate::transaction::{Transaction, TransactionContent}; use crate::upgrade; use crate::upgrade::*; use crate::Error; @@ -42,7 +42,7 @@ use tezos_smart_rollup_encoding::public_key::PublicKey; #[derive(Debug, PartialEq)] pub struct ProxyInboxContent { - pub transactions: Transactions, + pub transactions: Vec, } pub fn read_input( @@ -467,7 +467,7 @@ pub fn read_proxy_inbox( chain_configuration: &EvmChainConfig, ) -> Result, anyhow::Error> { let mut res = ProxyInboxContent { - transactions: Transactions::EthTxs(vec![]), + transactions: vec![], }; // The mutable variable is used to retrieve the information of whether the // inbox was empty or not. As we consume all the inbox in one go, if the @@ -618,7 +618,7 @@ mod tests { use crate::parsing::RollupType; use crate::storage::*; use crate::tick_model::constants::MAX_ALLOWED_TICKS; - use crate::transaction::{TransactionContent::Ethereum, Transactions::EthTxs}; + use crate::transaction::TransactionContent::Ethereum; use primitive_types::U256; use rlp::Encodable; use std::fmt::Write; @@ -773,7 +773,7 @@ mod tests { tx_hash, content: Ethereum(tx), }]; - assert_eq!(inbox_content.transactions, EthTxs(expected_transactions)); + assert_eq!(inbox_content.transactions, expected_transactions); } #[test] @@ -804,7 +804,7 @@ mod tests { tx_hash, content: Ethereum(tx), }]; - assert_eq!(inbox_content.transactions, EthTxs(expected_transactions)); + assert_eq!(inbox_content.transactions, expected_transactions); } #[test] @@ -1051,7 +1051,7 @@ mod tests { assert_eq!( inbox_content, ProxyInboxContent { - transactions: EthTxs(vec![]), + transactions: vec![], } ); @@ -1074,7 +1074,7 @@ mod tests { tx_hash, content: Ethereum(tx), }]; - assert_eq!(inbox_content.transactions, EthTxs(expected_transactions)); + assert_eq!(inbox_content.transactions, expected_transactions); } #[test] @@ -1135,7 +1135,7 @@ mod tests { tx_hash, content: Ethereum(tx), }]; - assert_eq!(inbox_content.transactions, EthTxs(expected_transactions)); + assert_eq!(inbox_content.transactions, expected_transactions); } #[test] diff --git a/etherlink/kernel_latest/kernel/src/sequencer_blueprint.rs b/etherlink/kernel_latest/kernel/src/sequencer_blueprint.rs index 6f2c4b682917..5f809960bb7f 100644 --- a/etherlink/kernel_latest/kernel/src/sequencer_blueprint.rs +++ b/etherlink/kernel_latest/kernel/src/sequencer_blueprint.rs @@ -264,7 +264,6 @@ mod tests { use crate::blueprint::Blueprint; use crate::transaction::Transaction; use crate::transaction::TransactionContent::Ethereum; - use crate::transaction::Transactions::EthTxs; use primitive_types::{H160, U256}; use tezos_crypto_rs::hash::UnknownSignature; use tezos_ethereum::{ @@ -302,7 +301,7 @@ mod tests { } fn dummy_blueprint_unsigned(chain_id: Option) -> UnsignedSequencerBlueprint { - let transactions = EthTxs(vec![dummy_transaction(0), dummy_transaction(1)]); + let transactions = vec![dummy_transaction(0), dummy_transaction(1)]; let timestamp = Timestamp::from(42); let blueprint = Blueprint { timestamp, diff --git a/etherlink/kernel_latest/kernel/src/stage_one.rs b/etherlink/kernel_latest/kernel/src/stage_one.rs index a8ad22d93e8a..c98d834104ca 100644 --- a/etherlink/kernel_latest/kernel/src/stage_one.rs +++ b/etherlink/kernel_latest/kernel/src/stage_one.rs @@ -17,7 +17,6 @@ use crate::event::Event; use crate::inbox::{read_proxy_inbox, read_sequencer_inbox}; use crate::inbox::{ProxyInboxContent, StageOneStatus}; use crate::storage::read_last_info_per_level_timestamp; -use crate::transaction::Transactions::EthTxs; use anyhow::Ok; use std::ops::Add; use tezos_crypto_rs::hash::ContractKt1Hash; @@ -103,7 +102,7 @@ fn fetch_delayed_transactions( // Create a new blueprint with the timed out transactions let blueprint = Blueprint { - transactions: EthTxs(timed_out), + transactions: timed_out, timestamp, }; // Store the blueprint. @@ -229,9 +228,7 @@ pub fn fetch_blueprints( mod tests { use crate::{ blueprint_storage::EVMBlockHeader, - chains::{ - test_chain_config, test_evm_chain_config, ChainHeaderTrait, TransactionsTrait, - }, + chains::{test_chain_config, test_evm_chain_config, ChainHeaderTrait}, dal_slot_import_signal::{ DalSlotImportSignals, DalSlotIndicesList, DalSlotIndicesOfLevel, UnsignedDalSlotSignals, @@ -445,7 +442,7 @@ mod tests { .0 { Some(Blueprint { transactions, .. }) => { - assert!(transactions.number_of_txs() == 1) + assert!(transactions.len() == 1) } _ => panic!("There should be a blueprint"), } @@ -474,7 +471,7 @@ mod tests { .0 { Some(Blueprint { transactions, .. }) => { - assert!(transactions.number_of_txs() == 1) + assert!(transactions.len() == 1) } _ => panic!("There should be a blueprint"), } @@ -641,7 +638,7 @@ mod tests { None => panic!("There should be an InboxContent"), Some(ProxyInboxContent { transactions, .. }) => assert_eq!( transactions, - EthTxs(vec![]), + vec![], "The proxy shouldn't have read any transaction" ), }; @@ -774,7 +771,7 @@ mod tests { { None => panic!("There should be a blueprint"), Some(Blueprint { transactions, .. }) => - assert_eq!(transactions.number_of_txs(), 0, + assert_eq!(transactions.len(), 0, "The transaction from the delayed bridge entrypoint should have been rejected in proxy mode"), } } @@ -805,7 +802,7 @@ mod tests { { None => panic!("There should be a blueprint"), Some(Blueprint { transactions, .. }) => assert_eq!( - transactions.number_of_txs(), + transactions.len(), 1, "The deposit should have been picked in the blueprint" ), @@ -840,7 +837,7 @@ mod tests { { None => panic!("There should be a blueprint"), Some(Blueprint { transactions, .. }) => assert_eq!( - transactions.number_of_txs(), + transactions.len(), 0, "The deposit shouldn't have been picked in the blueprint as it is invalid" ), diff --git a/etherlink/kernel_latest/kernel/src/transaction.rs b/etherlink/kernel_latest/kernel/src/transaction.rs index 5b2e221ee4f9..f8331d45e4b9 100644 --- a/etherlink/kernel_latest/kernel/src/transaction.rs +++ b/etherlink/kernel_latest/kernel/src/transaction.rs @@ -97,14 +97,6 @@ pub enum Transactions { EthTxs(Vec), } -impl Transactions { - pub fn push(&mut self, tx: Transaction) { - match self { - Self::EthTxs(transactions) => transactions.push(tx), - } - } -} - impl Encodable for Transactions { fn rlp_append(&self, s: &mut rlp::RlpStream) { match self { -- GitLab From cfd6488534a08711b19e63695bab8da175aaaf48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Fri, 5 Dec 2025 09:07:03 +0100 Subject: [PATCH 3/4] Etherlink+Tezlink/Kernel: remove Transactions and TezTransactions --- etherlink/kernel_latest/kernel/src/chains.rs | 26 ------------------- .../kernel_latest/kernel/src/transaction.rs | 24 +---------------- 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/chains.rs b/etherlink/kernel_latest/kernel/src/chains.rs index d7d0297704d6..79ca7b542cbc 100644 --- a/etherlink/kernel_latest/kernel/src/chains.rs +++ b/etherlink/kernel_latest/kernel/src/chains.rs @@ -223,32 +223,6 @@ impl Decodable for TezlinkContent { } } -#[derive(Debug)] -pub struct TezTransactions(pub Vec); - -impl Encodable for TezTransactions { - fn rlp_append(&self, stream: &mut rlp::RlpStream) { - let Self(operations) = self; - stream.begin_list(operations.len()); - for op in operations { - op.rlp_append(stream); - } - } -} - -impl Decodable for TezTransactions { - fn decode(decoder: &rlp::Rlp) -> Result { - if !decoder.is_list() { - return Err(rlp::DecoderError::RlpExpectedToBeList); - } - let operations = decoder - .iter() - .map(|rlp| TezlinkOperation::decode(&rlp)) - .collect::, rlp::DecoderError>>()?; - Ok(TezTransactions(operations)) - } -} - pub trait ChainHeaderTrait { fn hash(&self) -> H256; diff --git a/etherlink/kernel_latest/kernel/src/transaction.rs b/etherlink/kernel_latest/kernel/src/transaction.rs index f8331d45e4b9..84f39f78159b 100644 --- a/etherlink/kernel_latest/kernel/src/transaction.rs +++ b/etherlink/kernel_latest/kernel/src/transaction.rs @@ -17,7 +17,7 @@ use revm_etherlink::precompiles::constants::{ use revm_etherlink::Error; use rlp::{Decodable, DecoderError, Encodable}; use tezos_ethereum::block::BlockFees; -use tezos_ethereum::rlp_helpers::{self, decode_field, decode_tx_hash, next}; +use tezos_ethereum::rlp_helpers::{decode_field, decode_tx_hash, next}; use tezos_ethereum::transaction::{TransactionHash, TransactionType}; use tezos_ethereum::tx_common::EthereumTransactionCommon; use tezos_ethereum::tx_signature::TxSignature; @@ -92,28 +92,6 @@ impl Decodable for TransactionContent { } } -#[derive(PartialEq, Debug, Clone)] -pub enum Transactions { - EthTxs(Vec), -} - -impl Encodable for Transactions { - fn rlp_append(&self, s: &mut rlp::RlpStream) { - match self { - Self::EthTxs(transactions) => { - s.append_list(transactions); - } - } - } -} - -impl Decodable for Transactions { - fn decode(rlp: &rlp::Rlp) -> Result { - let transactions = rlp_helpers::decode_list(rlp, "transactions")?; - Ok(Self::EthTxs(transactions)) - } -} - #[derive(Debug, PartialEq, Clone)] pub struct Transaction { pub tx_hash: TransactionHash, -- GitLab From cc5188cec5f025fca041b29593060386b187be85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Mon, 8 Dec 2025 11:51:57 +0100 Subject: [PATCH 4/4] Etherlink+Tezlink/Kernel: use Vec in DelayedTransactionFetchingResult --- .../kernel/src/blueprint_storage.rs | 6 +++--- etherlink/kernel_latest/kernel/src/chains.rs | 17 +++++------------ 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/blueprint_storage.rs b/etherlink/kernel_latest/kernel/src/blueprint_storage.rs index d2cbc62f10a5..f5104d22b1ce 100644 --- a/etherlink/kernel_latest/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_latest/kernel/src/blueprint_storage.rs @@ -503,8 +503,8 @@ pub enum BlueprintValidity { StaleBlueprint, } -pub enum DelayedTransactionFetchingResult { - Ok(Txs), +pub enum DelayedTransactionFetchingResult { + Ok(Vec), BlueprintTooLarge, DelayedHashMissing(delayed_inbox::Hash), } @@ -514,7 +514,7 @@ pub fn fetch_hashes_from_delayed_inbox( delayed_hashes: Vec, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, -) -> anyhow::Result<(DelayedTransactionFetchingResult>, usize)> { +) -> anyhow::Result<(DelayedTransactionFetchingResult, usize)> { let mut delayed_txs = vec![]; let mut total_size = current_blueprint_size; for tx_hash in delayed_hashes { diff --git a/etherlink/kernel_latest/kernel/src/chains.rs b/etherlink/kernel_latest/kernel/src/chains.rs index 79ca7b542cbc..60015fb72e96 100644 --- a/etherlink/kernel_latest/kernel/src/chains.rs +++ b/etherlink/kernel_latest/kernel/src/chains.rs @@ -277,10 +277,7 @@ pub trait ChainConfigTrait: Debug { delayed_hashes: Vec, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, - ) -> anyhow::Result<( - DelayedTransactionFetchingResult>, - usize, - )>; + ) -> anyhow::Result<(DelayedTransactionFetchingResult, usize)>; fn transactions_from_bytes( bytes: Vec>, @@ -360,10 +357,8 @@ impl ChainConfigTrait for EvmChainConfig { delayed_hashes: Vec, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, - ) -> anyhow::Result<( - DelayedTransactionFetchingResult>, - usize, - )> { + ) -> anyhow::Result<(DelayedTransactionFetchingResult, usize)> + { crate::blueprint_storage::fetch_hashes_from_delayed_inbox( host, delayed_hashes, @@ -484,10 +479,8 @@ impl ChainConfigTrait for MichelsonChainConfig { delayed_hashes: Vec, delayed_inbox: &mut DelayedInbox, current_blueprint_size: usize, - ) -> anyhow::Result<( - DelayedTransactionFetchingResult>, - usize, - )> { + ) -> anyhow::Result<(DelayedTransactionFetchingResult, usize)> + { // By reusing 'fetch_hashes_from_delayed_inbox', Tezlink don't have to implement // the logic to retrieve delayed_inbox items. // -- GitLab