From 08b7a56a974e05f2a7ccac4ff5c106a57770f328 Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 7 Mar 2025 14:38:36 +0100 Subject: [PATCH 1/7] Tezlink/Kernel: Create a tezos block (hashing the content) --- etherlink/kernel_latest/Cargo.lock | 2 + etherlink/kernel_latest/tezos/Cargo.toml | 2 + etherlink/kernel_latest/tezos/src/block.rs | 44 +++++++++++++++------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/etherlink/kernel_latest/Cargo.lock b/etherlink/kernel_latest/Cargo.lock index fb24c1f98942..e5e4336ec542 100644 --- a/etherlink/kernel_latest/Cargo.lock +++ b/etherlink/kernel_latest/Cargo.lock @@ -2471,9 +2471,11 @@ dependencies = [ name = "tezos_tezlink_latest" version = "0.1.0" dependencies = [ + "hex", "primitive-types", "rlp", "tezos-smart-rollup", + "tezos_crypto_rs", "tezos_ethereum_latest", ] diff --git a/etherlink/kernel_latest/tezos/Cargo.toml b/etherlink/kernel_latest/tezos/Cargo.toml index 82f253f4a49e..77246aa24759 100644 --- a/etherlink/kernel_latest/tezos/Cargo.toml +++ b/etherlink/kernel_latest/tezos/Cargo.toml @@ -10,7 +10,9 @@ license = "MIT" [dependencies] +tezos_crypto_rs.workspace = true rlp.workspace = true +hex.workspace = true tezos_ethereum.workspace = true primitive-types.workspace = true diff --git a/etherlink/kernel_latest/tezos/src/block.rs b/etherlink/kernel_latest/tezos/src/block.rs index b1aebca921b9..64725fb67b78 100644 --- a/etherlink/kernel_latest/tezos/src/block.rs +++ b/etherlink/kernel_latest/tezos/src/block.rs @@ -4,6 +4,7 @@ use primitive_types::{H256, U256}; use std::{array::TryFromSliceError, str::FromStr}; +use tezos_crypto_rs::blake2b::digest_256; use tezos_smart_rollup::types::Timestamp; // WIP: This structure will evolve to look like Tezos block @@ -23,6 +24,34 @@ impl TezBlock { .unwrap() } + fn hash(&self) -> H256 { + let Self { + hash: _, + number, + timestamp, + previous_hash, + } = self; + let mut data = number.to_string(); + data.push_str(×tamp.i64().to_string()); + data.push_str(&previous_hash.to_string()); + let encoded_data = hex::encode(&data); + let hashed_data = digest_256(encoded_data.as_bytes()); + H256::from_slice(&hashed_data) + } + + pub fn new(number: U256, timestamp: Timestamp, previous_hash: H256) -> Self { + let block = Self { + hash: H256::zero(), + number, + timestamp, + previous_hash, + }; + Self { + hash: block.hash(), + ..block + } + } + // Encoded size for parameter were taken from this command: // `octez-codec describe block_header binary schema` pub fn to_bytes(&self) -> Vec { @@ -56,13 +85,7 @@ impl TezBlock { let timestamp_array: [u8; 8] = bytes[36..44].try_into()?; let timestamp = Timestamp::from(i64::from_le_bytes(timestamp_array)); - // In a next MR, genesis_block_hash will be replaced by a true hash function - Ok(TezBlock { - number, - hash: TezBlock::genesis_block_hash(), - timestamp, - previous_hash, - }) + Ok(TezBlock::new(number, timestamp, previous_hash)) } } @@ -84,12 +107,7 @@ mod tests { let number = U256::one(); let timestamp = Timestamp::from(0); let previous_hash = TezBlock::genesis_block_hash(); - TezBlock { - number, - hash: TezBlock::genesis_block_hash(), - timestamp, - previous_hash, - } + TezBlock::new(number, timestamp, previous_hash) } #[test] -- GitLab From 83ba222b2d82e2ffb654590ebe00ae39a46bc073 Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 7 Mar 2025 15:02:55 +0100 Subject: [PATCH 2/7] Tezlink/Kernel: Build tezos block in kernel --- etherlink/kernel_latest/kernel/src/block.rs | 37 +++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/block.rs b/etherlink/kernel_latest/kernel/src/block.rs index b1a3648e02bf..cd1359ccc742 100644 --- a/etherlink/kernel_latest/kernel/src/block.rs +++ b/etherlink/kernel_latest/kernel/src/block.rs @@ -249,14 +249,18 @@ fn compute( #[allow(clippy::large_enum_variant)] pub enum BlockInProgress { Etherlink(EthBlockInProgress), - Tezlink(U256, Timestamp), + Tezlink { + number: U256, + timestamp: Timestamp, + previous_hash: H256, + }, } impl BlockInProgress { pub fn number(&self) -> U256 { match self { Self::Etherlink(bip) => bip.number, - Self::Tezlink(n, _) => *n, + Self::Tezlink { number, .. } => *number, } } } @@ -330,11 +334,12 @@ fn next_bip_from_blueprints( BlockInProgress::Etherlink(bip), ))) } - (ChainConfig::Michelson(_), ChainHeader::Tez(_)) => { - Ok(BlueprintParsing::Next(Box::new(BlockInProgress::Tezlink( - next_bip_number, - blueprint.timestamp, - )))) + (ChainConfig::Michelson(_), ChainHeader::Tez(header)) => { + Ok(BlueprintParsing::Next(Box::new(BlockInProgress::Tezlink { + number: next_bip_number, + timestamp: blueprint.timestamp, + previous_hash: header.hash, + }))) } (_, _) => { log!( @@ -580,21 +585,25 @@ pub fn produce( &chain_config.evm_config, ) } - (ChainConfig::Michelson(_), BlockInProgress::Tezlink(number, timestamp)) => { + ( + ChainConfig::Michelson(_), + BlockInProgress::Tezlink { + number, + timestamp, + previous_hash, + }, + ) => { log!( safe_host, Debug, "Computing the BlockInProgress for Tezlink at level {}", number ); + + let tezblock = TezBlock::new(number, timestamp, previous_hash); Ok(BlockComputationResult::Finished { included_delayed_transactions: vec![], - block: L2Block::Tezlink(TezBlock { - number, - hash: TezBlock::genesis_block_hash(), - timestamp, - previous_hash: TezBlock::genesis_block_hash(), - }), + block: L2Block::Tezlink(tezblock), }) } (_, _) => { -- GitLab From dd4ff145db80be1a9f8091db0e618e133ee6291b Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 7 Mar 2025 16:37:21 +0100 Subject: [PATCH 3/7] Etherlink/Kernel/Tezlink: Introducing functions for L2block Introducing functions that will be useful for the next commit. For now mark all the implementation as dead_code --- etherlink/kernel_latest/kernel/src/l2block.rs | 88 ++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/l2block.rs b/etherlink/kernel_latest/kernel/src/l2block.rs index c7c37e07fbef..4a2cf1f8e94d 100644 --- a/etherlink/kernel_latest/kernel/src/l2block.rs +++ b/etherlink/kernel_latest/kernel/src/l2block.rs @@ -1,7 +1,13 @@ -use tezos_ethereum::block::EthBlock; +use primitive_types::{H256, U256}; +use rlp::DecoderError; +use tezos_ethereum::{block::EthBlock, rlp_helpers::VersionedEncoding}; +use tezos_smart_rollup::types::Timestamp; use tezos_tezlink::block::TezBlock; -use crate::blueprint_storage::{BlockHeader, ChainHeader}; +use crate::{ + blueprint_storage::{BlockHeader, ChainHeader}, + chains::ChainFamily, +}; #[derive(PartialEq, Debug)] pub enum L2Block { @@ -13,11 +19,89 @@ pub enum L2Block { Tezlink(TezBlock), } +#[allow(dead_code)] impl L2Block { + pub fn number(&self) -> U256 { + match self { + Self::Etherlink(block) => block.number, + Self::Tezlink(block) => block.number, + } + } + + pub fn timestamp(&self) -> Timestamp { + match self { + Self::Etherlink(block) => block.timestamp, + Self::Tezlink(block) => block.timestamp, + } + } + + pub fn number_of_transactions(&self) -> usize { + match &self { + Self::Etherlink(block) => block.transactions.len(), + Self::Tezlink(_) => 0, + } + } + + #[cfg(test)] + pub fn first_transaction_hash( + &self, + ) -> Option<&tezos_ethereum::transaction::TransactionHash> { + match &self { + Self::Etherlink(block) => block.transactions.first(), + Self::Tezlink(_) => None, + } + } + + pub fn gas_used(&self) -> U256 { + match self { + Self::Etherlink(block) => block.gas_used, + Self::Tezlink(_) => U256::zero(), + } + } + pub fn header(self) -> BlockHeader { match self { Self::Etherlink(block) => (*block).into(), Self::Tezlink(block) => block.into(), } } + + pub fn hash(&self) -> H256 { + match self { + Self::Etherlink(block) => block.hash, + Self::Tezlink(block) => block.hash, + } + } + + pub fn to_bytes(&self) -> Vec { + match self { + Self::Etherlink(block) => block.to_bytes(), + Self::Tezlink(block) => block.to_bytes(), + } + } + + #[cfg(test)] + pub fn base_fee_per_gas(&self) -> U256 { + use crate::fees::MINIMUM_BASE_FEE_PER_GAS; + match self { + Self::Etherlink(block) => block.base_fee_per_gas, + Self::Tezlink(_) => MINIMUM_BASE_FEE_PER_GAS.into(), + } + } + + pub fn try_from_bytes( + chain_family: &ChainFamily, + bytes: &[u8], + ) -> Result { + match chain_family { + ChainFamily::Evm => { + Ok(L2Block::Etherlink(Box::new(EthBlock::from_bytes(bytes)?))) + } + ChainFamily::Michelson => { + let block = TezBlock::try_from_bytes(bytes) + .map_err(|_| DecoderError::Custom("Binary decoding error"))?; + Ok(L2Block::Tezlink(block)) + } + } + } } -- GitLab From c8226a6fdc3122eb8eae3295abbd6ad1404191f4 Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 7 Mar 2025 16:43:02 +0100 Subject: [PATCH 4/7] Etherlink/Kernel/Tezlink: Use L2Block instead of EthBlock when storing a block Use functions that were marked as dead code in the previous commit --- etherlink/kernel_latest/kernel/src/block.rs | 26 ++++++------ .../kernel/src/block_in_progress.rs | 4 +- .../kernel_latest/kernel/src/block_storage.rs | 42 ++++++++++--------- .../kernel/src/blueprint_storage.rs | 10 +++++ etherlink/kernel_latest/kernel/src/inbox.rs | 11 ++++- etherlink/kernel_latest/kernel/src/lib.rs | 6 ++- .../kernel_latest/kernel/src/migration.rs | 2 +- .../kernel_latest/kernel/src/simulation.rs | 18 +++++++- 8 files changed, 79 insertions(+), 40 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/block.rs b/etherlink/kernel_latest/kernel/src/block.rs index cd1359ccc742..ce57dac7ad97 100644 --- a/etherlink/kernel_latest/kernel/src/block.rs +++ b/etherlink/kernel_latest/kernel/src/block.rs @@ -416,7 +416,7 @@ fn compute_bip( .context("Failed to finalize the block in progress")?; Ok(BlockComputationResult::Finished { included_delayed_transactions, - block: L2Block::Etherlink(Box::new(new_block)), + block: new_block, }) } } @@ -676,6 +676,7 @@ mod tests { use crate::blueprint_storage::read_next_blueprint; use crate::blueprint_storage::store_inbox_blueprint; use crate::blueprint_storage::store_inbox_blueprint_by_number; + use crate::chains::ChainFamily; use crate::chains::MichelsonChainConfig; use crate::fees::DA_FEE_PER_BYTE; use crate::fees::MINIMUM_BASE_FEE_PER_GAS; @@ -958,7 +959,7 @@ mod tests { } fn assert_current_block_reading_validity(host: &mut Host) { - match block_storage::read_current(host) { + match block_storage::read_current(host, &ChainFamily::Evm) { Ok(_) => (), Err(e) => { panic!("Block reading failed: {:?}\n", e) @@ -1360,11 +1361,12 @@ mod tests { let new_number_of_blocks_indexed = blocks_index.length(&host).unwrap(); - let current_block_hash = block_storage::read_current(&mut host) - .unwrap() - .hash - .as_bytes() - .to_vec(); + let current_block_hash = + block_storage::read_current(&mut host, &ChainFamily::Evm) + .unwrap() + .hash() + .as_bytes() + .to_vec(); assert_eq!(number_of_blocks_indexed + 1, new_number_of_blocks_indexed); @@ -1963,12 +1965,10 @@ mod tests { produce(&mut host, &mut configuration, None, None).expect("Should have produced"); - let block = - block_storage::read_current(&mut host).expect("Should have found a block"); - let failed_loop_hash = block - .transactions - .first() - .expect("There should have been a transaction"); + let block = block_storage::read_current(&mut host, &ChainFamily::Evm) + .expect("Should have found a block"); + let transaction = block.first_transaction_hash(); + let failed_loop_hash = transaction.expect("There should have been a transaction"); let failed_loop_status = storage::read_transaction_receipt_status(&mut host, failed_loop_hash) .expect("There should have been a receipt"); diff --git a/etherlink/kernel_latest/kernel/src/block_in_progress.rs b/etherlink/kernel_latest/kernel/src/block_in_progress.rs index 173a9e721d01..7bb71fa27489 100644 --- a/etherlink/kernel_latest/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_latest/kernel/src/block_in_progress.rs @@ -10,6 +10,7 @@ use crate::block_storage; use crate::error::Error; use crate::error::TransferError::CumulativeGasUsedOverflow; use crate::gas_price::base_fee_per_gas; +use crate::l2block::L2Block; use crate::storage::{self, object_path, receipt_path}; use crate::tick_model; use crate::transaction::{Transaction, Transactions::EthTxs, Transactions::TezTxs}; @@ -449,7 +450,7 @@ impl EthBlockInProgress { self, host: &mut Host, block_constants: &BlockConstants, - ) -> Result { + ) -> Result { let state_root = Self::safe_store_get_hash(host, &EVM_ACCOUNTS_PATH)?; let receipts_root = self.receipts_root(host, &self.previous_receipts_root)?; let transactions_root = @@ -472,6 +473,7 @@ impl EthBlockInProgress { block_constants, base_fee_per_gas, ); + let new_block = L2Block::Etherlink(Box::new(new_block)); block_storage::store_current(host, &new_block) .context("Failed to store the current block")?; Ok(new_block) diff --git a/etherlink/kernel_latest/kernel/src/block_storage.rs b/etherlink/kernel_latest/kernel/src/block_storage.rs index 22586cbdd07d..88f560398a8b 100644 --- a/etherlink/kernel_latest/kernel/src/block_storage.rs +++ b/etherlink/kernel_latest/kernel/src/block_storage.rs @@ -3,8 +3,6 @@ // SPDX-License-Identifier: MIT use primitive_types::{H256, U256}; -use tezos_ethereum::block::EthBlock; -use tezos_ethereum::rlp_helpers::VersionedEncoding; use tezos_evm_logging::{ log, Level::{Debug, Info}, @@ -16,9 +14,9 @@ use tezos_smart_rollup_host::path::OwnedPath; use tezos_smart_rollup_host::path::RefPath; use tezos_storage::{read_h256_be, read_u256_le, write_h256_be, write_u256_le}; -use crate::migration::allow_path_not_found; use crate::storage::EVM_TRANSACTIONS_OBJECTS; use crate::storage::EVM_TRANSACTIONS_RECEIPTS; +use crate::{chains::ChainFamily, l2block::L2Block, migration::allow_path_not_found}; mod path { use super::*; @@ -52,45 +50,45 @@ fn store_current_hash(host: &mut impl Runtime, hash: H256) -> anyhow::Result<()> fn store_block( host: &mut impl Runtime, - block: &EthBlock, + block: &L2Block, index_block: bool, ) -> anyhow::Result<()> { if index_block { // Index the block, /evm/world_state/indexes/blocks/ points to // the block hash. let index = IndexableStorage::new(&path::INDEXES)?; - index.push_value(host, block.hash.as_bytes())?; + index.push_value(host, block.hash().as_bytes())?; } - let path = path::path(block.hash)?; + let path = path::path(block.hash())?; let bytes = block.to_bytes(); Ok(host.store_write_all(&path, &bytes)?) } fn store_current_index_or_not( host: &mut impl Runtime, - block: &EthBlock, + block: &L2Block, index_block: bool, ) -> anyhow::Result<()> { - store_current_number(host, block.number)?; - store_current_hash(host, block.hash)?; + store_current_number(host, block.number())?; + store_current_hash(host, block.hash())?; store_block(host, block, index_block)?; log!( host, Info, "Storing block {} at {} containing {} transaction(s) for {} gas used.", - block.number, - block.timestamp, - block.transactions.len(), - U256::to_string(&block.gas_used) + block.number(), + block.timestamp(), + block.number_of_transactions(), + U256::to_string(&block.gas_used()) ); Ok(()) } -pub fn store_current(host: &mut impl Runtime, block: &EthBlock) -> anyhow::Result<()> { +pub fn store_current(host: &mut impl Runtime, block: &L2Block) -> anyhow::Result<()> { store_current_index_or_not(host, block, true) } -pub fn restore_current(host: &mut impl Runtime, block: &EthBlock) -> anyhow::Result<()> { +pub fn restore_current(host: &mut impl Runtime, block: &L2Block) -> anyhow::Result<()> { store_current_index_or_not(host, block, false) } @@ -102,17 +100,23 @@ pub fn read_current_hash(host: &impl Runtime) -> anyhow::Result { read_h256_be(host, &path::CURRENT_HASH) } -pub fn read_current(host: &mut impl Runtime) -> anyhow::Result { +pub fn read_current( + host: &mut impl Runtime, + chain_family: &ChainFamily, +) -> anyhow::Result { let hash = read_current_hash(host)?; let block_path = path::path(hash)?; let bytes = &host.store_read_all(&block_path)?; - let block_from_bytes = EthBlock::from_bytes(bytes)?; + let block_from_bytes = L2Block::try_from_bytes(chain_family, bytes)?; Ok(block_from_bytes) } -pub fn garbage_collect_blocks(host: &mut impl Runtime) -> anyhow::Result<()> { +pub fn garbage_collect_blocks( + host: &mut impl Runtime, + chain_family: &ChainFamily, +) -> anyhow::Result<()> { log!(host, Debug, "Garbage collecting blocks."); - if let Ok(block) = read_current(host) { + if let Ok(block) = read_current(host, chain_family) { // The kernel needs the current block to process the next one. Therefore // we garbage collect everything but the current block. host.store_delete(&path::PATH)?; diff --git a/etherlink/kernel_latest/kernel/src/blueprint_storage.rs b/etherlink/kernel_latest/kernel/src/blueprint_storage.rs index 2e325dde0812..1760b5998516 100644 --- a/etherlink/kernel_latest/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_latest/kernel/src/blueprint_storage.rs @@ -8,6 +8,7 @@ use crate::blueprint::Blueprint; use crate::chains::ChainFamily; use crate::configuration::{Configuration, ConfigurationMode}; use crate::error::{Error, StorageError}; +use crate::l2block::L2Block; use crate::sequencer_blueprint::{ BlueprintWithDelayedHashes, UnsignedSequencerBlueprint, }; @@ -190,6 +191,15 @@ impl From for BlockHeader { } } +impl From for BlockHeader { + fn from(value: L2Block) -> Self { + match value { + L2Block::Etherlink(block) => (*block).into(), + L2Block::Tezlink(block) => block.into(), + } + } +} + pub fn blueprint_path(number: U256) -> Result { let number_as_path: Vec = format!("/{}", number).into(); // The key being an integer value, it will always be valid as a path, diff --git a/etherlink/kernel_latest/kernel/src/inbox.rs b/etherlink/kernel_latest/kernel/src/inbox.rs index 71c6a3d049d2..ebc6e3daf197 100644 --- a/etherlink/kernel_latest/kernel/src/inbox.rs +++ b/etherlink/kernel_latest/kernel/src/inbox.rs @@ -379,6 +379,7 @@ pub fn handle_input( host: &mut impl Runtime, input: Input, inbox_content: &mut Mode::Inbox, + chain_family: &ChainFamily, garbage_collect_blocks: bool, ) -> anyhow::Result<()> { match input { @@ -392,7 +393,7 @@ pub fn handle_input( // New inbox level detected, remove all previous events. clear_events(host)?; if garbage_collect_blocks { - crate::block_storage::garbage_collect_blocks(host)?; + crate::block_storage::garbage_collect_blocks(host, chain_family)?; } store_last_info_per_level_timestamp(host, info.info.predecessor_timestamp)?; store_l1_level(host, info.level)? @@ -463,7 +464,13 @@ fn read_and_dispatch_input( Ok(ReadStatus::FinishedIgnore) } InputResult::Input(input) => { - handle_input(host, input, res, garbage_collect_blocks)?; + handle_input( + host, + input, + res, + &chain_configuration.get_chain_family(), + garbage_collect_blocks, + )?; Ok(ReadStatus::Ongoing) } } diff --git a/etherlink/kernel_latest/kernel/src/lib.rs b/etherlink/kernel_latest/kernel/src/lib.rs index 13c702d711a2..37462d3effa5 100644 --- a/etherlink/kernel_latest/kernel/src/lib.rs +++ b/etherlink/kernel_latest/kernel/src/lib.rs @@ -169,9 +169,11 @@ fn retrieve_base_fee_per_gas( host: &mut Host, minimum_base_fee_per_gas: U256, ) -> U256 { - match block_storage::read_current(host) { + use chains::ChainFamily; + + match block_storage::read_current(host, &ChainFamily::Evm) { Ok(current_block) => { - let current_base_fee_per_gas = current_block.base_fee_per_gas; + let current_base_fee_per_gas = current_block.base_fee_per_gas(); if current_base_fee_per_gas < minimum_base_fee_per_gas { minimum_base_fee_per_gas } else { diff --git a/etherlink/kernel_latest/kernel/src/migration.rs b/etherlink/kernel_latest/kernel/src/migration.rs index dcd6cb263da7..42d8b3f17080 100644 --- a/etherlink/kernel_latest/kernel/src/migration.rs +++ b/etherlink/kernel_latest/kernel/src/migration.rs @@ -271,7 +271,7 @@ fn migrate_to( } StorageVersion::V27 => { // Initialize the next_blueprint_info field - match block_storage::read_current(host) { + match block_storage::read_current(host, &crate::chains::ChainFamily::Evm) { Ok(block) => { store_current_block_header(host, &block.into())?; Ok(MigrationStatus::Done) diff --git a/etherlink/kernel_latest/kernel/src/simulation.rs b/etherlink/kernel_latest/kernel/src/simulation.rs index 155b2d1f356f..a2b126ad92ff 100644 --- a/etherlink/kernel_latest/kernel/src/simulation.rs +++ b/etherlink/kernel_latest/kernel/src/simulation.rs @@ -8,8 +8,12 @@ // Module containing most Simulation related code, in one place, to be deleted // when the proxy node simulates directly +use std::borrow::Cow; + use crate::block_storage; +use crate::chains::ChainFamily; use crate::fees::simulation_add_gas_for_fees; +use crate::l2block::L2Block; use crate::storage::{ read_last_info_per_level_timestamp, read_maximum_allowed_ticks, read_sequencer_pool_address, read_tracer_input, @@ -395,8 +399,8 @@ impl Evaluation { } } - let constants = match block_storage::read_current(host) { - Ok(block) => { + let constants = match block_storage::read_current(host, &ChainFamily::Evm) { + Ok(L2Block::Etherlink(block)) => { // Timestamp is taken from the simulation caller if provided. // If the timestamp is missing, because of an older evm-node, // default to last block timestamp. @@ -420,6 +424,16 @@ impl Evaluation { prevrandao: None, } } + Ok(L2Block::Tezlink(_block)) => { + log!( + host, + Fatal, + "Read a tezlink block when expecting an etherlink block" + ); + return Err(Error::Simulation(EthereumError::WrappedError(Cow::from( + "Should not have found a Tezlink block", + )))); + } Err(_) => { // Timestamp is taken from the simulation caller if provided. // If the timestamp is missing, because of an older evm-node, -- GitLab From 82dc5831273d4cf9a5aa85efec8ffe6828db24c6 Mon Sep 17 00:00:00 2001 From: arnaud Date: Mon, 10 Mar 2025 13:44:53 +0100 Subject: [PATCH 5/7] Etherlink/Kernel/Tezlink: Read and write tezlink hash so we can store th current block for tezlink --- etherlink/kernel_latest/kernel/src/block.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/block.rs b/etherlink/kernel_latest/kernel/src/block.rs index ce57dac7ad97..aca20ded4773 100644 --- a/etherlink/kernel_latest/kernel/src/block.rs +++ b/etherlink/kernel_latest/kernel/src/block.rs @@ -18,12 +18,12 @@ use crate::delayed_inbox::DelayedInbox; use crate::error::Error; use crate::event::Event; use crate::l2block::L2Block; -use crate::storage; use crate::transaction::Transaction; use crate::upgrade; use crate::upgrade::KernelUpgrade; use crate::Configuration; use crate::{block_in_progress, tick_model}; +use crate::{block_storage, storage}; use anyhow::Context; use block_in_progress::EthBlockInProgress; use evm::Config; @@ -601,9 +601,12 @@ pub fn produce( ); let tezblock = TezBlock::new(number, timestamp, previous_hash); + let new_block = L2Block::Tezlink(tezblock); + block_storage::store_current(&mut safe_host, &new_block) + .context("Failed to store the current block")?; Ok(BlockComputationResult::Finished { included_delayed_transactions: vec![], - block: L2Block::Tezlink(tezblock), + block: new_block, }) } (_, _) => { -- GitLab From 63f8bbad9c2522d4506b9498526cbb95e5d0227c Mon Sep 17 00:00:00 2001 From: arnaud Date: Mon, 10 Mar 2025 13:54:33 +0100 Subject: [PATCH 6/7] Tezlink/Kernel: Remove allow dead_code --- etherlink/kernel_latest/kernel/src/l2block.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/etherlink/kernel_latest/kernel/src/l2block.rs b/etherlink/kernel_latest/kernel/src/l2block.rs index 4a2cf1f8e94d..0b54131da712 100644 --- a/etherlink/kernel_latest/kernel/src/l2block.rs +++ b/etherlink/kernel_latest/kernel/src/l2block.rs @@ -19,7 +19,6 @@ pub enum L2Block { Tezlink(TezBlock), } -#[allow(dead_code)] impl L2Block { pub fn number(&self) -> U256 { match self { -- GitLab From 8058fa62d3c80dc39e2b7bafe1b5ab67335d085e Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 7 Mar 2025 17:46:51 +0100 Subject: [PATCH 7/7] Tezlink/Kernel: Test that we can produce block for tezlink --- etherlink/kernel_latest/kernel/src/block.rs | 24 ++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/block.rs b/etherlink/kernel_latest/kernel/src/block.rs index aca20ded4773..1baa7fd9147d 100644 --- a/etherlink/kernel_latest/kernel/src/block.rs +++ b/etherlink/kernel_latest/kernel/src/block.rs @@ -675,6 +675,7 @@ pub fn produce( mod tests { use super::*; use crate::block_storage; + use crate::block_storage::read_current_number; use crate::blueprint::Blueprint; use crate::blueprint_storage::read_next_blueprint; use crate::blueprint_storage::store_inbox_blueprint; @@ -971,18 +972,31 @@ mod tests { } #[test] - // Test if tezlink block production doesn't panic + // Test if tezlink block production works fn test_produce_tezlink_block() { let mut host = MockKernelHost::default(); let mut config = dummy_tez_configuration(); - store_blueprints(&mut host, vec![tezlink_blueprint()]); + store_blueprints( + &mut host, + vec![ + tezlink_blueprint(), + tezlink_blueprint(), + tezlink_blueprint(), + ], + ); + produce(&mut host, &mut config, None, None) + .expect("The block production should have succeeded."); + produce(&mut host, &mut config, None, None) + .expect("The block production should have succeeded."); + produce(&mut host, &mut config, None, None) + .expect("The block production should have succeeded."); let computation = produce(&mut host, &mut config, None, None) - .expect("The block production failed."); - - assert_eq!(computation, ComputationResult::RebootNeeded) + .expect("The block production should have succeeded."); + assert_eq!(ComputationResult::Finished, computation); + assert_eq!(U256::from(2), read_current_number(&host).unwrap()); } #[test] -- GitLab