From 53c6efd72a0011bcb9c7675d6dd5b656e5689c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Fri, 6 Dec 2024 13:31:20 +0100 Subject: [PATCH 01/31] Etherlink/Kernel: use blueprint number to check blueprint validity This commit changes a condition for blueprint validity from - number of considered blueprint > number of last applied block to - number of considered blueprint >= number of next expected blueprint It is currently semantically equivalent because the number of next expected blueprint is the successor of the number of last applied block but in a latter commit we will store the number of next expected blueprint outside of the world state. --- etherlink/kernel_evm/kernel/src/dal.rs | 34 ++++++++++--------- etherlink/kernel_evm/kernel/src/inbox.rs | 11 +++--- etherlink/kernel_evm/kernel/src/parsing.rs | 39 +++++++++++----------- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/dal.rs b/etherlink/kernel_evm/kernel/src/dal.rs index 47194ee950ad..fdda9fa33e6e 100644 --- a/etherlink/kernel_evm/kernel/src/dal.rs +++ b/etherlink/kernel_evm/kernel/src/dal.rs @@ -73,10 +73,13 @@ fn rlp_length(data: &[u8]) -> Result { fn parse_unsigned_sequencer_blueprint( host: &mut Host, bytes: &[u8], - head_level: &Option, + next_blueprint_number: &U256, ) -> (Option, usize) { if let Result::Ok(chunk_length) = rlp_length(bytes) { - match parse_unsigned_blueprint_chunk(&bytes[..chunk_length], head_level) { + match parse_unsigned_blueprint_chunk( + &bytes[..chunk_length], + next_blueprint_number, + ) { SequencerBlueprintRes::SequencerBlueprint(unsigned_chunk) => ( Some(ParsedInput::UnsignedSequencerBlueprint(unsigned_chunk)), chunk_length + TAG_SIZE, @@ -97,7 +100,7 @@ fn parse_unsigned_sequencer_blueprint( fn parse_input( host: &mut Host, bytes: &[u8], - head_level: &Option, + next_blueprint_number: &U256, ) -> (Option, usize) { // The expected format is: @@ -107,7 +110,7 @@ fn parse_input( DAL_PADDING_TAG => (Some(ParsedInput::Padding), TAG_SIZE), DAL_BLUEPRINT_INPUT_TAG => { let bytes = &bytes[TAG_SIZE..]; - parse_unsigned_sequencer_blueprint(host, bytes, head_level) + parse_unsigned_sequencer_blueprint(host, bytes, next_blueprint_number) } invalid_tag => { log!( @@ -125,7 +128,7 @@ fn parse_input( fn parse_slot( host: &mut Host, slot: &[u8], - head_level: &Option, + next_blueprint_number: &U256, ) -> Vec { // The format of a dal slot is // tagged chunk | tagged chunk | .. | padding @@ -145,7 +148,8 @@ fn parse_slot( if offset >= slot.len() { return buffer; }; - let (next_input, length) = parse_input(host, &slot[offset..], head_level); + let (next_input, length) = + parse_input(host, &slot[offset..], next_blueprint_number); match next_input { None => return buffer, // Once an unparsable input has been read, @@ -165,7 +169,7 @@ fn parse_slot( pub fn fetch_and_parse_sequencer_blueprint_from_dal( host: &mut Host, params: &RollupDalParameters, - head_level: &Option, + next_blueprint_number: &U256, slot_index: u8, published_level: u32, ) -> Option> { @@ -182,7 +186,7 @@ pub fn fetch_and_parse_sequencer_blueprint_from_dal( // size, we need to remove this padding before parsing the // slot as a blueprint chunk. - let chunks = parse_slot(host, &slot, head_level); + let chunks = parse_slot(host, &slot, next_blueprint_number); log!( host, Debug, @@ -358,7 +362,7 @@ pub mod tests { let chunks_from_slot = fetch_and_parse_sequencer_blueprint_from_dal( &mut host, &dal_parameters, - &None, + &0.into(), 0, published_level, ); @@ -398,7 +402,7 @@ pub mod tests { let chunks_from_slot = fetch_and_parse_sequencer_blueprint_from_dal( &mut host, &dal_parameters, - &None, + &0.into(), 0, published_level, ); @@ -464,7 +468,7 @@ pub mod tests { let chunks_from_slot = fetch_and_parse_sequencer_blueprint_from_dal( &mut host, &dal_parameters, - &None, + &0.into(), 0, published_level, ); @@ -542,7 +546,7 @@ pub mod tests { let chunks_from_slot = fetch_and_parse_sequencer_blueprint_from_dal( &mut host, &dal_parameters, - &None, + &0.into(), 0, published_level, ); @@ -556,7 +560,7 @@ pub mod tests { let chunks_from_slot = fetch_and_parse_sequencer_blueprint_from_dal( &mut host, &dal_parameters, - &None, + &0.into(), 0, published_level, ); @@ -576,7 +580,7 @@ pub mod tests { fn test_parse_slot_with_blueprints_from_the_past() { let mut host = MockKernelHost::default(); - let head_level = Some(2.into()); + let next_blueprint_number = 3.into(); let chunks = chunk_blueprint_range(0, 5); let expected_chunks = chunk_blueprint_range(3, 5); @@ -590,7 +594,7 @@ pub mod tests { let chunks_from_slot = fetch_and_parse_sequencer_blueprint_from_dal( &mut host, &dal_parameters, - &head_level, + &next_blueprint_number, 0, published_level, ); diff --git a/etherlink/kernel_evm/kernel/src/inbox.rs b/etherlink/kernel_evm/kernel/src/inbox.rs index 8cf2def8fe40..9a28eb3b6d34 100644 --- a/etherlink/kernel_evm/kernel/src/inbox.rs +++ b/etherlink/kernel_evm/kernel/src/inbox.rs @@ -359,8 +359,8 @@ impl InputHandler for SequencerInput { }) => { log!(host, Debug, "Importing {} DAL signals", &signals.0.len()); let params = host.reveal_dal_parameters(); - let head_level: Option = - crate::block_storage::read_current_number(host).ok(); + let next_blueprint_number: U256 = + crate::blueprint_storage::read_next_blueprint_number(host)?; for signal in signals.0.iter() { let published_level = signal.published_level; let slot_indices = &signal.slot_indices; @@ -376,7 +376,7 @@ impl InputHandler for SequencerInput { fetch_and_parse_sequencer_blueprint_from_dal( host, ¶ms, - &head_level, + &next_blueprint_number, *slot_index, published_level, ) @@ -684,7 +684,8 @@ pub fn read_sequencer_inbox( // during this kernel run. let mut inbox_is_empty = true; let limits = fetch_limits(host); - let head_level: Option = crate::block_storage::read_current_number(host).ok(); + let next_blueprint_number: U256 = + crate::blueprint_storage::read_next_blueprint_number(host)?; let mut parsing_context = SequencerParsingContext { sequencer, delayed_bridge, @@ -693,7 +694,7 @@ pub fn read_sequencer_inbox( .saturating_sub(TICKS_FOR_BLUEPRINT_INTERCEPT), dal_configuration: dal, buffer_transaction_chunks: None, - head_level, + next_blueprint_number, }; loop { // Checks there will be enough ticks to handle at least another chunk of diff --git a/etherlink/kernel_evm/kernel/src/parsing.rs b/etherlink/kernel_evm/kernel/src/parsing.rs index 813bcc848aab..98997aab8a1c 100644 --- a/etherlink/kernel_evm/kernel/src/parsing.rs +++ b/etherlink/kernel_evm/kernel/src/parsing.rs @@ -303,24 +303,21 @@ pub struct SequencerParsingContext { // Delayed inbox transactions may come in chunks. If the buffer is // [Some _] a chunked transaction is being parsed, pub buffer_transaction_chunks: Option, - // Head level of the chain, handling blueprints before the head is useless. - // It is optional to handle when the first block has not been produced - // yet. - pub head_level: Option, + // Number of the next expected blueprint, handling blueprints + // before this is useless. + pub next_blueprint_number: U256, } fn check_unsigned_blueprint_chunk( unsigned_seq_blueprint: UnsignedSequencerBlueprint, - head_level: &Option, + next_blueprint_number: &U256, ) -> SequencerBlueprintRes { if MAXIMUM_NUMBER_OF_CHUNKS < unsigned_seq_blueprint.nb_chunks { return SequencerBlueprintRes::InvalidNumberOfChunks; } - if let Some(head_level) = head_level { - if unsigned_seq_blueprint.number.le(head_level) { - return SequencerBlueprintRes::InvalidNumber; - } + if unsigned_seq_blueprint.number.lt(next_blueprint_number) { + return SequencerBlueprintRes::InvalidNumber; } SequencerBlueprintRes::SequencerBlueprint(unsigned_seq_blueprint) @@ -328,13 +325,13 @@ fn check_unsigned_blueprint_chunk( pub fn parse_unsigned_blueprint_chunk( bytes: &[u8], - head_level: &Option, + next_blueprint_number: &U256, ) -> SequencerBlueprintRes { // Parse an unsigned sequencer blueprint match UnsignedSequencerBlueprint::from_rlp_bytes(bytes).ok() { None => SequencerBlueprintRes::Unparsable, Some(unsigned_seq_blueprint) => { - check_unsigned_blueprint_chunk(unsigned_seq_blueprint, head_level) + check_unsigned_blueprint_chunk(unsigned_seq_blueprint, next_blueprint_number) } } } @@ -342,7 +339,7 @@ pub fn parse_unsigned_blueprint_chunk( pub fn parse_blueprint_chunk( bytes: &[u8], sequencer: &PublicKey, - head_level: &Option, + next_blueprint_number: &U256, ) -> SequencerBlueprintRes { // Parse the sequencer blueprint match SequencerBlueprint::from_rlp_bytes(bytes).ok() { @@ -350,7 +347,7 @@ pub fn parse_blueprint_chunk( Some(SequencerBlueprint { blueprint, signature, - }) => match check_unsigned_blueprint_chunk(blueprint, head_level) { + }) => match check_unsigned_blueprint_chunk(blueprint, next_blueprint_number) { SequencerBlueprintRes::SequencerBlueprint(unsigned_seq_blueprint) => { let bytes = unsigned_seq_blueprint.rlp_bytes().to_vec(); @@ -384,7 +381,11 @@ impl SequencerInput { .allocated_ticks .saturating_sub(TICKS_FOR_BLUEPRINT_CHUNK_SIGNATURE); - let res = parse_blueprint_chunk(bytes, &context.sequencer, &context.head_level); + let res = parse_blueprint_chunk( + bytes, + &context.sequencer, + &context.next_blueprint_number, + ); InputResult::Input(Input::ModeSpecific(Self::SequencerBlueprint(res))) } @@ -897,7 +898,7 @@ pub mod tests { "edsk422LGdmDnai4Cya6csM6oFmgHpDQKUhatTURJRAY4h7NHNz9sz", ) .unwrap(); - let head_level: Option = Some(6.into()); + let next_blueprint_number: U256 = 7.into(); let blueprint = UnsignedSequencerBlueprint { chunk: vec![], @@ -910,7 +911,7 @@ pub mod tests { let res = parse_blueprint_chunk( &sequencer_signed_blueprint_chunk_bytes(&blueprint, sk.clone()), &pk, - &head_level, + &next_blueprint_number, ); assert!(matches!(res, SequencerBlueprintRes::SequencerBlueprint(_))); @@ -921,7 +922,7 @@ pub mod tests { let res = parse_blueprint_chunk( &sequencer_signed_blueprint_chunk_bytes(&blueprint, invalid_sk), &pk, - &head_level, + &next_blueprint_number, ); assert!(matches!(res, SequencerBlueprintRes::InvalidSignature)); @@ -934,7 +935,7 @@ pub mod tests { sk.clone(), ), &pk, - &head_level, + &next_blueprint_number, ); assert!(matches!(res, SequencerBlueprintRes::InvalidNumber)); @@ -947,7 +948,7 @@ pub mod tests { sk.clone(), ), &pk, - &head_level, + &next_blueprint_number, ); assert!(matches!(res, SequencerBlueprintRes::InvalidNumber)); } -- GitLab From 1fd47bb5b49dc43833f4afc0ba290b5377e0d9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 22 Oct 2024 09:09:25 +0200 Subject: [PATCH 02/31] Etherlink/Kernel: store next blueprint number outside of world state --- etherlink/kernel_evm/kernel/src/block.rs | 5 ++++- etherlink/kernel_evm/kernel/src/blueprint_storage.rs | 11 ++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index 49d59578decc..69af9af6a86a 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -9,7 +9,9 @@ use crate::apply::{ apply_transaction, ExecutionInfo, ExecutionResult, Validity, WITHDRAWAL_OUTBOX_QUEUE, }; use crate::block_storage; -use crate::blueprint_storage::{drop_blueprint, read_next_blueprint}; +use crate::blueprint_storage::{ + drop_blueprint, read_next_blueprint, store_next_blueprint_number, +}; use crate::configuration::ConfigurationMode; use crate::configuration::Limits; use crate::delayed_inbox::DelayedInbox; @@ -396,6 +398,7 @@ fn promote_block( safe_host.promote()?; safe_host.promote_trace()?; drop_blueprint(safe_host.host, number)?; + store_next_blueprint_number(safe_host.host, number.saturating_add(U256::one()))?; let number = block_storage::read_current_number(safe_host.host)?; let hash = block_storage::read_current_hash(safe_host.host)?; diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index 35620856bbc5..4e85680b17b3 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -26,13 +26,15 @@ use tezos_smart_rollup_core::MAX_INPUT_MESSAGE_SIZE; use tezos_smart_rollup_host::path::*; use tezos_smart_rollup_host::runtime::RuntimeError; use tezos_storage::{ - error::Error as GenStorageError, read_rlp, store_read_slice, store_rlp, + error::Error as GenStorageError, read_rlp, store_read_slice, store_rlp, write_u256_le, }; pub const EVM_BLUEPRINTS: RefPath = RefPath::assert_from(b"/evm/blueprints"); const EVM_BLUEPRINT_NB_CHUNKS: RefPath = RefPath::assert_from(b"/nb_chunks"); +const NEXT_BLUEPRINT_NUMBER: RefPath = RefPath::assert_from(b"/evm/blueprints/next"); + /// The store representation of a blueprint. /// It's designed to support storing sequencer blueprints, /// which can be chunked, and blueprints constructed from @@ -175,6 +177,13 @@ pub fn read_next_blueprint_number(host: &Host) -> anyhow::Result< } } +pub fn store_next_blueprint_number( + host: &mut Host, + number: U256, +) -> anyhow::Result<()> { + Ok(write_u256_le(host, &NEXT_BLUEPRINT_NUMBER, number)?) +} + // Used to store a blueprint made out of forced delayed transactions. pub fn store_immediate_blueprint( host: &mut Host, -- GitLab From 2806edbdcc8ab0b019f7a4dc06049605b8be625d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 22 Oct 2024 09:11:10 +0200 Subject: [PATCH 03/31] Etherlink/Kernel: use stored next BP number instead of block number --- .../kernel_evm/kernel/src/blueprint_storage.rs | 15 +++++---------- etherlink/kernel_evm/kernel/src/inbox.rs | 7 ++----- etherlink/kernel_evm/kernel/src/stage_one.rs | 6 ++++-- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index 4e85680b17b3..5d4d179d08ef 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -26,7 +26,8 @@ use tezos_smart_rollup_core::MAX_INPUT_MESSAGE_SIZE; use tezos_smart_rollup_host::path::*; use tezos_smart_rollup_host::runtime::RuntimeError; use tezos_storage::{ - error::Error as GenStorageError, read_rlp, store_read_slice, store_rlp, write_u256_le, + error::Error as GenStorageError, read_rlp, read_u256_le, store_read_slice, store_rlp, + write_u256_le, }; pub const EVM_BLUEPRINTS: RefPath = RefPath::assert_from(b"/evm/blueprints"); @@ -164,16 +165,10 @@ pub fn store_inbox_blueprint( Ok(store_inbox_blueprint_by_number(host, blueprint, number)?) } -#[inline(always)] pub fn read_next_blueprint_number(host: &Host) -> anyhow::Result { - match block_storage::read_current_number(host) { - Err(err) => match err.downcast_ref() { - Some(GenStorageError::Runtime(RuntimeError::PathNotFound)) => { - Ok(U256::zero()) - } - _ => Err(err), - }, - Ok(block_number) => Ok(block_number.saturating_add(U256::one())), + match read_u256_le(host, &NEXT_BLUEPRINT_NUMBER) { + Err(GenStorageError::Runtime(RuntimeError::PathNotFound)) => Ok(U256::zero()), + res => Ok(res?), } } diff --git a/etherlink/kernel_evm/kernel/src/inbox.rs b/etherlink/kernel_evm/kernel/src/inbox.rs index 9a28eb3b6d34..7f470cc96b07 100644 --- a/etherlink/kernel_evm/kernel/src/inbox.rs +++ b/etherlink/kernel_evm/kernel/src/inbox.rs @@ -753,7 +753,7 @@ pub fn read_sequencer_inbox( #[cfg(test)] mod tests { use super::*; - use crate::blueprint_storage::blueprint_path; + use crate::blueprint_storage::{blueprint_path, store_next_blueprint_number}; use crate::configuration::TezosContracts; use crate::dal_slot_import_signal::{ DalSlotIndicesList, DalSlotIndicesOfLevel, UnsignedDalSlotSignals, @@ -1366,10 +1366,7 @@ mod tests { // Prepare the host. let mut host = MockKernelHost::default(); let address = smart_rollup_address(); - crate::block_storage::internal_for_tests::store_current_number( - &mut host, head_level, - ) - .unwrap(); + store_next_blueprint_number(&mut host, head_level + 1).unwrap(); // Prepare the blueprint. let mut blueprint_bytes = diff --git a/etherlink/kernel_evm/kernel/src/stage_one.rs b/etherlink/kernel_evm/kernel/src/stage_one.rs index 92574fc54671..ae39ece848b8 100644 --- a/etherlink/kernel_evm/kernel/src/stage_one.rs +++ b/etherlink/kernel_evm/kernel/src/stage_one.rs @@ -212,7 +212,9 @@ mod tests { use crate::{ block_storage::internal_for_tests::store_current_number, - blueprint_storage::read_next_blueprint, dal::tests::*, parsing::RollupType, + blueprint_storage::{read_next_blueprint, store_next_blueprint_number}, + dal::tests::*, + parsing::RollupType, }; use super::*; @@ -481,7 +483,7 @@ mod tests { fetch_blueprints(&mut host, DEFAULT_SR_ADDRESS, &mut conf).expect("fetch failed"); // The dummy chunk in the inbox is registered at block 10 - store_current_number(&mut host, U256::from(9)).unwrap(); + store_next_blueprint_number(&mut host, U256::from(10)).unwrap(); if read_next_blueprint(&mut host, &mut conf) .expect("Blueprint reading shouldn't fail") .0 -- GitLab From 27ec7d32225c372d90190f2554bdc9b96363e39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 18:43:31 +0200 Subject: [PATCH 04/31] Etherlink/Kernel: generalize timestamp store functions --- etherlink/kernel_evm/kernel/src/storage.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index 50bfe821a696..db66f9c7b386 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -525,7 +525,7 @@ pub fn store_sequencer_pool_address( pub fn store_timestamp_path( host: &mut Host, - path: &OwnedPath, + path: &impl Path, timestamp: &Timestamp, ) -> Result<(), Error> { host.store_write(path, ×tamp.i64().to_le_bytes(), 0)?; @@ -581,13 +581,13 @@ pub fn store_last_info_per_level_timestamp( host: &mut Host, timestamp: Timestamp, ) -> Result<(), Error> { - store_timestamp_path(host, &EVM_INFO_PER_LEVEL_TIMESTAMP.into(), ×tamp)?; + store_timestamp_path(host, &EVM_INFO_PER_LEVEL_TIMESTAMP, ×tamp)?; store_info_per_level_stats(host, timestamp) } pub fn read_timestamp_path( host: &Host, - path: &OwnedPath, + path: &impl Path, ) -> Result { let mut buffer = [0u8; 8]; store_read_slice(host, path, &mut buffer, 8)?; @@ -598,7 +598,7 @@ pub fn read_timestamp_path( pub fn read_last_info_per_level_timestamp( host: &Host, ) -> Result { - read_timestamp_path(host, &EVM_INFO_PER_LEVEL_TIMESTAMP.into()) + read_timestamp_path(host, &EVM_INFO_PER_LEVEL_TIMESTAMP) } pub fn read_admin(host: &mut Host) -> Option { -- GitLab From 22d6af2c3a3bbe15c39d2adb623fbdb645ad5aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 14:45:19 +0200 Subject: [PATCH 05/31] Etherlink/Kernel: store last block's timestamp outside of world state --- etherlink/kernel_evm/kernel/src/block.rs | 10 ++++---- .../kernel_evm/kernel/src/block_storage.rs | 6 +++++ .../kernel/src/blueprint_storage.rs | 24 ++++++++++++++++++- etherlink/kernel_evm/kernel/src/stage_one.rs | 8 ++----- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index 69af9af6a86a..8e180f935e42 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -10,7 +10,8 @@ use crate::apply::{ }; use crate::block_storage; use crate::blueprint_storage::{ - drop_blueprint, read_next_blueprint, store_next_blueprint_number, + drop_blueprint, read_next_blueprint, store_last_block_timestamp, + store_next_blueprint_number, }; use crate::configuration::ConfigurationMode; use crate::configuration::Limits; @@ -392,6 +393,7 @@ fn promote_block( config: &mut Configuration, delayed_txs: Vec, ) -> anyhow::Result<()> { + let current_timestamp = block_storage::read_current_timestamp(safe_host)?; if block_in_progress { storage::delete_block_in_progress(safe_host)?; } @@ -399,6 +401,7 @@ fn promote_block( safe_host.promote_trace()?; drop_blueprint(safe_host.host, number)?; store_next_blueprint_number(safe_host.host, number.saturating_add(U256::one()))?; + store_last_block_timestamp(safe_host.host, ¤t_timestamp)?; let number = block_storage::read_current_number(safe_host.host)?; let hash = block_storage::read_current_hash(safe_host.host)?; @@ -627,6 +630,7 @@ mod tests { use super::*; use crate::block_storage; use crate::blueprint::Blueprint; + use crate::blueprint_storage::read_last_block_timestamp; use crate::blueprint_storage::store_inbox_blueprint; use crate::blueprint_storage::store_inbox_blueprint_by_number; use crate::fees::DA_FEE_PER_BYTE; @@ -636,7 +640,6 @@ mod tests { use crate::inbox::TransactionContent::Ethereum; use crate::inbox::TransactionContent::EthereumDelayed; use crate::storage::read_block_in_progress; - use crate::storage::read_last_info_per_level_timestamp; use crate::storage::{read_transaction_receipt, read_transaction_receipt_status}; use crate::{retrieve_block_fees, retrieve_chain_id}; use evm_execution::account_storage::{ @@ -1291,8 +1294,7 @@ mod tests { } fn first_block(host: &mut MockHost) -> BlockConstants { - let timestamp = - read_last_info_per_level_timestamp(host).unwrap_or(Timestamp::from(0)); + let timestamp = read_last_block_timestamp(host).unwrap_or(Timestamp::from(0)); let timestamp = U256::from(timestamp.as_u64()); let chain_id = retrieve_chain_id(host); let block_fees = retrieve_block_fees(host); diff --git a/etherlink/kernel_evm/kernel/src/block_storage.rs b/etherlink/kernel_evm/kernel/src/block_storage.rs index f090c86b40f9..b45fd11bde4f 100644 --- a/etherlink/kernel_evm/kernel/src/block_storage.rs +++ b/etherlink/kernel_evm/kernel/src/block_storage.rs @@ -11,6 +11,7 @@ use tezos_evm_logging::{ }; use tezos_evm_runtime::runtime::Runtime; use tezos_indexable_storage::IndexableStorage; +use tezos_smart_rollup::types::Timestamp; use tezos_smart_rollup_host::path::concat; use tezos_smart_rollup_host::path::OwnedPath; use tezos_smart_rollup_host::path::RefPath; @@ -110,6 +111,11 @@ pub fn read_current(host: &mut impl Runtime) -> anyhow::Result { Ok(block_from_bytes) } +pub fn read_current_timestamp(host: &mut impl Runtime) -> anyhow::Result { + let block = read_current(host)?; + Ok(block.timestamp) +} + pub fn garbage_collect_blocks(host: &mut impl Runtime) -> anyhow::Result<()> { log!(host, Debug, "Garbage collecting blocks."); if let Ok(block) = read_current(host) { diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index 5d4d179d08ef..4b5fb3f77d55 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -12,7 +12,9 @@ use crate::inbox::{Transaction, TransactionContent}; use crate::sequencer_blueprint::{ BlueprintWithDelayedHashes, UnsignedSequencerBlueprint, }; -use crate::storage::read_last_info_per_level_timestamp; +use crate::storage::{ + read_last_info_per_level_timestamp, read_timestamp_path, store_timestamp_path, +}; use crate::{delayed_inbox, DelayedInbox}; use primitive_types::U256; use rlp::{Decodable, DecoderError, Encodable}; @@ -36,6 +38,9 @@ const EVM_BLUEPRINT_NB_CHUNKS: RefPath = RefPath::assert_from(b"/nb_chunks"); const NEXT_BLUEPRINT_NUMBER: RefPath = RefPath::assert_from(b"/evm/blueprints/next"); +const LAST_BLOCK_TIMESTAMP: RefPath = + RefPath::assert_from(b"/evm/blueprints/last_block_timestamp"); + /// The store representation of a blueprint. /// It's designed to support storing sequencer blueprints, /// which can be chunked, and blueprints constructed from @@ -179,6 +184,23 @@ pub fn store_next_blueprint_number( Ok(write_u256_le(host, &NEXT_BLUEPRINT_NUMBER, number)?) } +pub fn read_last_block_timestamp( + host: &Host, +) -> anyhow::Result { + Ok(read_timestamp_path(host, &LAST_BLOCK_TIMESTAMP)?) +} + +pub fn store_last_block_timestamp( + host: &mut Host, + timestamp: &Timestamp, +) -> anyhow::Result<()> { + Ok(store_timestamp_path( + host, + &LAST_BLOCK_TIMESTAMP, + timestamp, + )?) +} + // Used to store a blueprint made out of forced delayed transactions. pub fn store_immediate_blueprint( host: &mut Host, diff --git a/etherlink/kernel_evm/kernel/src/stage_one.rs b/etherlink/kernel_evm/kernel/src/stage_one.rs index ae39ece848b8..fca43f7c4f34 100644 --- a/etherlink/kernel_evm/kernel/src/stage_one.rs +++ b/etherlink/kernel_evm/kernel/src/stage_one.rs @@ -16,7 +16,6 @@ use crate::storage::read_last_info_per_level_timestamp; use anyhow::Ok; use std::ops::Add; use tezos_crypto_rs::hash::ContractKt1Hash; -use tezos_ethereum::block::L2Block; use tezos_evm_logging::{log, Level::*}; use tezos_evm_runtime::runtime::Runtime; use tezos_smart_rollup_encoding::public_key::PublicKey; @@ -69,11 +68,8 @@ fn fetch_delayed_transactions( timed_out.len() ); - let timestamp = match crate::block_storage::read_current(host) { - Result::Ok(L2Block { - timestamp: head_timestamp, - .. - }) => { + let timestamp = match crate::blueprint_storage::read_last_block_timestamp(host) { + Result::Ok(head_timestamp) => { // Timestamp has to be at least equal or greater than previous timestamp. // If it's not the case, we fallback and take the previous block timestamp. std::cmp::max(timestamp, head_timestamp) -- GitLab From 608b928f6b68119fd9b3ce232d05fc2a5e54d180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Thu, 24 Oct 2024 17:32:06 +0200 Subject: [PATCH 06/31] Etherlink/Kernel/BIP: temp dirs are kept in world state --- etherlink/kernel_evm/kernel/src/block_in_progress.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/block_in_progress.rs b/etherlink/kernel_evm/kernel/src/block_in_progress.rs index 00452ee4dae2..818eb331873a 100644 --- a/etherlink/kernel_evm/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_evm/kernel/src/block_in_progress.rs @@ -357,9 +357,10 @@ impl BlockInProgress { } } - const RECEIPTS: RefPath<'static> = RefPath::assert_from(b"/receipts"); + const RECEIPTS: RefPath<'static> = + RefPath::assert_from(b"/evm/world_state/__receipts"); const RECEIPTS_PREVIOUS_ROOT: RefPath<'static> = - RefPath::assert_from(b"/receipts/previous_root"); + RefPath::assert_from(b"/evm/world_state/__receipts/previous_root"); fn receipts_root( &self, @@ -381,9 +382,9 @@ impl BlockInProgress { } } - const OBJECTS: RefPath<'static> = RefPath::assert_from(b"/objects"); + const OBJECTS: RefPath<'static> = RefPath::assert_from(b"/evm/world_state/__objects"); const OBJECTS_PREVIOUS_ROOT: RefPath<'static> = - RefPath::assert_from(b"/objects/previous_root"); + RefPath::assert_from(b"/evm/world_state/__objects/previous_root"); fn transactions_root( &self, -- GitLab From 3d29fe998a5aa2e991709050e210e74302f764b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Fri, 18 Oct 2024 10:13:21 +0200 Subject: [PATCH 07/31] Etherlink/Kernel: EvalHost does not own its runtime --- .../kernel_evm/evm_evaluation/src/evalhost.rs | 22 ++++++++++-------- .../kernel_evm/evm_evaluation/src/runner.rs | 23 +++++++++++-------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index a2973b4fa14f..d7027631dfd2 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -20,21 +20,23 @@ use tezos_smart_rollup_host::{ use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; -pub struct EvalHost { - pub host: MockKernelHost, +pub struct EvalHost<'a> { + pub host: &'a mut MockKernelHost, pub buffer: RefCell>, } -impl EvalHost { +impl<'a> EvalHost<'a> { /// Create a new instance of the `MockHost`, additionally provide the buffer /// where the logs will be outputed. - pub fn default_with_buffer(buffer: RefCell>) -> Self { - let host = MockKernelHost::default(); + pub fn default_with_buffer( + buffer: RefCell>, + host: &'a mut MockKernelHost, + ) -> Self { Self { host, buffer } } } -impl SdkRuntime for EvalHost { +impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.write_output(from) @@ -202,7 +204,7 @@ impl SdkRuntime for EvalHost { } } -impl InternalRuntime for EvalHost { +impl<'a> InternalRuntime for EvalHost<'a> { fn __internal_store_get_hash( &mut self, path: &T, @@ -211,7 +213,7 @@ impl InternalRuntime for EvalHost { } } -impl ExtendedRuntime for EvalHost { +impl<'a> ExtendedRuntime for EvalHost<'a> { fn store_get_hash( &mut self, path: &T, @@ -220,13 +222,13 @@ impl ExtendedRuntime for EvalHost { } } -impl Verbosity for EvalHost { +impl<'a> Verbosity for EvalHost<'a> { fn verbosity(&self) -> tezos_evm_logging::Level { self.host.verbosity() } } -impl WithGas for EvalHost { +impl<'a> WithGas for EvalHost<'a> { // This is a blank implementation on purpose, as this is not useful for the // evaluation fn add_execution_gas(&mut self, _gas: u64) {} diff --git a/etherlink/kernel_evm/evm_evaluation/src/runner.rs b/etherlink/kernel_evm/evm_evaluation/src/runner.rs index db46bc957dad..82a75a49ac38 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/runner.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/runner.rs @@ -13,6 +13,7 @@ use evm_execution::precompiles::{precompile_set, PrecompileBTreeMap}; use evm_execution::{run_transaction, Config, EthereumError}; use tezos_ethereum::block::{BlockConstants, BlockFees}; +use tezos_evm_runtime::runtime::MockKernelHost; use hex_literal::hex; use primitive_types::{H160, H256, U256}; @@ -85,15 +86,18 @@ fn read_testsuite(path: &Path) -> Result { serde_json::from_reader(&*json_reader).map_err(TestError::from) } -fn prepare_host() -> EvalHost { +fn prepare_host(host: &mut MockKernelHost) -> EvalHost { let execution_buffer = Vec::new(); let buffer = RefCell::new(execution_buffer); - EvalHost::default_with_buffer(buffer) + EvalHost::default_with_buffer(buffer, host) } -fn prepare_host_with_buffer(execution_buffer: Vec) -> EvalHost { +fn prepare_host_with_buffer( + execution_buffer: Vec, + host: &mut MockKernelHost, +) -> EvalHost { let buffer = RefCell::new(execution_buffer); - EvalHost::default_with_buffer(buffer) + EvalHost::default_with_buffer(buffer, host) } fn prepare_filler_source( @@ -182,10 +186,10 @@ fn initialize_env(unit: &TestUnit) -> Result { } #[allow(clippy::too_many_arguments)] -fn execute_transaction( - host: &mut EvalHost, +fn execute_transaction<'a>( + host: &mut EvalHost<'a>, evm_account_storage: &mut EthereumAccountStorage, - precompiles: &PrecompileBTreeMap, + precompiles: &PrecompileBTreeMap>, config: &Config, unit: &TestUnit, env: &mut Env, @@ -315,7 +319,8 @@ pub fn run_test( skip_data: &SkipData, ) -> Result<(), TestError> { let suit = read_testsuite(path)?; - let mut host = prepare_host(); + let mut host = MockKernelHost::default(); + let mut host = prepare_host(&mut host); for (name, unit) in suit.0.into_iter() { if output.log { @@ -361,7 +366,7 @@ pub fn run_test( } continue; } - host = prepare_host_with_buffer(host.buffer.take()); + host = prepare_host_with_buffer(host.buffer.take(), host.host); initialize_accounts(&mut host, &unit); let data_label = info.labels.get(&data); if let Some(data_label) = data_label { -- GitLab From 1c4770d8e21dbd358954250252dfb1b5aa61ac5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Fri, 18 Oct 2024 10:36:06 +0200 Subject: [PATCH 08/31] Etherlink/Kernel: EvalHost relative to world state path --- .../kernel_evm/evm_evaluation/src/evalhost.rs | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index d7027631dfd2..2b458bf709b0 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -14,7 +14,7 @@ use tezos_smart_rollup_host::{ dal_parameters::RollupDalParameters, input::Message, metadata::RollupMetadata, - path::Path, + path::{concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; @@ -36,10 +36,16 @@ impl<'a> EvalHost<'a> { } } +const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); + +fn world_state_path(p: &impl Path) -> Result { + concat(&WORLD_STATE_PATH, p).map_err(|_| RuntimeError::PathNotFound) +} + impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { - self.host.write_output(from) + self.host.host.write_output(from) } #[inline(always)] @@ -52,12 +58,13 @@ impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn read_input(&mut self) -> Result, RuntimeError> { - self.host.read_input() + self.host.host.read_input() } #[inline(always)] fn store_has(&self, path: &T) -> Result, RuntimeError> { - self.host.store_has(path) + let path = world_state_path(path)?; + self.host.store_has(&path) } #[inline(always)] @@ -67,7 +74,8 @@ impl<'a> SdkRuntime for EvalHost<'a> { from_offset: usize, max_bytes: usize, ) -> Result, RuntimeError> { - self.host.store_read(path, from_offset, max_bytes) + let path = world_state_path(path)?; + self.host.store_read(&path, from_offset, max_bytes) } #[inline(always)] @@ -77,12 +85,14 @@ impl<'a> SdkRuntime for EvalHost<'a> { from_offset: usize, buffer: &mut [u8], ) -> Result { - self.host.store_read_slice(path, from_offset, buffer) + let path = world_state_path(path)?; + self.host.store_read_slice(&path, from_offset, buffer) } #[inline(always)] fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { - self.host.store_read_all(path) + let path = world_state_path(path)?; + self.host.store_read_all(&path) } #[inline(always)] @@ -92,7 +102,8 @@ impl<'a> SdkRuntime for EvalHost<'a> { src: &[u8], at_offset: usize, ) -> Result<(), RuntimeError> { - self.host.store_write(path, src, at_offset) + let path = world_state_path(path)?; + self.host.store_write(&path, src, at_offset) } #[inline(always)] @@ -101,22 +112,26 @@ impl<'a> SdkRuntime for EvalHost<'a> { path: &T, src: &[u8], ) -> Result<(), RuntimeError> { - self.host.store_write_all(path, src) + let path = world_state_path(path)?; + self.host.store_write_all(&path, src) } #[inline(always)] fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { - self.host.store_delete(path) + let path = world_state_path(path)?; + self.host.store_delete(&path) } #[inline(always)] fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { - self.host.store_delete_value(path) + let path = world_state_path(path)?; + self.host.store_delete_value(&path) } #[inline(always)] fn store_count_subkeys(&self, prefix: &T) -> Result { - self.host.store_count_subkeys(prefix) + let prefix = world_state_path(prefix)?; + self.host.store_count_subkeys(&prefix) } #[inline(always)] @@ -125,7 +140,9 @@ impl<'a> SdkRuntime for EvalHost<'a> { from_path: &impl Path, to_path: &impl Path, ) -> Result<(), RuntimeError> { - self.host.store_move(from_path, to_path) + let from_path = world_state_path(from_path)?; + let to_path = world_state_path(to_path)?; + self.host.store_move(&from_path, &to_path) } #[inline(always)] @@ -134,7 +151,9 @@ impl<'a> SdkRuntime for EvalHost<'a> { from_path: &impl Path, to_path: &impl Path, ) -> Result<(), RuntimeError> { - self.host.store_copy(from_path, to_path) + let from_path = world_state_path(from_path)?; + let to_path = world_state_path(to_path)?; + self.host.store_copy(&from_path, &to_path) } #[inline(always)] @@ -148,7 +167,8 @@ impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn store_value_size(&self, path: &impl Path) -> Result { - self.host.store_value_size(path) + let path = world_state_path(path)?; + self.host.store_value_size(&path) } #[inline(always)] @@ -214,11 +234,12 @@ impl<'a> InternalRuntime for EvalHost<'a> { } impl<'a> ExtendedRuntime for EvalHost<'a> { - fn store_get_hash( + fn store_get_hash( &mut self, - path: &T, + path: &P, ) -> Result, tezos_smart_rollup_host::runtime::RuntimeError> { - self.host.store_get_hash(path) + let path = world_state_path(path)?; + self.host.store_get_hash(&path) } } -- GitLab From 8d6fbe4aeff60c3dd4e4543fe20ed0be910fcd2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Fri, 8 Nov 2024 11:09:29 +0100 Subject: [PATCH 09/31] Etherlink/Kernel: use SafeStorage in tests --- .../evm_execution/src/account_storage.rs | 18 ++ .../evm_execution/src/code_storage.rs | 6 +- .../evm_execution/src/fa_bridge/test_utils.rs | 19 +- .../evm_execution/src/fa_bridge/tests.rs | 23 +- .../src/fa_bridge/ticket_table.rs | 4 +- .../kernel_evm/evm_execution/src/handler.rs | 179 ++++++++++---- etherlink/kernel_evm/evm_execution/src/lib.rs | 232 +++++++++++++----- .../src/precompiles/fa_bridge.rs | 35 ++- .../evm_execution/src/precompiles/mod.rs | 15 +- .../evm_execution/src/withdrawal_counter.rs | 5 +- etherlink/kernel_evm/kernel/src/apply.rs | 14 +- etherlink/kernel_evm/kernel/src/block.rs | 205 ++++++++++++---- etherlink/kernel_evm/kernel/src/bridge.rs | 4 +- etherlink/kernel_evm/kernel/src/fees.rs | 9 +- etherlink/kernel_evm/kernel/src/gas_price.rs | 6 +- etherlink/kernel_evm/kernel/src/inbox.rs | 2 +- etherlink/kernel_evm/kernel/src/lib.rs | 72 +++--- etherlink/kernel_evm/kernel/src/stage_one.rs | 5 +- etherlink/kernel_evm/kernel/src/storage.rs | 3 +- 19 files changed, 632 insertions(+), 224 deletions(-) diff --git a/etherlink/kernel_evm/evm_execution/src/account_storage.rs b/etherlink/kernel_evm/evm_execution/src/account_storage.rs index edd710855a0c..95eb38b0078c 100644 --- a/etherlink/kernel_evm/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/account_storage.rs @@ -557,6 +557,7 @@ mod test { use host::path::RefPath; use primitive_types::U256; use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::safe_storage::SafeStorage; use tezos_smart_rollup_host::runtime::Runtime as SdkRuntime; // Used for use tezos_storage::helpers::bytes_hash; use tezos_storage::write_u256_le; @@ -564,6 +565,7 @@ mod test { #[test] fn test_account_nonce_update() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -600,6 +602,7 @@ mod test { #[test] fn test_zero_account_balance_for_new_accounts() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -638,6 +641,7 @@ mod test { #[test] fn test_account_balance_add() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -682,6 +686,7 @@ mod test { #[test] fn test_account_balance_sub() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -726,6 +731,7 @@ mod test { #[test] fn test_account_balance_underflow() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -768,6 +774,7 @@ mod test { #[test] fn test_account_storage_zero_default() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -795,6 +802,7 @@ mod test { #[test] fn test_account_storage_update() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -836,6 +844,7 @@ mod test { #[test] fn test_account_storage_update_checked() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -917,6 +926,7 @@ mod test { #[test] fn test_account_code_storage_initial_code_is_zero() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -965,6 +975,7 @@ mod test { fn test_account_code_storage_write_code_aux(sample_code: Vec) { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1025,6 +1036,7 @@ mod test { #[test] fn test_account_code_storage_cant_be_overwritten() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1077,6 +1089,7 @@ mod test { #[test] fn test_account_code_storage_delete_code() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1131,6 +1144,7 @@ mod test { #[test] fn test_empty_contract_hash_matches_default() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1180,6 +1194,7 @@ mod test { #[test] fn test_read_u256_le_default_le() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let path = RefPath::assert_from(b"/value"); assert_eq!( read_u256_le_default(&host, &path, U256::from(128)).unwrap(), @@ -1209,6 +1224,7 @@ mod test { #[test] fn test_write_u256_le_le() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let path = RefPath::assert_from(b"/value"); write_u256_le(&mut host, &path, U256::from(255)).unwrap(); @@ -1224,6 +1240,7 @@ mod test { let sample_code_hash: H256 = bytes_hash(&sample_code); let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1291,6 +1308,7 @@ mod test { let sample_code_hash: H256 = bytes_hash(&sample_code); let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); diff --git a/etherlink/kernel_evm/evm_execution/src/code_storage.rs b/etherlink/kernel_evm/evm_execution/src/code_storage.rs index 6474eb67edd4..aa40f213743f 100644 --- a/etherlink/kernel_evm/evm_execution/src/code_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/code_storage.rs @@ -144,13 +144,14 @@ impl CodeStorage { #[cfg(test)] mod test { use crate::account_storage; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; use super::*; #[test] fn test_empty_contract_hash_matches_default() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let empty_code: Vec = vec![]; let empty_code_hash: H256 = account_storage::CODE_HASH_DEFAULT; @@ -163,6 +164,7 @@ mod test { #[test] fn test_get_code_matches_given() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let code: Vec = (0..100).collect(); let code_hash = CodeStorage::add(&mut host, &code).expect("Could not create code storage"); @@ -173,6 +175,7 @@ mod test { #[test] fn test_code_ref_is_incremented() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let code: Vec = (0..100).collect(); let code_hash = CodeStorage::add(&mut host, &code).expect("Could not create code storage"); @@ -201,6 +204,7 @@ mod test { #[test] fn test_code_is_deleted() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let code_hash: H256 = account_storage::CODE_HASH_DEFAULT; let code_storage = diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs index a6674b864487..b86de96fac44 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs @@ -13,7 +13,6 @@ use tezos_ethereum::{ block::{BlockConstants, BlockFees}, Log, }; -use tezos_evm_runtime::runtime::MockKernelHost; use tezos_evm_runtime::runtime::Runtime; use tezos_smart_rollup_encoding::{ contract::Contract, @@ -60,7 +59,7 @@ const REENTRANCY_TESTER_BYTECODE: &[u8] = /// Create a smart contract in the storage with the mocked token code pub fn deploy_mock_wrapper( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, ticket: &FA2_1Ticket, caller: &H160, @@ -76,7 +75,7 @@ pub fn deploy_mock_wrapper( )); let block = dummy_block_constants(); - let precompiles = precompile_set::(false); + let precompiles = precompile_set(false); set_balance(host, evm_account_storage, caller, U256::from(1_000_000)); run_transaction( @@ -103,7 +102,7 @@ pub fn deploy_mock_wrapper( /// Create a smart contract in the storage with the mocked token code pub fn deploy_reentrancy_tester( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, ticket: &FA2_1Ticket, caller: &H160, @@ -123,7 +122,7 @@ pub fn deploy_reentrancy_tester( )); let block = dummy_block_constants(); - let precompiles = precompile_set::(false); + let precompiles = precompile_set(false); set_balance(host, evm_account_storage, caller, U256::from(1_000_000)); run_transaction( @@ -150,7 +149,7 @@ pub fn deploy_reentrancy_tester( /// Execute FA deposit pub fn run_fa_deposit( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, deposit: &FaDeposit, caller: &H160, @@ -158,7 +157,7 @@ pub fn run_fa_deposit( enable_fa_withdrawals: bool, ) -> ExecutionOutcome { let block = dummy_block_constants(); - let precompiles = precompile_set::(enable_fa_withdrawals); + let precompiles = precompile_set(enable_fa_withdrawals); execute_fa_deposit( host, @@ -199,7 +198,7 @@ pub fn dummy_fa_deposit(ticket: FA2_1Ticket, proxy: Option) -> FaDeposit { /// } /// } pub fn get_storage_flag( - host: &MockKernelHost, + host: &impl Runtime, evm_account_storage: &EthereumAccountStorage, proxy: H160, ) -> u32 { @@ -382,13 +381,13 @@ pub fn dummy_fa_withdrawal( /// Execute FA withdrawal directly without going through the precompile pub fn fa_bridge_precompile_call_withdraw( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, withdrawal: FaWithdrawal, caller: H160, ) -> ExecutionOutcome { let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let config = Config::shanghai(); let mut handler = EvmHandler::new( diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs index 1b4a723c09e7..006e731fbe58 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs @@ -6,7 +6,7 @@ use alloy_primitives::FixedBytes; use alloy_sol_types::SolEvent; use evm::ExitError; use primitive_types::{H160, U256}; -use tezos_evm_runtime::runtime::MockKernelHost; +use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; use crate::{ account_storage::{account_path, init_account_storage}, @@ -27,6 +27,9 @@ use crate::{ #[test] fn fa_deposit_reached_wrapper_contract() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let caller = H160::zero(); @@ -109,6 +112,9 @@ fn fa_deposit_reached_wrapper_contract() { #[test] fn fa_deposit_refused_due_non_existing_contract() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let caller = H160::zero(); @@ -168,6 +174,9 @@ fn fa_deposit_refused_due_non_existing_contract() { #[test] fn fa_deposit_refused_non_compatible_interface() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let caller = H160::zero(); @@ -234,6 +243,9 @@ fn fa_deposit_refused_non_compatible_interface() { #[test] fn fa_deposit_proxy_state_reverted_if_ticket_balance_overflows() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let caller = H160::zero(); @@ -297,6 +309,9 @@ fn fa_deposit_proxy_state_reverted_if_ticket_balance_overflows() { #[test] fn fa_withdrawal_executed_via_l2_proxy_contract() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let sender = H160::from_low_u64_be(1); @@ -385,6 +400,9 @@ fn fa_withdrawal_executed_via_l2_proxy_contract() { #[test] fn fa_withdrawal_fails_due_to_faulty_l2_proxy() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let sender = H160::from_low_u64_be(1); @@ -438,6 +456,9 @@ fn fa_withdrawal_fails_due_to_faulty_l2_proxy() { #[test] fn fa_withdrawal_fails_due_to_insufficient_balance() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let sender = H160::from_low_u64_be(1); diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs index 119b9fa7886f..fb13af4cf206 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs @@ -84,7 +84,7 @@ impl TicketTable for EthereumAccount { #[cfg(test)] mod tests { - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; use tezos_smart_rollup_host::path::RefPath; use tezos_storage::read_u256_le_default; @@ -95,6 +95,7 @@ mod tests { #[test] fn ticket_table_balance_add_succeeds() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut account = EthereumAccount::from_address(&SYSTEM_ACCOUNT_ADDRESS).unwrap(); @@ -122,6 +123,7 @@ mod tests { #[test] fn ticket_table_balance_add_overflows() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut account = EthereumAccount::from_address(&SYSTEM_ACCOUNT_ADDRESS).unwrap(); diff --git a/etherlink/kernel_evm/evm_execution/src/handler.rs b/etherlink/kernel_evm/evm_execution/src/handler.rs index d2c52d374502..cf3cc2087a0e 100644 --- a/etherlink/kernel_evm/evm_execution/src/handler.rs +++ b/etherlink/kernel_evm/evm_execution/src/handler.rs @@ -2817,12 +2817,12 @@ mod test { use std::str::FromStr; use std::vec; use tezos_ethereum::block::BlockFees; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; const DUMMY_ALLOCATED_TICKS: u64 = 1_000_000_000; fn set_code( - handler: &mut EvmHandler<'_, MockKernelHost>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, code: Vec, ) { @@ -2831,22 +2831,18 @@ mod test { account.set_code(handler.borrow_host(), &code).unwrap(); } - fn set_nonce( - handler: &mut EvmHandler<'_, MockKernelHost>, - address: &H160, - nonce: u64, - ) { + fn set_nonce(handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, nonce: u64) { let mut account = handler.get_or_create_account(*address).unwrap(); account.set_nonce(handler.borrow_host(), nonce).unwrap() } - fn get_balance(handler: &mut EvmHandler<'_, MockKernelHost>, address: &H160) -> U256 { + fn get_balance(handler: &mut EvmHandler<'_, impl Runtime>, address: &H160) -> U256 { let account = handler.get_or_create_account(*address).unwrap(); account.balance(handler.borrow_host()).unwrap() } fn set_balance( - handler: &mut EvmHandler<'_, MockKernelHost>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, new_balance: U256, ) { @@ -2870,7 +2866,7 @@ mod test { } fn get_durable_slot( - handler: &mut EvmHandler<'_, MockKernelHost>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, index: &H256, ) -> H256 { @@ -2896,8 +2892,11 @@ mod test { #[test] fn legacy_create_to_correct_address() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); @@ -2939,8 +2938,11 @@ mod test { #[test] fn create2_to_correct_address() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller: H160 = @@ -2981,8 +2983,11 @@ mod test { #[test] fn create2_to_correct_address_nonzero_salt() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); @@ -3027,8 +3032,11 @@ mod test { #[test] fn origin_instruction_returns_origin_address() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(28349_u64); @@ -3092,8 +3100,11 @@ mod test { #[test] fn contract_call_produces_correct_output() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(28349_u64); @@ -3186,8 +3197,11 @@ mod test { #[test] fn contract_call_fails_beyond_max_stack_depth() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(2340); @@ -3281,8 +3295,11 @@ mod test { #[test] fn contract_call_succeeds_at_maximum_stack_depth() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(8213); @@ -3374,8 +3391,11 @@ mod test { #[test] fn contract_can_use_durable_storage() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(444); @@ -3446,8 +3466,11 @@ mod test { #[test] fn contract_create_can_use_durable_storage() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(117); @@ -3503,8 +3526,11 @@ mod test { #[test] fn contract_create_has_return_when_revert() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(117); @@ -3569,8 +3595,11 @@ mod test { #[test] fn contract_call_does_transfer() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(118); @@ -3632,8 +3661,11 @@ mod test { #[test] fn contract_call_fails_when_insufficient_funds_for_transfer() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -3694,8 +3726,11 @@ mod test { #[test] fn revert_can_return_a_value() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -3765,8 +3800,11 @@ mod test { #[test] fn return_hash_of_zero_for_unavailable_block() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -3793,8 +3831,11 @@ mod test { #[test] fn transactions_fails_if_not_enough_allocated_ticks() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::london(); let caller = H160::from_low_u64_be(523_u64); @@ -3854,8 +3895,11 @@ mod test { #[test] fn store_after_offset_1024() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -3906,8 +3950,11 @@ mod test { #[test] fn dont_crash_on_blockhash_instruction() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -3974,8 +4021,11 @@ mod test { #[test] fn prevent_collision_create2_selfdestruct() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); @@ -4043,8 +4093,11 @@ mod test { fn create_contract_with_insufficient_funds() { //Init let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); @@ -4086,8 +4139,11 @@ mod test { #[test] fn inter_call_with_non_zero_transfer_value_gets_call_stipend() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -4162,8 +4218,11 @@ mod test { #[test] fn code_hash_of_zero_for_non_existing_address() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -4191,8 +4250,11 @@ mod test { #[test] fn create_contract_with_selfdestruct_init_code() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); @@ -4235,8 +4297,11 @@ mod test { #[test] fn contract_that_selfdestruct_not_deleted_within_same_transaction() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -4318,8 +4383,11 @@ mod test { #[test] fn contract_that_selfdestruct_can_be_called_again_in_same_transaction() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -4418,8 +4486,11 @@ mod test { #[test] fn contract_selfdestruct_itself_has_no_balance_left() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); @@ -4484,8 +4555,11 @@ mod test { #[test] fn address_still_marked_as_hot_after_creation_fails() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); @@ -4558,8 +4632,9 @@ mod test { #[test] fn precompile_failure_are_not_fatal() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -4617,8 +4692,11 @@ mod test { #[test] fn inner_create_costs_gas() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -4699,8 +4777,11 @@ mod test { #[test] fn exceed_max_create_init_code_size_fail_with_error() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -4739,8 +4820,11 @@ mod test { #[test] fn create_fails_with_max_nonce() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); @@ -4781,8 +4865,11 @@ mod test { #[test] fn record_call_stipend_when_balance_not_enough_for_inner_call() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(523_u64); @@ -4859,8 +4946,11 @@ mod test { #[test] fn eip161_gas_consumption_rules_for_suicide() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(111_u64); @@ -4931,8 +5021,11 @@ mod test { #[test] fn eip161_gas_consumption_rules_for_call() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); let config = Config::shanghai(); let caller = H160::from_low_u64_be(111_u64); diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index efff45a85120..401e645277bc 100755 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -449,6 +449,7 @@ mod test { use tezos_ethereum::tx_common::EthereumTransactionCommon; use tezos_evm_runtime::runtime::MockKernelHost; use tezos_evm_runtime::runtime::Runtime; + use tezos_evm_runtime::safe_storage::SafeStorage; // The compiled initialization code for the Ethereum demo contract given // as an example in kernel_evm/solidity_examples/storage.sol @@ -474,7 +475,7 @@ mod test { const DUMMY_ALLOCATED_TICKS: u64 = 1_000_000_000; fn set_balance( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -495,7 +496,7 @@ mod test { } fn set_storage( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, index: &H256, @@ -508,7 +509,7 @@ mod test { } fn get_storage( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, index: &H256, @@ -520,7 +521,7 @@ mod test { } fn get_balance( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> U256 { @@ -543,7 +544,7 @@ mod test { } fn get_code( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> Vec { @@ -564,7 +565,7 @@ mod test { } fn get_nonce( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> u64 { @@ -592,8 +593,11 @@ mod test { #[test] fn transfer_without_sufficient_funds_fails() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = H160::from_low_u64_be(234213); @@ -657,8 +661,11 @@ mod test { #[test] fn transfer_funds_with_sufficient_balance() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = H160::from_low_u64_be(82193); @@ -723,8 +730,11 @@ mod test { #[test] fn create_contract_fails_with_insufficient_funds() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = None; @@ -777,8 +787,11 @@ mod test { #[test] fn create_contract_succeeds_with_valid_initialization() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = None; @@ -938,8 +951,11 @@ mod test { #[test] fn create_contract_erc20_succeeds() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = None; @@ -994,8 +1010,11 @@ mod test { #[test] fn create_contract_fails_when_initialization_fails() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = None; @@ -1052,8 +1071,11 @@ mod test { fn call_non_existing_contract() { // Arange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -1189,8 +1211,11 @@ mod test { fn call_simple_return_contract() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -1251,8 +1276,11 @@ mod test { fn call_simple_revert_contract() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -1320,8 +1348,11 @@ mod test { fn call_contract_with_invalid_opcode() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -1372,8 +1403,11 @@ mod test { #[test] fn no_transfer_when_contract_call_fails() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(118_u64); let gas_price = U256::from(21000); @@ -1437,8 +1471,11 @@ mod test { fn call_precompiled_contract() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let target = H160::from_low_u64_be(4u64); // identity contract let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(118u64); @@ -1492,8 +1529,11 @@ mod test { fn call_ecrecover() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); // example from https://www.evm.codes/precompiled?fork=shanghai let data_str = "456e9aea5e197a1f1af7a3e85a3212fa4049a3ba34c2289b4c860fc0b0c64ef3000000000000000000000000000000000000000000000000000000000000001c9242685bf161793cc25603c231bc2f568eb630ea16aa137d2664ac80388256084f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852ada"; let data = hex::decode(data_str) @@ -1554,8 +1594,11 @@ mod test { fn create_and_call_contract() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -1656,8 +1699,11 @@ mod test { #[test] fn static_calls_cannot_update_storage() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117_u64); let caller = H160::from_low_u64_be(118_u64); @@ -1750,8 +1796,11 @@ mod test { #[test] fn static_calls_fail_when_logging() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117_u64); let caller = H160::from_low_u64_be(118_u64); @@ -1844,8 +1893,11 @@ mod test { #[test] fn logs_get_written_to_output() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117_u64); let caller = H160::from_low_u64_be(118_u64); @@ -1965,8 +2017,11 @@ mod test { #[test] fn no_logs_when_contract_reverts() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117_u64); let caller = H160::from_low_u64_be(118_u64); @@ -2071,8 +2126,11 @@ mod test { #[test] fn contract_selfdestruct_deletes_contract() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(42_u64); let caller = H160::from_low_u64_be(115_u64); @@ -2181,8 +2239,11 @@ mod test { #[test] fn selfdestruct_is_ignored_when_call_fails() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(42_u64); let caller = H160::from_low_u64_be(115_u64); @@ -2300,6 +2361,9 @@ mod test { fn test_chain_id() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let chain_id = U256::from(42); let mut chain_id_bytes = [0u8; 32]; chain_id.to_big_endian(&mut chain_id_bytes); @@ -2315,7 +2379,7 @@ mod test { u64::MAX, H160::zero(), ); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -2385,6 +2449,9 @@ mod test { fn test_base_fee_per_gas() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let base_fee_per_gas = U256::from(23000); let mut base_fee_per_gas_bytes = [0u8; 32]; base_fee_per_gas.to_big_endian(&mut base_fee_per_gas_bytes); @@ -2400,7 +2467,7 @@ mod test { u64::MAX, H160::zero(), ); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -2491,8 +2558,11 @@ mod test { #[test] fn evm_should_fail_gracefully_when_balance_overflow_occurs() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(523); let target = H160::from_low_u64_be(210); @@ -2539,8 +2609,11 @@ mod test { #[test] fn create_contract_gas_cost() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = None; @@ -2598,8 +2671,11 @@ mod test { #[test] fn create_contract_fail_gas_cost() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = None; @@ -2656,6 +2732,9 @@ mod test { fn test_transaction_data_cost() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let base_fee_per_gas = U256::from(23000); let block_fees = BlockFees::new( U256::one(), @@ -2669,7 +2748,7 @@ mod test { u64::MAX, H160::zero(), ); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -2726,6 +2805,9 @@ mod test { fn test_transaction_data_cost_non_zero() { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let base_fee_per_gas = U256::from(23000); let block_fees = BlockFees::new( U256::one(), @@ -2739,7 +2821,7 @@ mod test { u64::MAX, H160::zero(), ); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let target = H160::from_low_u64_be(117u64); let caller = H160::from_low_u64_be(118u64); @@ -2814,8 +2896,11 @@ mod test { ) -> Result, EthereumError> { // Arrange let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_low_u64_be(118u64); let gas_price = U256::from(1356); @@ -2894,8 +2979,11 @@ mod test { #[test] fn test_create_to_address_with_code_returns_error() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = @@ -2967,8 +3055,11 @@ mod test { #[test] fn test_caller_nonce_after_create() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = @@ -3067,8 +3158,11 @@ mod test { #[test] fn test_caller_nonce_after_create_collision() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = @@ -3175,8 +3269,11 @@ mod test { #[test] fn test_create_to_address_with_non_zero_nonce_returns_error() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = @@ -3240,8 +3337,9 @@ mod test { #[test] fn created_contract_start_at_nonce_one() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = None; @@ -3285,8 +3383,9 @@ mod test { #[test] fn call_contract_create_contract_with_insufficient_funds() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = H160::from_str("095e7baea6a6c7c4c2dfeb977efac326af552d87").unwrap(); @@ -3350,8 +3449,9 @@ mod test { #[test] fn nested_create_check_nonce_start_at_one() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_str("a94f5374fce5edbc8e2a8697c15331677e6ebf0b").unwrap(); @@ -3463,17 +3563,16 @@ mod test { } fn out_of_tick_scenario( + host: &mut impl Runtime, retriable: bool, ) -> ( - MockKernelHost, Result, EthereumError>, EthereumAccount, U256, u64, ) { - let mut host = MockKernelHost::default(); let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let callee = None; let caller = H160::from_low_u64_be(117); @@ -3490,19 +3589,14 @@ mod test { let initial_balance = gas_price .saturating_mul(gas_limit.into()) .saturating_mul(U256::from(2)); - set_balance( - &mut host, - &mut evm_account_storage, - &caller, - initial_balance, - ); + set_balance(host, &mut evm_account_storage, &caller, initial_balance); let path = account_path(&caller).unwrap(); - let account = evm_account_storage.get_or_create(&host, &path).unwrap(); - let initial_caller_nonce = account.nonce(&host).unwrap(); + let account = evm_account_storage.get_or_create(host, &path).unwrap(); + let initial_caller_nonce = account.nonce(host).unwrap(); let result = run_transaction( - &mut host, + host, &block, &mut evm_account_storage, &precompiles, @@ -3520,13 +3614,15 @@ mod test { None, ); - (host, result, account, initial_balance, initial_caller_nonce) + (result, account, initial_balance, initial_caller_nonce) } #[test] fn transaction_has_no_impact_if_retriable() { - let (host, result, caller, initial_caller_balance, initial_caller_nonce) = - out_of_tick_scenario(true); + let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; + let (result, caller, initial_caller_balance, initial_caller_nonce) = + out_of_tick_scenario(&mut host, true); let caller_balance = caller.balance(&host).unwrap(); let caller_nonce = caller.nonce(&host).unwrap(); @@ -3547,8 +3643,10 @@ mod test { #[test] fn non_retriable_transaction_pays_for_exhausted_ticks() { - let (host, result, caller, initial_caller_balance, initial_caller_nonce) = - out_of_tick_scenario(false); + let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; + let (result, caller, initial_caller_balance, initial_caller_nonce) = + out_of_tick_scenario(&mut host, false); let caller_balance = caller.balance(&host).unwrap(); let caller_nonce = caller.nonce(&host).unwrap(); @@ -3576,8 +3674,9 @@ mod test { #[ignore] fn multiple_call_all_the_way_to_1024() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_str("a94f5374fce5edbc8e2a8697c15331677e6ebf0b").unwrap(); @@ -3663,8 +3762,9 @@ mod test { #[test] fn multiple_call_fails_right_after_1024() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_str("a94f5374fce5edbc8e2a8697c15331677e6ebf0b").unwrap(); @@ -3748,8 +3848,9 @@ mod test { #[ignore] fn call_too_deep_not_revert() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_str("a94f5374fce5edbc8e2a8697c15331677e6ebf0b").unwrap(); @@ -3799,8 +3900,9 @@ mod test { // The test was a bit tweaked so that the called contract transfer 1 WEI to the called contract. let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let address_1 = @@ -3904,8 +4006,9 @@ mod test { // with the second data. let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let address_1 = @@ -3981,8 +4084,9 @@ mod test { #[test] fn nonce_bump_before_tx() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block = dummy_first_block(); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); let caller = H160::from_str("a94f5374fce5edbc8e2a8697c15331677e6ebf0b").unwrap(); diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs index 91f613ff8166..ec37a9c68524 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs @@ -161,7 +161,10 @@ mod tests { use evm::{Config, ExitError}; use primitive_types::{H160, U256}; use tezos_data_encoding::enc::BinWriter; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{ + runtime::{MockKernelHost, Runtime}, + safe_storage::SafeStorage, + }; use crate::{ account_storage::{init_account_storage, EthereumAccountStorage}, @@ -181,7 +184,7 @@ mod tests { #[allow(clippy::too_many_arguments)] fn execute_precompile( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, caller: H160, value: U256, @@ -194,7 +197,7 @@ mod tests { let config = Config::shanghai(); let callee = FA_BRIDGE_PRECOMPILE_ADDRESS; - let precompiles = precompiles::precompile_set::(true); + let precompiles = precompiles::precompile_set(true); let mut handler = EvmHandler::new( host, @@ -221,6 +224,9 @@ mod tests { #[test] fn fa_bridge_precompile_fails_due_to_bad_selector() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let outcome = execute_precompile( @@ -242,6 +248,9 @@ mod tests { #[test] fn fa_bridge_precompile_fails_due_to_low_gas_limit() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let outcome = execute_precompile( @@ -264,6 +273,9 @@ mod tests { #[test] fn fa_bridge_precompile_fails_due_to_non_zero_value() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let caller = H160::from_low_u64_be(1); @@ -293,6 +305,9 @@ mod tests { #[test] fn fa_bridge_precompile_fails_due_to_static_call() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let caller = H160::from_low_u64_be(1); @@ -315,6 +330,9 @@ mod tests { #[test] fn fa_bridge_precompile_fails_due_to_delegate_call() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let caller = H160::from_low_u64_be(1); @@ -322,7 +340,7 @@ mod tests { let block = dummy_first_block(); let config = Config::shanghai(); - let precompiles = precompiles::precompile_set::(true); + let precompiles = precompiles::precompile_set(true); let mut handler = EvmHandler::new( &mut mock_runtime, @@ -357,6 +375,9 @@ mod tests { #[test] fn fa_bridge_precompile_fails_due_to_invalid_input() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let outcome = execute_precompile( @@ -378,6 +399,9 @@ mod tests { #[test] fn fa_bridge_precompile_succeeds_without_l2_proxy_contract() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let ticket_owner = H160::from_low_u64_be(1); @@ -446,6 +470,9 @@ mod tests { #[test] fn fa_bridge_precompile_cannot_call_itself() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let mut evm_account_storage = init_account_storage().unwrap(); let system = H160::zero(); diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs index f11eeee487fe..126acd6dc758 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs @@ -288,18 +288,20 @@ mod test_helpers { use crate::NATIVE_TOKEN_TICKETER_PATH; use evm::Config; use evm::Transfer; - use host::runtime::Runtime; use primitive_types::{H160, U256}; use tezos_ethereum::block::BlockConstants; use tezos_ethereum::block::BlockFees; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{ + runtime::{MockKernelHost, Runtime}, + safe_storage::SafeStorage, + }; use super::precompile_set; const DUMMY_ALLOCATED_TICKS: u64 = 100_000_000; pub const DUMMY_TICKETER: &str = "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5"; pub fn set_balance( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -328,6 +330,9 @@ mod test_helpers { ) -> Result { let caller = H160::from_low_u64_be(118u64); let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + }; let block_fees = BlockFees::new( U256::from(21000), U256::from(21000), @@ -341,7 +346,7 @@ mod test_helpers { H160::zero(), ); let mut evm_account_storage = init_evm_account_storage().unwrap(); - let precompiles = precompile_set::(false); + let precompiles = precompile_set(false); let config = Config::shanghai(); let gas_price = U256::from(21000); @@ -385,7 +390,7 @@ mod test_helpers { ) } - fn set_ticketer(host: &mut MockKernelHost, address: &str) { + fn set_ticketer(host: &mut impl Runtime, address: &str) { host.store_write(&NATIVE_TOKEN_TICKETER_PATH, address.as_bytes(), 0) .unwrap(); } diff --git a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs index d40d220b32bb..53f364cce4bb 100644 --- a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs +++ b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs @@ -49,7 +49,7 @@ impl WithdrawalCounter for EthereumAccount { #[cfg(test)] mod tests { use primitive_types::U256; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; use tezos_smart_rollup_host::path::RefPath; use tezos_storage::read_u256_le_default; @@ -60,6 +60,9 @@ mod tests { #[test] fn withdrawal_counter_initializes_and_increments() { let mut mock_host = MockKernelHost::default(); + let mut mock_host = SafeStorage { + host: &mut mock_host, + }; let mut account = EthereumAccount::from_address(&SYSTEM_ACCOUNT_ADDRESS).unwrap(); let path = b"/evm/world_state/eth_accounts/0000000000000000000000000000000000000000/withdrawal_counter"; diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index 19e346888a65..b0386b2967c6 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -690,7 +690,10 @@ mod tests { transaction::TransactionType, tx_common::EthereumTransactionCommon, }; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{ + runtime::{MockKernelHost, Runtime}, + safe_storage::SafeStorage, + }; use tezos_smart_rollup_encoding::timestamp::Timestamp; use super::is_valid_ethereum_transaction_common; @@ -718,7 +721,7 @@ mod tests { } fn set_balance( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -778,6 +781,7 @@ mod tests { #[test] fn test_tx_is_valid() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -810,6 +814,7 @@ mod tests { #[test] fn test_tx_is_invalid_cannot_prepay() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -844,6 +849,7 @@ mod tests { #[test] fn test_tx_is_invalid_signature() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -878,6 +884,7 @@ mod tests { #[test] fn test_tx_is_invalid_wrong_nonce() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -914,6 +921,7 @@ mod tests { #[test] fn test_tx_is_invalid_wrong_chain_id() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -948,6 +956,7 @@ mod tests { #[test] fn test_tx_is_invalid_max_fee_less_than_base_fee() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -982,6 +991,7 @@ mod tests { #[test] fn test_tx_invalid_not_enough_gas_for_fee() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index 8e180f935e42..278dc0ddd09b 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -654,6 +654,7 @@ mod tests { use tezos_ethereum::tx_common::EthereumTransactionCommon; use tezos_evm_runtime::runtime::MockKernelHost; use tezos_evm_runtime::runtime::Runtime; + use tezos_evm_runtime::safe_storage::{TMP_WORLD_STATE_PATH, WORLD_STATE_PATH}; use tezos_smart_rollup_encoding::timestamp::Timestamp; use tezos_smart_rollup_host::runtime::Runtime as SdkRuntime; @@ -845,7 +846,7 @@ mod tests { } fn produce_block_with_several_valid_txs( - host: &mut Host, + host: &mut SafeStorage<&mut Host>, evm_account_storage: &mut EthereumAccountStorage, ) { let tx_hash_0 = [0; TRANSACTION_HASH_SIZE]; @@ -862,9 +863,17 @@ mod tests { }, ]; - store_blueprints(host, vec![blueprint(transactions)]); + store_blueprints(host.host, vec![blueprint(transactions)]); let sender = dummy_eth_caller(); + assert!(host + .host + .store_has(&TMP_WORLD_STATE_PATH) + .unwrap() + .is_none()); + if host.host.store_has(&WORLD_STATE_PATH).unwrap().is_some() { + host.start().unwrap() + }; set_balance( host, evm_account_storage, @@ -872,9 +881,10 @@ mod tests { U256::from(10000000000000000000u64), ); store_block_fees(host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); produce( - host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -896,11 +906,13 @@ mod tests { // Test if the invalid transactions are producing receipts fn test_invalid_transactions_receipt_status() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), ) .unwrap(); + host.promote().unwrap(); let tx_hash = [0; TRANSACTION_HASH_SIZE]; @@ -910,10 +922,11 @@ mod tests { }; let transactions: Vec = vec![invalid_tx]; - store_blueprints(&mut host, vec![blueprint(transactions)]); + store_blueprints(host.host, vec![blueprint(transactions)]); let mut evm_account_storage = init_account_storage().unwrap(); let sender = dummy_eth_caller(); + host.start().unwrap(); set_balance( &mut host, &mut evm_account_storage, @@ -921,8 +934,9 @@ mod tests { U256::from(30000u64), ); store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -930,21 +944,25 @@ mod tests { ) .expect("The block production failed."); + host.start().unwrap(); assert!( read_transaction_receipt_status(&mut host, &tx_hash).is_err(), "Invalid transaction should not have a receipt" ); + host.revert().unwrap(); } #[test] // Test if a valid transaction is producing a receipt with a success status fn test_valid_transactions_receipt_status() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), ) .unwrap(); + host.promote().unwrap(); let tx_hash = [0; TRANSACTION_HASH_SIZE]; @@ -954,10 +972,11 @@ mod tests { }; let transactions: Vec = vec![valid_tx]; - store_blueprints(&mut host, vec![blueprint(transactions)]); + store_blueprints(host.host, vec![blueprint(transactions)]); let sender = dummy_eth_caller(); let mut evm_account_storage = init_account_storage().unwrap(); + host.start().unwrap(); set_balance( &mut host, &mut evm_account_storage, @@ -965,9 +984,10 @@ mod tests { U256::from(1_000_000_000_000_000_000u64), ); store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -975,8 +995,10 @@ mod tests { ) .expect("The block production failed."); + host.start().unwrap(); let status = read_transaction_receipt_status(&mut host, &tx_hash) .expect("Should have found receipt"); + host.revert().unwrap(); assert_eq!(TransactionStatus::Success, status); } @@ -984,6 +1006,13 @@ mod tests { // Test if a valid transaction is producing a receipt with a contract address fn test_valid_transactions_receipt_contract_address() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; + crate::storage::store_minimum_base_fee_per_gas( + &mut host, + DUMMY_BASE_FEE_PER_GAS.into(), + ) + .unwrap(); + host.promote().unwrap(); let tx_hash = [0; TRANSACTION_HASH_SIZE]; let tx = dummy_eth_transaction_deploy(); @@ -997,10 +1026,11 @@ mod tests { }; let transactions: Vec = vec![valid_tx]; - store_blueprints(&mut host, vec![blueprint(transactions)]); + store_blueprints(host.host, vec![blueprint(transactions)]); let sender = H160::from_str("af1276cbb260bb13deddb4209ae99ae6e497f446").unwrap(); let mut evm_account_storage = init_account_storage().unwrap(); + host.start().unwrap(); set_balance( &mut host, &mut evm_account_storage, @@ -1008,17 +1038,20 @@ mod tests { U256::from(5000000000000000u64), ); store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, None, ) .expect("The block production failed."); + host.start().unwrap(); let receipt = read_transaction_receipt(&mut host, &tx_hash) .expect("should have found receipt"); + host.revert().unwrap(); assert_eq!(TransactionStatus::Success, receipt.status); assert_eq!( H160::from_str("af1276cbb260bb13deddb4209ae99ae6e497f446").unwrap(), @@ -1034,20 +1067,24 @@ mod tests { // Test if several valid transactions can be performed fn test_several_valid_transactions() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), ) .unwrap(); + host.promote().unwrap(); let mut evm_account_storage = init_account_storage().unwrap(); produce_block_with_several_valid_txs(&mut host, &mut evm_account_storage); + host.start().unwrap(); let dest_address = H160::from_str("423163e58aabec5daa3dd1130b759d24bef0f6ea").unwrap(); let dest_balance = get_balance(&mut host, &mut evm_account_storage, &dest_address); + host.revert().unwrap(); assert_eq!(dest_balance, U256::from(1000000000u64)) } @@ -1056,11 +1093,13 @@ mod tests { // Test if several valid proposals can produce valid blocks fn test_several_valid_proposals() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), ) .unwrap(); + host.promote().unwrap(); let tx_hash_0 = [0; TRANSACTION_HASH_SIZE]; let tx_hash_1 = [1; TRANSACTION_HASH_SIZE]; @@ -1076,12 +1115,13 @@ mod tests { }]; store_blueprints( - &mut host, + host.host, vec![blueprint(transaction_0), blueprint(transaction_1)], ); let sender = dummy_eth_caller(); let mut evm_account_storage = init_account_storage().unwrap(); + host.start().unwrap(); set_balance( &mut host, &mut evm_account_storage, @@ -1089,10 +1129,11 @@ mod tests { U256::from(10000000000000000000u64), ); store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); // Produce block for blueprint containing transaction_0 produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -1101,7 +1142,7 @@ mod tests { .expect("The block production failed."); // Produce block for blueprint containing transaction_1 produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -1109,10 +1150,12 @@ mod tests { ) .expect("The block production failed."); + host.start().unwrap(); let dest_address = H160::from_str("423163e58aabec5daa3dd1130b759d24bef0f6ea").unwrap(); let dest_balance = get_balance(&mut host, &mut evm_account_storage, &dest_address); + host.revert().unwrap(); assert_eq!(dest_balance, U256::from(1000000000u64)) } @@ -1121,8 +1164,11 @@ mod tests { // Test transfers gas consumption consistency fn test_cumulative_transfers_gas_consumption() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let base_gas = U256::from(21000); + crate::storage::store_minimum_base_fee_per_gas(&mut host, base_gas).unwrap(); + host.promote().unwrap(); let dummy_block_fees = dummy_block_fees(); let gas_for_fees = crate::fees::gas_for_fees( dummy_block_fees.da_fee_per_byte(), @@ -1146,10 +1192,11 @@ mod tests { }, ]; - store_blueprints(&mut host, vec![blueprint(transactions)]); + store_blueprints(host.host, vec![blueprint(transactions)]); let sender = dummy_eth_caller(); let mut evm_account_storage = init_account_storage().unwrap(); + host.start().unwrap(); set_balance( &mut host, &mut evm_account_storage, @@ -1157,19 +1204,22 @@ mod tests { U256::from(10000000000000000000u64), ); store_block_fees(&mut host, &dummy_block_fees).unwrap(); + host.promote().unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, None, ) .expect("The block production failed."); + host.start().unwrap(); let receipt0 = read_transaction_receipt(&mut host, &tx_hash_0) .expect("should have found receipt"); let receipt1 = read_transaction_receipt(&mut host, &tx_hash_1) .expect("should have found receipt"); + host.revert().unwrap(); assert_eq!(receipt0.cumulative_gas_used, base_gas + gas_for_fees); assert_eq!( @@ -1183,18 +1233,28 @@ mod tests { // a block production fn test_read_storage_current_block_after_block_production_with_filled_queue() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = init_account_storage().unwrap(); produce_block_with_several_valid_txs(&mut host, &mut evm_account_storage); + host.start().unwrap(); assert_current_block_reading_validity(&mut host); + host.revert().unwrap(); } #[test] // Test that the same transaction can not be replayed twice fn test_replay_attack() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; + crate::storage::store_minimum_base_fee_per_gas( + &mut host, + DUMMY_BASE_FEE_PER_GAS.into(), + ) + .unwrap(); + host.promote().unwrap(); let tx = Transaction { tx_hash: [0; TRANSACTION_HASH_SIZE], @@ -1203,10 +1263,11 @@ mod tests { let transactions = vec![tx.clone(), tx]; store_blueprints( - &mut host, + host.host, vec![blueprint(transactions.clone()), blueprint(transactions)], ); + host.start().unwrap(); let sender = dummy_eth_caller(); let initial_sender_balance = U256::from(10000000000000000000u64); let mut evm_account_storage = init_account_storage().unwrap(); @@ -1217,9 +1278,10 @@ mod tests { initial_sender_balance, ); store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -1227,11 +1289,13 @@ mod tests { ) .expect("The block production failed."); + host.start().unwrap(); let dest_address = H160::from_str("423163e58aabec5daa3dd1130b759d24bef0f6ea").unwrap(); let sender_balance = get_balance(&mut host, &mut evm_account_storage, &sender); let dest_balance = get_balance(&mut host, &mut evm_account_storage, &dest_address); + host.revert().unwrap(); let expected_dest_balance = U256::from(500000000u64); let expected_gas = 21000; @@ -1247,17 +1311,20 @@ mod tests { #[test] fn test_blocks_are_indexed() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), ) .unwrap(); + host.promote().unwrap(); let blocks_index = block_storage::internal_for_tests::init_blocks_index().unwrap(); - store_blueprints(&mut host, vec![blueprint(vec![])]); + store_blueprints(host.host, vec![blueprint(vec![])]); + host.start().unwrap(); let number_of_blocks_indexed = blocks_index.length(&host).unwrap(); let sender = dummy_eth_caller(); let mut evm_account_storage = init_account_storage().unwrap(); @@ -1268,8 +1335,9 @@ mod tests { U256::from(10000000000000000000u64), ); store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -1277,6 +1345,7 @@ mod tests { ) .expect("The block production failed."); + host.start().unwrap(); let new_number_of_blocks_indexed = blocks_index.length(&host).unwrap(); let current_block_hash = block_storage::read_current(&mut host) @@ -1291,12 +1360,16 @@ mod tests { Ok(current_block_hash), blocks_index.get_value(&host, new_number_of_blocks_indexed - 1) ); + host.revert().unwrap(); } - fn first_block(host: &mut MockHost) -> BlockConstants { - let timestamp = read_last_block_timestamp(host).unwrap_or(Timestamp::from(0)); + fn first_block( + host: &mut SafeStorage<&mut MockHost>, + ) -> BlockConstants { + let timestamp = + read_last_block_timestamp(host.host).unwrap_or(Timestamp::from(0)); let timestamp = U256::from(timestamp.as_u64()); - let chain_id = retrieve_chain_id(host); + let chain_id = retrieve_chain_id(host.host); let block_fees = retrieve_block_fees(host); assert!(chain_id.is_ok(), "chain_id should be defined"); assert!(block_fees.is_ok(), "block fees should be defined"); @@ -1313,6 +1386,7 @@ mod tests { fn test_stop_computation() { // init host let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let block_constants = first_block(&mut host); let precompiles = precompiles::precompile_set(false); @@ -1395,6 +1469,7 @@ mod tests { #[test] fn invalid_transaction_should_bump_nonce() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -1421,12 +1496,12 @@ mod tests { tx_hash, content: Ethereum(tx), }; - store_blueprints(&mut host, vec![blueprint(vec![transaction])]); + store_blueprints(host.host, vec![blueprint(vec![transaction])]); // Apply the transaction store_block_fees(&mut host, &dummy_block_fees()).unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -1467,46 +1542,54 @@ mod tests { #[test] fn test_first_blocks() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; + store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); // first block should be 0 let blueprint = almost_empty_blueprint(); - store_inbox_blueprint(&mut host, blueprint).expect("Should store a blueprint"); - store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + store_inbox_blueprint(host.host, blueprint).expect("Should store a blueprint"); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, None, ) .expect("Empty block should have been produced"); + host.start().unwrap(); check_current_block_number(&mut host, 0); + host.revert().unwrap(); // second block let blueprint = almost_empty_blueprint(); - store_inbox_blueprint(&mut host, blueprint).expect("Should store a blueprint"); + store_inbox_blueprint(host.host, blueprint).expect("Should store a blueprint"); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, None, ) .expect("Empty block should have been produced"); + host.start().unwrap(); check_current_block_number(&mut host, 1); + host.revert().unwrap(); // third block let blueprint = almost_empty_blueprint(); - store_inbox_blueprint(&mut host, blueprint).expect("Should store a blueprint"); + store_inbox_blueprint(host.host, blueprint).expect("Should store a blueprint"); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, None, ) .expect("Empty block should have been produced"); + host.start().unwrap(); check_current_block_number(&mut host, 2); + host.revert().unwrap(); } fn hash_from_nonce(nonce: u64) -> TransactionHash { @@ -1578,6 +1661,7 @@ mod tests { fn test_reboot_many_tx_one_proposal() { // init host let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1600,6 +1684,8 @@ mod tests { &sender, sender_initial_balance, ); + store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); // These transactions are generated with the loop.sol contract, which are: // - create the contract @@ -1625,9 +1711,9 @@ mod tests { wrap_transaction(2, loop_4600_tx), ]; - store_blueprints(&mut host, vec![blueprint(proposals)]); + store_blueprints(host.host, vec![blueprint(proposals)]); - host.reboot_left().expect("should be some reboot left"); + host.host.reboot_left().expect("should be some reboot left"); // Set the tick limit to 11bn ticks - 2bn, which is the old limit minus the safety margin. let limits = Limits { @@ -1640,16 +1726,17 @@ mod tests { ..Configuration::default() }; - store_block_fees(&mut host, &dummy_block_fees()).unwrap(); let computation_result = - produce(&mut host, DUMMY_CHAIN_ID, &mut configuration, None, None) + produce(host.host, DUMMY_CHAIN_ID, &mut configuration, None, None) .expect("Should have produced"); + host.start().unwrap(); // test no new block assert!( block_storage::read_current_number(&host).is_err(), "Should not have found current block number" ); + host.revert().unwrap(); // test reboot is set matches!(computation_result, ComputationResult::RebootNeeded); @@ -1659,6 +1746,7 @@ mod tests { fn test_reboot_many_tx_many_proposal() { // init host let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, @@ -1681,6 +1769,8 @@ mod tests { &sender, sender_initial_balance, ); + store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); // These transactions are generated with the loop.sol contract, which are: // - create the contract @@ -1708,7 +1798,7 @@ mod tests { ]), ]; - store_blueprints(&mut host, proposals); + store_blueprints(host.host, proposals); // Set the tick limit to 11bn ticks - 2bn, which is the old limit minus the safety margin. let limits = Limits { @@ -1720,15 +1810,14 @@ mod tests { limits, ..Configuration::default() }; - store_block_fees(&mut host, &dummy_block_fees()).unwrap(); let computation_result = - produce(&mut host, DUMMY_CHAIN_ID, &mut configuration, None, None) + produce(host.host, DUMMY_CHAIN_ID, &mut configuration, None, None) .expect("Should have produced"); // test reboot is set matches!(computation_result, ComputationResult::RebootNeeded); let computation_result = - produce(&mut host, DUMMY_CHAIN_ID, &mut configuration, None, None) + produce(host.host, DUMMY_CHAIN_ID, &mut configuration, None, None) .expect("Should have produced"); // test no new block @@ -1743,8 +1832,7 @@ mod tests { matches!(computation_result, ComputationResult::RebootNeeded); // The block is in progress, therefore it is in the safe storage. - let safe_host = SafeStorage { host: &mut host }; - let bip = read_block_in_progress(&safe_host) + let bip = read_block_in_progress(&host) .expect("Should be able to read the block in progress") .expect("The reboot context should have a block in progress"); @@ -1754,7 +1842,7 @@ mod tests { ); let _next_blueprint = - read_next_blueprint(&mut host, &mut Configuration::default()) + read_next_blueprint(host.host, &mut Configuration::default()) .expect("The next blueprint should be available"); } @@ -1772,6 +1860,7 @@ mod tests { // init host let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; // see // https://basescan.org/tx/0x07471adfe8f4ec553c1199f495be97fc8be8e0626ae307281c22534460184ed1 @@ -1799,7 +1888,7 @@ mod tests { let transactions: Vec = vec![tx]; - store_blueprints(&mut host, vec![blueprint(transactions)]); + store_blueprints(host.host, vec![blueprint(transactions)]); let sender = H160::from_str("05f32b3cc3888453ff71b01135b34ff8e41263f2").unwrap(); let mut evm_account_storage = init_account_storage().unwrap(); @@ -1809,9 +1898,10 @@ mod tests { &sender, U256::from(1_000_000_000_000_000_000u64), ); + host.promote().unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -1823,8 +1913,10 @@ mod tests { let expected_created_contract = H160::from_str("0xcA11bde05977b3631167028862bE2a173976CA11").unwrap(); + host.start().unwrap(); let receipt = read_transaction_receipt(&mut host, &tx_hash) .expect("Should have found receipt"); + host.revert().unwrap(); assert_eq!(TransactionStatus::Success, receipt.status); assert_eq!(Some(expected_created_contract), receipt.contract_address); } @@ -1833,6 +1925,7 @@ mod tests { fn test_non_retriable_transaction_are_marked_as_failed() { // init host let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1849,6 +1942,8 @@ mod tests { &sender, sender_initial_balance, ); + store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); // These transactions are generated with the loop.sol contract, which are: // - create the contract @@ -1868,7 +1963,7 @@ mod tests { let proposals_first_reboot = vec![wrap_transaction(0, create_transaction)]; - store_inbox_blueprint(&mut host, blueprint(proposals_first_reboot)).unwrap(); + store_inbox_blueprint(host.host, blueprint(proposals_first_reboot)).unwrap(); // Set the tick limit to 11bn ticks - 2bn, which is the old limit minus the safety margin. let limits = Limits { @@ -1881,29 +1976,32 @@ mod tests { ..Configuration::default() }; // sanity check: no current block + host.start().unwrap(); assert!( block_storage::read_current_number(&host).is_err(), "Should not have found current block number" ); - store_block_fees(&mut host, &dummy_block_fees()).unwrap(); - produce(&mut host, DUMMY_CHAIN_ID, &mut configuration, None, None) + host.revert().unwrap(); + produce(host.host, DUMMY_CHAIN_ID, &mut configuration, None, None) .expect("Should have produced"); + host.start().unwrap(); assert!( block_storage::read_current_number(&host).is_ok(), "Should have found a block" ); + host.revert().unwrap(); // We start a new proposal, calling produce again simulates a reboot. let proposals_second_reboot = vec![wrap_transaction(2, loop_5800_tx)]; - store_inbox_blueprint(&mut host, blueprint(proposals_second_reboot)).unwrap(); - store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + store_inbox_blueprint(host.host, blueprint(proposals_second_reboot)).unwrap(); - produce(&mut host, DUMMY_CHAIN_ID, &mut configuration, None, None) + produce(host.host, DUMMY_CHAIN_ID, &mut configuration, None, None) .expect("Should have produced"); + host.start().unwrap(); let block = block_storage::read_current(&mut host).expect("Should have found a block"); let failed_loop_hash = block @@ -1913,6 +2011,7 @@ mod tests { let failed_loop_status = storage::read_transaction_receipt_status(&mut host, failed_loop_hash) .expect("There should have been a receipt"); + host.revert().unwrap(); assert_eq!( failed_loop_status, @@ -1944,6 +2043,7 @@ mod tests { // Test if a valid transaction is producing a receipt with a success status fn test_type_propagation() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1971,7 +2071,7 @@ mod tests { let transactions: Vec = vec![valid_tx, valid_tx_eip1559, valid_tx_eip2930]; - store_blueprints(&mut host, vec![blueprint(transactions)]); + store_blueprints(host.host, vec![blueprint(transactions)]); let sender = dummy_eth_caller(); let mut evm_account_storage = init_account_storage().unwrap(); @@ -1982,9 +2082,10 @@ mod tests { U256::from(1_000_000_000_000_000_000u64), ); store_block_fees(&mut host, &dummy_block_fees()).unwrap(); + host.promote().unwrap(); produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut Configuration::default(), None, @@ -1992,6 +2093,7 @@ mod tests { ) .expect("The block production failed."); + host.start().unwrap(); let receipt = read_transaction_receipt(&mut host, &tx_hash) .expect("Should have found receipt"); assert_eq!(receipt.type_, TransactionType::Legacy); @@ -2003,5 +2105,6 @@ mod tests { let receipt_eip2930 = read_transaction_receipt(&mut host, &tx_hash_eip2930) .expect("Should have found receipt"); assert_eq!(receipt_eip2930.type_, TransactionType::Eip2930); + host.revert().unwrap(); } } diff --git a/etherlink/kernel_evm/kernel/src/bridge.rs b/etherlink/kernel_evm/kernel/src/bridge.rs index 0fd6fa892475..e4f40d2ca687 100644 --- a/etherlink/kernel_evm/kernel/src/bridge.rs +++ b/etherlink/kernel_evm/kernel/src/bridge.rs @@ -223,7 +223,7 @@ mod tests { use evm_execution::account_storage::init_account_storage; use primitive_types::{H160, U256}; use rlp::Decodable; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; use crate::{bridge::DEPOSIT_EVENT_TOPIC, CONFIG}; @@ -275,6 +275,7 @@ mod tests { #[test] fn deposit_execution_outcome_contains_event() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = init_account_storage().unwrap(); let deposit = dummy_deposit(); @@ -302,6 +303,7 @@ mod tests { #[test] fn deposit_execution_fails_due_to_balance_overflow() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = init_account_storage().unwrap(); let mut deposit = dummy_deposit(); diff --git a/etherlink/kernel_evm/kernel/src/fees.rs b/etherlink/kernel_evm/kernel/src/fees.rs index c2a0e82bf416..ced3eea74d63 100644 --- a/etherlink/kernel_evm/kernel/src/fees.rs +++ b/etherlink/kernel_evm/kernel/src/fees.rs @@ -311,7 +311,7 @@ mod tests { use evm::ExitSucceed; use evm_execution::account_storage::{account_path, EthereumAccountStorage}; use primitive_types::{H160, U256}; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; use proptest::prelude::*; @@ -363,6 +363,7 @@ mod tests { fn apply_updates_balances_no_sequencer() { // Arrange let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); @@ -400,6 +401,7 @@ mod tests { fn apply_updates_balances_with_sequencer() { // Arrange let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let sequencer_address = address_from_str("0123456789ABCDEF0123456789ABCDEF01234567"); @@ -457,6 +459,7 @@ mod tests { fn apply_fails_user_charge_too_large() { // Arrange let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); @@ -510,7 +513,7 @@ mod tests { } fn get_balance( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: H160, ) -> U256 { @@ -521,7 +524,7 @@ mod tests { } fn set_balance( - host: &mut MockKernelHost, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: H160, balance: U256, diff --git a/etherlink/kernel_evm/kernel/src/gas_price.rs b/etherlink/kernel_evm/kernel/src/gas_price.rs index 8d79fec4f759..7696f9a18aaf 100644 --- a/etherlink/kernel_evm/kernel/src/gas_price.rs +++ b/etherlink/kernel_evm/kernel/src/gas_price.rs @@ -155,7 +155,10 @@ mod test { use proptest::prelude::*; use std::collections::VecDeque; use tezos_ethereum::block::BlockConstants; - use tezos_evm_runtime::runtime::{MockKernelHost, Runtime}; + use tezos_evm_runtime::{ + runtime::{MockKernelHost, Runtime}, + safe_storage::SafeStorage, + }; proptest! { #[test] @@ -186,6 +189,7 @@ mod test { #[test] fn gas_price_responds_to_load() { let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let timestamp = 0_i64; let block_fees = crate::retrieve_block_fees(&mut host).unwrap(); let dummy_block_constants = BlockConstants::first_block( diff --git a/etherlink/kernel_evm/kernel/src/inbox.rs b/etherlink/kernel_evm/kernel/src/inbox.rs index 7f470cc96b07..d529626ea534 100644 --- a/etherlink/kernel_evm/kernel/src/inbox.rs +++ b/etherlink/kernel_evm/kernel/src/inbox.rs @@ -1399,7 +1399,7 @@ mod tests { let path = blueprint_path(unsigned_blueprint.number).unwrap(); // The blueprint was valid if it was stored in the storage. - host.host.store_has(&path).unwrap().is_some() + host.store_has(&path).unwrap().is_some() } #[test] diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index ef13486007cd..33a4b5110aef 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -533,12 +533,15 @@ mod tests { fn test_reboot_during_block_production() { // init host let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; + let block_fees = dummy_block_fees(); crate::storage::store_minimum_base_fee_per_gas( &mut host, - DUMMY_BASE_FEE_PER_GAS.into(), + block_fees.minimum_base_fee_per_gas(), ) .unwrap(); + crate::storage::store_da_fee(&mut host, block_fees.da_fee_per_byte()).unwrap(); // sanity check: no current block assert!( @@ -556,6 +559,7 @@ mod tests { &sender, sender_initial_balance, ); + host.promote().unwrap(); // These transactions are generated with the loop.sol contract, which are: // - create the contract @@ -584,7 +588,7 @@ mod tests { ]; // Store blueprints for (i, blueprint) in proposals.into_iter().enumerate() { - store_inbox_blueprint_by_number(&mut host, blueprint, U256::from(i)) + store_inbox_blueprint_by_number(host.host, blueprint, U256::from(i)) .expect("Should have stored blueprint"); } // the upgrade mechanism should not start otherwise it will fail @@ -592,11 +596,9 @@ mod tests { preimage_hash: [0u8; PREIMAGE_HASH_SIZE], activation_timestamp: Timestamp::from(1_000_000i64), }; - crate::upgrade::store_kernel_upgrade(&mut host, &broken_kernel_upgrade) + crate::upgrade::store_kernel_upgrade(host.host, &broken_kernel_upgrade) .expect("Should be able to store kernel upgrade"); - let block_fees = dummy_block_fees(); - // Set the tick limit to 11bn ticks - 2bn, which is the old limit minus the safety margin. let limits = Limits { maximum_allowed_ticks: 9_000_000_000, @@ -608,16 +610,9 @@ mod tests { ..Configuration::default() }; - crate::storage::store_minimum_base_fee_per_gas( - &mut host, - block_fees.minimum_base_fee_per_gas(), - ) - .unwrap(); - crate::storage::store_da_fee(&mut host, block_fees.da_fee_per_byte()).unwrap(); - // If the upgrade is started, it should raise an error let computation_result = crate::block::produce( - &mut host, + host.host, DUMMY_CHAIN_ID, &mut configuration, None, @@ -626,12 +621,14 @@ mod tests { .expect("Should have produced"); // test there is a new block + host.start().unwrap(); assert_eq!( block_storage::read_current_number(&host) .expect("should have found a block number"), U256::zero(), "There should have been a block registered" ); + host.revert().unwrap(); // test reboot is set matches!( @@ -644,6 +641,7 @@ mod tests { fn load_block_fees_new() { // Arrange let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; // Act let result = crate::retrieve_block_fees(&mut host); @@ -666,6 +664,7 @@ mod tests { // Arrange let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let min_base_fee = U256::from(17); tezos_storage::write_u256_le(&mut host, &min_path, min_base_fee).unwrap(); @@ -692,12 +691,14 @@ mod tests { b"KT1DWVsu4Jtu2ficZ1qtNheGPunm5YVniegT", ) .unwrap(); - store_chain_id(&mut safe_storage, DUMMY_CHAIN_ID).unwrap(); + safe_storage.promote().unwrap(); + store_chain_id(safe_storage.host, DUMMY_CHAIN_ID).unwrap(); // run level in order to initialize outbox counter (by SOL message) let level = safe_storage.host.host.run_level(|_| ()); // provision sender account + safe_storage.start().unwrap(); let sender = H160::from_str("af1276cbb260bb13deddb4209ae99ae6e497f446").unwrap(); let sender_initial_balance = U256::from(10000000000000000000u64); let mut evm_account_storage = account_storage::init_account_storage().unwrap(); @@ -707,6 +708,7 @@ mod tests { &sender, sender_initial_balance, ); + safe_storage.promote().unwrap(); // cast calldata "withdraw_base58(string)" "tz1RjtZUVeLhADFHDL8UwDZA6vjWWhojpu5w": let data = hex::decode( @@ -763,12 +765,14 @@ mod tests { safe_storage.host.host.add_external(message); // run kernel twice to get to the stage with block creation: - main(&mut safe_storage).expect("Kernel error"); - main(&mut safe_storage).expect("Kernel error"); + main(safe_storage.host).expect("Kernel error"); + main(safe_storage.host).expect("Kernel error"); // verify outbox is not empty + safe_storage.start().unwrap(); let outbox = safe_storage.host.host.outbox_at(level + 1); assert!(!outbox.is_empty()); + safe_storage.revert().unwrap(); // check message contents: let message_bytes = &outbox[0]; @@ -805,13 +809,10 @@ mod tests { fn send_fa_deposit(enable_fa_bridge: bool) -> Option { // init host let mut mock_host = MockKernelHost::default(); - let mut safe_storage = SafeStorage { - host: &mut mock_host, - }; // enable FA bridge feature if enable_fa_bridge { - safe_storage + mock_host .store_write_all(&ENABLE_FA_BRIDGE, &[1u8]) .unwrap(); } @@ -849,12 +850,12 @@ mod tests { "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5", "tz1P2Po7YM526ughEsRbY4oR9zaUPDZjxFrb", ); - safe_storage.host.host.add_transfer(payload, &metadata); + mock_host.host.add_transfer(payload, &metadata); // run kernel - main(&mut safe_storage).expect("Kernel error"); + main(&mut mock_host).expect("Kernel error"); // QUESTION: looks like to get to the stage with block creation we need to call main twice (maybe check blueprint instead?) [1] - main(&mut safe_storage).expect("Kernel error"); + main(&mut mock_host).expect("Kernel error"); // reconstruct ticket let ticket = FA2_1Ticket::new( @@ -876,7 +877,7 @@ mod tests { let deposit = FaDeposit { amount: 42.into(), proxy: Some(H160([2u8; 20])), - inbox_level: safe_storage.host.host.level(), // level not yet advanced + inbox_level: mock_host.host.level(), // level not yet advanced inbox_msg_id: 2, receiver: H160([1u8; 20]), ticket_hash: ticket_hash(&ticket).unwrap(), @@ -885,7 +886,13 @@ mod tests { let tx_hash = deposit.hash(&[0u8; 20]); // read transaction receipt - read_transaction_receipt_status(&mut safe_storage, &tx_hash.0).ok() + let mut safe_storage = SafeStorage { + host: &mut mock_host, + }; + safe_storage.start().unwrap(); + let res = read_transaction_receipt_status(&mut safe_storage, &tx_hash.0).ok(); + safe_storage.revert().unwrap(); + res } #[test] @@ -901,24 +908,24 @@ mod tests { fn send_fa_withdrawal(enable_fa_bridge: bool) -> Vec> { // init host let mut mock_host = MockKernelHost::default(); - let mut safe_storage = SafeStorage { - host: &mut mock_host, - }; // enable FA bridge feature if enable_fa_bridge { - safe_storage + mock_host .store_write_all(&ENABLE_FA_BRIDGE, &[1u8]) .unwrap(); } // run level in order to initialize outbox counter (by SOL message) - let level = safe_storage.host.host.run_level(|_| ()); + let level = mock_host.host.run_level(|_| ()); // provision sender account let sender = H160::from_str("af1276cbb260bb13deddb4209ae99ae6e497f446").unwrap(); let sender_initial_balance = U256::from(10000000000000000000u64); let mut evm_account_storage = account_storage::init_account_storage().unwrap(); + let mut safe_storage = SafeStorage { + host: &mut mock_host, + }; set_balance( &mut safe_storage, &mut evm_account_storage, @@ -939,6 +946,7 @@ mod tests { &sender, amount, ); + safe_storage.promote().unwrap(); // construct withdraw calldata let (ticketer, content) = ticket_id(&ticket); @@ -998,9 +1006,9 @@ mod tests { safe_storage.host.host.add_external(message); // run kernel - main(&mut safe_storage).expect("Kernel error"); + main(safe_storage.host).expect("Kernel error"); // QUESTION: looks like to get to the stage with block creation we need to call main twice (maybe check blueprint instead?) [2] - main(&mut safe_storage).expect("Kernel error"); + main(safe_storage.host).expect("Kernel error"); safe_storage.host.host.outbox_at(level + 1) } diff --git a/etherlink/kernel_evm/kernel/src/stage_one.rs b/etherlink/kernel_evm/kernel/src/stage_one.rs index fca43f7c4f34..e5171f86ba83 100644 --- a/etherlink/kernel_evm/kernel/src/stage_one.rs +++ b/etherlink/kernel_evm/kernel/src/stage_one.rs @@ -191,7 +191,7 @@ mod tests { use rlp::Encodable; use tezos_crypto_rs::hash::{HashTrait, SecretKeyEd25519, UnknownSignature}; use tezos_data_encoding::types::Bytes; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; use tezos_smart_rollup::{ michelson::{ ticket::FA2_1Ticket, MichelsonBytes, MichelsonOption, MichelsonOr, @@ -551,8 +551,9 @@ mod tests { }; // The dummy chunk in the inbox is registered at block 10 + let mut host = SafeStorage { host: &mut host }; store_current_number(&mut host, U256::from(9)).unwrap(); - if read_next_blueprint(&mut host, &mut conf) + if read_next_blueprint(host.host, &mut conf) .expect("Blueprint reading shouldn't fail") .0 .is_some() diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index db66f9c7b386..cbcd0bfb8c24 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -941,12 +941,13 @@ pub fn read_delayed_transaction_bridge( #[cfg(test)] mod tests { - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; #[test] fn update_burned_fees() { // Arrange let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let fst = 17.into(); let snd = 19.into(); -- GitLab From 6b85d6848f704687e44e83679e79e85a25ddfc6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 18:30:12 +0200 Subject: [PATCH 10/31] Etherlink/Kernel: Relative Runtime --- etherlink/kernel_evm/runtime/src/lib.rs | 1 + .../runtime/src/relative_runtime.rs | 235 ++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 etherlink/kernel_evm/runtime/src/relative_runtime.rs diff --git a/etherlink/kernel_evm/runtime/src/lib.rs b/etherlink/kernel_evm/runtime/src/lib.rs index fc7a995790bb..dff1c105fdaf 100644 --- a/etherlink/kernel_evm/runtime/src/lib.rs +++ b/etherlink/kernel_evm/runtime/src/lib.rs @@ -5,5 +5,6 @@ pub mod extensions; pub mod internal_runtime; pub mod mock_internal; +pub mod relative_runtime; pub mod runtime; pub mod safe_storage; diff --git a/etherlink/kernel_evm/runtime/src/relative_runtime.rs b/etherlink/kernel_evm/runtime/src/relative_runtime.rs new file mode 100644 index 000000000000..6c4d50170ec0 --- /dev/null +++ b/etherlink/kernel_evm/runtime/src/relative_runtime.rs @@ -0,0 +1,235 @@ +// SPDX-FileCopyrightText: 2023 Nomadic Labs +// +// SPDX-License-Identifier: MIT + +use crate::extensions::WithGas; +use crate::internal_runtime::{ExtendedRuntime, InternalRuntime}; +use crate::runtime::Runtime; +use tezos_evm_logging::Verbosity; +use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; +use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; +use tezos_smart_rollup_host::{ + input::Message, + metadata::RollupMetadata, + path::{concat, OwnedPath, Path, RefPath}, + runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, +}; + +pub struct RelativeRuntime { + pub root: &'static RefPath<'static>, + pub host: Host, +} + +impl RelativeRuntime { + pub fn absolute_path(&self, path: &impl Path) -> Result { + concat(self.root, path).map_err(|_| RuntimeError::PathNotFound) + } +} + +impl InternalRuntime for RelativeRuntime<&mut Host> { + fn __internal_store_get_hash( + &mut self, + path: &P, + ) -> Result, RuntimeError> { + self.host.__internal_store_get_hash(path) + } +} + +impl ExtendedRuntime for RelativeRuntime<&mut Host> { + #[inline(always)] + fn store_get_hash(&mut self, path: &P) -> Result, RuntimeError> { + let path = self.absolute_path(path)?; + self.__internal_store_get_hash(&path) + } +} + +impl SdkRuntime for RelativeRuntime<&mut Host> { + #[inline(always)] + fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { + self.host.write_output(from) + } + + #[inline(always)] + fn write_debug(&self, msg: &str) { + self.host.write_debug(msg) + } + + #[inline(always)] + fn read_input(&mut self) -> Result, RuntimeError> { + self.host.read_input() + } + + #[inline(always)] + fn store_has(&self, path: &P) -> Result, RuntimeError> { + let path = self.absolute_path(path)?; + self.host.store_has(&path) + } + + #[inline(always)] + fn store_read( + &self, + path: &P, + from_offset: usize, + max_bytes: usize, + ) -> Result, RuntimeError> { + let path = self.absolute_path(path)?; + self.host.store_read(&path, from_offset, max_bytes) + } + + #[inline(always)] + fn store_read_slice( + &self, + path: &P, + from_offset: usize, + buffer: &mut [u8], + ) -> Result { + let path = self.absolute_path(path)?; + self.host.store_read_slice(&path, from_offset, buffer) + } + + #[inline(always)] + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + let path = self.absolute_path(path)?; + self.host.store_read_all(&path) + } + + #[inline(always)] + fn store_write( + &mut self, + path: &P, + src: &[u8], + at_offset: usize, + ) -> Result<(), RuntimeError> { + let path = self.absolute_path(path)?; + self.host.store_write(&path, src, at_offset) + } + + #[inline(always)] + fn store_write_all( + &mut self, + path: &P, + src: &[u8], + ) -> Result<(), RuntimeError> { + let path = self.absolute_path(path)?; + self.host.store_write_all(&path, src) + } + + #[inline(always)] + fn store_delete(&mut self, path: &P) -> Result<(), RuntimeError> { + let path = self.absolute_path(path)?; + self.host.store_delete(&path) + } + + #[inline(always)] + fn store_delete_value(&mut self, path: &P) -> Result<(), RuntimeError> { + let path = self.absolute_path(path)?; + self.host.store_delete_value(&path) + } + + #[inline(always)] + fn store_count_subkeys(&self, prefix: &P) -> Result { + let prefix = self.absolute_path(prefix)?; + self.host.store_count_subkeys(&prefix) + } + + #[inline(always)] + fn store_move( + &mut self, + from_path: &impl Path, + to_path: &impl Path, + ) -> Result<(), RuntimeError> { + let from_path = self.absolute_path(from_path)?; + let to_path = self.absolute_path(to_path)?; + self.host.store_move(&from_path, &to_path) + } + + #[inline(always)] + fn store_copy( + &mut self, + from_path: &impl Path, + to_path: &impl Path, + ) -> Result<(), RuntimeError> { + let from_path = self.absolute_path(from_path)?; + let to_path = self.absolute_path(to_path)?; + self.host.store_copy(&from_path, &to_path) + } + + #[inline(always)] + fn reveal_preimage( + &self, + hash: &[u8; PREIMAGE_HASH_SIZE], + destination: &mut [u8], + ) -> Result { + self.host.reveal_preimage(hash, destination) + } + + #[inline(always)] + fn store_value_size(&self, path: &impl Path) -> Result { + let path = self.absolute_path(path)?; + self.host.store_value_size(&path) + } + + #[inline(always)] + fn mark_for_reboot(&mut self) -> Result<(), RuntimeError> { + self.host.mark_for_reboot() + } + + #[inline(always)] + fn reveal_metadata(&self) -> RollupMetadata { + self.host.reveal_metadata() + } + + #[inline(always)] + fn reveal_dal_page( + &self, + published_level: i32, + slot_index: u8, + page_index: i16, + destination: &mut [u8], + ) -> Result { + self.host + .reveal_dal_page(published_level, slot_index, page_index, destination) + } + + #[inline(always)] + fn reveal_dal_parameters(&self) -> RollupDalParameters { + self.host.reveal_dal_parameters() + } + + #[inline(always)] + fn last_run_aborted(&self) -> Result { + self.host.last_run_aborted() + } + + #[inline(always)] + fn upgrade_failed(&self) -> Result { + self.host.upgrade_failed() + } + + #[inline(always)] + fn restart_forced(&self) -> Result { + self.host.restart_forced() + } + + #[inline(always)] + fn reboot_left(&self) -> Result { + self.host.reboot_left() + } + + #[inline(always)] + fn runtime_version(&self) -> Result { + self.host.runtime_version() + } +} + +impl Verbosity for RelativeRuntime<&mut Host> { + fn verbosity(&self) -> tezos_evm_logging::Level { + self.host.verbosity() + } +} + +impl WithGas for RelativeRuntime<&mut Host> { + fn add_execution_gas(&mut self, gas: u64) { + self.host.add_execution_gas(gas) + } +} -- GitLab From 6c8adf213f616ec0def830ee9b850706cfc23193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 12 Nov 2024 12:06:19 +0100 Subject: [PATCH 11/31] Kernel SDK: make meta path of outbox mandatory --- etherlink/kernel_evm/kernel/src/apply.rs | 3 +++ etherlink/kernel_evm/kernel/src/block.rs | 14 +++++++++-- src/kernel_sdk/sdk/src/outbox.rs | 30 +++++++++++------------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index b0386b2967c6..10f952d58476 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -501,6 +501,9 @@ fn apply_fa_deposit( pub const WITHDRAWAL_OUTBOX_QUEUE: RefPath = RefPath::assert_from(b"/evm/world_state/__outbox_queue"); +pub const WITHDRAWAL_OUTBOX_QUEUE_META: RefPath = + RefPath::assert_from(b"/evm/world_state/__outbox_queue/meta"); + pub struct ExecutionInfo { pub receipt_info: TransactionReceiptInfo, pub object_info: TransactionObjectInfo, diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index 278dc0ddd09b..e3a7c90d24dc 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -7,6 +7,7 @@ use crate::apply::{ apply_transaction, ExecutionInfo, ExecutionResult, Validity, WITHDRAWAL_OUTBOX_QUEUE, + WITHDRAWAL_OUTBOX_QUEUE_META, }; use crate::block_storage; use crate::blueprint_storage::{ @@ -465,7 +466,11 @@ pub fn produce( let at_most_one_block = host.store_has(&AT_MOST_ONE_BLOCK)?.is_some(); let mut safe_host = SafeStorage { host }; - let outbox_queue = OutboxQueue::new(&WITHDRAWAL_OUTBOX_QUEUE, u32::MAX)?; + let outbox_queue = OutboxQueue::new( + &WITHDRAWAL_OUTBOX_QUEUE, + &WITHDRAWAL_OUTBOX_QUEUE_META, + u32::MAX, + )?; let precompiles = precompiles::precompile_set::>(config.enable_fa_bridge); @@ -1421,7 +1426,12 @@ mod tests { // act let result = compute( &mut host, - &OutboxQueue::new(&WITHDRAWAL_OUTBOX_QUEUE, u32::MAX).unwrap(), + &OutboxQueue::new( + &WITHDRAWAL_OUTBOX_QUEUE, + &WITHDRAWAL_OUTBOX_QUEUE_META, + u32::MAX, + ) + .unwrap(), &mut block_in_progress, &block_constants, &precompiles, diff --git a/src/kernel_sdk/sdk/src/outbox.rs b/src/kernel_sdk/sdk/src/outbox.rs index 9bf8b5e798d7..b2b1b3f9c2b0 100644 --- a/src/kernel_sdk/sdk/src/outbox.rs +++ b/src/kernel_sdk/sdk/src/outbox.rs @@ -97,7 +97,7 @@ const META_SUFFIX: RefPath = RefPath::assert_from(b"/meta"); /// the queue, and be written to the outbox. pub const OUTBOX_QUEUE: OutboxQueue<'static, RefPath> = OutboxQueue { root: &OUTBOX_QUEUE_ROOT, - meta: None, + meta: &OUTBOX_QUEUE_META, max: u16::MAX as u32, }; @@ -107,7 +107,7 @@ pub const OUTBOX_QUEUE: OutboxQueue<'static, RefPath> = OutboxQueue { #[derive(Debug)] pub struct OutboxQueue<'a, P: Path> { root: &'a P, - meta: Option, + meta: &'a P, max: u32, } @@ -116,20 +116,26 @@ impl<'a, P: Path> OutboxQueue<'a, P> { /// /// - `root` specifies the path in storage that the queue will be stored at. /// - `max` allows you to specify a different maximum queue length to the default. - pub fn new(root: &'a P, max: u32) -> Result { + pub fn new(root: &'a P, meta: &'a P, max: u32) -> Result { // Ensure we have enough room for the hex-encoded u32 indexes if root.size() > PATH_MAX_SIZE - 2 * core::mem::size_of::() + 1 { return Err(PathError::PathTooLong); } // The meta suffix is less long than the index paths. - let meta = concat(root, &META_SUFFIX)?; + let meta_expected = concat(root, &META_SUFFIX)?; + if meta_expected == meta.into() { Ok(Self { root, max, - meta: Some(meta), + meta, }) + } else { + // TODO: add a proper error to PathError for this case + Err(PathError::PathTooLong) + } + } /// Queues a message into the outbox queue. @@ -239,11 +245,8 @@ impl<'a, P: Path> OutboxQueue<'a, P> { const BUFF_SIZE: usize = 2 * core::mem::size_of::(); let mut buffer = [0; BUFF_SIZE]; - let result = if let Some(meta) = &self.meta { - host.store_read_slice(meta, 0, buffer.as_mut_slice()) - } else { - host.store_read_slice(&OUTBOX_QUEUE_META, 0, buffer.as_mut_slice()) - }; + let result = + host.store_read_slice(self.meta, 0, buffer.as_mut_slice()); let Ok(BUFF_SIZE) = result else { return (0, 0) }; @@ -266,12 +269,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { let buffer = [s0, s1, s2, s3, l0, l1, l2, l3]; - if let Some(meta) = &self.meta { - host.store_write(meta, buffer.as_slice(), 0).unwrap(); - } else { - host.store_write(&OUTBOX_QUEUE_META, buffer.as_slice(), 0) - .unwrap(); - } + host.store_write(self.meta, buffer.as_slice(), 0).unwrap(); } } -- GitLab From 17cc6c2f13a249e6d9127bcec118179c38c2c62a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Thu, 24 Oct 2024 13:19:54 +0200 Subject: [PATCH 12/31] INVASIVE: Etherlink/Kernel: Relative versus absolute paths --- .../kernel_evm/evm_evaluation/src/evalhost.rs | 49 ++++--- .../evm_execution/src/account_storage.rs | 26 ++-- .../evm_execution/src/code_storage.rs | 14 +- .../src/fa_bridge/ticket_table.rs | 4 +- etherlink/kernel_evm/evm_execution/src/lib.rs | 2 +- .../kernel_evm/evm_execution/src/storage.rs | 20 +-- .../evm_execution/src/withdrawal_counter.rs | 3 +- .../kernel_evm/indexable_storage/src/lib.rs | 14 +- etherlink/kernel_evm/kernel/src/apply.rs | 8 +- etherlink/kernel_evm/kernel/src/block.rs | 8 +- .../kernel/src/block_in_progress.rs | 17 +-- .../kernel_evm/kernel/src/block_storage.rs | 11 +- .../kernel/src/blueprint_storage.rs | 27 ++-- .../kernel_evm/kernel/src/delayed_inbox.rs | 4 +- .../kernel/src/evm_node_entrypoint.rs | 2 +- .../kernel_evm/kernel/src/fallback_upgrade.rs | 4 +- .../kernel_evm/kernel/src/linked_list.rs | 32 +++-- etherlink/kernel_evm/kernel/src/migration.rs | 4 +- .../kernel_evm/kernel/src/reveal_storage.rs | 8 +- etherlink/kernel_evm/kernel/src/storage.rs | 121 ++++++++++-------- etherlink/kernel_evm/kernel/src/upgrade.rs | 9 +- .../runtime/src/internal_runtime.rs | 9 +- .../kernel_evm/runtime/src/mock_internal.rs | 2 +- .../runtime/src/relative_runtime.rs | 55 +++++--- etherlink/kernel_evm/runtime/src/runtime.rs | 46 ++++--- .../kernel_evm/runtime/src/safe_storage.rs | 61 +++++---- etherlink/kernel_evm/storage/src/lib.rs | 48 ++++--- .../encoding/src/dac/certificate.rs | 2 +- src/kernel_sdk/host/src/lib.rs | 2 +- src/kernel_sdk/host/src/path.rs | 81 +++++++----- src/kernel_sdk/host/src/runtime.rs | 104 +++++++-------- src/kernel_sdk/installer-client/src/config.rs | 4 +- src/kernel_sdk/installer-client/src/lib.rs | 4 +- .../installer-config/src/binary/bin.rs | 10 +- .../installer-config/src/binary/instr.rs | 14 +- .../installer-config/src/binary/nom.rs | 20 +-- .../installer-config/src/binary/preimage.rs | 8 +- .../installer-config/src/yaml/convert.rs | 2 +- src/kernel_sdk/installer-kernel/src/instr.rs | 4 +- src/kernel_sdk/installer-kernel/src/lib.rs | 6 +- .../mock/src/state/in_memory_store.rs | 4 +- src/kernel_sdk/sdk/src/outbox.rs | 16 +-- src/kernel_sdk/storage/src/layer.rs | 18 +-- src/kernel_sdk/storage/src/storage.rs | 36 +++--- 44 files changed, 522 insertions(+), 421 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index 2b458bf709b0..50891f94f8c4 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -14,7 +14,7 @@ use tezos_smart_rollup_host::{ dal_parameters::RollupDalParameters, input::Message, metadata::RollupMetadata, - path::{concat, OwnedPath, Path, RefPath}, + path::{force_concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; @@ -36,10 +36,10 @@ impl<'a> EvalHost<'a> { } } -const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); +const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); -fn world_state_path(p: &impl Path) -> Result { - concat(&WORLD_STATE_PATH, p).map_err(|_| RuntimeError::PathNotFound) +fn world_state_path(p: &impl Path) -> Result, RuntimeError> { + force_concat(&WORLD_STATE_PATH, p).map_err(|_| RuntimeError::PathNotFound) } impl<'a> SdkRuntime for EvalHost<'a> { @@ -62,13 +62,16 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_has(&self, path: &T) -> Result, RuntimeError> { + fn store_has>( + &self, + path: &T, + ) -> Result, RuntimeError> { let path = world_state_path(path)?; self.host.store_has(&path) } #[inline(always)] - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -79,7 +82,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -90,13 +93,13 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { let path = world_state_path(path)?; self.host.store_read_all(&path) } #[inline(always)] - fn store_write( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -107,7 +110,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_write_all( + fn store_write_all>( &mut self, path: &T, src: &[u8], @@ -117,19 +120,25 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { let path = world_state_path(path)?; self.host.store_delete(&path) } #[inline(always)] - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete_value>( + &mut self, + path: &T, + ) -> Result<(), RuntimeError> { let path = world_state_path(path)?; self.host.store_delete_value(&path) } #[inline(always)] - fn store_count_subkeys(&self, prefix: &T) -> Result { + fn store_count_subkeys>( + &self, + prefix: &T, + ) -> Result { let prefix = world_state_path(prefix)?; self.host.store_count_subkeys(&prefix) } @@ -137,8 +146,8 @@ impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = world_state_path(from_path)?; let to_path = world_state_path(to_path)?; @@ -148,8 +157,8 @@ impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = world_state_path(from_path)?; let to_path = world_state_path(to_path)?; @@ -166,7 +175,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { let path = world_state_path(path)?; self.host.store_value_size(&path) } @@ -225,7 +234,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } impl<'a> InternalRuntime for EvalHost<'a> { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, tezos_smart_rollup_host::runtime::RuntimeError> { @@ -234,7 +243,7 @@ impl<'a> InternalRuntime for EvalHost<'a> { } impl<'a> ExtendedRuntime for EvalHost<'a> { - fn store_get_hash( + fn store_get_hash>( &mut self, path: &P, ) -> Result, tezos_smart_rollup_host::runtime::RuntimeError> { diff --git a/etherlink/kernel_evm/evm_execution/src/account_storage.rs b/etherlink/kernel_evm/evm_execution/src/account_storage.rs index 95eb38b0078c..3a5251901e72 100644 --- a/etherlink/kernel_evm/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/account_storage.rs @@ -120,44 +120,44 @@ pub struct StorageEffect { /// an account. We don't currently require it, and so it's omitted. #[derive(Debug, PartialEq)] pub struct EthereumAccount { - path: OwnedPath, + path: OwnedPath, } -impl From for EthereumAccount { - fn from(path: OwnedPath) -> Self { +impl From> for EthereumAccount { + fn from(path: OwnedPath) -> Self { Self { path } } } /// Path where Ethereum accounts are stored -pub const EVM_ACCOUNTS_PATH: RefPath = +pub const EVM_ACCOUNTS_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/eth_accounts"); /// Path where an account nonce is stored. This should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. -const NONCE_PATH: RefPath = RefPath::assert_from(b"/nonce"); +const NONCE_PATH: RefPath = RefPath::assert_from(b"/nonce"); /// Path where an account balance, ether held, is stored. This should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. -const BALANCE_PATH: RefPath = RefPath::assert_from(b"/balance"); +const BALANCE_PATH: RefPath = RefPath::assert_from(b"/balance"); /// "Internal" accounts - accounts with contract code have a contract code hash. /// This value is computed when the code is stored and kept for future queries. This /// path should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. -const CODE_HASH_PATH: RefPath = RefPath::assert_from(b"/code.hash"); +const CODE_HASH_PATH: RefPath = RefPath::assert_from(b"/code.hash"); /// "Internal" accounts - accounts with contract code, have their code stored here. /// This /// path should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. -const CODE_PATH: RefPath = RefPath::assert_from(b"/code"); +const CODE_PATH: RefPath = RefPath::assert_from(b"/code"); /// The contracts of "internal" accounts have their own storage area. The account /// location prefixed to this path gives the root path (prefix) to where such storage /// values are kept. Each index in durable storage gives one complete path to one /// such 256 bit integer value in storage. -const STORAGE_ROOT_PATH: RefPath = RefPath::assert_from(b"/storage"); +const STORAGE_ROOT_PATH: RefPath = RefPath::assert_from(b"/storage"); /// If a contract tries to read a value from storage and it has previously not written /// anything to this location or if it wrote the default value, then it gets this @@ -182,7 +182,7 @@ const CODE_HASH_BYTES: [u8; WORD_SIZE] = Decoder::Hex pub const CODE_HASH_DEFAULT: H256 = H256(CODE_HASH_BYTES); /// Turn an Ethereum address - a H160 - into a valid path -pub fn account_path(address: &H160) -> Result { +pub fn account_path(address: &H160) -> Result, DurableStorageError> { let path_string = alloc::format!("/{}", hex::encode(address.to_fixed_bytes())); OwnedPath::try_from(path_string).map_err(DurableStorageError::from) } @@ -338,13 +338,13 @@ impl EthereumAccount { /// Get the path to a custom account state section, can be used by precompiles pub fn custom_path( &self, - suffix: &impl Path, - ) -> Result { + suffix: &impl Path, + ) -> Result, AccountStorageError> { concat(&self.path, suffix).map_err(AccountStorageError::from) } /// Get the path to an index in durable storage for an account. - fn storage_path(&self, index: &H256) -> Result { + fn storage_path(&self, index: &H256) -> Result, AccountStorageError> { let storage_path = concat(&self.path, &STORAGE_ROOT_PATH)?; let index_path = path_from_h256(index)?; concat(&storage_path, &index_path).map_err(AccountStorageError::from) diff --git a/etherlink/kernel_evm/evm_execution/src/code_storage.rs b/etherlink/kernel_evm/evm_execution/src/code_storage.rs index aa40f213743f..005013f968b0 100644 --- a/etherlink/kernel_evm/evm_execution/src/code_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/code_storage.rs @@ -12,15 +12,15 @@ use tezos_storage::helpers::bytes_hash; use tezos_storage::{error::Error as GenStorageError, read_u64_le, write_u64_le}; /// Path where Ethereum account's code are stored -const EVM_CODES_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/eth_codes"); +const EVM_CODES_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/eth_codes"); /// Path to the number of accounts to use a particular code -const REFERENCE_PATH: RefPath = RefPath::assert_from(b"/ref_count"); +const REFERENCE_PATH: RefPath = RefPath::assert_from(b"/ref_count"); /// Path to the code -const CODE_PATH: RefPath = RefPath::assert_from(b"/code"); +const CODE_PATH: RefPath = RefPath::assert_from(b"/code"); -fn code_hash_path(code_hash: &H256) -> Result { +fn code_hash_path(code_hash: &H256) -> Result, GenStorageError> { let code_hash_hex = hex::encode(code_hash); let code_hash_path_string = format!("/{}", code_hash_hex); OwnedPath::try_from(code_hash_path_string).map_err(Into::into) @@ -28,11 +28,11 @@ fn code_hash_path(code_hash: &H256) -> Result { #[derive(Debug, PartialEq)] pub struct CodeStorage { - path: OwnedPath, + path: OwnedPath, } -impl From for CodeStorage { - fn from(path: OwnedPath) -> Self { +impl From> for CodeStorage { + fn from(path: OwnedPath) -> Self { Self { path } } } diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs index fb13af4cf206..a466ba2e05fa 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs @@ -14,7 +14,7 @@ use tezos_smart_rollup_host::path::{concat, OwnedPath, RefPath}; use tezos_storage::{path_from_h256, read_u256_le_default, write_u256_le}; /// Path where global ticket table is stored -const TICKET_TABLE_PATH: RefPath = RefPath::assert_from(b"/ticket_table"); +const TICKET_TABLE_PATH: RefPath = RefPath::assert_from(b"/ticket_table"); pub trait TicketTable { /// Increases ticket balance @@ -39,7 +39,7 @@ pub trait TicketTable { pub(crate) fn ticket_balance_path( ticket_hash: &H256, address: &H160, -) -> Result { +) -> Result, AccountStorageError> { let suffix = concat(&path_from_h256(ticket_hash)?, &account_path(address)?)?; concat(&TICKET_TABLE_PATH, &suffix).map_err(Into::into) } diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index 401e645277bc..633d668e3eb8 100755 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -419,7 +419,7 @@ where Ok(None) } } -pub const NATIVE_TOKEN_TICKETER_PATH: RefPath = +pub const NATIVE_TOKEN_TICKETER_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/ticketer"); /// Reads the ticketer address set by the installer, if any, encoded in b58. diff --git a/etherlink/kernel_evm/evm_execution/src/storage.rs b/etherlink/kernel_evm/evm_execution/src/storage.rs index 11f5c431bca8..2e63d1c1bc84 100644 --- a/etherlink/kernel_evm/evm_execution/src/storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/storage.rs @@ -20,12 +20,12 @@ pub mod tracer { use crate::trace::CallTrace; use crate::trace::StructLog; - const EVM_TRACE: RefPath = RefPath::assert_from(b"/evm/trace"); + const EVM_TRACE: RefPath = RefPath::assert_from(b"/evm/trace"); - const GAS: RefPath = RefPath::assert_from(b"/gas"); - const FAILED: RefPath = RefPath::assert_from(b"/failed"); - const RETURN_VALUE: RefPath = RefPath::assert_from(b"/return_value"); - const STRUCT_LOGS: RefPath = RefPath::assert_from(b"/struct_logs"); + const GAS: RefPath = RefPath::assert_from(b"/gas"); + const FAILED: RefPath = RefPath::assert_from(b"/failed"); + const RETURN_VALUE: RefPath = RefPath::assert_from(b"/return_value"); + const STRUCT_LOGS: RefPath = RefPath::assert_from(b"/struct_logs"); #[derive(Eq, Error, Debug, PartialEq)] pub enum Error { @@ -39,8 +39,8 @@ pub mod tracer { pub fn trace_tx_path( hash: &Option, - field: &RefPath, - ) -> Result { + field: &RefPath, + ) -> Result, Error> { let trace_tx_path = match hash { None => EVM_TRACE.into(), Some(hash) => { @@ -101,7 +101,7 @@ pub mod tracer { Ok(()) } - const CALL_TRACE: RefPath = RefPath::assert_from(b"/call_trace"); + const CALL_TRACE: RefPath = RefPath::assert_from(b"/call_trace"); pub fn store_call_trace( host: &mut Host, @@ -180,7 +180,9 @@ pub mod blocks { } } - fn to_block_hash_path(block_number: U256) -> Result { + fn to_block_hash_path( + block_number: U256, + ) -> Result, EvmBlockStorageError> { let path: Vec = format!("/evm/world_state/indexes/blocks/{}", block_number).into(); let owned_path = OwnedPath::try_from(path)?; diff --git a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs index 53f364cce4bb..a80517a56acd 100644 --- a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs +++ b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs @@ -19,7 +19,8 @@ use tezos_storage::{read_u256_le_default, write_u256_le}; use crate::account_storage::{AccountStorageError, EthereumAccount}; /// Path where withdrawal counter is stored (relative to account) -pub const WITHDRAWAL_COUNTER_PATH: RefPath = RefPath::assert_from(b"/withdrawal_counter"); +pub const WITHDRAWAL_COUNTER_PATH: RefPath = + RefPath::assert_from(b"/withdrawal_counter"); pub trait WithdrawalCounter { /// Returns current withdrawal ID from the storage (or 0 if it's not initialized) diff --git a/etherlink/kernel_evm/indexable_storage/src/lib.rs b/etherlink/kernel_evm/indexable_storage/src/lib.rs index 383d87337623..243f728445ed 100644 --- a/etherlink/kernel_evm/indexable_storage/src/lib.rs +++ b/etherlink/kernel_evm/indexable_storage/src/lib.rs @@ -13,7 +13,7 @@ use tezos_smart_rollup_storage::StorageError; use tezos_storage::{error::Error as GenStorageError, read_u64_le, write_u64_le}; use thiserror::Error; -const LENGTH: RefPath = RefPath::assert_from(b"/length"); +const LENGTH: RefPath = RefPath::assert_from(b"/length"); /// An indexable storage is a push-only mapping between increasing integers to /// bytes. It can serve as a replacement for the combination of the host @@ -22,7 +22,7 @@ pub struct IndexableStorage { /// An indexable storage is stored at a given path and consists of: /// - `/length`: the number of keys /// - `/` where keys are from `0` to `length - 1` - pub path: OwnedPath, + pub path: OwnedPath, } #[derive(Error, Debug, Eq, PartialEq)] @@ -58,15 +58,15 @@ impl From for IndexableStorageError { } impl IndexableStorage { - pub fn new(path: &RefPath<'_>) -> Result { + pub fn new(path: &RefPath<'_, true>) -> Result { Ok(Self { path: path.into() }) } - pub fn new_owned_path(path: OwnedPath) -> Self { + pub fn new_owned_path(path: OwnedPath) -> Self { Self { path } } - fn value_path(&self, index: u64) -> Result { + fn value_path(&self, index: u64) -> Result, PathError> { let index_as_path: Vec = format!("/{}", index).into(); // The key being an integer value, it will always be valid as a path, // `assert_from` cannot fail. @@ -74,9 +74,9 @@ impl IndexableStorage { concat(&self.path, &index_subkey) } - fn store_index( + fn store_index( &self, - host: &mut Host, + host: &mut impl Runtime, index: u64, value_repr: &[u8], ) -> Result<(), IndexableStorageError> { diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index 10f952d58476..140cc28c3ee2 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -498,10 +498,10 @@ fn apply_fa_deposit( })) } -pub const WITHDRAWAL_OUTBOX_QUEUE: RefPath = +pub const WITHDRAWAL_OUTBOX_QUEUE: RefPath = RefPath::assert_from(b"/evm/world_state/__outbox_queue"); -pub const WITHDRAWAL_OUTBOX_QUEUE_META: RefPath = +pub const WITHDRAWAL_OUTBOX_QUEUE_META: RefPath = RefPath::assert_from(b"/evm/world_state/__outbox_queue/meta"); pub struct ExecutionInfo { @@ -528,7 +528,7 @@ impl From> for ExecutionResult { #[allow(clippy::too_many_arguments)] pub fn handle_transaction_result( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, impl Path>, block_constants: &BlockConstants, transaction: &Transaction, index: u32, @@ -588,7 +588,7 @@ pub fn handle_transaction_result( #[allow(clippy::too_many_arguments)] pub fn apply_transaction( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, impl Path>, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, transaction: &Transaction, diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index e3a7c90d24dc..8a729e3fadc2 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -99,7 +99,7 @@ fn on_invalid_transaction( #[allow(clippy::too_many_arguments)] fn compute( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, impl Path>, block_in_progress: &mut BlockInProgress, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, @@ -283,7 +283,7 @@ fn next_bip_from_blueprints( #[allow(clippy::too_many_arguments)] fn compute_bip( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, impl Path>, mut block_in_progress: BlockInProgress, current_block_number: &mut U256, current_block_parent_hash: &mut H256, @@ -388,7 +388,7 @@ fn clean_delayed_transactions( fn promote_block( safe_host: &mut SafeStorage<&mut Host>, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, impl Path>, block_in_progress: bool, number: U256, config: &mut Configuration, @@ -426,7 +426,7 @@ fn promote_block( Ok(()) } -const AT_MOST_ONE_BLOCK: RefPath = RefPath::assert_from(b"/__at_most_one_block"); +const AT_MOST_ONE_BLOCK: RefPath = RefPath::assert_from(b"/__at_most_one_block"); pub fn produce( host: &mut Host, diff --git a/etherlink/kernel_evm/kernel/src/block_in_progress.rs b/etherlink/kernel_evm/kernel/src/block_in_progress.rs index 818eb331873a..f66dfc0f58a7 100644 --- a/etherlink/kernel_evm/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_evm/kernel/src/block_in_progress.rs @@ -28,7 +28,7 @@ use tezos_ethereum::Bloom; use tezos_evm_logging::{log, Level::*}; use tezos_evm_runtime::runtime::Runtime; use tezos_smart_rollup_encoding::timestamp::Timestamp; -use tezos_smart_rollup_host::path::{concat, RefPath}; +use tezos_smart_rollup_host::path::{force_concat, RefPath}; #[derive(Debug, PartialEq, Clone)] /// Container for all data needed during block computation @@ -349,7 +349,7 @@ impl BlockInProgress { fn safe_store_get_hash( host: &mut Host, - path: &RefPath, + path: &RefPath, ) -> Result, anyhow::Error> { match host.store_get_hash(path) { Ok(hash) => Ok(hash), @@ -357,9 +357,9 @@ impl BlockInProgress { } } - const RECEIPTS: RefPath<'static> = + const RECEIPTS: RefPath<'static, true> = RefPath::assert_from(b"/evm/world_state/__receipts"); - const RECEIPTS_PREVIOUS_ROOT: RefPath<'static> = + const RECEIPTS_PREVIOUS_ROOT: RefPath<'static, true> = RefPath::assert_from(b"/evm/world_state/__receipts/previous_root"); fn receipts_root( @@ -372,7 +372,7 @@ impl BlockInProgress { } else { for hash in &self.valid_txs { let receipt_path = receipt_path(hash)?; - let new_receipt_path = concat(&Self::RECEIPTS, &receipt_path)?; + let new_receipt_path = force_concat(&Self::RECEIPTS, &receipt_path)?; host.store_copy(&receipt_path, &new_receipt_path)?; } host.store_write_all(&Self::RECEIPTS_PREVIOUS_ROOT, &previous_receipts_root)?; @@ -382,8 +382,9 @@ impl BlockInProgress { } } - const OBJECTS: RefPath<'static> = RefPath::assert_from(b"/evm/world_state/__objects"); - const OBJECTS_PREVIOUS_ROOT: RefPath<'static> = + const OBJECTS: RefPath<'static, true> = + RefPath::assert_from(b"/evm/world_state/__objects"); + const OBJECTS_PREVIOUS_ROOT: RefPath<'static, true> = RefPath::assert_from(b"/evm/world_state/__objects/previous_root"); fn transactions_root( @@ -396,7 +397,7 @@ impl BlockInProgress { } else { for hash in &self.valid_txs { let object_path = object_path(hash)?; - let new_object_path = concat(&Self::OBJECTS, &object_path)?; + let new_object_path = force_concat(&Self::OBJECTS, &object_path)?; host.store_copy(&object_path, &new_object_path)?; } host.store_write_all( diff --git a/etherlink/kernel_evm/kernel/src/block_storage.rs b/etherlink/kernel_evm/kernel/src/block_storage.rs index b45fd11bde4f..0c4574667975 100644 --- a/etherlink/kernel_evm/kernel/src/block_storage.rs +++ b/etherlink/kernel_evm/kernel/src/block_storage.rs @@ -24,18 +24,19 @@ use crate::storage::EVM_TRANSACTIONS_RECEIPTS; mod path { use super::*; - pub const PATH: RefPath = RefPath::assert_from(b"/evm/world_state/blocks"); + pub const PATH: RefPath = RefPath::assert_from(b"/evm/world_state/blocks"); - pub const CURRENT_NUMBER: RefPath = + pub const CURRENT_NUMBER: RefPath = RefPath::assert_from(b"/evm/world_state/blocks/current/number"); - pub const CURRENT_HASH: RefPath = + pub const CURRENT_HASH: RefPath = RefPath::assert_from(b"/evm/world_state/blocks/current/hash"); - pub const INDEXES: RefPath = RefPath::assert_from(b"/evm/world_state/indexes/blocks"); + pub const INDEXES: RefPath = + RefPath::assert_from(b"/evm/world_state/indexes/blocks"); /// Path to the block in the storage. The path to the block is /// indexed by its hash. - pub fn path(hash: H256) -> anyhow::Result { + pub fn path(hash: H256) -> anyhow::Result> { let hash = hex::encode(hash); let raw_hash_path: Vec = format!("/{}", &hash).into(); let hash_path = OwnedPath::try_from(raw_hash_path)?; diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index 4b5fb3f77d55..e5f46f1af542 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -32,13 +32,14 @@ use tezos_storage::{ write_u256_le, }; -pub const EVM_BLUEPRINTS: RefPath = RefPath::assert_from(b"/evm/blueprints"); +pub const EVM_BLUEPRINTS: RefPath = RefPath::assert_from(b"/evm/blueprints"); -const EVM_BLUEPRINT_NB_CHUNKS: RefPath = RefPath::assert_from(b"/nb_chunks"); +const EVM_BLUEPRINT_NB_CHUNKS: RefPath = RefPath::assert_from(b"/nb_chunks"); -const NEXT_BLUEPRINT_NUMBER: RefPath = RefPath::assert_from(b"/evm/blueprints/next"); +const NEXT_BLUEPRINT_NUMBER: RefPath = + RefPath::assert_from(b"/evm/blueprints/next"); -const LAST_BLOCK_TIMESTAMP: RefPath = +const LAST_BLOCK_TIMESTAMP: RefPath = RefPath::assert_from(b"/evm/blueprints/last_block_timestamp"); /// The store representation of a blueprint. @@ -95,7 +96,7 @@ impl Decodable for StoreBlueprint { } } -pub fn blueprint_path(number: U256) -> Result { +pub fn blueprint_path(number: U256) -> Result, StorageError> { let number_as_path: Vec = format!("/{}", number).into(); // The key being an integer value, it will always be valid as a path, // `assert_from` cannot fail. @@ -104,23 +105,23 @@ pub fn blueprint_path(number: U256) -> Result { } fn blueprint_chunk_path( - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, chunk_index: u16, -) -> Result { +) -> Result, StorageError> { let chunk_index_as_path: Vec = format!("/{}", chunk_index).into(); let chunk_index_subkey = RefPath::assert_from(&chunk_index_as_path); concat(blueprint_path, &chunk_index_subkey).map_err(StorageError::from) } fn blueprint_nb_chunks_path( - blueprint_path: &OwnedPath, -) -> Result { + blueprint_path: &OwnedPath, +) -> Result, StorageError> { concat(blueprint_path, &EVM_BLUEPRINT_NB_CHUNKS).map_err(StorageError::from) } fn read_blueprint_nb_chunks( host: &Host, - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, ) -> Result { let path = blueprint_nb_chunks_path(blueprint_path)?; let mut buffer = [0u8; 2]; @@ -130,7 +131,7 @@ fn read_blueprint_nb_chunks( fn store_blueprint_nb_chunks( host: &mut Host, - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, nb_chunks: u16, ) -> Result<(), Error> { let path = blueprint_nb_chunks_path(blueprint_path)?; @@ -371,7 +372,7 @@ fn parse_and_validate_blueprint( fn invalidate_blueprint( host: &mut Host, - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, error: &BlueprintValidity, ) -> Result<(), RuntimeError> { log!( @@ -387,7 +388,7 @@ fn invalidate_blueprint( fn read_all_chunks_and_validate( host: &mut Host, - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, nb_chunks: u16, config: &mut Configuration, ) -> anyhow::Result<(Option, usize)> { diff --git a/etherlink/kernel_evm/kernel/src/delayed_inbox.rs b/etherlink/kernel_evm/kernel/src/delayed_inbox.rs index 840236908060..37708adea79f 100644 --- a/etherlink/kernel_evm/kernel/src/delayed_inbox.rs +++ b/etherlink/kernel_evm/kernel/src/delayed_inbox.rs @@ -24,14 +24,14 @@ use tezos_storage::read_u16_le_default; pub struct DelayedInbox(LinkedList); -pub const DELAYED_INBOX_PATH: RefPath = RefPath::assert_from(b"/evm/delayed-inbox"); +pub const DELAYED_INBOX_PATH: RefPath = RefPath::assert_from(b"/evm/delayed-inbox"); // Maximum number of transaction included in a blueprint when // forcing timed-out transactions from the delayed inbox. pub const DEFAULT_MAX_DELAYED_INBOX_BLUEPRINT_LENGTH: u16 = 1000; // Path to override the default value. -pub const MAX_DELAYED_INBOX_BLUEPRINT_LENGTH_PATH: RefPath = +pub const MAX_DELAYED_INBOX_BLUEPRINT_LENGTH_PATH: RefPath = RefPath::assert_from(b"/evm/max_delayed_inbox_blueprint_length"); // Tag that indicates the delayed transaction is a eth transaction. diff --git a/etherlink/kernel_evm/kernel/src/evm_node_entrypoint.rs b/etherlink/kernel_evm/kernel/src/evm_node_entrypoint.rs index c2791fae5d40..ca98da046942 100644 --- a/etherlink/kernel_evm/kernel/src/evm_node_entrypoint.rs +++ b/etherlink/kernel_evm/kernel/src/evm_node_entrypoint.rs @@ -14,7 +14,7 @@ use tezos_evm_runtime::runtime::KernelHost; use tezos_smart_rollup_core::rollup_host::RollupHost; use tezos_smart_rollup_host::{path::RefPath, runtime::Runtime}; -const DELAYED_INPUT_PATH: RefPath = RefPath::assert_from(b"/__delayed_input"); +const DELAYED_INPUT_PATH: RefPath = RefPath::assert_from(b"/__delayed_input"); #[allow(dead_code)] #[no_mangle] diff --git a/etherlink/kernel_evm/kernel/src/fallback_upgrade.rs b/etherlink/kernel_evm/kernel/src/fallback_upgrade.rs index d1a8caecfb6f..170c7fce4ac8 100644 --- a/etherlink/kernel_evm/kernel/src/fallback_upgrade.rs +++ b/etherlink/kernel_evm/kernel/src/fallback_upgrade.rs @@ -9,10 +9,10 @@ use tezos_smart_rollup_host::{path::RefPath, runtime::RuntimeError, KERNEL_BOOT_ use crate::upgrade::KERNEL_ROOT_HASH; -const BACKUP_KERNEL_BOOT_PATH: RefPath = +const BACKUP_KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/__backup_kernel/boot.wasm"); -const BACKUP_KERNEL_ROOT_HASH: RefPath = +const BACKUP_KERNEL_ROOT_HASH: RefPath = RefPath::assert_from(b"/__backup_kernel/root_hash"); pub fn backup_current_kernel(host: &mut impl Runtime) -> Result<(), RuntimeError> { diff --git a/etherlink/kernel_evm/kernel/src/linked_list.rs b/etherlink/kernel_evm/kernel/src/linked_list.rs index 8ec7d95f9c9a..3b5438c67002 100644 --- a/etherlink/kernel_evm/kernel/src/linked_list.rs +++ b/etherlink/kernel_evm/kernel/src/linked_list.rs @@ -22,7 +22,7 @@ where Elt: Encodable + Decodable + Clone, { /// Absolute path to queue - path: OwnedPath, + path: OwnedPath, /// None indicates an empty list pointers: Option>, _type: PhantomData<(Id, Elt)>, @@ -50,7 +50,7 @@ struct Pointer { fn decode_path( it: &mut RlpIterator, field_name: &'static str, -) -> Result { +) -> Result, rlp::DecoderError> { let path: Vec = decode_field(&next(it)?, field_name)?; OwnedPath::try_from(path).map_err(|_| DecoderError::Custom("not a path")) } @@ -150,7 +150,7 @@ where impl, Elt: Encodable + Decodable> Pointer { - fn pointer_path(id: &Id, prefix: &impl Path) -> Result { + fn pointer_path(id: &Id, prefix: &impl Path) -> Result> { let path = hex::encode(id); let path: Vec = format!("/{}/pointer", path).into(); let path = OwnedPath::try_from(path)?; @@ -161,12 +161,12 @@ impl, Elt: Encodable + Decodable> /// Path to the pointer /// /// This path is used when you want to read a pointer or to remove it. - fn path(&self, prefix: &impl Path) -> Result { + fn path(&self, prefix: &impl Path) -> Result> { Self::pointer_path(&self.id, prefix) } /// Path to the data held by the pointer. - fn data_path(&self, prefix: &impl Path) -> Result { + fn data_path(&self, prefix: &impl Path) -> Result> { let path = hex::encode(&self.id); let path: Vec = format!("/{}/data", path).into(); let path = OwnedPath::try_from(path)?; @@ -177,25 +177,29 @@ impl, Elt: Encodable + Decodable> fn save_data( &self, host: &mut impl Runtime, - prefix: &impl Path, + prefix: &impl Path, data: &Elt, ) -> Result<()> { let path = self.data_path(prefix)?; store_rlp(data, host, &path).context("cannot save the pointer's data") } - fn get_data(&self, host: &impl Runtime, prefix: &impl Path) -> Result { + fn get_data(&self, host: &impl Runtime, prefix: &impl Path) -> Result { let path = self.data_path(prefix)?; read_rlp(host, &path).context("cannot read the pointer's data") } /// Load the pointer from the durable storage - fn read(host: &impl Runtime, prefix: &impl Path, id: &Id) -> Result> { + fn read( + host: &impl Runtime, + prefix: &impl Path, + id: &Id, + ) -> Result> { read_optional_rlp(host, &Self::pointer_path(id, prefix)?) } /// Save the pointer in the durable storage - fn save(&self, host: &mut impl Runtime, prefix: &impl Path) -> Result<()> { + fn save(&self, host: &mut impl Runtime, prefix: &impl Path) -> Result<()> { store_rlp(self, host, &self.path(prefix)?) .context("cannot save pointer to storage") } @@ -204,7 +208,7 @@ impl, Elt: Encodable + Decodable> fn remove_with_data( &self, host: &mut impl Runtime, - prefix: &impl Path, + prefix: &impl Path, ) -> Result<()> { let path = hex::encode(&self.id); let path: Vec = format!("/{}", path).into(); @@ -224,7 +228,7 @@ where /// Load a list from the storage. /// If the list does not exist, a new empty list is created. /// Otherwise the existing list is read from the storage. - pub fn new(path: &impl Path, host: &impl Runtime) -> Result { + pub fn new(path: &impl Path, host: &impl Runtime) -> Result { let list = Self::read(host, path)?.unwrap_or(Self { path: path.into(), pointers: None, @@ -234,7 +238,7 @@ where } /// Path to the metadata that defines the list. - fn metadata_path(root: &impl Path) -> Result { + fn metadata_path(root: &impl Path) -> Result> { let meta_path: Vec = "/meta".into(); let meta_path = OwnedPath::try_from(meta_path)?; let path = concat(root, &meta_path)?; @@ -250,7 +254,7 @@ where } /// Load the LinkedList from the durable storage. - fn read(host: &impl Runtime, path: &impl Path) -> Result> { + fn read(host: &impl Runtime, path: &impl Path) -> Result> { let path = Self::metadata_path(path)?; read_optional_rlp(host, &path) } @@ -539,7 +543,7 @@ mod tests { fn traverse_f( host: &MockKernelHost, - list_path: &OwnedPath, + list_path: &OwnedPath, pointer: Pointer, f: &dyn Fn(&Pointer) -> Option, ) -> (Pointer, usize) { diff --git a/etherlink/kernel_evm/kernel/src/migration.rs b/etherlink/kernel_evm/kernel/src/migration.rs index abc240d1a110..eba85e6927b7 100644 --- a/etherlink/kernel_evm/kernel/src/migration.rs +++ b/etherlink/kernel_evm/kernel/src/migration.rs @@ -66,7 +66,7 @@ pub fn allow_path_not_found(res: Result<(), RuntimeError>) -> Result<(), Runtime } } -const TMP_NEXT_BLUEPRINT_PATH: RefPath = +const TMP_NEXT_BLUEPRINT_PATH: RefPath = RefPath::assert_from(b"/__tmp_next_blueprint_path"); fn migrate_to( @@ -212,7 +212,7 @@ fn migrate_to( Ok(MigrationStatus::Done) } StorageVersion::V24 => { - const EVM_BASE_FEE_PER_GAS: RefPath = + const EVM_BASE_FEE_PER_GAS: RefPath = RefPath::assert_from(b"/evm/world_state/fees/base_fee_per_gas"); host.store_delete(&EVM_BASE_FEE_PER_GAS)?; Ok(MigrationStatus::Done) diff --git a/etherlink/kernel_evm/kernel/src/reveal_storage.rs b/etherlink/kernel_evm/kernel/src/reveal_storage.rs index 294670a97282..11da770422ac 100644 --- a/etherlink/kernel_evm/kernel/src/reveal_storage.rs +++ b/etherlink/kernel_evm/kernel/src/reveal_storage.rs @@ -17,11 +17,11 @@ use tezos_smart_rollup_host::runtime::ValueType; /// chain into a new deployment. It is not tick-safe, and should obviously not be used in a /// production setup. -const CONFIG_PATH: RefPath = RefPath::assert_from(b"/__tmp/reveal_config"); +const CONFIG_PATH: RefPath = RefPath::assert_from(b"/__tmp/reveal_config"); #[derive(Debug)] struct Set { - to: OwnedPath, + to: OwnedPath, value: Vec, } @@ -36,8 +36,8 @@ impl Decodable for Set { let mut it = decoder.iter(); let to: Vec = decode_field(&next(&mut it)?, "to")?; - let to: RefPath = RefPath::assert_from(&to); - let to: OwnedPath = to.into(); + let to: RefPath = RefPath::assert_from(&to); + let to: OwnedPath = to.into(); let value: Vec = decode_field(&next(&mut it)?, "value")?; Ok(Self { to, value }) diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index cbcd0bfb8c24..305b7b6ef2af 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -73,113 +73,120 @@ impl StorageVersion { pub const STORAGE_VERSION: StorageVersion = StorageVersion::V24; -pub const PRIVATE_FLAG_PATH: RefPath = RefPath::assert_from(b"/evm/remove_whitelist"); +pub const PRIVATE_FLAG_PATH: RefPath = + RefPath::assert_from(b"/evm/remove_whitelist"); -pub const STORAGE_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/storage_version"); +pub const STORAGE_VERSION_PATH: RefPath = + RefPath::assert_from(b"/evm/storage_version"); -const KERNEL_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/kernel_version"); +const KERNEL_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/kernel_version"); -pub const ADMIN: RefPath = RefPath::assert_from(b"/evm/admin"); -pub const SEQUENCER_GOVERNANCE: RefPath = +pub const ADMIN: RefPath = RefPath::assert_from(b"/evm/admin"); +pub const SEQUENCER_GOVERNANCE: RefPath = RefPath::assert_from(b"/evm/sequencer_governance"); -pub const KERNEL_GOVERNANCE: RefPath = RefPath::assert_from(b"/evm/kernel_governance"); -pub const KERNEL_SECURITY_GOVERNANCE: RefPath = +pub const KERNEL_GOVERNANCE: RefPath = + RefPath::assert_from(b"/evm/kernel_governance"); +pub const KERNEL_SECURITY_GOVERNANCE: RefPath = RefPath::assert_from(b"/evm/kernel_security_governance"); -pub const DELAYED_BRIDGE: RefPath = RefPath::assert_from(b"/evm/delayed_bridge"); +pub const DELAYED_BRIDGE: RefPath = RefPath::assert_from(b"/evm/delayed_bridge"); -pub const MAXIMUM_ALLOWED_TICKS: RefPath = +pub const MAXIMUM_ALLOWED_TICKS: RefPath = RefPath::assert_from(b"/evm/maximum_allowed_ticks"); -pub const MAXIMUM_GAS_PER_TRANSACTION: RefPath = +pub const MAXIMUM_GAS_PER_TRANSACTION: RefPath = RefPath::assert_from(b"/evm/maximum_gas_per_transaction"); // Path to the block in progress, used between reboots -const EVM_BLOCK_IN_PROGRESS: RefPath = +const EVM_BLOCK_IN_PROGRESS: RefPath = RefPath::assert_from(b"/evm/world_state/blocks/in_progress"); -const EVENTS: RefPath = RefPath::assert_from(b"/evm/events"); +const EVENTS: RefPath = RefPath::assert_from(b"/evm/events"); -pub const EVM_TRANSACTIONS_RECEIPTS: RefPath = +pub const EVM_TRANSACTIONS_RECEIPTS: RefPath = RefPath::assert_from(b"/evm/world_state/transactions_receipts"); -pub const EVM_TRANSACTIONS_OBJECTS: RefPath = +pub const EVM_TRANSACTIONS_OBJECTS: RefPath = RefPath::assert_from(b"/evm/world_state/transactions_objects"); -const EVM_CHAIN_ID: RefPath = RefPath::assert_from(b"/evm/chain_id"); +const EVM_CHAIN_ID: RefPath = RefPath::assert_from(b"/evm/chain_id"); -const EVM_MINIMUM_BASE_FEE_PER_GAS: RefPath = +const EVM_MINIMUM_BASE_FEE_PER_GAS: RefPath = RefPath::assert_from(b"/evm/world_state/fees/minimum_base_fee_per_gas"); -const EVM_DA_FEE: RefPath = +const EVM_DA_FEE: RefPath = RefPath::assert_from(b"/evm/world_state/fees/da_fee_per_byte"); -const TICK_BACKLOG_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/fees/backlog"); -const TICK_BACKLOG_TIMESTAMP_PATH: RefPath = +const TICK_BACKLOG_PATH: RefPath = + RefPath::assert_from(b"/evm/world_state/fees/backlog"); +const TICK_BACKLOG_TIMESTAMP_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/fees/last_timestamp"); /// The sequencer pool is the designated account that the data-availability fees are sent to. /// /// This may be updated by the governance mechanism over time. If it is not set, the data-availability /// fees are instead burned. -pub const SEQUENCER_POOL_PATH: RefPath = +pub const SEQUENCER_POOL_PATH: RefPath = RefPath::assert_from(b"/evm/sequencer_pool_address"); /// Path to the last L1 level seen. -const EVM_L1_LEVEL: RefPath = RefPath::assert_from(b"/evm/l1_level"); +const EVM_L1_LEVEL: RefPath = RefPath::assert_from(b"/evm/l1_level"); -const EVM_BURNED_FEES: RefPath = RefPath::assert_from(b"/evm/world_state/fees/burned"); +const EVM_BURNED_FEES: RefPath = + RefPath::assert_from(b"/evm/world_state/fees/burned"); /// Path to the last info per level timestamp seen. -const EVM_INFO_PER_LEVEL_TIMESTAMP: RefPath = +const EVM_INFO_PER_LEVEL_TIMESTAMP: RefPath = RefPath::assert_from(b"/evm/info_per_level/timestamp"); /// Path to the number of timestamps read, use to compute the average block time. -const EVM_INFO_PER_LEVEL_STATS_NUMBERS: RefPath = +const EVM_INFO_PER_LEVEL_STATS_NUMBERS: RefPath = RefPath::assert_from(b"/evm/info_per_level/stats/numbers"); /// Path to the sum of distance between blocks, used to compute the average block time. -const EVM_INFO_PER_LEVEL_STATS_TOTAL: RefPath = +const EVM_INFO_PER_LEVEL_STATS_TOTAL: RefPath = RefPath::assert_from(b"/evm/info_per_level/stats/total"); -pub const SIMULATION_RESULT: RefPath = RefPath::assert_from(b"/evm/simulation_result"); +pub const SIMULATION_RESULT: RefPath = + RefPath::assert_from(b"/evm/simulation_result"); // Path to the number of seconds until delayed txs are timed out. -const EVM_DELAYED_INBOX_TIMEOUT: RefPath = +const EVM_DELAYED_INBOX_TIMEOUT: RefPath = RefPath::assert_from(b"/evm/delayed_inbox_timeout"); // Path to the number of l1 levels that need to pass for a // delayed tx to be timed out. -const EVM_DELAYED_INBOX_MIN_LEVELS: RefPath = +const EVM_DELAYED_INBOX_MIN_LEVELS: RefPath = RefPath::assert_from(b"/evm/delayed_inbox_min_levels"); // Path to the tz1 administrating the sequencer. If there is nothing // at this path, the kernel is in proxy mode. -pub const SEQUENCER: RefPath = RefPath::assert_from(b"/evm/sequencer"); +pub const SEQUENCER: RefPath = RefPath::assert_from(b"/evm/sequencer"); // Path to the DAL feature flag. If there is nothing at this path, DAL // is not used. -pub const ENABLE_DAL: RefPath = RefPath::assert_from(b"/evm/feature_flags/enable_dal"); +pub const ENABLE_DAL: RefPath = + RefPath::assert_from(b"/evm/feature_flags/enable_dal"); // Path to the DAL slot indices to use. -pub const DAL_SLOTS: RefPath = RefPath::assert_from(b"/evm/dal_slots"); +pub const DAL_SLOTS: RefPath = RefPath::assert_from(b"/evm/dal_slots"); // Path where the input for the tracer is stored by the sequencer. -const TRACER_INPUT: RefPath = RefPath::assert_from(b"/evm/trace/input"); +const TRACER_INPUT: RefPath = RefPath::assert_from(b"/evm/trace/input"); // If this path contains a value, the fa bridge is enabled in the kernel. -pub const ENABLE_FA_BRIDGE: RefPath = +pub const ENABLE_FA_BRIDGE: RefPath = RefPath::assert_from(b"/evm/feature_flags/enable_fa_bridge"); // If the flag is set, the kernel consider that this is local evm node execution. -const EVM_NODE_FLAG: RefPath = RefPath::assert_from(b"/__evm_node"); +const EVM_NODE_FLAG: RefPath = RefPath::assert_from(b"/__evm_node"); -const MAX_BLUEPRINT_LOOKAHEAD_IN_SECONDS: RefPath = +const MAX_BLUEPRINT_LOOKAHEAD_IN_SECONDS: RefPath = RefPath::assert_from(b"/evm/max_blueprint_lookahead_in_seconds"); -pub fn receipt_path(receipt_hash: &TransactionHash) -> Result { +pub fn receipt_path(receipt_hash: &TransactionHash) -> Result, Error> { let hash = hex::encode(receipt_hash); let raw_receipt_path: Vec = format!("/{}", &hash).into(); let receipt_path = OwnedPath::try_from(raw_receipt_path)?; concat(&EVM_TRANSACTIONS_RECEIPTS, &receipt_path).map_err(Error::from) } -pub fn object_path(object_hash: &TransactionHash) -> Result { +pub fn object_path(object_hash: &TransactionHash) -> Result, Error> { let hash = hex::encode(object_hash); let raw_object_path: Vec = format!("/{}", &hash).into(); let object_path = OwnedPath::try_from(raw_object_path)?; @@ -230,11 +237,15 @@ pub fn store_transaction_object( Ok(encoded.len().try_into()?) } -const CHUNKED_TRANSACTIONS: RefPath = RefPath::assert_from(b"/chunked_transactions"); -const CHUNKED_TRANSACTION_NUM_CHUNKS: RefPath = RefPath::assert_from(b"/num_chunks"); -const CHUNKED_HASHES: RefPath = RefPath::assert_from(b"/chunk_hashes"); +const CHUNKED_TRANSACTIONS: RefPath = + RefPath::assert_from(b"/chunked_transactions"); +const CHUNKED_TRANSACTION_NUM_CHUNKS: RefPath = + RefPath::assert_from(b"/num_chunks"); +const CHUNKED_HASHES: RefPath = RefPath::assert_from(b"/chunk_hashes"); -pub fn chunked_transaction_path(tx_hash: &TransactionHash) -> Result { +pub fn chunked_transaction_path( + tx_hash: &TransactionHash, +) -> Result, Error> { let hash = hex::encode(tx_hash); let raw_chunked_transaction_path: Vec = format!("/{}", hash).into(); let chunked_transaction_path = OwnedPath::try_from(raw_chunked_transaction_path)?; @@ -242,15 +253,15 @@ pub fn chunked_transaction_path(tx_hash: &TransactionHash) -> Result Result { + chunked_transaction_path: &OwnedPath, +) -> Result, Error> { concat(chunked_transaction_path, &CHUNKED_TRANSACTION_NUM_CHUNKS).map_err(Error::from) } pub fn chunked_hash_transaction_path( chunked_hash: &[u8], - chunked_transaction_path: &OwnedPath, -) -> Result { + chunked_transaction_path: &OwnedPath, +) -> Result, Error> { let hash = hex::encode(chunked_hash); let raw_chunked_hash_key: Vec = format!("/{}", hash).into(); let chunked_hash_key = OwnedPath::try_from(raw_chunked_hash_key)?; @@ -259,9 +270,9 @@ pub fn chunked_hash_transaction_path( } pub fn transaction_chunk_path( - chunked_transaction_path: &OwnedPath, + chunked_transaction_path: &OwnedPath, i: u16, -) -> Result { +) -> Result, Error> { let raw_i_path: Vec = format!("/{}", i).into(); let i_path = OwnedPath::try_from(raw_i_path)?; concat(chunked_transaction_path, &i_path).map_err(Error::from) @@ -269,7 +280,7 @@ pub fn transaction_chunk_path( fn is_transaction_complete( host: &mut Host, - chunked_transaction_path: &OwnedPath, + chunked_transaction_path: &OwnedPath, num_chunks: u16, ) -> Result { let n_subkeys = host.store_count_subkeys(chunked_transaction_path)? as u16; @@ -279,7 +290,7 @@ fn is_transaction_complete( fn chunked_transaction_num_chunks_by_path( host: &mut Host, - chunked_transaction_path: &OwnedPath, + chunked_transaction_path: &OwnedPath, ) -> Result { let chunked_transaction_num_chunks_path = chunked_transaction_num_chunks_path(chunked_transaction_path)?; @@ -298,7 +309,7 @@ pub fn chunked_transaction_num_chunks( fn store_transaction_chunk_data( host: &mut Host, - transaction_chunk_path: &OwnedPath, + transaction_chunk_path: &OwnedPath, data: Vec, ) -> Result<(), Error> { match host.store_has(transaction_chunk_path)? { @@ -319,7 +330,7 @@ fn store_transaction_chunk_data( pub fn read_transaction_chunk_data( host: &mut Host, - transaction_chunk_path: &OwnedPath, + transaction_chunk_path: &OwnedPath, ) -> Result, Error> { let data_size = host.store_value_size(transaction_chunk_path)?; @@ -340,7 +351,7 @@ pub fn read_transaction_chunk_data( fn get_full_transaction( host: &mut Host, - chunked_transaction_path: &OwnedPath, + chunked_transaction_path: &OwnedPath, num_chunks: u16, ) -> Result, Error> { let mut buffer = Vec::new(); @@ -354,7 +365,7 @@ fn get_full_transaction( pub fn remove_chunked_transaction_by_path( host: &mut Host, - path: &OwnedPath, + path: &OwnedPath, ) -> Result<(), Error> { host.store_delete(path).map_err(Error::from) } @@ -525,7 +536,7 @@ pub fn store_sequencer_pool_address( pub fn store_timestamp_path( host: &mut Host, - path: &impl Path, + path: &impl Path, timestamp: &Timestamp, ) -> Result<(), Error> { host.store_write(path, ×tamp.i64().to_le_bytes(), 0)?; @@ -587,7 +598,7 @@ pub fn store_last_info_per_level_timestamp( pub fn read_timestamp_path( host: &Host, - path: &impl Path, + path: &impl Path, ) -> Result { let mut buffer = [0u8; 8]; store_read_slice(host, path, &mut buffer, 8)?; diff --git a/etherlink/kernel_evm/kernel/src/upgrade.rs b/etherlink/kernel_evm/kernel/src/upgrade.rs index 90c413ff4f09..39b53c57e05f 100644 --- a/etherlink/kernel_evm/kernel/src/upgrade.rs +++ b/etherlink/kernel_evm/kernel/src/upgrade.rs @@ -34,9 +34,10 @@ use tezos_smart_rollup_host::path::RefPath; use tezos_smart_rollup_installer_config::binary::promote::upgrade_reveal_flow; use tezos_storage::read_optional_rlp; -const KERNEL_UPGRADE: RefPath = RefPath::assert_from(b"/evm/kernel_upgrade"); -pub const KERNEL_ROOT_HASH: RefPath = RefPath::assert_from(b"/evm/kernel_root_hash"); -const SEQUENCER_UPGRADE: RefPath = RefPath::assert_from(b"/evm/sequencer_upgrade"); +const KERNEL_UPGRADE: RefPath = RefPath::assert_from(b"/evm/kernel_upgrade"); +pub const KERNEL_ROOT_HASH: RefPath = + RefPath::assert_from(b"/evm/kernel_root_hash"); +const SEQUENCER_UPGRADE: RefPath = RefPath::assert_from(b"/evm/sequencer_upgrade"); #[derive(Debug, PartialEq, Clone)] pub struct KernelUpgrade { @@ -99,7 +100,7 @@ pub fn store_kernel_upgrade( fn read_kernel_upgrade_at( host: &impl Runtime, - path: &impl Path, + path: &impl Path, ) -> anyhow::Result> { read_optional_rlp(host, path).context("Failed to decode kernel upgrade") } diff --git a/etherlink/kernel_evm/runtime/src/internal_runtime.rs b/etherlink/kernel_evm/runtime/src/internal_runtime.rs index 495da6f232de..321ebe621ee6 100644 --- a/etherlink/kernel_evm/runtime/src/internal_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/internal_runtime.rs @@ -20,7 +20,7 @@ extern "C" { } pub trait InternalRuntime { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError>; @@ -31,13 +31,16 @@ pub trait InternalRuntime { // The path is optional to be able to get the hash // of the root directory. pub trait ExtendedRuntime { - fn store_get_hash(&mut self, path: &T) -> Result, RuntimeError>; + fn store_get_hash>( + &mut self, + path: &T, + ) -> Result, RuntimeError>; } pub struct InternalHost(); impl InternalRuntime for InternalHost { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError> { diff --git a/etherlink/kernel_evm/runtime/src/mock_internal.rs b/etherlink/kernel_evm/runtime/src/mock_internal.rs index 37e820a7b50b..7c6cf1156f83 100644 --- a/etherlink/kernel_evm/runtime/src/mock_internal.rs +++ b/etherlink/kernel_evm/runtime/src/mock_internal.rs @@ -8,7 +8,7 @@ use tezos_smart_rollup_host::path::Path; use tezos_smart_rollup_host::runtime::RuntimeError; pub struct MockInternal(); impl InternalRuntime for MockInternal { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError> { diff --git a/etherlink/kernel_evm/runtime/src/relative_runtime.rs b/etherlink/kernel_evm/runtime/src/relative_runtime.rs index 6c4d50170ec0..4e50e2135e4b 100644 --- a/etherlink/kernel_evm/runtime/src/relative_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/relative_runtime.rs @@ -11,23 +11,26 @@ use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; use tezos_smart_rollup_host::{ input::Message, metadata::RollupMetadata, - path::{concat, OwnedPath, Path, RefPath}, + path::{force_concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; pub struct RelativeRuntime { - pub root: &'static RefPath<'static>, + pub root: &'static RefPath<'static, true>, pub host: Host, } impl RelativeRuntime { - pub fn absolute_path(&self, path: &impl Path) -> Result { - concat(self.root, path).map_err(|_| RuntimeError::PathNotFound) + pub fn absolute_path( + &self, + path: &impl Path, + ) -> Result, RuntimeError> { + force_concat(self.root, path).map_err(|_| RuntimeError::PathNotFound) } } impl InternalRuntime for RelativeRuntime<&mut Host> { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &P, ) -> Result, RuntimeError> { @@ -37,7 +40,10 @@ impl InternalRuntime for RelativeRuntime<&mut Host> { impl ExtendedRuntime for RelativeRuntime<&mut Host> { #[inline(always)] - fn store_get_hash(&mut self, path: &P) -> Result, RuntimeError> { + fn store_get_hash>( + &mut self, + path: &P, + ) -> Result, RuntimeError> { let path = self.absolute_path(path)?; self.__internal_store_get_hash(&path) } @@ -60,13 +66,16 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_has(&self, path: &P) -> Result, RuntimeError> { + fn store_has>( + &self, + path: &P, + ) -> Result, RuntimeError> { let path = self.absolute_path(path)?; self.host.store_has(&path) } #[inline(always)] - fn store_read( + fn store_read>( &self, path: &P, from_offset: usize, @@ -77,7 +86,7 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_read_slice( + fn store_read_slice>( &self, path: &P, from_offset: usize, @@ -88,13 +97,13 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { let path = self.absolute_path(path)?; self.host.store_read_all(&path) } #[inline(always)] - fn store_write( + fn store_write>( &mut self, path: &P, src: &[u8], @@ -105,7 +114,7 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_write_all( + fn store_write_all>( &mut self, path: &P, src: &[u8], @@ -115,19 +124,25 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_delete(&mut self, path: &P) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &P) -> Result<(), RuntimeError> { let path = self.absolute_path(path)?; self.host.store_delete(&path) } #[inline(always)] - fn store_delete_value(&mut self, path: &P) -> Result<(), RuntimeError> { + fn store_delete_value>( + &mut self, + path: &P, + ) -> Result<(), RuntimeError> { let path = self.absolute_path(path)?; self.host.store_delete_value(&path) } #[inline(always)] - fn store_count_subkeys(&self, prefix: &P) -> Result { + fn store_count_subkeys>( + &self, + prefix: &P, + ) -> Result { let prefix = self.absolute_path(prefix)?; self.host.store_count_subkeys(&prefix) } @@ -135,8 +150,8 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = self.absolute_path(from_path)?; let to_path = self.absolute_path(to_path)?; @@ -146,8 +161,8 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = self.absolute_path(from_path)?; let to_path = self.absolute_path(to_path)?; @@ -164,7 +179,7 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { let path = self.absolute_path(path)?; self.host.store_value_size(&path) } diff --git a/etherlink/kernel_evm/runtime/src/runtime.rs b/etherlink/kernel_evm/runtime/src/runtime.rs index 64a24c9fe51a..b01c618c809d 100644 --- a/etherlink/kernel_evm/runtime/src/runtime.rs +++ b/etherlink/kernel_evm/runtime/src/runtime.rs @@ -31,7 +31,7 @@ use tezos_smart_rollup_host::{ use tezos_smart_rollup_mock::MockHost; // Set by the node, contains the verbosity for the logs -pub const VERBOSITY_PATH: RefPath = RefPath::assert_from(b"/evm/logging_verbosity"); +pub const VERBOSITY_PATH: RefPath = RefPath::assert_from(b"/evm/logging_verbosity"); pub trait Runtime: SdkRuntime + InternalRuntime + ExtendedRuntime + Verbosity + WithGas @@ -88,12 +88,15 @@ impl + Borrow, Internal: InternalRuntime> S } #[inline(always)] - fn store_has(&self, path: &T) -> Result, RuntimeError> { + fn store_has>( + &self, + path: &T, + ) -> Result, RuntimeError> { self.host.borrow().store_has(path) } #[inline(always)] - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -103,7 +106,7 @@ impl + Borrow, Internal: InternalRuntime> S } #[inline(always)] - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -115,12 +118,12 @@ impl + Borrow, Internal: InternalRuntime> S } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { self.host.borrow().store_read_all(path) } #[inline(always)] - fn store_write( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -130,7 +133,7 @@ impl + Borrow, Internal: InternalRuntime> S } #[inline(always)] - fn store_write_all( + fn store_write_all>( &mut self, path: &T, src: &[u8], @@ -139,25 +142,31 @@ impl + Borrow, Internal: InternalRuntime> S } #[inline(always)] - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { self.host.borrow_mut().store_delete(path) } #[inline(always)] - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete_value>( + &mut self, + path: &T, + ) -> Result<(), RuntimeError> { self.host.borrow_mut().store_delete_value(path) } #[inline(always)] - fn store_count_subkeys(&self, prefix: &T) -> Result { + fn store_count_subkeys>( + &self, + prefix: &T, + ) -> Result { self.host.borrow().store_count_subkeys(prefix) } #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { self.host.borrow_mut().store_move(from_path, to_path) } @@ -165,8 +174,8 @@ impl + Borrow, Internal: InternalRuntime> S #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { self.host.borrow_mut().store_copy(from_path, to_path) } @@ -181,7 +190,7 @@ impl + Borrow, Internal: InternalRuntime> S } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { self.host.borrow().store_value_size(path) } @@ -254,7 +263,7 @@ impl + BorrowMut, Internal: InternalRuntime> InternalRuntime for KernelHost { #[inline(always)] - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError> { @@ -266,7 +275,10 @@ impl + Borrow, Internal: InternalRuntime> ExtendedRuntime for KernelHost { #[inline(always)] - fn store_get_hash(&mut self, path: &T) -> Result, RuntimeError> { + fn store_get_hash>( + &mut self, + path: &T, + ) -> Result, RuntimeError> { self.__internal_store_get_hash(path) } } diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index d55feb706e33..e2ebc7b8a6fc 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -14,18 +14,19 @@ use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; use tezos_smart_rollup_host::{ input::Message, metadata::RollupMetadata, - path::{concat, OwnedPath, Path, RefPath}, + path::{force_concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; -pub const TMP_PATH: RefPath = RefPath::assert_from(b"/tmp"); -pub const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); -pub const TMP_WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/world_state"); -pub const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); -pub const TMP_TRACE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/trace"); +pub const TMP_PATH: RefPath = RefPath::assert_from(b"/tmp"); +pub const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); +pub const TMP_WORLD_STATE_PATH: RefPath = + RefPath::assert_from(b"/tmp/evm/world_state"); +pub const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); +pub const TMP_TRACE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/trace"); -pub fn safe_path(path: &T) -> Result { - concat(&TMP_PATH, path).map_err(|_| RuntimeError::PathNotFound) +pub fn safe_path>(path: &T) -> Result, RuntimeError> { + force_concat(&TMP_PATH, path).map_err(|_| RuntimeError::PathNotFound) } pub struct SafeStorage { @@ -33,7 +34,7 @@ pub struct SafeStorage { } impl InternalRuntime for SafeStorage<&mut Host> { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError> { @@ -43,7 +44,10 @@ impl InternalRuntime for SafeStorage<&mut Host> { impl ExtendedRuntime for SafeStorage<&mut Host> { #[inline(always)] - fn store_get_hash(&mut self, path: &P) -> Result, RuntimeError> { + fn store_get_hash>( + &mut self, + path: &P, + ) -> Result, RuntimeError> { let path = safe_path(path)?; self.__internal_store_get_hash(&path) } @@ -66,13 +70,16 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_has(&self, path: &T) -> Result, RuntimeError> { + fn store_has>( + &self, + path: &T, + ) -> Result, RuntimeError> { let path = safe_path(path)?; self.host.store_has(&path) } #[inline(always)] - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -83,7 +90,7 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -94,13 +101,13 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { let path = safe_path(path)?; self.host.store_read_all(&path) } #[inline(always)] - fn store_write( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -111,7 +118,7 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_write_all( + fn store_write_all>( &mut self, path: &T, src: &[u8], @@ -121,19 +128,25 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { let path = safe_path(path)?; self.host.store_delete(&path) } #[inline(always)] - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete_value>( + &mut self, + path: &T, + ) -> Result<(), RuntimeError> { let path = safe_path(path)?; self.host.store_delete_value(&path) } #[inline(always)] - fn store_count_subkeys(&self, prefix: &T) -> Result { + fn store_count_subkeys>( + &self, + prefix: &T, + ) -> Result { let prefix = safe_path(prefix)?; self.host.store_count_subkeys(&prefix) } @@ -141,8 +154,8 @@ impl SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = safe_path(from_path)?; let to_path = safe_path(to_path)?; @@ -152,8 +165,8 @@ impl SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = safe_path(from_path)?; let to_path = safe_path(to_path)?; @@ -170,7 +183,7 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { let path = safe_path(path)?; self.host.store_value_size(&path) } diff --git a/etherlink/kernel_evm/storage/src/lib.rs b/etherlink/kernel_evm/storage/src/lib.rs index a4834e10f972..aae947a3e4c1 100644 --- a/etherlink/kernel_evm/storage/src/lib.rs +++ b/etherlink/kernel_evm/storage/src/lib.rs @@ -17,7 +17,7 @@ use tezos_crypto_rs::hash::{ContractKt1Hash, HashTrait}; use tezos_ethereum::rlp_helpers::FromRlpBytes; use tezos_evm_runtime::runtime::Runtime; use tezos_smart_rollup_host::path::*; -use tezos_smart_rollup_host::runtime::{RuntimeError, ValueType}; +use tezos_smart_rollup_host::runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}; /// The size of one 256 bit word. Size in bytes. pub const WORD_SIZE: usize = 32usize; @@ -28,7 +28,7 @@ pub const WORD_SIZE: usize = 32usize; /// NB: Value is read starting 0. pub fn store_read_slice( host: &impl Runtime, - path: &impl Path, + path: &impl Path, buffer: &mut [u8], expected_size: usize, ) -> Result<(), Error> { @@ -44,7 +44,7 @@ pub fn store_read_slice( } /// Get the path corresponding to an index of H256. -pub fn path_from_h256(index: &H256) -> Result { +pub fn path_from_h256(index: &H256) -> Result, Error> { let path_string = format!("/{}", hex::encode(index.to_fixed_bytes())); OwnedPath::try_from(path_string).map_err(Error::from) } @@ -52,7 +52,7 @@ pub fn path_from_h256(index: &H256) -> Result { /// Return a 32 bytes hash from storage at the given `path`. /// /// NB: The given bytes are interpreted in big endian order. -pub fn read_h256_be(host: &impl Runtime, path: &impl Path) -> anyhow::Result { +pub fn read_h256_be(host: &impl Runtime, path: &impl Path) -> anyhow::Result { let mut buffer = [0_u8; WORD_SIZE]; store_read_slice(host, path, &mut buffer, WORD_SIZE)?; Ok(H256::from_slice(&buffer)) @@ -63,7 +63,7 @@ pub fn read_h256_be(host: &impl Runtime, path: &impl Path) -> anyhow::Result, ) -> Result, Error> { match host.store_read_all(path) { Ok(bytes) if bytes.len() == WORD_SIZE => Ok(Some(H256::from_slice(&bytes))), @@ -78,7 +78,7 @@ pub fn read_h256_be_opt( /// NB: The given bytes are interpreted in big endian order. pub fn read_h256_be_default( host: &impl Runtime, - path: &impl Path, + path: &impl Path, default: H256, ) -> Result { match read_h256_be_opt(host, path)? { @@ -92,7 +92,7 @@ pub fn read_h256_be_default( /// NB: The hash is stored in big endian order. pub fn write_h256_be( host: &mut impl Runtime, - path: &impl Path, + path: &impl Path, hash: H256, ) -> anyhow::Result<()> { Ok(host.store_write_all(path, hash.as_bytes())?) @@ -101,7 +101,7 @@ pub fn write_h256_be( /// Return an unsigned 32 bytes value from storage at the given `path`. /// /// NB: The given bytes are interpreted in little endian order. -pub fn read_u256_le(host: &impl Runtime, path: &impl Path) -> Result { +pub fn read_u256_le(host: &impl Runtime, path: &impl Path) -> Result { let bytes = host.store_read_all(path)?; Ok(U256::from_little_endian(&bytes)) } @@ -112,7 +112,7 @@ pub fn read_u256_le(host: &impl Runtime, path: &impl Path) -> Result, default: U256, ) -> Result { match host.store_read_all(path) { @@ -127,7 +127,7 @@ pub fn read_u256_le_default( /// NB: The value is stored in little endian order. pub fn write_u256_le( host: &mut impl Runtime, - path: &impl Path, + path: &impl Path, value: U256, ) -> Result<(), Error> { let mut bytes: [u8; WORD_SIZE] = value.into(); @@ -138,7 +138,7 @@ pub fn write_u256_le( /// Return an unsigned 8 bytes value from storage at the given `path`. /// /// NB: The given bytes are interpreted in little endian order. -pub fn read_u64_le(host: &impl Runtime, path: &impl Path) -> Result { +pub fn read_u64_le(host: &impl SdkRuntime, path: &impl Path) -> Result { let mut bytes = [0; std::mem::size_of::()]; host.store_read_slice(path, 0, bytes.as_mut_slice())?; Ok(u64::from_le_bytes(bytes)) @@ -150,7 +150,7 @@ pub fn read_u64_le(host: &impl Runtime, path: &impl Path) -> Result /// NB: The given bytes are interpreted in little endian order. pub fn read_u64_le_default( host: &impl Runtime, - path: &impl Path, + path: &impl Path, default: u64, ) -> Result { match host.store_read_all(path) { @@ -171,7 +171,7 @@ pub fn read_u64_le_default( /// NB: The given bytes are interpreted in little endian order. pub fn read_u16_le_default( host: &impl Runtime, - path: &impl Path, + path: &impl Path, default: u16, ) -> Result { // This is exactly the same function as `read_u64_le_default`, but you know @@ -192,8 +192,8 @@ pub fn read_u16_le_default( /// /// NB: The value is stored in little endian order. pub fn write_u64_le( - host: &mut impl Runtime, - path: &impl Path, + host: &mut impl SdkRuntime, + path: &impl Path, value: u64, ) -> Result<(), Error> { host.store_write_all(path, value.to_le_bytes().as_slice()) @@ -202,10 +202,10 @@ pub fn write_u64_le( /// Store `src` (which must be encodable) as rlp bytes into storage /// at the given `path`. -pub fn store_rlp( - src: &T, +pub fn store_rlp( + src: &impl Encodable, host: &mut impl Runtime, - path: &impl Path, + path: &impl Path, ) -> Result<(), Error> { host.store_write_all(path, &src.rlp_bytes()) .map_err(Error::from) @@ -213,7 +213,10 @@ pub fn store_rlp( /// Return a decodable value from storage as rlp bytes /// at the given `path`. -pub fn read_rlp(host: &impl Runtime, path: &impl Path) -> Result { +pub fn read_rlp( + host: &impl Runtime, + path: &impl Path, +) -> Result { let bytes = host.store_read_all(path)?; FromRlpBytes::from_rlp_bytes(&bytes).map_err(Error::from) } @@ -224,7 +227,7 @@ pub fn read_rlp(host: &impl Runtime, path: &impl Path) -> Result( host: &impl Runtime, - path: &impl Path, + path: &impl Path, ) -> Result, anyhow::Error> { if let Some(ValueType::Value) = host.store_has(path)? { let elt = read_rlp(host, path)?; @@ -235,7 +238,10 @@ pub fn read_optional_rlp( } /// Return a base58 contract address from storage at the given `path`. -pub fn read_b58_kt1(host: &impl Runtime, path: &impl Path) -> Option { +pub fn read_b58_kt1( + host: &impl Runtime, + path: &impl Path, +) -> Option { let bytes = host.store_read_all(path).ok()?; let kt1_b58 = String::from_utf8(bytes).ok()?; ContractKt1Hash::from_b58check(&kt1_b58).ok() diff --git a/src/kernel_sdk/encoding/src/dac/certificate.rs b/src/kernel_sdk/encoding/src/dac/certificate.rs index b86b0887c840..42ff24a964bc 100644 --- a/src/kernel_sdk/encoding/src/dac/certificate.rs +++ b/src/kernel_sdk/encoding/src/dac/certificate.rs @@ -168,7 +168,7 @@ impl Certificate { pub fn reveal_to_store( &self, host: &mut Host, - path: &impl Path, + path: &impl Path, ) -> Result { const MAX_TOP_LEVEL_HASHES: usize = 20; diff --git a/src/kernel_sdk/host/src/lib.rs b/src/kernel_sdk/host/src/lib.rs index 284b56a65e40..bac4be0b314d 100644 --- a/src/kernel_sdk/host/src/lib.rs +++ b/src/kernel_sdk/host/src/lib.rs @@ -26,7 +26,7 @@ pub use crate::metadata::METADATA_SIZE; use path::RefPath; /// Boot path for kernels -pub const KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); +pub const KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); /// Defines the errors possibly returned by an host functions. #[repr(i32)] diff --git a/src/kernel_sdk/host/src/path.rs b/src/kernel_sdk/host/src/path.rs index 364b27041c59..0137050f3db0 100644 --- a/src/kernel_sdk/host/src/path.rs +++ b/src/kernel_sdk/host/src/path.rs @@ -22,7 +22,7 @@ const DURABLE_STORAGE_PREFIX_INNER: &[u8] = b"/durable"; /// The *wasm-encoded* binary blob of either the currently running kernel, or the next /// kernel to be rebooted into. -pub const PATH_KERNEL_BOOT: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); +pub const PATH_KERNEL_BOOT: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); /// Marker trait for methods on types representing *path-encodings*. /// @@ -42,7 +42,7 @@ pub const PATH_KERNEL_BOOT: RefPath = RefPath::assert_from(b"/kernel/boot.wasm") /// `T: impl Path` being correctly path-encoded. /// /// [`Runtime`]: crate::runtime::Runtime -pub unsafe trait Path: core::fmt::Debug + core::fmt::Display { +pub unsafe trait Path: core::fmt::Debug + core::fmt::Display { /// Returns a read-only reference to the underlying path-encoded byte-slice. fn as_bytes(&self) -> &[u8]; @@ -121,11 +121,11 @@ impl core::fmt::Display for PathError { /// /// Otherwise, you can use [OwnedPath]. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct RefPath<'a> { +pub struct RefPath<'a, const IS_ABSOLUTE: bool> { inner: &'a str, } -impl<'a> RefPath<'a> { +impl<'a, const IS_ABSOLUTE: bool> RefPath<'a, IS_ABSOLUTE> { /// Constructs a [`RefPath`] from a byte slice. /// /// # Panics @@ -151,7 +151,7 @@ impl<'a> RefPath<'a> { /// # use tezos_smart_rollup_host::path::RefPath; /// let path = RefPath::assert_from("!&(*(".as_bytes()); /// ``` - pub const fn assert_from(path: &[u8]) -> RefPath { + pub const fn assert_from(path: &'a[u8]) -> Self { assert_ok(validate_path(path)); RefPath { @@ -163,7 +163,7 @@ impl<'a> RefPath<'a> { /// is writable, i.e. not prefixed with `/readonly`. This function /// is to be used only internally to create [`RefPath`] for the /// `readonly` part of the storage. See `runtime.rs` for example. - pub(crate) const fn assert_from_readonly(path: &[u8]) -> RefPath { + pub(crate) const fn assert_from_readonly(path: &'a [u8]) -> Self { assert_ok(validate_path_internal(path)); RefPath { @@ -172,13 +172,13 @@ impl<'a> RefPath<'a> { } } -impl core::fmt::Display for RefPath<'_> { +impl core::fmt::Display for RefPath<'_, IS_ABSOLUTE> { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { self.inner.fmt(f) } } -unsafe impl Path for RefPath<'_> { +unsafe impl Path for RefPath<'_, IS_ABSOLUTE> { fn as_bytes(&self) -> &[u8] { self.inner.as_bytes() } @@ -255,18 +255,18 @@ const fn validate_path(path: &[u8]) -> Result<(), PathError> { } } -impl<'a> TryFrom<&'a str> for RefPath<'a> { +impl<'a, const IS_ABSOLUTE: bool> TryFrom<&'a str> for RefPath<'a, IS_ABSOLUTE> { type Error = PathError; - fn try_from(slice: &'a str) -> Result { + fn try_from(slice: &'a str) -> Result { Self::try_from(slice.as_bytes()) } } -impl<'a> TryFrom<&'a [u8]> for RefPath<'a> { +impl<'a, const IS_ABSOLUTE: bool> TryFrom<&'a [u8]> for RefPath<'a, IS_ABSOLUTE> { type Error = PathError; - fn try_from(slice: &'a [u8]) -> Result { + fn try_from(slice: &'a [u8]) -> Result { validate_path(slice)?; // SAFETY: we've validated that every byte is either alphanumeric or SEPARATOR @@ -292,11 +292,11 @@ mod owned { /// Useful when a new path is being constructed at runtime, which is not a sub-path of an /// already existing path (in which case you may use [RefPath]). #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] - pub struct OwnedPath { + pub struct OwnedPath { inner: String, } - impl OwnedPath { + impl OwnedPath { /// Constructs an [`OwnedPath`] from an arbitrary sequence of bytes. /// /// # Safety @@ -309,21 +309,20 @@ mod owned { } } - unsafe impl Path for OwnedPath { + unsafe impl Path for OwnedPath { fn as_bytes(&self) -> &[u8] { self.inner.as_bytes() } } - impl<'a> From> for OwnedPath { - fn from(path: RefPath<'a>) -> Self { + impl<'a, const IS_ABSOLUTE : bool> From> for OwnedPath { + fn from(path: RefPath<'a, IS_ABSOLUTE>) -> Self { Self { inner: path.inner.to_string(), } } } - - impl From<&P> for OwnedPath { + impl> From<&P> for OwnedPath { fn from(path: &P) -> Self { let path_bytes = path.as_bytes().to_vec(); @@ -335,13 +334,13 @@ mod owned { } } - impl<'a> From<&'a OwnedPath> for RefPath<'a> { - fn from(path: &'a OwnedPath) -> Self { + impl<'a, const IS_ABSOLUTE: bool> From<&'a OwnedPath> for RefPath<'a, IS_ABSOLUTE> { + fn from(path: &'a OwnedPath) -> Self { Self { inner: &path.inner } } } - impl TryFrom for OwnedPath { + impl TryFrom for OwnedPath { type Error = PathError; fn try_from(inner: String) -> Result { @@ -351,10 +350,10 @@ mod owned { } } - impl TryFrom> for OwnedPath { + impl TryFrom> for OwnedPath { type Error = PathError; - fn try_from(bytes: Vec) -> Result { + fn try_from(bytes: Vec) -> Result { validate_path(&bytes)?; // SAFETY: we've validated that every byte is either alphanumeric or SEPARATOR @@ -364,7 +363,7 @@ mod owned { } } - impl core::fmt::Display for OwnedPath { + impl core::fmt::Display for OwnedPath { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { self.inner.fmt(f) } @@ -373,10 +372,32 @@ mod owned { /// Given a prefix and a suffix create a new path that concatenates the two. /// /// Returns error in case the resulting path is too long. - pub fn concat( - prefix: &impl Path, - suffix: &impl Path, - ) -> Result { + pub fn concat( + prefix: &impl Path, + suffix: &impl Path, + ) -> Result, PathError> { + let mut bytes = Vec::with_capacity(prefix.size() + suffix.size()); + + bytes.extend_from_slice(prefix.as_bytes()); + bytes.extend_from_slice(suffix.as_bytes()); + + if bytes.len() <= PATH_MAX_SIZE { + // Since both prefix and suffix are paths, we can assume they only + // contain valid characters and start with '/', ie bytes contain + // a valid path as well. Also knowing that bytes contains valid + // number of bytes, we can use the unsafe, faster call below. + Ok(unsafe { OwnedPath::from_bytes_unchecked(bytes) }) + } else { + Err(PathError::PathTooLong) + } + } + + /// Same as concat but suffix is allowed to be an absolute path. + /// This is useful to backup an absolute path in /tmp/ + pub fn force_concat( + prefix: &impl Path, + suffix: &impl Path, + ) -> Result, PathError> { let mut bytes = Vec::with_capacity(prefix.size() + suffix.size()); bytes.extend_from_slice(prefix.as_bytes()); @@ -393,7 +414,7 @@ mod owned { } } - impl<'a> BinWriter for RefPath<'a> { + impl<'a, const IS_ABSOLUTE: bool> BinWriter for RefPath<'a, IS_ABSOLUTE> { fn bin_write(&self, output: &mut Vec) -> BinResult { let data = self.inner; put_bytes(data.as_bytes(), output); diff --git a/src/kernel_sdk/host/src/runtime.rs b/src/kernel_sdk/host/src/runtime.rs index 66ac91c0a63f..d7af72af67ab 100644 --- a/src/kernel_sdk/host/src/runtime.rs +++ b/src/kernel_sdk/host/src/runtime.rs @@ -99,11 +99,11 @@ pub trait Runtime { fn read_input(&mut self) -> Result, RuntimeError>; /// Returns whether a given path exists in storage. - fn store_has(&self, path: &T) -> Result, RuntimeError>; + fn store_has>(&self, path: &T) -> Result, RuntimeError>; /// Read up to `max_bytes` from the given path in storage, starting `from_offset`. #[cfg(feature = "alloc")] - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -117,7 +117,7 @@ pub trait Runtime { /// The total bytes read is returned. /// If the returned value `n` is `n < buffer.len()`, then only the first `n` /// bytes of the buffer will have been written too. - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -126,14 +126,14 @@ pub trait Runtime { /// Read an entire value from the given path in storage. #[cfg(feature = "alloc")] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError>; + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError>; /// Write the bytes given by `src` to storage at `path`, starting `at_offset`. /// /// Contrary to `store_write_all`, this does not replace the value (if any) /// previously stored under `path`. This allows for splicing/patching values /// directly in storage, without having to read the entire value from disk. - fn store_write( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -144,30 +144,30 @@ pub trait Runtime { /// /// Contrary to `store_write`, this replaces the value (if any) that /// was previously stored at `path`. - fn store_write_all( + fn store_write_all>( &mut self, path: &T, src: &[u8], ) -> Result<(), RuntimeError>; /// Delete `path` from storage. - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError>; + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError>; /// Delete value under `path` from storage. - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError>; + fn store_delete_value>(&mut self, path: &T) -> Result<(), RuntimeError>; /// Count the number of subkeys under `prefix`. /// /// See [SmartRollupCore::store_list_size]. - fn store_count_subkeys(&self, prefix: &T) -> Result; + fn store_count_subkeys>(&self, prefix: &T) -> Result; /// Move one part of durable storage to a different location /// /// See [SmartRollupCore::store_move]. fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError>; /// Copy one part of durable storage to a different location @@ -175,8 +175,8 @@ pub trait Runtime { /// See [SmartRollupCore::store_copy]. fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError>; /// Reveal pre-image from a hash of size `PREIMAGE_HASH_SIZE` in bytes. @@ -204,7 +204,7 @@ pub trait Runtime { fn reveal_dal_parameters(&self) -> RollupDalParameters; /// Return the size of value stored at `path` - fn store_value_size(&self, path: &impl Path) -> Result; + fn store_value_size(&self, path: &impl Path) -> Result; /// Mark the kernel for reboot. /// @@ -244,7 +244,7 @@ pub trait Runtime { fn runtime_version(&self) -> Result; } -const REBOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/env/reboot"); +const REBOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/env/reboot"); impl Runtime for Host where @@ -299,7 +299,7 @@ where Ok(Some(input)) } - fn store_has(&self, path: &T) -> Result, RuntimeError> { + fn store_has>(&self, path: &T) -> Result, RuntimeError> { let result = unsafe { SmartRollupCore::store_has(self, path.as_ptr(), path.size()) }; @@ -317,7 +317,7 @@ where } #[cfg(feature = "alloc")] - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -352,7 +352,7 @@ where Ok(buffer) } - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -375,7 +375,7 @@ where } #[cfg(feature = "alloc")] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { use tezos_smart_rollup_core::MAX_FILE_CHUNK_SIZE; let length = Runtime::store_value_size(self, path)?; @@ -418,7 +418,7 @@ where Ok(buffer) } - fn store_write( + fn store_write>( &mut self, path: &T, mut src: &[u8], @@ -461,7 +461,7 @@ where } } - fn store_write_all( + fn store_write_all>( &mut self, path: &T, value: &[u8], @@ -483,7 +483,7 @@ where Runtime::store_write(self, path, value, 0) } - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { if let Ok(None) = Runtime::store_has(self, path) { return Err(RuntimeError::PathNotFound); } @@ -496,7 +496,7 @@ where } } - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete_value>(&mut self, path: &T) -> Result<(), RuntimeError> { let res = unsafe { SmartRollupCore::store_delete_value(self, path.as_ptr(), path.size()) }; @@ -506,7 +506,7 @@ where } } - fn store_count_subkeys(&self, path: &T) -> Result { + fn store_count_subkeys>(&self, path: &T) -> Result { let count = unsafe { SmartRollupCore::store_list_size(self, path.as_ptr(), path.size()) }; @@ -519,8 +519,8 @@ where fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let res = unsafe { SmartRollupCore::store_move( @@ -541,8 +541,8 @@ where fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let res = unsafe { SmartRollupCore::store_copy( @@ -665,7 +665,7 @@ where } } - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { let res = unsafe { SmartRollupCore::store_value_size(self, path.as_ptr(), path.size()) }; @@ -682,14 +682,14 @@ where } fn last_run_aborted(&self) -> Result { - const PATH_STUCK_FLAG: RefPath = + const PATH_STUCK_FLAG: RefPath = RefPath::assert_from_readonly(b"/readonly/kernel/env/stuck"); let last_run_aborted = Runtime::store_has(self, &PATH_STUCK_FLAG)?.is_some(); Ok(last_run_aborted) } fn upgrade_failed(&self) -> Result { - const PATH_UPGRADE_ERROR_FLAG: RefPath = + const PATH_UPGRADE_ERROR_FLAG: RefPath = RefPath::assert_from_readonly(b"/readonly/kernel/env/upgrade_error"); let upgrade_failed = Runtime::store_has(self, &PATH_UPGRADE_ERROR_FLAG)?.is_some(); @@ -697,7 +697,7 @@ where } fn restart_forced(&self) -> Result { - const PATH_TOO_MANY_REBOOT_FLAG: RefPath = + const PATH_TOO_MANY_REBOOT_FLAG: RefPath = RefPath::assert_from_readonly(b"/readonly/kernel/env/too_many_reboot"); let restart_forced = Runtime::store_has(self, &PATH_TOO_MANY_REBOOT_FLAG)?.is_some(); @@ -705,7 +705,7 @@ where } fn reboot_left(&self) -> Result { - const PATH_REBOOT_COUNTER: RefPath = + const PATH_REBOOT_COUNTER: RefPath = RefPath::assert_from_readonly(b"/readonly/kernel/env/reboot_counter"); const SIZE: usize = core::mem::size_of::(); @@ -718,7 +718,7 @@ where #[cfg(feature = "alloc")] fn runtime_version(&self) -> Result { - const PATH_VERSION: RefPath = + const PATH_VERSION: RefPath = RefPath::assert_from_readonly(b"/readonly/wasm_version"); let bytes = Runtime::store_read(self, &PATH_VERSION, 0, 9)?; // SAFETY: This storage can only contains valid version string which are utf8 safe. @@ -729,7 +729,7 @@ where fn check_path_has_value<'a>( runtime: &'a impl Runtime, - path: &'a impl Path, + path: &'a impl Path, ) -> impl FnOnce(RuntimeError) -> RuntimeError + 'a { |err| { if let Ok(Some(ValueType::Value | ValueType::ValueWithSubtree)) = @@ -742,7 +742,7 @@ fn check_path_has_value<'a>( } } -fn check_path_exists<'a, T: Path>( +fn check_path_exists<'a, T: Path>( runtime: &'a impl Runtime, path: &'a T, ) -> impl FnOnce(RuntimeError) -> RuntimeError + 'a { @@ -861,7 +861,7 @@ mod tests { fn store_has_existing_return_true() { // Arrange let mut mock = MockSmartRollupCore::new(); - let existing_path = RefPath::assert_from("/an/Existing/path".as_bytes()); + let existing_path = RefPath::::assert_from("/an/Existing/path".as_bytes()); mock.expect_store_has() .withf(move |ptr, size| { @@ -911,7 +911,7 @@ mod tests { fn store_has_not_existing_returns_false() { // Arrange let path_bytes = String::from("/does/not.exist").into_bytes(); - let non_existent_path: OwnedPath = RefPath::assert_from(&path_bytes).into(); + let non_existent_path: OwnedPath = RefPath::assert_from(&path_bytes).into(); let mock = mock_path_not_existing(path_bytes); @@ -926,7 +926,7 @@ mod tests { fn store_read_max_bytes() { // Arrange const FRACTION: usize = 1; - const PATH: RefPath<'static> = RefPath::assert_from("/a/simple/path".as_bytes()); + const PATH: RefPath<'static, true> = RefPath::assert_from("/a/simple/path".as_bytes()); const OFFSET: usize = 5; let mut mock = mock_path_exists(PATH.as_bytes()); @@ -958,7 +958,7 @@ mod tests { fn store_read_lt_max_bytes() { // Arrange const FRACTION: usize = 5; - const PATH: RefPath<'static> = RefPath::assert_from("/a/simple/path".as_bytes()); + const PATH: RefPath<'static, true> = RefPath::assert_from("/a/simple/path".as_bytes()); const OFFSET: usize = 10; let mut mock = mock_path_exists(PATH.as_bytes()); @@ -990,7 +990,7 @@ mod tests { fn store_read_path_not_found() { // Arrange let bytes = "/a/2nd/PATH.which/doesnt/exist".as_bytes().to_vec(); - let path: OwnedPath = RefPath::assert_from(&bytes).into(); + let path: OwnedPath = RefPath::assert_from(&bytes).into(); let offset = 25; let mock = mock_path_not_existing(bytes); @@ -1008,7 +1008,7 @@ mod tests { // The value read is formed of 3 chunks, two of the max chunk value and // the last one being less than the max size. - const PATH: RefPath<'static> = RefPath::assert_from("/a/simple/path".as_bytes()); + const PATH: RefPath<'static, true> = RefPath::assert_from("/a/simple/path".as_bytes()); const VALUE_FIRST_CHUNK: [u8; MAX_FILE_CHUNK_SIZE] = [b'a'; MAX_FILE_CHUNK_SIZE]; const VALUE_SECOND_CHUNK: [u8; MAX_FILE_CHUNK_SIZE] = [b'b'; MAX_FILE_CHUNK_SIZE]; const VALUE_LAST_CHUNK: [u8; MAX_FILE_CHUNK_SIZE / 2] = @@ -1065,7 +1065,7 @@ mod tests { #[test] fn store_write_ok() { // Arrange - const PATH: RefPath<'static> = RefPath::assert_from("/a/simple/path".as_bytes()); + const PATH: RefPath<'static, true> = RefPath::assert_from("/a/simple/path".as_bytes()); const OUTPUT: &[u8] = "One two three four five".as_bytes(); const OFFSET: usize = 12398; @@ -1091,7 +1091,7 @@ mod tests { #[test] fn store_write_too_large() { // Arrange - const PATH: RefPath<'static> = RefPath::assert_from("/a/simple/path".as_bytes()); + const PATH: RefPath<'static, true> = RefPath::assert_from("/a/simple/path".as_bytes()); const OUTPUT: &[u8] = "once I saw a fish alive".as_bytes(); const OFFSET: usize = 0; @@ -1119,7 +1119,7 @@ mod tests { #[test] fn store_write_all() { - const PATH: RefPath<'static> = RefPath::assert_from("/a/simple/path".as_bytes()); + const PATH: RefPath<'static, true> = RefPath::assert_from("/a/simple/path".as_bytes()); const VALUE_FIRST_CHUNK: [u8; MAX_FILE_CHUNK_SIZE] = [b'a'; MAX_FILE_CHUNK_SIZE]; const VALUE_SECOND_CHUNK: [u8; MAX_FILE_CHUNK_SIZE] = [b'b'; MAX_FILE_CHUNK_SIZE]; const VALUE_LAST_CHUNK: [u8; MAX_FILE_CHUNK_SIZE / 2] = @@ -1195,7 +1195,7 @@ mod tests { #[test] fn store_delete() { // Arrange - const PATH: RefPath<'static> = + const PATH: RefPath<'static, true> = RefPath::assert_from("/a/2nd/PATH.which/does/exist".as_bytes()); let mut mock = mock_path_exists(PATH.as_bytes()); @@ -1218,7 +1218,7 @@ mod tests { fn store_delete_path_not_found() { // Arrange let bytes = String::from("/a/2nd/PATH.which/doesnt/exist").into_bytes(); - let path: OwnedPath = RefPath::assert_from(&bytes).into(); + let path: OwnedPath = RefPath::assert_from(&bytes).into(); let mut mock = mock_path_not_existing(bytes); @@ -1232,10 +1232,10 @@ mod tests { #[test] fn store_delete_value() { // Arrange - const PATH: RefPath<'static> = + const PATH: RefPath<'static, true> = RefPath::assert_from("/a/PATH.which/does/exist".as_bytes()); - const REMAINING_PATH: RefPath<'static> = + const REMAINING_PATH: RefPath<'static, true> = RefPath::assert_from("/a/PATH.which/does/exist/and/survived".as_bytes()); let mut mock = mock_path_exists(PATH.as_bytes()); @@ -1265,7 +1265,7 @@ mod tests { #[test] fn store_count_subkeys() { // Arrange - const PATH: RefPath<'static> = + const PATH: RefPath<'static, true> = RefPath::assert_from("/prefix/of/other/keys".as_bytes()); let subkey_count = 14; @@ -1316,7 +1316,7 @@ mod tests { #[test] fn store_value_size() { let mut mock = MockSmartRollupCore::new(); - const PATH: RefPath<'static> = RefPath::assert_from(b"/prefix/of/other/paths"); + const PATH: RefPath<'static, true> = RefPath::assert_from(b"/prefix/of/other/paths"); let size = 256_usize; mock.expect_store_has() .return_const(tezos_smart_rollup_core::VALUE_TYPE_VALUE); @@ -1329,7 +1329,7 @@ mod tests { #[test] fn store_value_size_path_not_found() { let mut mock = MockSmartRollupCore::new(); - const PATH: RefPath<'static> = RefPath::assert_from(b"/prefix/of/other/paths"); + const PATH: RefPath<'static, true> = RefPath::assert_from(b"/prefix/of/other/paths"); mock.expect_store_value_size() .return_const(tezos_smart_rollup_core::STORE_NOT_A_VALUE); mock.expect_store_has() diff --git a/src/kernel_sdk/installer-client/src/config.rs b/src/kernel_sdk/installer-client/src/config.rs index 336612d748ae..cfc9281ebded 100644 --- a/src/kernel_sdk/installer-client/src/config.rs +++ b/src/kernel_sdk/installer-client/src/config.rs @@ -24,10 +24,10 @@ pub enum ConfigurationError { } // Path that we write the kernel to, before upgrading. -const PREPARE_KERNEL_PATH: RefPath = RefPath::assert_from(b"/installer/kernel/boot.wasm"); +const PREPARE_KERNEL_PATH: RefPath = RefPath::assert_from(b"/installer/kernel/boot.wasm"); // Path of currently running kernel. -const KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); +const KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); pub fn create_installer_config( root_hash: PreimageHash, diff --git a/src/kernel_sdk/installer-client/src/lib.rs b/src/kernel_sdk/installer-client/src/lib.rs index 6a5e79ff9d71..f979b6980486 100644 --- a/src/kernel_sdk/installer-client/src/lib.rs +++ b/src/kernel_sdk/installer-client/src/lib.rs @@ -9,8 +9,8 @@ pub mod preimages; use tezos_smart_rollup_host::path::RefPath; // Path that we write the kernel to, before upgrading. -pub const PREPARE_KERNEL_PATH: RefPath = +pub const PREPARE_KERNEL_PATH: RefPath = RefPath::assert_from(b"/installer/kernel/boot.wasm"); // Path of currently running kernel. -pub const KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); +pub const KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); diff --git a/src/kernel_sdk/installer-config/src/binary/bin.rs b/src/kernel_sdk/installer-config/src/binary/bin.rs index 2cd4d945f92c..c2507c071f3a 100644 --- a/src/kernel_sdk/installer-config/src/binary/bin.rs +++ b/src/kernel_sdk/installer-config/src/binary/bin.rs @@ -28,7 +28,7 @@ fn put_le_size(size: usize, out: &mut Vec) -> BinResult { } /// Encode RefPath as a bytes with prepended path size -fn path_dynamic(p: &impl Path, output: &mut Vec) -> BinResult { +fn path_dynamic(p: &impl Path, output: &mut Vec) -> BinResult { let data = p.as_bytes(); // We can cast it to u8 as path length doesn't exceed 250 let size = data.len() as u8; @@ -49,7 +49,7 @@ impl<'a> BinWriter for RefBytes<'a> { } } -impl BinWriter for MoveInstruction

{ +impl> BinWriter for MoveInstruction

{ fn bin_write(&self, out: &mut Vec) -> tezos_data_encoding::enc::BinResult { (|data: &Self, out: &mut Vec| { tezos_data_encoding::enc::field("MoveInstruction::from", path_dynamic)( @@ -63,7 +63,7 @@ impl BinWriter for MoveInstruction

{ } } -impl> BinWriter for RevealInstruction { +impl, B: AsRef<[u8]>> BinWriter for RevealInstruction { fn bin_write(&self, out: &mut Vec) -> tezos_data_encoding::enc::BinResult { (|data: &Self, out: &mut Vec| { field("RevealInstruction::hash", bytes_dynamic)(&data.hash, out)?; @@ -73,7 +73,7 @@ impl> BinWriter for RevealInstruction { } } -impl> BinWriter for SetInstruction { +impl, B: AsRef<[u8]>> BinWriter for SetInstruction { fn bin_write(&self, out: &mut Vec) -> tezos_data_encoding::enc::BinResult { (|data: &Self, out: &mut Vec| { field("SetInstruction::value", bytes_dynamic)(&data.value, out)?; @@ -83,7 +83,7 @@ impl> BinWriter for SetInstruction { } } -impl> BinWriter for ConfigInstruction { +impl, B: AsRef<[u8]>> BinWriter for ConfigInstruction { fn bin_write(&self, out: &mut Vec) -> tezos_data_encoding::enc::BinResult { use tezos_data_encoding::enc::{u8, variant_with_field}; match self { diff --git a/src/kernel_sdk/installer-config/src/binary/instr.rs b/src/kernel_sdk/installer-config/src/binary/instr.rs index 2fccbc676790..85778d61b56a 100644 --- a/src/kernel_sdk/installer-config/src/binary/instr.rs +++ b/src/kernel_sdk/installer-config/src/binary/instr.rs @@ -50,7 +50,7 @@ pub enum ConfigInstruction { Set(SetInstruction), } -pub type RefConfigInstruction<'a> = ConfigInstruction, RefBytes<'a>>; +pub type RefConfigInstruction<'a> = ConfigInstruction, RefBytes<'a>>; #[cfg(feature = "alloc")] pub mod owned { @@ -73,7 +73,7 @@ pub mod owned { } } - pub type OwnedConfigInstruction = ConfigInstruction; + pub type OwnedConfigInstruction = ConfigInstruction, OwnedBytes>; #[derive(Debug, PartialEq, Eq)] pub struct OwnedConfigProgram(pub Vec); @@ -96,18 +96,18 @@ pub mod owned { } impl OwnedConfigInstruction { - pub fn reveal_instr(hash: PreimageHash, to: OwnedPath) -> Self { + pub fn reveal_instr(hash: PreimageHash, to: OwnedPath) -> Self { OwnedConfigInstruction::Reveal(RevealInstruction { hash: OwnedBytes(hash.into()), to, }) } - pub fn move_instr(from: OwnedPath, to: OwnedPath) -> Self { + pub fn move_instr(from: OwnedPath, to: OwnedPath) -> Self { OwnedConfigInstruction::Move(MoveInstruction { from, to }) } - pub fn set_instr(value: OwnedBytes, to: OwnedPath) -> Self { + pub fn set_instr(value: OwnedBytes, to: OwnedPath) -> Self { OwnedConfigInstruction::Set(SetInstruction { value, to }) } } @@ -148,7 +148,7 @@ pub mod evaluation { /// config.evaluate(host) /// } /// ``` - pub fn eval_config_instr>( + pub fn eval_config_instr, Bytes: AsRef<[u8]>>( host: &mut impl Runtime, config_instr: &ConfigInstruction, ) -> Result<(), &'static str> { @@ -181,7 +181,7 @@ pub mod promote { KERNEL_BOOT_PATH, }; - const TMP_REVEAL_PATH: RefPath = RefPath::assert_from(b"/__sdk/installer/reveal"); + const TMP_REVEAL_PATH: RefPath = RefPath::assert_from(b"/__sdk/installer/reveal"); pub fn upgrade_reveal_flow( root_hash: [u8; PREIMAGE_HASH_SIZE], diff --git a/src/kernel_sdk/installer-config/src/binary/nom.rs b/src/kernel_sdk/installer-config/src/binary/nom.rs index b6689cfa8eb2..b3a3c7aedad7 100644 --- a/src/kernel_sdk/installer-config/src/binary/nom.rs +++ b/src/kernel_sdk/installer-config/src/binary/nom.rs @@ -67,16 +67,16 @@ fn bounded_u8_size(max: usize) -> impl FnMut(NomInput) -> NomResult { } } -fn nom_read_ref_path(input: &[u8]) -> NomResult { +fn nom_read_ref_path(input: &[u8]) -> NomResult> { map_res( complete(nom::multi::length_data(bounded_u8_size(PATH_MAX_SIZE))), - |bytes| Ok::, NomError<'_>>(RefPath::assert_from(bytes)), + |bytes| Ok::, NomError<'_>>(RefPath::assert_from(bytes)), )(input) } pub fn read_size( host: &impl Runtime, - path: &impl Path, + path: &impl Path, offset: &mut usize, ) -> Result { let mut size_buffer = [0; 4]; @@ -104,7 +104,7 @@ impl<'a> NomReader<'a> for RefBytes<'a> { } } -impl<'a> NomReader<'a> for RevealInstruction, RefBytes<'a>> { +impl<'a> NomReader<'a> for RevealInstruction, RefBytes<'a>> { fn nom_read(bytes: &'a [u8]) -> NomResult { map( nom::sequence::tuple(( @@ -116,7 +116,7 @@ impl<'a> NomReader<'a> for RevealInstruction, RefBytes<'a>> { } } -impl<'a> NomReader<'a> for MoveInstruction> { +impl<'a> NomReader<'a> for MoveInstruction> { fn nom_read(bytes: &'a [u8]) -> NomResult { map( tuple((nom_read_ref_path, nom_read_ref_path)), @@ -125,7 +125,7 @@ impl<'a> NomReader<'a> for MoveInstruction> { } } -impl<'a> NomReader<'a> for SetInstruction, RefBytes<'a>> { +impl<'a> NomReader<'a> for SetInstruction, RefBytes<'a>> { fn nom_read(bytes: &'a [u8]) -> NomResult { map( nom::sequence::tuple(( @@ -137,20 +137,20 @@ impl<'a> NomReader<'a> for SetInstruction, RefBytes<'a>> { } } -impl<'a> NomReader<'a> for ConfigInstruction, RefBytes<'a>> { +impl<'a> NomReader<'a> for ConfigInstruction, RefBytes<'a>> { fn nom_read(bytes: &'a [u8]) -> NomResult { let (input, tag) = nom::number::complete::u8(bytes)?; let (input, variant) = match tag { 0 => (map( - , RefBytes<'a>> as NomReader>::nom_read, + , RefBytes<'a>> as NomReader>::nom_read, ConfigInstruction::Reveal, ))(input)?, 1 => (map( - > as NomReader>::nom_read, + > as NomReader>::nom_read, ConfigInstruction::Move, ))(input)?, 2 => (map( - , RefBytes<'a>> as NomReader>::nom_read, + , RefBytes<'a>> as NomReader>::nom_read, ConfigInstruction::Set, ))(input)?, _ => { diff --git a/src/kernel_sdk/installer-config/src/binary/preimage.rs b/src/kernel_sdk/installer-config/src/binary/preimage.rs index f4a6a354b236..16a1f651410e 100644 --- a/src/kernel_sdk/installer-config/src/binary/preimage.rs +++ b/src/kernel_sdk/installer-config/src/binary/preimage.rs @@ -20,7 +20,7 @@ const MAX_DAC_LEVELS: usize = 4; pub fn reveal_root_hash_to_store( host: &mut impl Runtime, root_hash: &[u8; PREIMAGE_HASH_SIZE], - reveal_to: &impl Path, + reveal_to: &impl Path, ) -> Result<(), &'static str> { let mut reveal_buffer = [0; MAX_PAGE_SIZE * MAX_DAC_LEVELS]; @@ -38,7 +38,7 @@ pub fn reveal_root_hash_to_store( /// Appends the content of the page path given. fn write_kernel_page( - reveal_to: &impl Path, + reveal_to: &impl Path, ) -> impl FnMut(&mut Host, V0SliceContentPage) -> Result<(), &'static str> + '_ { let mut kernel_size = 0; move |host, page| { @@ -52,7 +52,7 @@ fn append_content( host: &mut Host, kernel_size: usize, content: V0SliceContentPage, - reveal_to: &impl Path, + reveal_to: &impl Path, ) -> Result { let content = content.as_ref(); @@ -69,7 +69,7 @@ mod test { use tezos_smart_rollup_host::{path::RefPath, runtime::Runtime}; use tezos_smart_rollup_mock::MockHost; - const TMP_REVEAL_PATH: RefPath = RefPath::assert_from(b"/__sdk/installer/reveal"); + const TMP_REVEAL_PATH: RefPath = RefPath::assert_from(b"/__sdk/installer/reveal"); fn preliminary_upgrade(host: &mut MockHost) -> (PreimageHash, Vec) { let kernel = [1_u8; 1000]; diff --git a/src/kernel_sdk/installer-config/src/yaml/convert.rs b/src/kernel_sdk/installer-config/src/yaml/convert.rs index 9e475825ced1..f61a8324aee6 100644 --- a/src/kernel_sdk/installer-config/src/yaml/convert.rs +++ b/src/kernel_sdk/installer-config/src/yaml/convert.rs @@ -22,7 +22,7 @@ pub enum ConfigConversionError { #[error("Invalid reveal path: {0}")] PathError(PathError), #[error("Unable to convert set for {0} to reveal")] - SetToReveal(OwnedPath), + SetToReveal(OwnedPath), } pub fn reveal_instr_hex( diff --git a/src/kernel_sdk/installer-kernel/src/instr.rs b/src/kernel_sdk/installer-kernel/src/instr.rs index 90aba7bd3f06..bd3dbdef790b 100644 --- a/src/kernel_sdk/installer-kernel/src/instr.rs +++ b/src/kernel_sdk/installer-kernel/src/instr.rs @@ -10,7 +10,7 @@ use tezos_smart_rollup_installer_config::binary::read_size; pub fn read_config_program_size( host: &impl Runtime, - config_interpretation_path: &RefPath, + config_interpretation_path: &RefPath, ) -> Result { let kernel_size = host .store_value_size(config_interpretation_path) @@ -26,7 +26,7 @@ pub fn read_config_program_size( pub fn read_instruction_bytes( host: &impl Runtime, - path: &impl Path, + path: &impl Path, offset: &mut usize, mut buffer: &mut [u8], ) -> Result<(), &'static str> { diff --git a/src/kernel_sdk/installer-kernel/src/lib.rs b/src/kernel_sdk/installer-kernel/src/lib.rs index 9235476c6890..d9a7906f51df 100644 --- a/src/kernel_sdk/installer-kernel/src/lib.rs +++ b/src/kernel_sdk/installer-kernel/src/lib.rs @@ -33,11 +33,11 @@ use tezos_smart_rollup_installer_config::binary::{ }; // Path of currently running kernel. -const KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); +const KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/boot.wasm"); // Installer kernel will copy to this path before execution of config. // This is done in order avoid rewriting kernel during config execution. -const AUXILIARY_CONFIG_INTERPRETATION_PATH: RefPath = +const AUXILIARY_CONFIG_INTERPRETATION_PATH: RefPath = RefPath::assert_from(b"/__installer_kernel/auxiliary/kernel/boot.wasm"); /// Installer. @@ -72,7 +72,7 @@ fn panic(_info: &PanicInfo) -> ! { // TODO: provide a concrete example (see https://gitlab.com/tezos/tezos/-/issues/5855) pub fn install_kernel( host: &mut impl Runtime, - config_interpretation_path: RefPath, + config_interpretation_path: RefPath, ) -> Result<(), &'static str> { if let Ok(config_program_size) = read_config_program_size(host, &config_interpretation_path) diff --git a/src/kernel_sdk/mock/src/state/in_memory_store.rs b/src/kernel_sdk/mock/src/state/in_memory_store.rs index 08ee6d066bf8..8e2d492c1839 100644 --- a/src/kernel_sdk/mock/src/state/in_memory_store.rs +++ b/src/kernel_sdk/mock/src/state/in_memory_store.rs @@ -129,7 +129,7 @@ impl InMemoryStore { } fn validate_path(s: &[u8]) -> Result { - match RefPath::try_from(s) { + match RefPath::::try_from(s) { Err(PathError::PathTooLong) => Err(Error::StoreKeyTooLarge), Err(_) => Err(Error::StoreInvalidKey), Ok(_) => { @@ -152,7 +152,7 @@ fn validate_path_maybe_readonly(s: &[u8]) -> Result { } else { s }; - match RefPath::try_from(to_check) { + match RefPath::::try_from(to_check) { Err(PathError::PathTooLong) => Err(Error::StoreKeyTooLarge), Err(_) => Err(Error::StoreInvalidKey), Ok(_) => { diff --git a/src/kernel_sdk/sdk/src/outbox.rs b/src/kernel_sdk/sdk/src/outbox.rs index b2b1b3f9c2b0..290869285e6e 100644 --- a/src/kernel_sdk/sdk/src/outbox.rs +++ b/src/kernel_sdk/sdk/src/outbox.rs @@ -84,9 +84,9 @@ use tezos_smart_rollup_host::{ use alloc::vec::Vec; -const OUTBOX_QUEUE_ROOT: RefPath = RefPath::assert_from(b"/__sdk/outbox"); -const OUTBOX_QUEUE_META: RefPath = RefPath::assert_from(b"/__sdk/outbox/meta"); -const META_SUFFIX: RefPath = RefPath::assert_from(b"/meta"); +const OUTBOX_QUEUE_ROOT: RefPath = RefPath::assert_from(b"/__sdk/outbox"); +const OUTBOX_QUEUE_META: RefPath = RefPath::assert_from(b"/__sdk/outbox/meta"); +const META_SUFFIX: RefPath = RefPath::assert_from(b"/meta"); /// The default outbox queue. /// @@ -95,7 +95,7 @@ const META_SUFFIX: RefPath = RefPath::assert_from(b"/meta"); /// It is configured with a maximum queue size of 65536. If you flush the queue every /// tezos level, it will take roughly 2h45mins for a message to make its way through /// the queue, and be written to the outbox. -pub const OUTBOX_QUEUE: OutboxQueue<'static, RefPath> = OutboxQueue { +pub const OUTBOX_QUEUE: OutboxQueue<'static, RefPath> = OutboxQueue { root: &OUTBOX_QUEUE_ROOT, meta: &OUTBOX_QUEUE_META, max: u16::MAX as u32, @@ -105,13 +105,13 @@ pub const OUTBOX_QUEUE: OutboxQueue<'static, RefPath> = OutboxQueue { /// /// See [`OUTBOX_QUEUE`] for more information. #[derive(Debug)] -pub struct OutboxQueue<'a, P: Path> { +pub struct OutboxQueue<'a, P: Path> { root: &'a P, meta: &'a P, max: u32, } -impl<'a, P: Path> OutboxQueue<'a, P> { +impl<'a, P: Path> OutboxQueue<'a, P> { /// Setup the outbox queue to operate over non-default parameters. /// /// - `root` specifies the path in storage that the queue will be stored at. @@ -228,7 +228,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { // if we had a 'path::append_hex_into' method, we could have an alloc free // version of this. // 'concat_into' would be useful also. - fn message_path(&self, idx: u32) -> OwnedPath { + fn message_path(&self, idx: u32) -> OwnedPath { let mut path = [b'/'; 1 + 2 * core::mem::size_of::()]; let idx = idx.to_le_bytes(); @@ -338,7 +338,7 @@ mod test { #[test] fn push_overflow_then_flush() { let mut host = MockHost::default(); - let root = RefPath::assert_from(b"/hello"); + let root = RefPath::::assert_from(b"/hello"); let queue = OutboxQueue::new(&root, 15).unwrap(); let start = u32::MAX - 12; diff --git a/src/kernel_sdk/storage/src/layer.rs b/src/kernel_sdk/storage/src/layer.rs index f290c0cf8139..b8a0d363156c 100644 --- a/src/kernel_sdk/storage/src/layer.rs +++ b/src/kernel_sdk/storage/src/layer.rs @@ -20,8 +20,8 @@ use core::marker::PhantomData; use tezos_smart_rollup_host::path::{concat, OwnedPath, Path}; use tezos_smart_rollup_host::runtime::{Runtime, RuntimeError, ValueType}; -pub(crate) struct Layer> { - pub(crate) path: OwnedPath, +pub(crate) struct Layer>> { + pub(crate) path: OwnedPath, phantom: PhantomData, } @@ -31,7 +31,7 @@ fn has_subtree_res(v: Result, RuntimeError>) -> bool { matches!(v, Ok(Some(Subtree | ValueWithSubtree))) } -impl> Layer { +impl>> Layer { /// Create layer for the path given. /// /// Create a new layer object with all account data stored under path given, ie, @@ -39,7 +39,7 @@ impl> Layer { /// contain all data for account with id "alpha". /// /// This function is used solely for creating the bottom layer of the storage. - pub(crate) fn with_path(name: &impl Path) -> Self { + pub(crate) fn with_path(name: &impl Path) -> Self { Self { path: OwnedPath::from(name), phantom: PhantomData, @@ -57,7 +57,7 @@ impl> Layer { pub(crate) fn force_make_copy( &self, host: &mut impl Runtime, - name: &impl Path, + name: &impl Path, ) -> Result { let copy = Self { path: OwnedPath::from(name), @@ -101,7 +101,7 @@ impl> Layer { pub(crate) fn create_new( &mut self, host: &impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result, StorageError> { let account_path = concat(&self.path, id)?; @@ -119,7 +119,7 @@ impl> Layer { pub(crate) fn get( &self, host: &impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result, StorageError> { let account_path = concat(&self.path, id)?; @@ -137,7 +137,7 @@ impl> Layer { pub(crate) fn get_or_create( &self, _host: &impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result { // We could get rid of the host parameter, but in the future, it would be nice // if we had the option of interacting with storage when creating an object. @@ -152,7 +152,7 @@ impl> Layer { pub(crate) fn delete( &mut self, host: &mut impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result<(), StorageError> { let account_path = concat(&self.path, id)?; diff --git a/src/kernel_sdk/storage/src/storage.rs b/src/kernel_sdk/storage/src/storage.rs index b222eafa7b04..7ac92b339492 100644 --- a/src/kernel_sdk/storage/src/storage.rs +++ b/src/kernel_sdk/storage/src/storage.rs @@ -13,14 +13,14 @@ use tezos_smart_rollup_host::runtime::Runtime; extern crate alloc; /// Failsafe storage interface -pub struct Storage> { +pub struct Storage>> { prefix: String, layers: Vec>, } -impl> Storage { +impl>> Storage { /// Create the initial storage - pub fn init(name: &impl Path) -> Result { + pub fn init(name: &impl Path) -> Result { let name_bytes = name.as_bytes().to_vec(); Ok(Self { @@ -35,7 +35,7 @@ impl> Storage { pub fn get( &self, host: &impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result, StorageError> { if let Some(top_layer) = self.layers.last() { Ok(top_layer.get(host, id)?) @@ -48,7 +48,7 @@ impl> Storage { pub fn get_original( &self, host: &impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result, StorageError> { if let Some(bottom_layer) = self.layers.first() { Ok(bottom_layer.get(host, id)?) @@ -61,7 +61,7 @@ impl> Storage { pub fn create_new( &mut self, host: &mut impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result, StorageError> { if let Some(top_layer) = self.layers.last_mut() { Ok(top_layer.create_new(host, id)?) @@ -73,7 +73,7 @@ impl> Storage { pub fn get_or_create( &self, host: &impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result { if let Some(top_layer) = self.layers.last() { Ok(top_layer.get_or_create(host, id)?) @@ -86,7 +86,7 @@ impl> Storage { pub fn delete( &mut self, host: &mut impl Runtime, - id: &impl Path, + id: &impl Path, ) -> Result<(), StorageError> { if let Some(top_layer) = self.layers.last_mut() { top_layer.delete(host, id) @@ -162,35 +162,35 @@ mod test { #[derive(PartialEq, Debug)] struct TestAccount { - path: OwnedPath, + path: OwnedPath, } - const VALUE_A_PATH: RefPath = RefPath::assert_from(b"/a"); - const VALUE_B_PATH: RefPath = RefPath::assert_from(b"/b"); + const VALUE_A_PATH: RefPath = RefPath::assert_from(b"/a"); + const VALUE_B_PATH: RefPath = RefPath::assert_from(b"/b"); impl TestAccount { - pub fn set_a(&mut self, host: &mut impl Runtime, v: &str) { + pub fn set_a(&mut self, host: &mut impl Runtime, v: &str) { let value_path = concat(&self.path, &VALUE_A_PATH) .expect("The account should have a path for a"); host.store_write(&value_path, v.as_bytes(), 0) .expect("Cannot set value for b") } - pub fn set_b(&mut self, host: &mut impl Runtime, v: &str) { + pub fn set_b(&mut self, host: &mut impl Runtime, v: &str) { let value_path = concat(&self.path, &VALUE_B_PATH) .expect("The account should have a path for b"); host.store_write(&value_path, v.as_bytes(), 0) .expect("Cannot set value for b") } - pub fn get_a(&self, host: &impl Runtime) -> Vec { + pub fn get_a(&self, host: &impl Runtime) -> Vec { let value_path = concat(&self.path, &VALUE_A_PATH) .expect("The account should have a path for a"); host.store_read(&value_path, 0, 1024) .expect("No value for a") } - pub fn get_b(&self, host: &impl Runtime) -> Vec { + pub fn get_b(&self, host: &impl Runtime) -> Vec { let value_path = concat(&self.path, &VALUE_B_PATH) .expect("The account should have a path for b"); host.store_read(&value_path, 0, 1024) @@ -198,13 +198,13 @@ mod test { } } - impl From for TestAccount { - fn from(path: OwnedPath) -> Self { + impl From> for TestAccount { + fn from(path: OwnedPath) -> Self { Self { path } } } - const ACCOUNTS_PATH: RefPath = RefPath::assert_from(b"/accounts"); + const ACCOUNTS_PATH: RefPath = RefPath::assert_from(b"/accounts"); #[test] fn test_commit() { -- GitLab From 6afc2bb0bae5dc129826083585d964d53d54b011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Fri, 8 Nov 2024 11:38:05 +0100 Subject: [PATCH 13/31] INVASIVE: Etherlink/Kernel: generalize Runtime by IS_ABSOLUTE --- .../kernel_evm/evm_evaluation/src/evalhost.rs | 8 +- .../evm_execution/src/account_storage.rs | 57 ++++--- .../evm_execution/src/code_storage.rs | 21 +-- .../evm_execution/src/fa_bridge/mod.rs | 12 +- .../evm_execution/src/fa_bridge/test_utils.rs | 18 +-- .../src/fa_bridge/ticket_table.rs | 8 +- .../kernel_evm/evm_execution/src/handler.rs | 39 +++-- etherlink/kernel_evm/evm_execution/src/lib.rs | 28 ++-- .../evm_execution/src/precompiles/blake2.rs | 4 +- .../evm_execution/src/precompiles/ecdsa.rs | 2 +- .../src/precompiles/fa_bridge.rs | 4 +- .../evm_execution/src/precompiles/hash.rs | 4 +- .../evm_execution/src/precompiles/identity.rs | 2 +- .../evm_execution/src/precompiles/mod.rs | 18 +-- .../evm_execution/src/precompiles/modexp.rs | 2 +- .../evm_execution/src/precompiles/revert.rs | 2 +- .../src/precompiles/withdrawal.rs | 2 +- .../src/precompiles/zero_knowledge.rs | 12 +- .../kernel_evm/evm_execution/src/storage.rs | 12 +- .../evm_execution/src/withdrawal_counter.rs | 4 +- .../kernel_evm/indexable_storage/src/lib.rs | 34 ++-- etherlink/kernel_evm/kernel/src/apply.rs | 20 +-- etherlink/kernel_evm/kernel/src/block.rs | 35 ++-- .../kernel/src/block_in_progress.rs | 10 +- .../kernel_evm/kernel/src/block_storage.rs | 37 +++-- .../kernel/src/blueprint_storage.rs | 39 +++-- etherlink/kernel_evm/kernel/src/bridge.rs | 2 +- .../kernel_evm/kernel/src/configuration.rs | 10 +- etherlink/kernel_evm/kernel/src/dal.rs | 10 +- .../kernel_evm/kernel/src/delayed_inbox.rs | 18 +-- etherlink/kernel_evm/kernel/src/event.rs | 2 +- .../kernel_evm/kernel/src/fallback_upgrade.rs | 4 +- etherlink/kernel_evm/kernel/src/fees.rs | 6 +- etherlink/kernel_evm/kernel/src/gas_price.rs | 10 +- etherlink/kernel_evm/kernel/src/inbox.rs | 38 ++--- etherlink/kernel_evm/kernel/src/lib.rs | 30 ++-- .../kernel_evm/kernel/src/linked_list.rs | 47 ++++-- etherlink/kernel_evm/kernel/src/migration.rs | 8 +- etherlink/kernel_evm/kernel/src/parsing.rs | 10 +- .../kernel_evm/kernel/src/reveal_storage.rs | 4 +- etherlink/kernel_evm/kernel/src/simulation.rs | 12 +- etherlink/kernel_evm/kernel/src/stage_one.rs | 10 +- etherlink/kernel_evm/kernel/src/storage.rs | 149 ++++++++++-------- etherlink/kernel_evm/kernel/src/upgrade.rs | 20 +-- .../runtime/src/internal_runtime.rs | 6 +- .../runtime/src/relative_runtime.rs | 14 +- etherlink/kernel_evm/runtime/src/runtime.rs | 50 +++--- .../kernel_evm/runtime/src/safe_storage.rs | 16 +- etherlink/kernel_evm/storage/src/lib.rs | 93 ++++++----- .../encoding/src/dac/certificate.rs | 4 +- src/kernel_sdk/encoding/src/dac/pages.rs | 4 +- src/kernel_sdk/host/src/runtime.rs | 36 ++--- .../installer-config/src/binary/instr.rs | 4 +- .../installer-config/src/binary/nom.rs | 2 +- .../installer-config/src/binary/preimage.rs | 6 +- src/kernel_sdk/installer-kernel/src/instr.rs | 4 +- src/kernel_sdk/installer-kernel/src/lib.rs | 4 +- src/kernel_sdk/sdk/src/outbox.rs | 8 +- src/kernel_sdk/storage/src/layer.rs | 26 +-- src/kernel_sdk/storage/src/storage.rs | 26 +-- 60 files changed, 617 insertions(+), 510 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index 50891f94f8c4..ad81e08d90bb 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -42,7 +42,7 @@ fn world_state_path(p: &impl Path) -> Result, RuntimeError force_concat(&WORLD_STATE_PATH, p).map_err(|_| RuntimeError::PathNotFound) } -impl<'a> SdkRuntime for EvalHost<'a> { +impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.host.write_output(from) @@ -242,10 +242,10 @@ impl<'a> InternalRuntime for EvalHost<'a> { } } -impl<'a> ExtendedRuntime for EvalHost<'a> { - fn store_get_hash>( +impl<'a> ExtendedRuntime for EvalHost<'a> { + fn store_get_hash( &mut self, - path: &P, + path: &impl Path, ) -> Result, tezos_smart_rollup_host::runtime::RuntimeError> { let path = world_state_path(path)?; self.host.store_get_hash(&path) diff --git a/etherlink/kernel_evm/evm_execution/src/account_storage.rs b/etherlink/kernel_evm/evm_execution/src/account_storage.rs index 3a5251901e72..c2c0626b3123 100644 --- a/etherlink/kernel_evm/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/account_storage.rs @@ -210,7 +210,7 @@ impl EthereumAccount { /// Get the **nonce** for the Ethereum account. Default value is zero, so an account will /// _always_ have this **nonce**. - pub fn nonce(&self, host: &impl Runtime) -> Result { + pub fn nonce(&self, host: &impl Runtime) -> Result { let path = concat(&self.path, &NONCE_PATH)?; read_u64_le_default(host, &path, NONCE_DEFAULT_VALUE) .map_err(AccountStorageError::from) @@ -221,7 +221,7 @@ impl EthereumAccount { /// integer. pub fn increment_nonce( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &NONCE_PATH)?; @@ -239,7 +239,7 @@ impl EthereumAccount { pub fn decrement_nonce( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &NONCE_PATH)?; @@ -255,7 +255,7 @@ impl EthereumAccount { pub fn set_nonce( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, nonce: u64, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &NONCE_PATH)?; @@ -267,7 +267,10 @@ impl EthereumAccount { } /// Get the **balance** of an account in Wei held by the account. - pub fn balance(&self, host: &impl Runtime) -> Result { + pub fn balance( + &self, + host: &impl Runtime, + ) -> Result { let path = concat(&self.path, &BALANCE_PATH)?; read_u256_le_default(host, &path, BALANCE_DEFAULT_VALUE) .map_err(AccountStorageError::from) @@ -277,7 +280,7 @@ impl EthereumAccount { /// final amount exceeds the range of a a 256 bit unsigned integer. pub fn balance_add( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, amount: U256, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &BALANCE_PATH)?; @@ -301,7 +304,7 @@ impl EthereumAccount { /// ie the account held enough funds, the function returns `Ok(true)`. pub fn balance_remove( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, amount: U256, ) -> Result { let path = concat(&self.path, &BALANCE_PATH)?; @@ -323,7 +326,7 @@ impl EthereumAccount { /// Set the balance of an account to an amount in Wei pub fn set_balance( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, new_balance: U256, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &BALANCE_PATH)?; @@ -353,7 +356,7 @@ impl EthereumAccount { /// Clear the entire storage in durable storage for an account. pub fn clear_storage( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { let storage_path = concat(&self.path, &STORAGE_ROOT_PATH)?; if host.store_has(&storage_path)?.is_some() { @@ -366,7 +369,7 @@ impl EthereumAccount { /// Get the value stored in contract permanent storage at a given index for an account. pub fn get_storage( &self, - host: &impl Runtime, + host: &impl Runtime, index: &H256, ) -> Result { let path = self.storage_path(index)?; @@ -376,7 +379,7 @@ impl EthereumAccount { pub fn read_storage( &self, - host: &impl Runtime, + host: &impl Runtime, index: &H256, ) -> Result { let path = self.storage_path(index)?; @@ -393,7 +396,7 @@ impl EthereumAccount { /// non-default to default, et.c. This is for the purpose of calculating gas cost. pub fn set_storage_checked( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, index: &H256, value: &H256, ) -> Result { @@ -424,7 +427,7 @@ impl EthereumAccount { /// values being stored. This function does no tracking for the purpose of gas cost. pub fn set_storage( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, index: &H256, value: &H256, ) -> Result<(), AccountStorageError> { @@ -437,7 +440,10 @@ impl EthereumAccount { } /// Find whether the account has any code associated with it. - pub fn code_exists(&self, host: &impl Runtime) -> Result { + pub fn code_exists( + &self, + host: &impl Runtime, + ) -> Result { let path = concat(&self.path, &CODE_HASH_PATH)?; match host.store_has(&path) { @@ -453,7 +459,10 @@ impl EthereumAccount { /// retrieve it within the code_storage module. // There is a possibility here to migrate lazily all code in order // to have all legacy contract uses the new code storage. - pub fn code(&self, host: &impl Runtime) -> Result, AccountStorageError> { + pub fn code( + &self, + host: &impl Runtime, + ) -> Result, AccountStorageError> { let path = concat(&self.path, &CODE_PATH)?; // If we ever do the lazy migration of code for account @@ -471,7 +480,10 @@ impl EthereumAccount { /// Get the hash of the code associated with an account. This value is computed and /// stored when the code of a contract is set. - pub fn code_hash(&self, host: &impl Runtime) -> Result { + pub fn code_hash( + &self, + host: &impl Runtime, + ) -> Result { let path = concat(&self.path, &CODE_HASH_PATH)?; read_h256_be_default(host, &path, CODE_HASH_DEFAULT) .map_err(AccountStorageError::from) @@ -479,7 +491,10 @@ impl EthereumAccount { /// Get the size of a contract in number of bytes used for opcodes. This value is /// computed and stored when the code of a contract is set. - pub fn code_size(&self, host: &impl Runtime) -> Result { + pub fn code_size( + &self, + host: &impl Runtime, + ) -> Result { let path = concat(&self.path, &CODE_PATH)?; // If we ever do the lazy migration of code for account // (i.e. moving code from account to code_storage) then this @@ -499,7 +514,7 @@ impl EthereumAccount { /// not before. pub fn set_code( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, code: &[u8], ) -> Result<(), AccountStorageError> { if self.code_exists(host)? { @@ -516,7 +531,7 @@ impl EthereumAccount { /// Delete all code associated with a contract. Also sets code length and size accordingly pub fn delete_code( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { let code_hash_path = concat(&self.path, &CODE_HASH_PATH)?; @@ -542,12 +557,12 @@ impl EthereumAccount { } /// The type of the storage API for accessing the Ethereum World State. -pub type EthereumAccountStorage = Storage; +pub type EthereumAccountStorage = Storage; /// Get the storage API for accessing the Ethereum World State and do transactions /// on it. pub fn init_account_storage() -> Result { - Storage::::init(&EVM_ACCOUNTS_PATH) + Storage::::init(&EVM_ACCOUNTS_PATH) .map_err(AccountStorageError::from) } diff --git a/etherlink/kernel_evm/evm_execution/src/code_storage.rs b/etherlink/kernel_evm/evm_execution/src/code_storage.rs index 005013f968b0..c97ad081735b 100644 --- a/etherlink/kernel_evm/evm_execution/src/code_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/code_storage.rs @@ -44,19 +44,22 @@ impl CodeStorage { Ok(Self { path }) } - fn exists(&self, host: &impl Runtime) -> Result { + fn exists(&self, host: &impl Runtime) -> Result { let store_has_code = host.store_has(&self.path)?; Ok(store_has_code.is_some()) } - fn get_ref_count(&self, host: &mut impl Runtime) -> Result { + fn get_ref_count( + &self, + host: &mut impl Runtime, + ) -> Result { let reference_path = concat(&self.path, &REFERENCE_PATH)?; read_u64_le(host, &reference_path).or(Ok(0u64)) } fn set_ref_count( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, number_ref: u64, ) -> Result<(), GenStorageError> { let reference_path = concat(&self.path, &REFERENCE_PATH)?; @@ -66,7 +69,7 @@ impl CodeStorage { fn increment_code_usage( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), GenStorageError> { let number_reference = self.get_ref_count(host)?; let number_reference = number_reference.saturating_add(1u64); @@ -75,7 +78,7 @@ impl CodeStorage { fn decrement_code_usage( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result { let number_reference = self.get_ref_count(host)?; let number_reference = number_reference.saturating_sub(1u64); @@ -84,7 +87,7 @@ impl CodeStorage { } pub fn add( - host: &mut impl Runtime, + host: &mut impl Runtime, bytecode: &[u8], ) -> Result { let code_hash: H256 = bytes_hash(bytecode); @@ -98,7 +101,7 @@ impl CodeStorage { } pub fn delete( - host: &mut impl Runtime, + host: &mut impl Runtime, code_hash: &H256, ) -> Result<(), GenStorageError> { let code = Self::new(code_hash)?; @@ -113,7 +116,7 @@ impl CodeStorage { } pub fn get_code( - host: &impl Runtime, + host: &impl Runtime, code_hash: &H256, ) -> Result, GenStorageError> { let code = Self::new(code_hash)?; @@ -126,7 +129,7 @@ impl CodeStorage { } pub fn code_size( - host: &impl Runtime, + host: &impl Runtime, code_hash: &H256, ) -> Result { let code = Self::new(code_hash)?; diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/mod.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/mod.rs index 2c31dc896318..d5aa0a67c88c 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/mod.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/mod.rs @@ -124,7 +124,7 @@ macro_rules! create_outcome_error { /// account storage transaction, and we can open one. #[allow(clippy::too_many_arguments)] #[cfg_attr(feature = "benchmark", inline(never))] -pub fn execute_fa_deposit<'a, Host: Runtime>( +pub fn execute_fa_deposit<'a, Host: Runtime>( host: &'a mut Host, block: &'a BlockConstants, evm_account_storage: &'a mut EthereumAccountStorage, @@ -193,7 +193,7 @@ pub fn execute_fa_deposit<'a, Host: Runtime>( /// on errors and the caller is responsible of cleaning up intermediate layer in /// case of errors (i.e. using `end_inter_transaction`). It also can return the /// withdrawal if it was succesful. -fn execute_layered_fa_withdrawal( +fn execute_layered_fa_withdrawal>( handler: &mut EvmHandler, caller: H160, withdrawal: FaWithdrawal, @@ -226,7 +226,7 @@ fn execute_layered_fa_withdrawal( /// another smart contract. /// /// We assume there is an open account storage transaction. -pub fn execute_fa_withdrawal( +pub fn execute_fa_withdrawal>( handler: &mut EvmHandler, caller: H160, withdrawal: FaWithdrawal, @@ -311,7 +311,7 @@ pub fn execute_fa_withdrawal( /// Updates ticket table according to the deposit and actual ticket owner. /// Assuming there is an open account storage transaction. -fn inner_execute_deposit( +fn inner_execute_deposit>( handler: &mut EvmHandler, ticket_owner: H160, deposit: &FaDeposit, @@ -344,7 +344,7 @@ fn inner_execute_deposit( /// Updates ticket ledger and outbox counter according to the withdrawal. /// Assuming there is an open account storage transaction. -fn inner_execute_withdrawal( +fn inner_execute_withdrawal>( handler: &mut EvmHandler, withdrawal: &FaWithdrawal, ) -> Result { @@ -378,7 +378,7 @@ fn inner_execute_withdrawal( /// Invokes proxy (ERC wrapper) contract from within a deposit or /// withdrawal handling function. /// Assuming there is an open account storage transaction. -fn inner_execute_proxy( +fn inner_execute_proxy>( handler: &mut EvmHandler, caller: H160, proxy: H160, diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs index b86de96fac44..39b2709d41a2 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs @@ -59,7 +59,7 @@ const REENTRANCY_TESTER_BYTECODE: &[u8] = /// Create a smart contract in the storage with the mocked token code pub fn deploy_mock_wrapper( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, ticket: &FA2_1Ticket, caller: &H160, @@ -102,7 +102,7 @@ pub fn deploy_mock_wrapper( /// Create a smart contract in the storage with the mocked token code pub fn deploy_reentrancy_tester( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, ticket: &FA2_1Ticket, caller: &H160, @@ -149,7 +149,7 @@ pub fn deploy_reentrancy_tester( /// Execute FA deposit pub fn run_fa_deposit( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, deposit: &FaDeposit, caller: &H160, @@ -198,7 +198,7 @@ pub fn dummy_fa_deposit(ticket: FA2_1Ticket, proxy: Option) -> FaDeposit { /// } /// } pub fn get_storage_flag( - host: &impl Runtime, + host: &impl Runtime, evm_account_storage: &EthereumAccountStorage, proxy: H160, ) -> u32 { @@ -232,7 +232,7 @@ pub fn dummy_block_constants() -> BlockConstants { /// Provision ticket balance for a specified account pub fn ticket_balance_add( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, ticket_hash: &H256, address: &H160, @@ -248,7 +248,7 @@ pub fn ticket_balance_add( /// Get ticket balance for a specified account pub fn ticket_balance_get( - host: &impl Runtime, + host: &impl Runtime, evm_account_storage: &EthereumAccountStorage, ticket_hash: &H256, address: &H160, @@ -266,7 +266,7 @@ pub fn ticket_balance_get( /// Get next withdrawal counter value pub fn withdrawal_counter_next( - host: &impl Runtime, + host: &impl Runtime, evm_account_storage: &EthereumAccountStorage, ) -> Option { let system = evm_account_storage @@ -282,7 +282,7 @@ pub fn withdrawal_counter_next( /// Provision TEZ balance for a specified account pub fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -381,7 +381,7 @@ pub fn dummy_fa_withdrawal( /// Execute FA withdrawal directly without going through the precompile pub fn fa_bridge_precompile_call_withdraw( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, withdrawal: FaWithdrawal, caller: H160, diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs index a466ba2e05fa..2397652a21ae 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs @@ -20,7 +20,7 @@ pub trait TicketTable { /// Increases ticket balance fn ticket_balance_add( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ticket_hash: &H256, address: &H160, amount: U256, @@ -29,7 +29,7 @@ pub trait TicketTable { /// Decreases ticket balance fn ticket_balance_remove( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ticket_hash: &H256, address: &H160, amount: U256, @@ -47,7 +47,7 @@ pub(crate) fn ticket_balance_path( impl TicketTable for EthereumAccount { fn ticket_balance_add( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ticket_hash: &H256, owner: &H160, amount: U256, @@ -65,7 +65,7 @@ impl TicketTable for EthereumAccount { fn ticket_balance_remove( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ticket_hash: &H256, owner: &H160, amount: U256, diff --git a/etherlink/kernel_evm/evm_execution/src/handler.rs b/etherlink/kernel_evm/evm_execution/src/handler.rs index cf3cc2087a0e..7ef642ef0cc1 100644 --- a/etherlink/kernel_evm/evm_execution/src/handler.rs +++ b/etherlink/kernel_evm/evm_execution/src/handler.rs @@ -236,7 +236,7 @@ mod benchmarks { *b"__wasm_debugger__::start_section(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0)"; #[inline(always)] - pub fn start_opcode_section(host: &mut Host, opcode: &Opcode) { + pub fn start_opcode_section>(host: &mut Host, opcode: &Opcode) { unsafe { START_OPCODE_SECTION_MSG[33] = opcode.as_u8(); host.write_debug(core::str::from_utf8_unchecked(&START_OPCODE_SECTION_MSG)); @@ -244,7 +244,7 @@ mod benchmarks { } #[inline(always)] - pub fn start_precompile_section( + pub fn start_precompile_section>( host: &mut Host, address: H160, input: &Vec, @@ -272,7 +272,7 @@ mod benchmarks { *b"__wasm_debugger__::end_section()"; #[inline(always)] - pub fn end_opcode_section( + pub fn end_opcode_section, T>( host: &mut Host, gas: u64, step_result: &Result<(), Capture>, @@ -285,7 +285,7 @@ mod benchmarks { } #[inline(always)] - pub fn end_precompile_section(host: &mut Host) { + pub fn end_precompile_section>(host: &mut Host) { unsafe { host.write_debug(core::str::from_utf8_unchecked(&END_PRECOMPILE_SECTION_MSG)); } @@ -329,7 +329,7 @@ pub type LayerCache = HashMap; pub type StorageCache = HashMap; /// The implementation of the SputnikVM [Handler] trait -pub struct EvmHandler<'a, Host: Runtime> { +pub struct EvmHandler<'a, Host: Runtime> { /// The host pub host: &'a mut Host, /// The ethereum accounts storage @@ -369,7 +369,7 @@ pub struct EvmHandler<'a, Host: Runtime> { reentrancy_guard: ReentrancyGuard, } -impl<'a, Host: Runtime> EvmHandler<'a, Host> { +impl<'a, Host: Runtime> EvmHandler<'a, Host> { /// Create a new handler to suit a new, initial EVM call context #[allow(clippy::too_many_arguments)] pub fn new( @@ -2129,7 +2129,7 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { } } -fn update_cache( +fn update_cache>( handler: &mut EvmHandler<'_, Host>, address: H160, index: H256, @@ -2145,7 +2145,7 @@ fn update_cache( } } -fn find_storage_key( +fn find_storage_key>( handler: &mut EvmHandler<'_, Host>, address: H160, index: H256, @@ -2163,7 +2163,7 @@ fn find_storage_key( /// Committing the storage cache means that the current layer changes /// are propagated to the previous one and the current layer is popped. -fn commit_storage_cache( +fn commit_storage_cache>( handler: &mut EvmHandler<'_, Host>, current_layer: usize, ) { @@ -2177,7 +2177,7 @@ fn commit_storage_cache( } } -fn cached_storage_access( +fn cached_storage_access>( handler: &mut EvmHandler<'_, Host>, address: H160, index: H256, @@ -2209,7 +2209,7 @@ fn cached_storage_access( } #[allow(unused_variables)] -impl<'a, Host: Runtime> Handler for EvmHandler<'a, Host> { +impl<'a, Host: Runtime> Handler for EvmHandler<'a, Host> { type CreateInterrupt = Infallible; type CreateFeedback = Infallible; type CallInterrupt = Infallible; @@ -2822,7 +2822,7 @@ mod test { const DUMMY_ALLOCATED_TICKS: u64 = 1_000_000_000; fn set_code( - handler: &mut EvmHandler<'_, impl Runtime>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, code: Vec, ) { @@ -2831,18 +2831,25 @@ mod test { account.set_code(handler.borrow_host(), &code).unwrap(); } - fn set_nonce(handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, nonce: u64) { + fn set_nonce( + handler: &mut EvmHandler<'_, impl Runtime>, + address: &H160, + nonce: u64, + ) { let mut account = handler.get_or_create_account(*address).unwrap(); account.set_nonce(handler.borrow_host(), nonce).unwrap() } - fn get_balance(handler: &mut EvmHandler<'_, impl Runtime>, address: &H160) -> U256 { + fn get_balance( + handler: &mut EvmHandler<'_, impl Runtime>, + address: &H160, + ) -> U256 { let account = handler.get_or_create_account(*address).unwrap(); account.balance(handler.borrow_host()).unwrap() } fn set_balance( - handler: &mut EvmHandler<'_, impl Runtime>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, new_balance: U256, ) { @@ -2866,7 +2873,7 @@ mod test { } fn get_durable_slot( - handler: &mut EvmHandler<'_, impl Runtime>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, index: &H256, ) -> H256 { diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index 633d668e3eb8..52a6db3e9028 100755 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -134,7 +134,7 @@ pub enum EthereumError { Tracer(#[from] tracer::Error), } -fn trace_outcome( +fn trace_outcome>( handler: EvmHandler, is_success: bool, output: Option<&[u8]>, @@ -150,7 +150,7 @@ fn trace_outcome( } #[allow(clippy::too_many_arguments)] -fn call_trace_outcome( +fn call_trace_outcome>( handler: EvmHandler, base_call_type: &str, call_data: Vec, @@ -204,7 +204,7 @@ fn call_trace_outcome( } #[allow(clippy::too_many_arguments)] -fn call_trace_error( +fn call_trace_error>( handler: EvmHandler, base_call_type: &str, call_data: Vec, @@ -266,7 +266,7 @@ pub fn run_transaction<'a, Host>( tracer: Option, ) -> Result, EthereumError> where - Host: Runtime, + Host: Runtime, { fn do_refund(outcome: &handler::ExecutionOutcome, pay_for_gas: bool) -> bool { match outcome.result { @@ -423,7 +423,7 @@ pub const NATIVE_TOKEN_TICKETER_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/ticketer"); /// Reads the ticketer address set by the installer, if any, encoded in b58. -pub fn read_ticketer(host: &impl Runtime) -> Option { +pub fn read_ticketer(host: &impl Runtime) -> Option { let ticketer = host.store_read_all(&NATIVE_TOKEN_TICKETER_PATH).ok()?; let kt1_b58 = String::from_utf8(ticketer.to_vec()).ok()?; @@ -475,7 +475,7 @@ mod test { const DUMMY_ALLOCATED_TICKS: u64 = 1_000_000_000; fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -496,7 +496,7 @@ mod test { } fn set_storage( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, index: &H256, @@ -509,7 +509,7 @@ mod test { } fn get_storage( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, index: &H256, @@ -521,7 +521,7 @@ mod test { } fn get_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> U256 { @@ -533,7 +533,7 @@ mod test { // Simple utility function to set some code for an account fn set_account_code( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, code: &[u8], @@ -544,7 +544,7 @@ mod test { } fn get_code( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> Vec { @@ -555,7 +555,7 @@ mod test { } fn bump_nonce( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) { @@ -565,7 +565,7 @@ mod test { } fn get_nonce( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> u64 { @@ -3563,7 +3563,7 @@ mod test { } fn out_of_tick_scenario( - host: &mut impl Runtime, + host: &mut impl Runtime, retriable: bool, ) -> ( Result, EthereumError>, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs index 7dc032392128..f1953ae58159 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs @@ -112,7 +112,7 @@ fn blake2f_output_for_wrong_input() -> EthereumError { }) } -fn blake2f_precompile_without_gas_draining( +fn blake2f_precompile_without_gas_draining>( handler: &mut EvmHandler, input: &[u8], ) -> Result { @@ -193,7 +193,7 @@ fn blake2f_precompile_without_gas_draining( }) } -pub fn blake2f_precompile( +pub fn blake2f_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs index 93b505082685..b05be8a5d8f3 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs @@ -52,7 +52,7 @@ fn erec_parse_inputs(input: &[u8]) -> ([u8; 32], [u8; 32], [u8; 64]) { } // Implementation of 0x01 ECDSA recover -pub fn ecrecover_precompile( +pub fn ecrecover_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs index ec37a9c68524..0915f73b445d 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs @@ -80,7 +80,7 @@ macro_rules! precompile_outcome_error { /// FA bridge precompile entrypoint. #[allow(unused)] -pub fn fa_bridge_precompile( +pub fn fa_bridge_precompile>( handler: &mut EvmHandler, input: &[u8], context: &Context, @@ -184,7 +184,7 @@ mod tests { #[allow(clippy::too_many_arguments)] fn execute_precompile( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, caller: H160, value: U256, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs index c3d25159b422..e1e3f4e4ac38 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs @@ -14,7 +14,7 @@ use tezos_evm_logging::Level::Debug; use tezos_evm_runtime::runtime::Runtime; // Implementation of 0x03 precompiled (sha256) -pub fn sha256_precompile( +pub fn sha256_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, @@ -49,7 +49,7 @@ pub fn sha256_precompile( } // Implementation of 0x04 precompiled (ripemd160) -pub fn ripemd160_precompile( +pub fn ripemd160_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/identity.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/identity.rs index 680288ae9f9f..b38f9f1a6675 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/identity.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/identity.rs @@ -13,7 +13,7 @@ use tezos_evm_logging::Level::Debug; use tezos_evm_runtime::runtime::Runtime; // Implementation of 0x02 precompiled (identity) -pub fn identity_precompile( +pub fn identity_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs index 126acd6dc758..1ff66c90ea1c 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs @@ -84,7 +84,7 @@ pub type PrecompileFn = fn( /// This is adapted from SputnikVM trait with same name. It has been /// modified to take the Host into account, so that precompiles can /// interact with log and durable storage and the rest of the kernel. -pub trait PrecompileSet { +pub trait PrecompileSet> { /// Execute a single contract call to a precompiled contract. Should /// return None (and have no effect), if there is no precompiled contract /// at the address given. @@ -106,7 +106,7 @@ pub trait PrecompileSet { /// One implementation for PrecompileSet above. Adapted from SputnikVM. pub type PrecompileBTreeMap = BTreeMap>; -impl PrecompileSet for PrecompileBTreeMap { +impl> PrecompileSet for PrecompileBTreeMap { fn execute( &self, handler: &mut EvmHandler, @@ -117,7 +117,7 @@ impl PrecompileSet for PrecompileBTreeMap { transfer: Option, ) -> Option> where - Host: Runtime, + Host: Runtime, { self.get(&address) .map(|precompile| (*precompile)(handler, input, context, is_static, transfer)) @@ -134,7 +134,7 @@ impl PrecompileSet for PrecompileBTreeMap { type PrecompileWithoutGasDrainFn = fn(_: &mut EvmHandler, _: &[u8]) -> Result; -pub fn call_precompile_with_gas_draining( +pub fn call_precompile_with_gas_draining>( handler: &mut EvmHandler, input: &[u8], precompile_contract_without_gas: PrecompileWithoutGasDrainFn, @@ -162,7 +162,7 @@ pub const WITHDRAWAL_ADDRESS: H160 = H160([ 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ]); -pub fn evm_precompile_set() -> PrecompileBTreeMap { +pub fn evm_precompile_set>() -> PrecompileBTreeMap { BTreeMap::from([ ( H160::from_low_u64_be(1u64), @@ -204,7 +204,7 @@ pub fn evm_precompile_set() -> PrecompileBTreeMap { } /// Factory function for generating the precompileset that the EVM kernel uses. -pub fn precompile_set( +pub fn precompile_set>( enable_fa_withdrawals: bool, ) -> PrecompileBTreeMap { let mut precompiles = evm_precompile_set(); @@ -223,7 +223,7 @@ pub fn precompile_set( precompiles } -pub fn precompile_set_with_revert_withdrawals( +pub fn precompile_set_with_revert_withdrawals>( enable_fa_withdrawals: bool, ) -> PrecompileBTreeMap { let mut precompiles = evm_precompile_set(); @@ -301,7 +301,7 @@ mod test_helpers { pub const DUMMY_TICKETER: &str = "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5"; pub fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -390,7 +390,7 @@ mod test_helpers { ) } - fn set_ticketer(host: &mut impl Runtime, address: &str) { + fn set_ticketer(host: &mut impl Runtime, address: &str) { host.store_write(&NATIVE_TOKEN_TICKETER_PATH, address.as_bytes(), 0) .unwrap(); } diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs index 132bafe5163b..862dbc9382cc 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs @@ -75,7 +75,7 @@ fn modexp_mod_overflow_exit(reason: &'static str) -> PrecompileOutcome { // to be taken up by the next value const HEADER_LENGTH: usize = 96; -pub fn modexp_precompile( +pub fn modexp_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/revert.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/revert.rs index 4fa410f69d56..c87f23d4a1cb 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/revert.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/revert.rs @@ -12,7 +12,7 @@ use crate::{handler::EvmHandler, EthereumError}; use super::PrecompileOutcome; -pub fn revert_precompile( +pub fn revert_precompile>( _handler: &mut EvmHandler, _input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs index ceeb6eea8e41..b6f772623fa0 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs @@ -92,7 +92,7 @@ fn prepare_message( } /// Implementation of Etherlink specific withdrawals precompiled contract. -pub fn withdrawal_precompile( +pub fn withdrawal_precompile>( handler: &mut EvmHandler, input: &[u8], context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs index c351d7cb53fa..f9fa04fe1f36 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs @@ -60,7 +60,7 @@ fn read_point(input: &[u8], pos: usize) -> Result { } } -fn ecadd_precompile_without_gas_draining( +fn ecadd_precompile_without_gas_draining>( handler: &mut EvmHandler, input: &[u8], ) -> Result { @@ -103,7 +103,7 @@ fn ecadd_precompile_without_gas_draining( }) } -pub fn ecadd_precompile( +pub fn ecadd_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, @@ -117,7 +117,7 @@ pub fn ecadd_precompile( ) } -fn ecmul_precompile_without_gas_draining( +fn ecmul_precompile_without_gas_draining>( handler: &mut EvmHandler, input: &[u8], ) -> Result { @@ -158,7 +158,7 @@ fn ecmul_precompile_without_gas_draining( }) } -pub fn ecmul_precompile( +pub fn ecmul_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, @@ -172,7 +172,7 @@ pub fn ecmul_precompile( ) } -fn ecpairing_precompile_without_gas_draining( +fn ecpairing_precompile_without_gas_draining>( handler: &mut EvmHandler, input: &[u8], ) -> Result { @@ -281,7 +281,7 @@ fn ecpairing_precompile_without_gas_draining( }) } -pub fn ecpairing_precompile( +pub fn ecpairing_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/storage.rs b/etherlink/kernel_evm/evm_execution/src/storage.rs index 2e63d1c1bc84..d3511206776a 100644 --- a/etherlink/kernel_evm/evm_execution/src/storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/storage.rs @@ -53,7 +53,7 @@ pub mod tracer { concat(&trace_tx_path, field).map_err(Error::PathError) } - pub fn store_trace_gas( + pub fn store_trace_gas>( host: &mut Host, gas: u64, hash: &Option, @@ -63,7 +63,7 @@ pub mod tracer { Ok(()) } - pub fn store_trace_failed( + pub fn store_trace_failed>( host: &mut Host, is_success: bool, hash: &Option, @@ -74,7 +74,7 @@ pub mod tracer { Ok(()) } - pub fn store_return_value( + pub fn store_return_value>( host: &mut Host, value: &[u8], hash: &Option, @@ -85,7 +85,7 @@ pub mod tracer { Ok(()) } - pub fn store_struct_log( + pub fn store_struct_log>( host: &mut Host, struct_log: StructLog, hash: &Option, @@ -103,7 +103,7 @@ pub mod tracer { const CALL_TRACE: RefPath = RefPath::assert_from(b"/call_trace"); - pub fn store_call_trace( + pub fn store_call_trace>( host: &mut Host, call_trace: CallTrace, hash: &Option, @@ -167,7 +167,7 @@ pub mod blocks { /// Get block hash by block number. pub fn get_block_hash( - host: &impl Runtime, + host: &impl Runtime, block_number: U256, ) -> Result { let block_path = to_block_hash_path(block_number)?; diff --git a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs index a80517a56acd..70243a238e75 100644 --- a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs +++ b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs @@ -27,14 +27,14 @@ pub trait WithdrawalCounter { /// and increments & store the new value (will fail in case of overflow). fn withdrawal_counter_get_and_increment( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result; } impl WithdrawalCounter for EthereumAccount { fn withdrawal_counter_get_and_increment( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result { let path = self.custom_path(&WITHDRAWAL_COUNTER_PATH)?; let old_value = read_u256_le_default(host, &path, U256::zero())?; diff --git a/etherlink/kernel_evm/indexable_storage/src/lib.rs b/etherlink/kernel_evm/indexable_storage/src/lib.rs index 243f728445ed..70bb0918ec5f 100644 --- a/etherlink/kernel_evm/indexable_storage/src/lib.rs +++ b/etherlink/kernel_evm/indexable_storage/src/lib.rs @@ -18,11 +18,11 @@ const LENGTH: RefPath = RefPath::assert_from(b"/length"); /// An indexable storage is a push-only mapping between increasing integers to /// bytes. It can serve as a replacement for the combination of the host /// functions `store_get_nth` and `store_list_size` that are unsafe. -pub struct IndexableStorage { +pub struct IndexableStorage { /// An indexable storage is stored at a given path and consists of: /// - `/length`: the number of keys /// - `/` where keys are from `0` to `length - 1` - pub path: OwnedPath, + pub path: OwnedPath, } #[derive(Error, Debug, Eq, PartialEq)] @@ -57,16 +57,16 @@ impl From for IndexableStorageError { } } -impl IndexableStorage { - pub fn new(path: &RefPath<'_, true>) -> Result { +impl IndexableStorage { + pub fn new(path: &RefPath<'_, IS_ABSOLUTE>) -> Result { Ok(Self { path: path.into() }) } - pub fn new_owned_path(path: OwnedPath) -> Self { + pub fn new_owned_path(path: OwnedPath) -> Self { Self { path } } - fn value_path(&self, index: u64) -> Result, PathError> { + fn value_path(&self, index: u64) -> Result, PathError> { let index_as_path: Vec = format!("/{}", index).into(); // The key being an integer value, it will always be valid as a path, // `assert_from` cannot fail. @@ -76,7 +76,7 @@ impl IndexableStorage { fn store_index( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, index: u64, value_repr: &[u8], ) -> Result<(), IndexableStorageError> { @@ -85,9 +85,9 @@ impl IndexableStorage { .map_err(IndexableStorageError::from) } - fn get_length_and_increment( + fn get_length_and_increment( &self, - host: &mut Host, + host: &mut impl Runtime, ) -> Result { let path = concat(&self.path, &LENGTH)?; let length = read_u64_le(host, &path).unwrap_or(0); @@ -98,9 +98,9 @@ impl IndexableStorage { #[allow(dead_code)] /// `length` returns the number of keys in the storage. If `/length` does /// not exists, the storage is considered as empty and returns '0'. - pub fn length( + pub fn length( &self, - host: &Host, + host: &impl Runtime, ) -> Result { let path = concat(&self.path, &LENGTH)?; match read_u64_le(host, &path) { @@ -126,9 +126,9 @@ impl IndexableStorage { #[allow(dead_code)] /// Same as `get_value`, but doesn't check for bounds. - pub fn unsafe_get_value( + pub fn unsafe_get_value( &self, - host: &Host, + host: &impl Runtime, index: u64, ) -> Result, StorageError> { let key_path = self.value_path(index)?; @@ -138,9 +138,9 @@ impl IndexableStorage { /// Returns the value a the given index. Fails if the index is greater or /// equal to the length. #[cfg(debug_assertions)] - pub fn get_value( + pub fn get_value( &self, - host: &Host, + host: &impl Runtime, index: u64, ) -> Result, IndexableStorageError> { let length = self.length(host)?; @@ -152,9 +152,9 @@ impl IndexableStorage { } /// Push a value at index `length`, and increments the length. - pub fn push_value( + pub fn push_value( &self, - host: &mut Host, + host: &mut impl Runtime, value: &[u8], ) -> Result<(), IndexableStorageError> { let new_index = self.get_length_and_increment(host)?; diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index 140cc28c3ee2..1c4b0bebb3c8 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -175,7 +175,7 @@ fn make_object_info( }) } -fn account( +fn account>( host: &mut Host, caller: H160, evm_account_storage: &mut EthereumAccountStorage, @@ -200,7 +200,7 @@ pub enum Validity { // TODO: https://gitlab.com/tezos/tezos/-/issues/6812 // arguably, effective_gas_price should be set on EthereumTransactionCommon // directly - initialised when constructed. -fn is_valid_ethereum_transaction_common( +fn is_valid_ethereum_transaction_common>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, transaction: &EthereumTransactionCommon, @@ -288,7 +288,7 @@ pub struct TransactionResult { /// Technically incorrect: it is possible to do a call without sending any data, /// however it's done for benchmarking only, and benchmarking doesn't include /// such a scenario -fn log_transaction_type(host: &Host, to: Option, data: &[u8]) { +fn log_transaction_type>(host: &Host, to: Option, data: &[u8]) { if to.is_none() { log!(host, Benchmarking, "Transaction type: CREATE"); } else if data.is_empty() { @@ -299,7 +299,7 @@ fn log_transaction_type(host: &Host, to: Option, data: &[u8 } #[allow(clippy::too_many_arguments)] -fn apply_ethereum_transaction_common( +fn apply_ethereum_transaction_common>( host: &mut Host, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, @@ -388,7 +388,7 @@ fn apply_ethereum_transaction_common( } } -fn trace_deposit( +fn trace_deposit>( host: &mut Host, amount: U256, receiver: Option, @@ -420,7 +420,7 @@ fn trace_deposit( } } -fn apply_deposit( +fn apply_deposit>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, deposit: &Deposit, @@ -448,7 +448,7 @@ fn apply_deposit( } #[allow(clippy::too_many_arguments)] -fn apply_fa_deposit( +fn apply_fa_deposit>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, fa_deposit: &FaDeposit, @@ -526,7 +526,7 @@ impl From> for ExecutionResult { } #[allow(clippy::too_many_arguments)] -pub fn handle_transaction_result( +pub fn handle_transaction_result>( host: &mut Host, outbox_queue: &OutboxQueue<'_, impl Path>, block_constants: &BlockConstants, @@ -586,7 +586,7 @@ pub fn handle_transaction_result( } #[allow(clippy::too_many_arguments)] -pub fn apply_transaction( +pub fn apply_transaction>( host: &mut Host, outbox_queue: &OutboxQueue<'_, impl Path>, block_constants: &BlockConstants, @@ -724,7 +724,7 @@ mod tests { } fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index 8a729e3fadc2..fd4aff9f0ade 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -77,7 +77,7 @@ pub enum ComputationResult { Finished, } -fn on_invalid_transaction( +fn on_invalid_transaction>( host: &mut Host, transaction: &Transaction, block_in_progress: &mut BlockInProgress, @@ -97,7 +97,7 @@ fn on_invalid_transaction( } #[allow(clippy::too_many_arguments)] -fn compute( +fn compute>( host: &mut Host, outbox_queue: &OutboxQueue<'_, impl Path>, block_in_progress: &mut BlockInProgress, @@ -234,7 +234,7 @@ enum BlueprintParsing { } #[cfg_attr(feature = "benchmark", inline(never))] -fn next_bip_from_blueprints( +fn next_bip_from_blueprints>( host: &mut Host, current_block_number: U256, current_block_parent_hash: H256, @@ -281,7 +281,7 @@ fn next_bip_from_blueprints( } #[allow(clippy::too_many_arguments)] -fn compute_bip( +fn compute_bip>( host: &mut Host, outbox_queue: &OutboxQueue<'_, impl Path>, mut block_in_progress: BlockInProgress, @@ -356,7 +356,7 @@ fn compute_bip( Ok(result) } -fn revert_block( +fn revert_block>( safe_host: &mut SafeStorage<&mut Host>, block_in_progress: bool, number: U256, @@ -376,7 +376,7 @@ fn revert_block( } fn clean_delayed_transactions( - host: &mut impl Runtime, + host: &mut impl Runtime, delayed_inbox: &mut DelayedInbox, delayed_txs: Vec, ) -> anyhow::Result<()> { @@ -386,7 +386,7 @@ fn clean_delayed_transactions( Ok(()) } -fn promote_block( +fn promote_block>( safe_host: &mut SafeStorage<&mut Host>, outbox_queue: &OutboxQueue<'_, impl Path>, block_in_progress: bool, @@ -428,7 +428,7 @@ fn promote_block( const AT_MOST_ONE_BLOCK: RefPath = RefPath::assert_from(b"/__at_most_one_block"); -pub fn produce( +pub fn produce>( host: &mut Host, chain_id: U256, config: &mut Configuration, @@ -675,7 +675,7 @@ mod tests { Some(H160::from_slice(data)) } - fn set_balance( + fn set_balance>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, address: &H160, @@ -696,7 +696,7 @@ mod tests { } } - fn get_balance( + fn get_balance>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, address: &H160, @@ -831,14 +831,17 @@ mod tests { ) } - fn store_blueprints(host: &mut Host, blueprints: Vec) { + fn store_blueprints>( + host: &mut Host, + blueprints: Vec, + ) { for (i, blueprint) in blueprints.into_iter().enumerate() { store_inbox_blueprint_by_number(host, blueprint, U256::from(i)) .expect("Should have stored blueprint"); } } - fn store_block_fees( + fn store_block_fees>( host: &mut Host, block_fees: &BlockFees, ) -> anyhow::Result<()> { @@ -850,7 +853,7 @@ mod tests { Ok(()) } - fn produce_block_with_several_valid_txs( + fn produce_block_with_several_valid_txs>( host: &mut SafeStorage<&mut Host>, evm_account_storage: &mut EthereumAccountStorage, ) { @@ -898,7 +901,7 @@ mod tests { .expect("The block production failed."); } - fn assert_current_block_reading_validity(host: &mut Host) { + fn assert_current_block_reading_validity>(host: &mut Host) { match block_storage::read_current(host) { Ok(_) => (), Err(e) => { @@ -1368,7 +1371,7 @@ mod tests { host.revert().unwrap(); } - fn first_block( + fn first_block>( host: &mut SafeStorage<&mut MockHost>, ) -> BlockConstants { let timestamp = @@ -1543,7 +1546,7 @@ mod tests { blueprint(transactions) } - fn check_current_block_number(host: &mut Host, nb: usize) { + fn check_current_block_number>(host: &mut Host, nb: usize) { let current_nb = block_storage::read_current_number(host) .expect("Should have manage to check block number"); assert_eq!(current_nb, U256::from(nb), "Incorrect block number"); diff --git a/etherlink/kernel_evm/kernel/src/block_in_progress.rs b/etherlink/kernel_evm/kernel/src/block_in_progress.rs index f66dfc0f58a7..d78d6612b92b 100644 --- a/etherlink/kernel_evm/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_evm/kernel/src/block_in_progress.rs @@ -286,7 +286,7 @@ impl BlockInProgress { self.delayed_txs.push(hash); } - pub fn register_valid_transaction( + pub fn register_valid_transaction>( &mut self, transaction: &Transaction, object_info: TransactionObjectInfo, @@ -347,7 +347,7 @@ impl BlockInProgress { self.add_ticks(tick_model::ticks_of_invalid_transaction(tx_data_size)); } - fn safe_store_get_hash( + fn safe_store_get_hash>( host: &mut Host, path: &RefPath, ) -> Result, anyhow::Error> { @@ -364,7 +364,7 @@ impl BlockInProgress { fn receipts_root( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, previous_receipts_root: Vec, ) -> anyhow::Result> { if self.valid_txs.is_empty() { @@ -389,7 +389,7 @@ impl BlockInProgress { fn transactions_root( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, previous_transactions_root: Vec, ) -> anyhow::Result> { if self.valid_txs.is_empty() { @@ -411,7 +411,7 @@ impl BlockInProgress { } #[cfg_attr(feature = "benchmark", inline(never))] - pub fn finalize_and_store( + pub fn finalize_and_store>( self, host: &mut Host, block_constants: &BlockConstants, diff --git a/etherlink/kernel_evm/kernel/src/block_storage.rs b/etherlink/kernel_evm/kernel/src/block_storage.rs index 0c4574667975..3155fcd1b211 100644 --- a/etherlink/kernel_evm/kernel/src/block_storage.rs +++ b/etherlink/kernel_evm/kernel/src/block_storage.rs @@ -44,16 +44,19 @@ mod path { } } -fn store_current_number(host: &mut impl Runtime, number: U256) -> anyhow::Result<()> { +fn store_current_number( + host: &mut impl Runtime, + number: U256, +) -> anyhow::Result<()> { Ok(write_u256_le(host, &path::CURRENT_NUMBER, number)?) } -fn store_current_hash(host: &mut impl Runtime, hash: H256) -> anyhow::Result<()> { +fn store_current_hash(host: &mut impl Runtime, hash: H256) -> anyhow::Result<()> { write_h256_be(host, &path::CURRENT_HASH, hash) } fn store_block( - host: &mut impl Runtime, + host: &mut impl Runtime, block: &L2Block, index_block: bool, ) -> anyhow::Result<()> { @@ -69,7 +72,7 @@ fn store_block( } fn store_current_index_or_not( - host: &mut impl Runtime, + host: &mut impl Runtime, block: &L2Block, index_block: bool, ) -> anyhow::Result<()> { @@ -88,23 +91,29 @@ fn store_current_index_or_not( Ok(()) } -pub fn store_current(host: &mut impl Runtime, block: &L2Block) -> 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: &L2Block) -> anyhow::Result<()> { +pub fn restore_current( + host: &mut impl Runtime, + block: &L2Block, +) -> anyhow::Result<()> { store_current_index_or_not(host, block, false) } -pub fn read_current_number(host: &impl Runtime) -> anyhow::Result { +pub fn read_current_number(host: &impl Runtime) -> anyhow::Result { Ok(read_u256_le(host, &path::CURRENT_NUMBER)?) } -pub fn read_current_hash(host: &impl Runtime) -> anyhow::Result { +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) -> anyhow::Result { let hash = read_current_hash(host)?; let block_path = path::path(hash)?; let bytes = &host.store_read_all(&block_path)?; @@ -112,12 +121,14 @@ pub fn read_current(host: &mut impl Runtime) -> anyhow::Result { Ok(block_from_bytes) } -pub fn read_current_timestamp(host: &mut impl Runtime) -> anyhow::Result { +pub fn read_current_timestamp( + host: &mut impl Runtime, +) -> anyhow::Result { let block = read_current(host)?; Ok(block.timestamp) } -pub fn garbage_collect_blocks(host: &mut impl Runtime) -> anyhow::Result<()> { +pub fn garbage_collect_blocks(host: &mut impl Runtime) -> anyhow::Result<()> { log!(host, Debug, "Garbage collecting blocks."); if let Ok(block) = read_current(host) { // The kernel needs the current block to process the next one. Therefore @@ -135,12 +146,12 @@ pub fn garbage_collect_blocks(host: &mut impl Runtime) -> anyhow::Result<()> { pub mod internal_for_tests { use super::*; - pub fn init_blocks_index() -> anyhow::Result { + pub fn init_blocks_index() -> anyhow::Result> { Ok(IndexableStorage::new(&path::INDEXES)?) } pub fn store_current_number( - host: &mut impl Runtime, + host: &mut impl Runtime, number: U256, ) -> anyhow::Result<()> { super::store_current_number(host, number) diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index e5f46f1af542..182428fcf5e8 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -119,7 +119,7 @@ fn blueprint_nb_chunks_path( concat(blueprint_path, &EVM_BLUEPRINT_NB_CHUNKS).map_err(StorageError::from) } -fn read_blueprint_nb_chunks( +fn read_blueprint_nb_chunks>( host: &Host, blueprint_path: &OwnedPath, ) -> Result { @@ -129,7 +129,7 @@ fn read_blueprint_nb_chunks( Ok(u16::from_le_bytes(buffer)) } -fn store_blueprint_nb_chunks( +fn store_blueprint_nb_chunks>( host: &mut Host, blueprint_path: &OwnedPath, nb_chunks: u16, @@ -139,7 +139,7 @@ fn store_blueprint_nb_chunks( host.store_write_all(&path, &bytes).map_err(Error::from) } -pub fn store_sequencer_blueprint( +pub fn store_sequencer_blueprint>( host: &mut Host, blueprint: UnsignedSequencerBlueprint, ) -> Result<(), Error> { @@ -151,7 +151,7 @@ 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, number: U256, @@ -163,7 +163,7 @@ 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, ) -> anyhow::Result<()> { @@ -171,27 +171,29 @@ pub fn store_inbox_blueprint( Ok(store_inbox_blueprint_by_number(host, blueprint, number)?) } -pub fn read_next_blueprint_number(host: &Host) -> anyhow::Result { +pub fn read_next_blueprint_number>( + host: &Host, +) -> anyhow::Result { match read_u256_le(host, &NEXT_BLUEPRINT_NUMBER) { Err(GenStorageError::Runtime(RuntimeError::PathNotFound)) => Ok(U256::zero()), res => Ok(res?), } } -pub fn store_next_blueprint_number( +pub fn store_next_blueprint_number>( host: &mut Host, number: U256, ) -> anyhow::Result<()> { Ok(write_u256_le(host, &NEXT_BLUEPRINT_NUMBER, number)?) } -pub fn read_last_block_timestamp( +pub fn read_last_block_timestamp>( host: &Host, ) -> anyhow::Result { Ok(read_timestamp_path(host, &LAST_BLOCK_TIMESTAMP)?) } -pub fn store_last_block_timestamp( +pub fn store_last_block_timestamp>( host: &mut Host, timestamp: &Timestamp, ) -> anyhow::Result<()> { @@ -203,7 +205,7 @@ pub fn store_last_block_timestamp( } // Used to store a blueprint made out of forced delayed transactions. -pub fn store_immediate_blueprint( +pub fn store_immediate_blueprint>( host: &mut Host, blueprint: Blueprint, number: U256, @@ -239,7 +241,7 @@ pub enum BlueprintValidity { BlueprintTooLarge, } -fn fetch_delayed_txs( +fn fetch_delayed_txs>( host: &mut Host, blueprint_with_hashes: BlueprintWithDelayedHashes, delayed_inbox: &mut DelayedInbox, @@ -295,7 +297,7 @@ fn fetch_delayed_txs( // wish to refuse such blueprints. pub const DEFAULT_MAX_BLUEPRINT_LOOKAHEAD_IN_SECONDS: i64 = 300i64; -fn parse_and_validate_blueprint( +fn parse_and_validate_blueprint>( host: &mut Host, bytes: &[u8], delayed_inbox: &mut DelayedInbox, @@ -370,7 +372,7 @@ fn parse_and_validate_blueprint( } } -fn invalidate_blueprint( +fn invalidate_blueprint>( host: &mut Host, blueprint_path: &OwnedPath, error: &BlueprintValidity, @@ -386,7 +388,7 @@ fn invalidate_blueprint( host.store_delete(blueprint_path) } -fn read_all_chunks_and_validate( +fn read_all_chunks_and_validate>( host: &mut Host, blueprint_path: &OwnedPath, nb_chunks: u16, @@ -450,7 +452,7 @@ fn read_all_chunks_and_validate( } } -pub fn read_next_blueprint( +pub fn read_next_blueprint>( host: &mut Host, config: &mut Configuration, ) -> anyhow::Result<(Option, usize)> { @@ -495,12 +497,15 @@ pub fn read_next_blueprint( } } -pub fn drop_blueprint(host: &mut Host, number: U256) -> Result<(), Error> { +pub fn drop_blueprint>( + host: &mut Host, + number: U256, +) -> Result<(), Error> { let path = blueprint_path(number)?; host.store_delete(&path).map_err(Error::from) } -pub fn clear_all_blueprints(host: &mut Host) -> Result<(), Error> { +pub fn clear_all_blueprints>(host: &mut Host) -> Result<(), Error> { if host.store_has(&EVM_BLUEPRINTS)?.is_some() { Ok(host.store_delete(&EVM_BLUEPRINTS)?) } else { diff --git a/etherlink/kernel_evm/kernel/src/bridge.rs b/etherlink/kernel_evm/kernel/src/bridge.rs index e4f40d2ca687..841514e3803d 100644 --- a/etherlink/kernel_evm/kernel/src/bridge.rs +++ b/etherlink/kernel_evm/kernel/src/bridge.rs @@ -177,7 +177,7 @@ impl Decodable for Deposit { } } -pub fn execute_deposit( +pub fn execute_deposit>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, deposit: &Deposit, diff --git a/etherlink/kernel_evm/kernel/src/configuration.rs b/etherlink/kernel_evm/kernel/src/configuration.rs index 0c7486f3e384..7bf0aa04eba8 100644 --- a/etherlink/kernel_evm/kernel/src/configuration.rs +++ b/etherlink/kernel_evm/kernel/src/configuration.rs @@ -145,7 +145,7 @@ impl TezosContracts { } } -fn fetch_tezos_contracts(host: &mut impl Runtime) -> TezosContracts { +fn fetch_tezos_contracts(host: &mut impl Runtime) -> TezosContracts { // 1. Fetch the kernel's ticketer, returns `None` if it is badly // encoded or absent. let ticketer = read_ticketer(host); @@ -171,7 +171,7 @@ fn fetch_tezos_contracts(host: &mut impl Runtime) -> TezosContracts { } } -pub fn fetch_limits(host: &mut impl Runtime) -> Limits { +pub fn fetch_limits(host: &mut impl Runtime) -> Limits { let maximum_allowed_ticks = read_maximum_allowed_ticks(host).unwrap_or(MAX_ALLOWED_TICKS); @@ -184,7 +184,9 @@ pub fn fetch_limits(host: &mut impl Runtime) -> Limits { } } -fn fetch_dal_configuration(host: &mut Host) -> Option { +fn fetch_dal_configuration>( + host: &mut Host, +) -> Option { let enable_dal = enable_dal(host).unwrap_or(false); if enable_dal { let slot_indices: Vec = dal_slots(host).unwrap_or(None)?; @@ -194,7 +196,7 @@ fn fetch_dal_configuration(host: &mut Host) -> Option(host: &mut Host) -> Configuration { +pub fn fetch_configuration>(host: &mut Host) -> Configuration { let tezos_contracts = fetch_tezos_contracts(host); let limits = fetch_limits(host); let sequencer = sequencer(host).unwrap_or_default(); diff --git a/etherlink/kernel_evm/kernel/src/dal.rs b/etherlink/kernel_evm/kernel/src/dal.rs index fdda9fa33e6e..79e78bc8ce4f 100644 --- a/etherlink/kernel_evm/kernel/src/dal.rs +++ b/etherlink/kernel_evm/kernel/src/dal.rs @@ -24,7 +24,7 @@ enum ParsedInput { } // Import all the pages of a DAL slot and concatenate them. -fn import_dal_slot( +fn import_dal_slot>( host: &mut Host, params: &RollupDalParameters, published_level: u32, @@ -70,7 +70,7 @@ fn rlp_length(data: &[u8]) -> Result { Result::Ok(header_len + value_len) } -fn parse_unsigned_sequencer_blueprint( +fn parse_unsigned_sequencer_blueprint>( host: &mut Host, bytes: &[u8], next_blueprint_number: &U256, @@ -97,7 +97,7 @@ fn parse_unsigned_sequencer_blueprint( } } -fn parse_input( +fn parse_input>( host: &mut Host, bytes: &[u8], next_blueprint_number: &U256, @@ -125,7 +125,7 @@ fn parse_input( } } -fn parse_slot( +fn parse_slot>( host: &mut Host, slot: &[u8], next_blueprint_number: &U256, @@ -166,7 +166,7 @@ fn parse_slot( } } -pub fn fetch_and_parse_sequencer_blueprint_from_dal( +pub fn fetch_and_parse_sequencer_blueprint_from_dal>( host: &mut Host, params: &RollupDalParameters, next_blueprint_number: &U256, diff --git a/etherlink/kernel_evm/kernel/src/delayed_inbox.rs b/etherlink/kernel_evm/kernel/src/delayed_inbox.rs index 37708adea79f..4b8bbdf29a19 100644 --- a/etherlink/kernel_evm/kernel/src/delayed_inbox.rs +++ b/etherlink/kernel_evm/kernel/src/delayed_inbox.rs @@ -182,12 +182,12 @@ impl Decodable for DelayedInboxItem { } impl DelayedInbox { - pub fn new(host: &mut Host) -> Result { + pub fn new>(host: &mut Host) -> Result { let linked_list = LinkedList::new(&DELAYED_INBOX_PATH, host)?; Ok(Self(linked_list)) } - pub fn save_transaction( + pub fn save_transaction>( &mut self, host: &mut Host, tx: Transaction, @@ -239,7 +239,7 @@ impl DelayedInbox { } } - pub fn find_transaction( + pub fn find_transaction>( &mut self, host: &mut Host, tx_hash: Hash, @@ -262,7 +262,7 @@ impl DelayedInbox { // Returns the oldest tx in the delayed inbox (and its hash) if it // timed out - fn first_if_timed_out( + fn first_if_timed_out>( &mut self, host: &mut Host, now: Timestamp, @@ -298,12 +298,12 @@ impl DelayedInbox { } #[cfg(test)] - pub fn is_empty(&self, host: &mut Host) -> Result { + pub fn is_empty>(&self, host: &mut Host) -> Result { let first = self.0.first_with_id(host)?; Ok(first.is_none()) } - fn pop_first( + fn pop_first>( &mut self, host: &mut Host, ) -> Result> { @@ -320,7 +320,7 @@ impl DelayedInbox { } /// Returns whether the oldest tx in the delayed inbox has timed out. - pub fn first_has_timed_out( + pub fn first_has_timed_out>( &mut self, host: &mut Host, ) -> Result { @@ -338,7 +338,7 @@ impl DelayedInbox { /// signal that we're done. /// Note that this function assumes we're on a "timeout" state, /// which should be checked before calling it. - pub fn next_delayed_inbox_blueprint( + pub fn next_delayed_inbox_blueprint>( &mut self, host: &mut Host, ) -> Result>> { @@ -367,7 +367,7 @@ impl DelayedInbox { /// a transaction is removed or not. The only property ensured by the /// function is that the transaction is not part of the delayed inbox /// after the call. - pub fn delete( + pub fn delete>( &mut self, host: &mut Host, tx_hash: Hash, diff --git a/etherlink/kernel_evm/kernel/src/event.rs b/etherlink/kernel_evm/kernel/src/event.rs index 4a4266307c3e..1bea180f2a85 100644 --- a/etherlink/kernel_evm/kernel/src/event.rs +++ b/etherlink/kernel_evm/kernel/src/event.rs @@ -70,7 +70,7 @@ impl Encodable for Event<'_> { } impl Event<'_> { - pub fn store(&self, host: &mut Host) -> anyhow::Result<()> { + pub fn store>(&self, host: &mut Host) -> anyhow::Result<()> { storage::store_event(host, self) } } diff --git a/etherlink/kernel_evm/kernel/src/fallback_upgrade.rs b/etherlink/kernel_evm/kernel/src/fallback_upgrade.rs index 170c7fce4ac8..b19e6fef345a 100644 --- a/etherlink/kernel_evm/kernel/src/fallback_upgrade.rs +++ b/etherlink/kernel_evm/kernel/src/fallback_upgrade.rs @@ -15,7 +15,7 @@ const BACKUP_KERNEL_BOOT_PATH: RefPath = const BACKUP_KERNEL_ROOT_HASH: RefPath = RefPath::assert_from(b"/__backup_kernel/root_hash"); -pub fn backup_current_kernel(host: &mut impl Runtime) -> Result<(), RuntimeError> { +pub fn backup_current_kernel(host: &mut impl Runtime) -> Result<(), RuntimeError> { // Fallback preparation detected // Storing the current kernel boot path under a temporary path in // order to fallback on it if something goes wrong in the upcoming @@ -38,7 +38,7 @@ pub fn backup_current_kernel(host: &mut impl Runtime) -> Result<(), RuntimeError host.store_copy(&KERNEL_BOOT_PATH, &BACKUP_KERNEL_BOOT_PATH) } -pub fn fallback_backup_kernel(host: &mut impl Runtime) -> Result<(), RuntimeError> { +pub fn fallback_backup_kernel(host: &mut impl Runtime) -> Result<(), RuntimeError> { log!( host, Error, diff --git a/etherlink/kernel_evm/kernel/src/fees.rs b/etherlink/kernel_evm/kernel/src/fees.rs index ced3eea74d63..f02dbeefae7a 100644 --- a/etherlink/kernel_evm/kernel/src/fees.rs +++ b/etherlink/kernel_evm/kernel/src/fees.rs @@ -167,7 +167,7 @@ impl FeeUpdates { pub fn apply( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, accounts: &mut EthereumAccountStorage, caller: H160, sequencer_pool_address: Option, @@ -513,7 +513,7 @@ mod tests { } fn get_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: H160, ) -> U256 { @@ -524,7 +524,7 @@ mod tests { } fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: H160, balance: U256, diff --git a/etherlink/kernel_evm/kernel/src/gas_price.rs b/etherlink/kernel_evm/kernel/src/gas_price.rs index 7696f9a18aaf..a62f2e1fc06a 100644 --- a/etherlink/kernel_evm/kernel/src/gas_price.rs +++ b/etherlink/kernel_evm/kernel/src/gas_price.rs @@ -23,7 +23,7 @@ const ALPHA: F64 = softfloat::f64!(0.000_000_000_007); /// Register a completed block into the tick backlog pub fn register_block( - host: &mut impl Runtime, + host: &mut impl Runtime, bip: &BlockInProgress, ) -> anyhow::Result<()> { if bip.queue_length() > 0 { @@ -37,7 +37,7 @@ pub fn register_block( /// Retrieve *base fee per gas*, according to the current timestamp. pub fn base_fee_per_gas( - host: &impl Runtime, + host: &impl Runtime, timestamp: Timestamp, minimum_gas_price: U256, ) -> U256 { @@ -53,7 +53,7 @@ pub fn base_fee_per_gas( } fn backlog_with_time_elapsed( - host: &impl Runtime, + host: &impl Runtime, extra_ticks: u64, current_timestamp: u64, last_timestamp: u64, @@ -69,7 +69,7 @@ fn backlog_with_time_elapsed( } fn update_tick_backlog( - host: &mut impl Runtime, + host: &mut impl Runtime, ticks_in_block: u64, timestamp: Timestamp, ) -> anyhow::Result<()> { @@ -242,7 +242,7 @@ mod test { ); } - fn load_gas_price(host: &mut impl Runtime) -> (U256, U256) { + fn load_gas_price(host: &mut impl Runtime) -> (U256, U256) { let bf = crate::retrieve_block_fees(host).unwrap(); (bf.minimum_base_fee_per_gas(), bf.base_fee_per_gas()) diff --git a/etherlink/kernel_evm/kernel/src/inbox.rs b/etherlink/kernel_evm/kernel/src/inbox.rs index d529626ea534..1ba57a49bd48 100644 --- a/etherlink/kernel_evm/kernel/src/inbox.rs +++ b/etherlink/kernel_evm/kernel/src/inbox.rs @@ -196,7 +196,7 @@ pub struct ProxyInboxContent { pub transactions: Vec, } -pub fn read_input( +pub fn read_input, Mode: Parsable>( host: &mut Host, smart_rollup_address: [u8; 20], tezos_contracts: &TezosContracts, @@ -230,19 +230,19 @@ where /// Abstracts the type used to store the inputs once handled type Inbox; - fn handle_input( + fn handle_input>( host: &mut Host, input: Self, inbox_content: &mut Self::Inbox, ) -> anyhow::Result<()>; - fn handle_deposit( + fn handle_deposit>( host: &mut Host, deposit: Deposit, inbox_content: &mut Self::Inbox, ) -> anyhow::Result<()>; - fn handle_fa_deposit( + fn handle_fa_deposit>( host: &mut Host, fa_deposit: FaDeposit, inbox_content: &mut Self::Inbox, @@ -254,7 +254,7 @@ impl InputHandler for ProxyInput { // everything is doable in a single kernel_run. type Inbox = ProxyInboxContent; - fn handle_input( + fn handle_input>( host: &mut Host, input: Self, inbox_content: &mut Self::Inbox, @@ -282,7 +282,7 @@ impl InputHandler for ProxyInput { Ok(()) } - fn handle_deposit( + fn handle_deposit>( host: &mut Host, deposit: Deposit, inbox_content: &mut Self::Inbox, @@ -294,7 +294,7 @@ impl InputHandler for ProxyInput { } #[cfg_attr(feature = "benchmark", inline(never))] - fn handle_fa_deposit( + fn handle_fa_deposit>( host: &mut Host, fa_deposit: FaDeposit, inbox_content: &mut Self::Inbox, @@ -306,7 +306,7 @@ impl InputHandler for ProxyInput { } } -fn handle_blueprint_chunk( +fn handle_blueprint_chunk>( host: &mut Host, blueprint: UnsignedSequencerBlueprint, ) -> anyhow::Result<()> { @@ -327,7 +327,7 @@ impl InputHandler for SequencerInput { // there is nothing to return in the end. type Inbox = DelayedInbox; - fn handle_input( + fn handle_input>( host: &mut Host, input: Self, delayed_inbox: &mut Self::Inbox, @@ -398,7 +398,7 @@ impl InputHandler for SequencerInput { } } - fn handle_deposit( + fn handle_deposit>( host: &mut Host, deposit: Deposit, delayed_inbox: &mut Self::Inbox, @@ -410,7 +410,7 @@ impl InputHandler for SequencerInput { } #[cfg_attr(feature = "benchmark", inline(never))] - fn handle_fa_deposit( + fn handle_fa_deposit>( host: &mut Host, fa_deposit: FaDeposit, delayed_inbox: &mut Self::Inbox, @@ -422,7 +422,7 @@ impl InputHandler for SequencerInput { } } -fn handle_transaction_chunk( +fn handle_transaction_chunk>( host: &mut Host, tx_hash: TransactionHash, i: u16, @@ -475,7 +475,7 @@ fn handle_transaction_chunk( Ok(None) } -fn handle_deposit( +fn handle_deposit>( host: &mut Host, deposit: Deposit, ) -> Result { @@ -488,7 +488,7 @@ fn handle_deposit( } #[cfg_attr(feature = "benchmark", inline(never))] -fn handle_fa_deposit( +fn handle_fa_deposit>( host: &mut Host, fa_deposit: FaDeposit, ) -> Result { @@ -500,7 +500,7 @@ fn handle_fa_deposit( }) } -fn force_kernel_upgrade(host: &mut impl Runtime) -> anyhow::Result<()> { +fn force_kernel_upgrade(host: &mut impl Runtime) -> anyhow::Result<()> { match upgrade::read_kernel_upgrade(host)? { Some(kernel_upgrade) => { let current_timestamp = read_last_info_per_level_timestamp(host)?.i64(); @@ -518,7 +518,7 @@ fn force_kernel_upgrade(host: &mut impl Runtime) -> anyhow::Result<()> { } pub fn handle_input( - host: &mut impl Runtime, + host: &mut impl Runtime, input: Input, inbox_content: &mut Mode::Inbox, garbage_collect_blocks: bool, @@ -555,7 +555,7 @@ enum ReadStatus { } #[allow(clippy::too_many_arguments)] -fn read_and_dispatch_input( +fn read_and_dispatch_input, Mode: Parsable + InputHandler>( host: &mut Host, smart_rollup_address: [u8; 20], tezos_contracts: &TezosContracts, @@ -601,7 +601,7 @@ fn read_and_dispatch_input( } } -pub fn read_proxy_inbox( +pub fn read_proxy_inbox>( host: &mut Host, smart_rollup_address: [u8; 20], tezos_contracts: &TezosContracts, @@ -667,7 +667,7 @@ pub enum StageOneStatus { } #[allow(clippy::too_many_arguments)] -pub fn read_sequencer_inbox( +pub fn read_sequencer_inbox>( host: &mut Host, smart_rollup_address: [u8; 20], tezos_contracts: &TezosContracts, diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index 33a4b5110aef..09eae102c4a4 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -87,7 +87,7 @@ const CONFIG: Config = Config { const KERNEL_VERSION: &str = env!("GIT_HASH"); -fn switch_to_public_rollup(host: &mut Host) -> Result<(), Error> { +fn switch_to_public_rollup(host: &mut impl Runtime) -> Result<(), Error> { if let Some(ValueType::Value) = host.store_has(&PRIVATE_FLAG_PATH)? { log!( host, @@ -107,7 +107,7 @@ fn switch_to_public_rollup(host: &mut Host) -> Result<(), Error> } } -pub fn stage_zero(host: &mut Host) -> Result { +pub fn stage_zero(host: &mut impl Runtime) -> Result { log!(host, Debug, "Entering stage zero."); init_storage_versioning(host)?; switch_to_public_rollup(host)?; @@ -118,8 +118,8 @@ pub fn stage_zero(host: &mut Host) -> Result( - host: &mut Host, +pub fn stage_one( + host: &mut impl Runtime, smart_rollup_address: [u8; 20], configuration: &mut Configuration, ) -> Result { @@ -129,7 +129,7 @@ pub fn stage_one( fetch_blueprints(host, smart_rollup_address, configuration) } -fn set_kernel_version(host: &mut Host) -> Result<(), Error> { +fn set_kernel_version(host: &mut impl Runtime) -> Result<(), Error> { match read_kernel_version(host) { Ok(kernel_version) => { if kernel_version != KERNEL_VERSION { @@ -141,14 +141,14 @@ fn set_kernel_version(host: &mut Host) -> Result<(), Error> { } } -fn init_storage_versioning(host: &mut Host) -> Result<(), Error> { +fn init_storage_versioning(host: &mut impl Runtime) -> Result<(), Error> { match host.store_read(&STORAGE_VERSION_PATH, 0, 0) { Ok(_) => Ok(()), Err(_) => store_storage_version(host, STORAGE_VERSION), } } -fn retrieve_chain_id(host: &mut Host) -> Result { +fn retrieve_chain_id(host: &mut impl Runtime) -> Result { match read_chain_id(host) { Ok(chain_id) => Ok(chain_id), Err(_) => { @@ -159,7 +159,7 @@ fn retrieve_chain_id(host: &mut Host) -> Result { } } -fn retrieve_minimum_base_fee_per_gas( +fn retrieve_minimum_base_fee_per_gas>( host: &mut Host, ) -> Result { match read_minimum_base_fee_per_gas(host) { @@ -173,7 +173,7 @@ fn retrieve_minimum_base_fee_per_gas( } #[cfg(test)] -fn retrieve_base_fee_per_gas( +fn retrieve_base_fee_per_gas>( host: &mut Host, minimum_base_fee_per_gas: U256, ) -> U256 { @@ -190,7 +190,7 @@ fn retrieve_base_fee_per_gas( } } -fn retrieve_da_fee(host: &mut Host) -> Result { +fn retrieve_da_fee>(host: &mut Host) -> Result { match read_da_fee(host) { Ok(da_fee) => Ok(da_fee), Err(_) => { @@ -202,7 +202,7 @@ fn retrieve_da_fee(host: &mut Host) -> Result { } #[cfg(test)] -fn retrieve_block_fees( +fn retrieve_block_fees>( host: &mut Host, ) -> Result { let minimum_base_fee_per_gas = retrieve_minimum_base_fee_per_gas(host)?; @@ -217,7 +217,7 @@ fn retrieve_block_fees( Ok(block_fees) } -pub fn main(host: &mut Host) -> Result<(), anyhow::Error> { +pub fn main(host: &mut impl Runtime) -> Result<(), anyhow::Error> { let chain_id = retrieve_chain_id(host).context("Failed to retrieve chain id")?; // We always start by doing the migration if needed. @@ -318,7 +318,9 @@ pub fn main(host: &mut Host) -> Result<(), anyhow::Error> { } #[entrypoint::main] -pub fn kernel_loop(host: &mut Host) { +pub fn kernel_loop>( + host: &mut Host, +) { // In order to setup the temporary directory, we need to move something // from /evm to /tmp, so /evm must be non empty, this only happen // at the first run. @@ -442,7 +444,7 @@ mod tests { ) } - fn set_balance( + fn set_balance>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, address: &H160, diff --git a/etherlink/kernel_evm/kernel/src/linked_list.rs b/etherlink/kernel_evm/kernel/src/linked_list.rs index 3b5438c67002..94a6a84d4efa 100644 --- a/etherlink/kernel_evm/kernel/src/linked_list.rs +++ b/etherlink/kernel_evm/kernel/src/linked_list.rs @@ -176,7 +176,7 @@ impl, Elt: Encodable + Decodable> fn save_data( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, prefix: &impl Path, data: &Elt, ) -> Result<()> { @@ -184,14 +184,18 @@ impl, Elt: Encodable + Decodable> store_rlp(data, host, &path).context("cannot save the pointer's data") } - fn get_data(&self, host: &impl Runtime, prefix: &impl Path) -> Result { + fn get_data( + &self, + host: &impl Runtime, + prefix: &impl Path, + ) -> Result { let path = self.data_path(prefix)?; read_rlp(host, &path).context("cannot read the pointer's data") } /// Load the pointer from the durable storage fn read( - host: &impl Runtime, + host: &impl Runtime, prefix: &impl Path, id: &Id, ) -> Result> { @@ -199,7 +203,11 @@ impl, Elt: Encodable + Decodable> } /// Save the pointer in the durable storage - fn save(&self, host: &mut impl Runtime, prefix: &impl Path) -> Result<()> { + fn save( + &self, + host: &mut impl Runtime, + prefix: &impl Path, + ) -> Result<()> { store_rlp(self, host, &self.path(prefix)?) .context("cannot save pointer to storage") } @@ -207,7 +215,7 @@ impl, Elt: Encodable + Decodable> /// Removes the pointer and its data frm the durable storage. fn remove_with_data( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, prefix: &impl Path, ) -> Result<()> { let path = hex::encode(&self.id); @@ -228,7 +236,7 @@ where /// Load a list from the storage. /// If the list does not exist, a new empty list is created. /// Otherwise the existing list is read from the storage. - pub fn new(path: &impl Path, host: &impl Runtime) -> Result { + pub fn new(path: &impl Path, host: &impl Runtime) -> Result { let list = Self::read(host, path)?.unwrap_or(Self { path: path.into(), pointers: None, @@ -248,13 +256,13 @@ where /// Saves the LinkedList in the durable storage. /// /// Only save the back and front pointers. - fn save(&self, host: &mut impl Runtime) -> Result<()> { + fn save(&self, host: &mut impl Runtime) -> Result<()> { let path = Self::metadata_path(&self.path)?; store_rlp(self, host, &path).context("cannot save linked list from the storage") } /// Load the LinkedList from the durable storage. - fn read(host: &impl Runtime, path: &impl Path) -> Result> { + fn read(host: &impl Runtime, path: &impl Path) -> Result> { let path = Self::metadata_path(path)?; read_optional_rlp(host, &path) } @@ -270,7 +278,12 @@ where /// The Id has to be unique by element. /// The Id will be later use to retrieve the element /// (example: it can be the hash of the element). - pub fn push(&mut self, host: &mut impl Runtime, id: &Id, elt: &Elt) -> Result<()> { + pub fn push( + &mut self, + host: &mut impl Runtime, + id: &Id, + elt: &Elt, + ) -> Result<()> { // Check if the path already exist if (Pointer::read(host, &self.path, id)? as Option>).is_some() { return Ok(()); @@ -338,7 +351,7 @@ where /// Returns an element at a given index. /// /// Returns None if the element is not present - pub fn find(&self, host: &impl Runtime, id: &Id) -> Result> { + pub fn find(&self, host: &impl Runtime, id: &Id) -> Result> { let Some::>(pointer) = Pointer::read(host, &self.path, id)? else { return Ok(None); @@ -347,7 +360,11 @@ where } /// Removes and returns the element at position index within the vector. - pub fn remove(&mut self, host: &mut impl Runtime, id: &Id) -> Result> { + pub fn remove( + &mut self, + host: &mut impl Runtime, + id: &Id, + ) -> Result> { // Check if the list is empty let Some(LinkedListPointer { front, back }) = &self.pointers else { return Ok(None); @@ -470,7 +487,7 @@ where /// Returns the first element of the list /// or `None` if it is empty. - pub fn first(&self, host: &impl Runtime) -> Result> { + pub fn first(&self, host: &impl Runtime) -> Result> { let Some(LinkedListPointer { front, .. }) = &self.pointers else { return Ok(None); }; @@ -479,7 +496,7 @@ where /// Returns the first element of the list alongside its id /// or `None` if it is empty. - pub fn first_with_id(&self, host: &impl Runtime) -> Result> { + pub fn first_with_id(&self, host: &impl Runtime) -> Result> { let Some(LinkedListPointer { front, .. }) = &self.pointers else { return Ok(None); }; @@ -487,7 +504,7 @@ where } /// Removes the first element of the list and returns it - pub fn pop_first(&mut self, host: &mut impl Runtime) -> Result> { + pub fn pop_first(&mut self, host: &mut impl Runtime) -> Result> { let Some(LinkedListPointer { front, .. }) = &self.pointers else { return Ok(None); }; @@ -496,7 +513,7 @@ where } /// Deletes the entire list - pub fn delete(&mut self, host: &mut impl Runtime) -> Result<()> { + pub fn delete(&mut self, host: &mut impl Runtime) -> Result<()> { if host.store_has(&self.path)?.is_some() { host.store_delete(&self.path)?; }; diff --git a/etherlink/kernel_evm/kernel/src/migration.rs b/etherlink/kernel_evm/kernel/src/migration.rs index eba85e6927b7..2cba33ebba46 100644 --- a/etherlink/kernel_evm/kernel/src/migration.rs +++ b/etherlink/kernel_evm/kernel/src/migration.rs @@ -45,7 +45,7 @@ const MAINNET_CHAIN_ID: u64 = 42793; #[allow(dead_code)] fn is_etherlink_network( - host: &impl Runtime, + host: &impl Runtime, expected_chain_id: u64, ) -> Result { match read_chain_id(host) { @@ -69,7 +69,7 @@ pub fn allow_path_not_found(res: Result<(), RuntimeError>) -> Result<(), Runtime const TMP_NEXT_BLUEPRINT_PATH: RefPath = RefPath::assert_from(b"/__tmp_next_blueprint_path"); -fn migrate_to( +fn migrate_to>( host: &mut Host, version: StorageVersion, ) -> anyhow::Result { @@ -239,7 +239,7 @@ fn migrate_to( // in an inconsistent storage. // /!\ // -fn migration(host: &mut Host) -> anyhow::Result { +fn migration>(host: &mut Host) -> anyhow::Result { match read_storage_version(host)?.next() { Some(next_version) => { let status = migrate_to(host, next_version)?; @@ -259,7 +259,7 @@ fn migration(host: &mut Host) -> anyhow::Result } } -pub fn storage_migration( +pub fn storage_migration>( host: &mut Host, ) -> Result { let migration_result = migration(host); diff --git a/etherlink/kernel_evm/kernel/src/parsing.rs b/etherlink/kernel_evm/kernel/src/parsing.rs index 98997aab8a1c..86e5850bf728 100644 --- a/etherlink/kernel_evm/kernel/src/parsing.rs +++ b/etherlink/kernel_evm/kernel/src/parsing.rs @@ -639,7 +639,7 @@ impl InputResult { } } - fn parse_fa_deposit( + fn parse_fa_deposit>( host: &mut Host, ticket: FA2_1Ticket, routing_info: MichelsonBytes, @@ -667,7 +667,7 @@ impl InputResult { } } - fn parse_deposit( + fn parse_deposit>( host: &mut Host, ticket: FA2_1Ticket, receiver: MichelsonBytes, @@ -696,7 +696,7 @@ impl InputResult { } #[allow(clippy::too_many_arguments)] - fn parse_internal_transfer( + fn parse_internal_transfer>( host: &mut Host, transfer: Transfer, smart_rollup_address: &[u8], @@ -779,7 +779,7 @@ impl InputResult { } #[allow(clippy::too_many_arguments)] - fn parse_internal( + fn parse_internal>( host: &mut Host, message: InternalInboxMessage, smart_rollup_address: &[u8], @@ -807,7 +807,7 @@ impl InputResult { } } - pub fn parse( + pub fn parse>( host: &mut Host, input: Message, smart_rollup_address: [u8; 20], diff --git a/etherlink/kernel_evm/kernel/src/reveal_storage.rs b/etherlink/kernel_evm/kernel/src/reveal_storage.rs index 11da770422ac..cf31fab074e4 100644 --- a/etherlink/kernel_evm/kernel/src/reveal_storage.rs +++ b/etherlink/kernel_evm/kernel/src/reveal_storage.rs @@ -54,7 +54,7 @@ impl Decodable for Sets { } } -pub fn is_revealed_storage(host: &impl Runtime) -> bool { +pub fn is_revealed_storage(host: &impl Runtime) -> bool { matches!( host.store_has(&CONFIG_PATH).unwrap_or_default(), Some(ValueType::Value) @@ -62,7 +62,7 @@ pub fn is_revealed_storage(host: &impl Runtime) -> bool { } pub fn reveal_storage( - host: &mut impl Runtime, + host: &mut impl Runtime, sequencer: Option, admin: Option, ) { diff --git a/etherlink/kernel_evm/kernel/src/simulation.rs b/etherlink/kernel_evm/kernel/src/simulation.rs index 9f45101ee254..953aff1d0138 100644 --- a/etherlink/kernel_evm/kernel/src/simulation.rs +++ b/etherlink/kernel_evm/kernel/src/simulation.rs @@ -364,7 +364,7 @@ impl Evaluation { } /// Execute the simulation - pub fn run( + pub fn run>( &self, host: &mut Host, tracer_input: Option, @@ -581,7 +581,7 @@ impl Input { } } -fn read_chunks( +fn read_chunks>( host: &mut Host, num_chunks: u16, ) -> Result { @@ -601,14 +601,14 @@ fn read_chunks( Ok(buffer.as_slice().try_into()?) } -fn read_input(host: &mut Host) -> Result { +fn read_input>(host: &mut Host) -> Result { match host.read_input()? { Some(input) => Ok(Input::parse(input.as_ref())), None => Ok(Input::Unparsable), } } -fn parse_inbox(host: &mut Host) -> Result { +fn parse_inbox>(host: &mut Host) -> Result { // we just received simulation tag // next message is either a simulation or the nb of chunks needed match read_input(host)? { @@ -631,7 +631,7 @@ impl VersionedEncoding for SimulationResult } } -pub fn start_simulation_mode( +pub fn start_simulation_mode>( host: &mut Host, enable_fa_withdrawals: bool, ) -> Result<(), anyhow::Error> { @@ -729,7 +729,7 @@ mod tests { fn create_contract(host: &mut Host) -> H160 where - Host: Runtime, + Host: Runtime, { let timestamp = read_last_info_per_level_timestamp(host).unwrap_or(Timestamp::from(0)); diff --git a/etherlink/kernel_evm/kernel/src/stage_one.rs b/etherlink/kernel_evm/kernel/src/stage_one.rs index e5171f86ba83..861414100847 100644 --- a/etherlink/kernel_evm/kernel/src/stage_one.rs +++ b/etherlink/kernel_evm/kernel/src/stage_one.rs @@ -22,7 +22,7 @@ use tezos_smart_rollup_encoding::public_key::PublicKey; use tezos_smart_rollup_encoding::timestamp::Timestamp; use tezos_smart_rollup_host::metadata::RAW_ROLLUP_ADDRESS_SIZE; -pub fn fetch_proxy_blueprints( +pub fn fetch_proxy_blueprints>( host: &mut Host, smart_rollup_address: [u8; RAW_ROLLUP_ADDRESS_SIZE], tezos_contracts: &TezosContracts, @@ -50,7 +50,7 @@ pub fn fetch_proxy_blueprints( } } -fn fetch_delayed_transactions( +fn fetch_delayed_transactions>( host: &mut Host, delayed_inbox: &mut DelayedInbox, ) -> anyhow::Result<()> { @@ -103,7 +103,7 @@ fn fetch_delayed_transactions( } #[allow(clippy::too_many_arguments)] -fn fetch_sequencer_blueprints( +fn fetch_sequencer_blueprints>( host: &mut Host, smart_rollup_address: [u8; RAW_ROLLUP_ADDRESS_SIZE], tezos_contracts: &TezosContracts, @@ -143,7 +143,7 @@ fn fetch_sequencer_blueprints( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn fetch_blueprints( +pub fn fetch_blueprints>( host: &mut Host, smart_rollup_address: [u8; RAW_ROLLUP_ADDRESS_SIZE], config: &mut Configuration, @@ -364,7 +364,7 @@ mod tests { } } - fn delayed_inbox_is_empty( + fn delayed_inbox_is_empty>( conf: &Configuration, host: &mut Host, ) -> bool { diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index 305b7b6ef2af..4b98e5832c99 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -193,7 +193,7 @@ pub fn object_path(object_hash: &TransactionHash) -> Result, Err concat(&EVM_TRANSACTIONS_OBJECTS, &object_path).map_err(Error::from) } -pub fn store_simulation_result( +pub fn store_simulation_result, T: Decodable + Encodable>( host: &mut Host, result: SimulationResult, ) -> Result<(), anyhow::Error> { @@ -206,7 +206,7 @@ pub fn store_simulation_result( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn store_transaction_receipt( +pub fn store_transaction_receipt>( host: &mut Host, receipt: &TransactionReceipt, ) -> Result { @@ -221,7 +221,7 @@ pub fn store_transaction_receipt( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn store_transaction_object( +pub fn store_transaction_object>( host: &mut Host, object: &TransactionObject, ) -> Result { @@ -278,7 +278,7 @@ pub fn transaction_chunk_path( concat(chunked_transaction_path, &i_path).map_err(Error::from) } -fn is_transaction_complete( +fn is_transaction_complete>( host: &mut Host, chunked_transaction_path: &OwnedPath, num_chunks: u16, @@ -288,7 +288,7 @@ fn is_transaction_complete( Ok(n_subkeys >= num_chunks + 2) } -fn chunked_transaction_num_chunks_by_path( +fn chunked_transaction_num_chunks_by_path>( host: &mut Host, chunked_transaction_path: &OwnedPath, ) -> Result { @@ -299,7 +299,7 @@ fn chunked_transaction_num_chunks_by_path( Ok(u16::from_le_bytes(buffer)) } -pub fn chunked_transaction_num_chunks( +pub fn chunked_transaction_num_chunks>( host: &mut Host, tx_hash: &TransactionHash, ) -> Result { @@ -307,7 +307,7 @@ pub fn chunked_transaction_num_chunks( chunked_transaction_num_chunks_by_path(host, &chunked_transaction_path) } -fn store_transaction_chunk_data( +fn store_transaction_chunk_data>( host: &mut Host, transaction_chunk_path: &OwnedPath, data: Vec, @@ -328,7 +328,7 @@ fn store_transaction_chunk_data( } } -pub fn read_transaction_chunk_data( +pub fn read_transaction_chunk_data>( host: &mut Host, transaction_chunk_path: &OwnedPath, ) -> Result, Error> { @@ -349,7 +349,7 @@ pub fn read_transaction_chunk_data( } } -fn get_full_transaction( +fn get_full_transaction>( host: &mut Host, chunked_transaction_path: &OwnedPath, num_chunks: u16, @@ -363,14 +363,14 @@ fn get_full_transaction( Ok(buffer) } -pub fn remove_chunked_transaction_by_path( +pub fn remove_chunked_transaction_by_path>( host: &mut Host, path: &OwnedPath, ) -> Result<(), Error> { host.store_delete(path).map_err(Error::from) } -pub fn remove_chunked_transaction( +pub fn remove_chunked_transaction>( host: &mut Host, tx_hash: &TransactionHash, ) -> Result<(), Error> { @@ -380,7 +380,7 @@ pub fn remove_chunked_transaction( /// Store the transaction chunk in the storage. Returns the full transaction /// if the last chunk to store is the last missing chunk. -pub fn store_transaction_chunk( +pub fn store_transaction_chunk>( host: &mut Host, tx_hash: &TransactionHash, i: u16, @@ -405,7 +405,7 @@ pub fn store_transaction_chunk( } } -pub fn create_chunked_transaction( +pub fn create_chunked_transaction>( host: &mut Host, tx_hash: &TransactionHash, num_chunks: u16, @@ -446,42 +446,47 @@ pub fn create_chunked_transaction( Ok(()) } -pub fn store_chain_id( +pub fn store_chain_id>( host: &mut Host, chain_id: U256, ) -> Result<(), Error> { write_u256_le(host, &EVM_CHAIN_ID, chain_id).map_err(Error::from) } -pub fn read_chain_id(host: &Host) -> Result { +pub fn read_chain_id>(host: &Host) -> Result { read_u256_le(host, &EVM_CHAIN_ID).map_err(Error::from) } -pub fn read_minimum_base_fee_per_gas(host: &Host) -> Result { +pub fn read_minimum_base_fee_per_gas>( + host: &Host, +) -> Result { read_u256_le(host, &EVM_MINIMUM_BASE_FEE_PER_GAS).map_err(Error::from) } -pub fn read_tick_backlog(host: &impl Runtime) -> Result { +pub fn read_tick_backlog(host: &impl Runtime) -> Result { read_u64_le(host, &TICK_BACKLOG_PATH).map_err(Error::from) } -pub fn store_tick_backlog(host: &mut impl Runtime, value: u64) -> Result<(), Error> { +pub fn store_tick_backlog( + host: &mut impl Runtime, + value: u64, +) -> Result<(), Error> { write_u64_le(host, &TICK_BACKLOG_PATH, value).map_err(Error::from) } -pub fn read_tick_backlog_timestamp(host: &impl Runtime) -> Result { +pub fn read_tick_backlog_timestamp(host: &impl Runtime) -> Result { read_u64_le(host, &TICK_BACKLOG_TIMESTAMP_PATH).map_err(Error::from) } pub fn store_tick_backlog_timestamp( - host: &mut impl Runtime, + host: &mut impl Runtime, value: u64, ) -> Result<(), Error> { write_u64_le(host, &TICK_BACKLOG_TIMESTAMP_PATH, value)?; Ok(()) } -pub fn store_minimum_base_fee_per_gas( +pub fn store_minimum_base_fee_per_gas>( host: &mut Host, price: U256, ) -> Result<(), Error> { @@ -489,18 +494,18 @@ pub fn store_minimum_base_fee_per_gas( } pub fn store_da_fee( - host: &mut impl Runtime, + host: &mut impl Runtime, base_fee_per_gas: U256, ) -> Result<(), Error> { write_u256_le(host, &EVM_DA_FEE, base_fee_per_gas).map_err(Error::from) } -pub fn read_da_fee(host: &impl Runtime) -> Result { +pub fn read_da_fee(host: &impl Runtime) -> Result { read_u256_le(host, &EVM_DA_FEE).map_err(Error::from) } pub fn update_burned_fees( - host: &mut impl Runtime, + host: &mut impl Runtime, burned_fee: U256, ) -> Result<(), Error> { let path = &EVM_BURNED_FEES; @@ -510,12 +515,12 @@ pub fn update_burned_fees( } #[cfg(test)] -pub fn read_burned_fees(host: &mut impl Runtime) -> U256 { +pub fn read_burned_fees(host: &mut impl Runtime) -> U256 { let path = &EVM_BURNED_FEES; read_u256_le(host, path).unwrap_or_else(|_| U256::zero()) } -pub fn read_sequencer_pool_address(host: &impl Runtime) -> Option { +pub fn read_sequencer_pool_address(host: &impl Runtime) -> Option { let mut bytes = [0; std::mem::size_of::()]; let Ok(20) = host.store_read_slice(&SEQUENCER_POOL_PATH, 0, bytes.as_mut_slice()) else { @@ -526,7 +531,7 @@ pub fn read_sequencer_pool_address(host: &impl Runtime) -> Option { } pub fn store_sequencer_pool_address( - host: &mut impl Runtime, + host: &mut impl Runtime, address: H160, ) -> Result<(), Error> { let bytes = address.to_fixed_bytes(); @@ -534,7 +539,7 @@ pub fn store_sequencer_pool_address( Ok(()) } -pub fn store_timestamp_path( +pub fn store_timestamp_path>( host: &mut Host, path: &impl Path, timestamp: &Timestamp, @@ -544,20 +549,23 @@ pub fn store_timestamp_path( } #[allow(dead_code)] -pub fn read_l1_level(host: &mut Host) -> Result { +pub fn read_l1_level>(host: &mut Host) -> Result { let mut buffer = [0u8; 4]; store_read_slice(host, &EVM_L1_LEVEL, &mut buffer, 4)?; let level = u32::from_le_bytes(buffer); Ok(level) } -pub fn store_l1_level(host: &mut Host, level: u32) -> Result<(), Error> { +pub fn store_l1_level>( + host: &mut Host, + level: u32, +) -> Result<(), Error> { host.store_write(&EVM_L1_LEVEL, &level.to_le_bytes(), 0)?; Ok(()) } -pub fn read_last_info_per_level_timestamp_stats( - host: &mut Host, +pub fn read_last_info_per_level_timestamp_stats>( + host: &Host, ) -> Result<(i64, i64), Error> { let mut buffer = [0u8; 8]; store_read_slice(host, &EVM_INFO_PER_LEVEL_STATS_NUMBERS, &mut buffer, 8)?; @@ -570,7 +578,7 @@ pub fn read_last_info_per_level_timestamp_stats( Ok((numbers, total)) } -fn store_info_per_level_stats( +fn store_info_per_level_stats>( host: &mut Host, new_timestamp: Timestamp, ) -> Result<(), Error> { @@ -588,7 +596,7 @@ fn store_info_per_level_stats( Ok(()) } -pub fn store_last_info_per_level_timestamp( +pub fn store_last_info_per_level_timestamp>( host: &mut Host, timestamp: Timestamp, ) -> Result<(), Error> { @@ -596,7 +604,7 @@ pub fn store_last_info_per_level_timestamp( store_info_per_level_stats(host, timestamp) } -pub fn read_timestamp_path( +pub fn read_timestamp_path>( host: &Host, path: &impl Path, ) -> Result { @@ -606,40 +614,42 @@ pub fn read_timestamp_path( Ok(timestamp_as_i64.into()) } -pub fn read_last_info_per_level_timestamp( +pub fn read_last_info_per_level_timestamp>( host: &Host, ) -> Result { read_timestamp_path(host, &EVM_INFO_PER_LEVEL_TIMESTAMP) } -pub fn read_admin(host: &mut Host) -> Option { +pub fn read_admin>(host: &mut Host) -> Option { read_b58_kt1(host, &ADMIN) } -pub fn read_sequencer_governance( +pub fn read_sequencer_governance>( host: &mut Host, ) -> Option { read_b58_kt1(host, &SEQUENCER_GOVERNANCE) } -pub fn read_kernel_governance(host: &mut Host) -> Option { +pub fn read_kernel_governance>( + host: &mut Host, +) -> Option { read_b58_kt1(host, &KERNEL_GOVERNANCE) } -pub fn read_kernel_security_governance( +pub fn read_kernel_security_governance>( host: &mut Host, ) -> Option { read_b58_kt1(host, &KERNEL_SECURITY_GOVERNANCE) } -pub fn read_maximum_allowed_ticks(host: &mut Host) -> Option { +pub fn read_maximum_allowed_ticks>(host: &mut Host) -> Option { read_u64_le(host, &MAXIMUM_ALLOWED_TICKS).ok() } /// Reads the maximum gas per transaction. If the value cannot found in the storage, /// we write the kernel default value in the storage. The value becomes accessible /// from outside the kernel. -pub fn read_or_set_maximum_gas_per_transaction( +pub fn read_or_set_maximum_gas_per_transaction>( host: &mut Host, ) -> anyhow::Result { match read_u64_le(host, &MAXIMUM_GAS_PER_TRANSACTION) { @@ -651,7 +661,7 @@ pub fn read_or_set_maximum_gas_per_transaction( } } -pub fn store_storage_version( +pub fn store_storage_version>( host: &mut Host, storage_version: StorageVersion, ) -> Result<(), Error> { @@ -660,7 +670,7 @@ pub fn store_storage_version( .map_err(Error::from) } -pub fn read_storage_version( +pub fn read_storage_version>( host: &mut Host, ) -> Result { match host.store_read_all(&STORAGE_VERSION_PATH) { @@ -676,7 +686,9 @@ pub fn read_storage_version( } } -pub fn read_kernel_version(host: &mut Host) -> Result { +pub fn read_kernel_version>( + host: &mut Host, +) -> Result { match host.store_read_all(&KERNEL_VERSION_PATH) { Ok(bytes) => { let kernel_version = @@ -687,7 +699,7 @@ pub fn read_kernel_version(host: &mut Host) -> Result( +pub fn store_kernel_version>( host: &mut Host, kernel_version: &str, ) -> Result<(), Error> { @@ -700,7 +712,7 @@ pub fn store_kernel_version( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn store_block_in_progress( +pub fn store_block_in_progress>( host: &mut Host, bip: &BlockInProgress, ) -> anyhow::Result<()> { @@ -720,7 +732,7 @@ pub fn store_block_in_progress( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn read_block_in_progress( +pub fn read_block_in_progress>( host: &Host, ) -> anyhow::Result> { let path = OwnedPath::from(EVM_BLOCK_IN_PROGRESS); @@ -743,12 +755,14 @@ pub fn read_block_in_progress( } } -pub fn delete_block_in_progress(host: &mut Host) -> anyhow::Result<()> { +pub fn delete_block_in_progress>( + host: &mut Host, +) -> anyhow::Result<()> { host.store_delete(&EVM_BLOCK_IN_PROGRESS) .context("Failed to delete block in progress") } -pub fn sequencer(host: &Host) -> anyhow::Result> { +pub fn sequencer>(host: &Host) -> anyhow::Result> { if host.store_has(&SEQUENCER)?.is_some() { let bytes = host.store_read_all(&SEQUENCER)?; let Ok(tz1_b58) = String::from_utf8(bytes) else { @@ -763,7 +777,7 @@ pub fn sequencer(host: &Host) -> anyhow::Result } } -pub fn enable_dal(host: &Host) -> anyhow::Result { +pub fn enable_dal>(host: &Host) -> anyhow::Result { if let Some(ValueType::Value) = host.store_has(&ENABLE_DAL)? { // When run from the EVM node, the DAL feature is always // considered as disabled. @@ -774,7 +788,7 @@ pub fn enable_dal(host: &Host) -> anyhow::Result { } } -pub fn dal_slots(host: &Host) -> anyhow::Result>> { +pub fn dal_slots>(host: &Host) -> anyhow::Result>> { if host.store_has(&DAL_SLOTS)?.is_some() { let bytes = host.store_read_all(&DAL_SLOTS)?; Ok(Some(bytes)) @@ -783,11 +797,11 @@ pub fn dal_slots(host: &Host) -> anyhow::Result>> } } -pub fn remove_sequencer(host: &mut Host) -> anyhow::Result<()> { +pub fn remove_sequencer>(host: &mut Host) -> anyhow::Result<()> { host.store_delete(&SEQUENCER).map_err(Into::into) } -pub fn store_sequencer( +pub fn store_sequencer>( host: &mut Host, public_key: &PublicKey, ) -> anyhow::Result<()> { @@ -796,7 +810,7 @@ pub fn store_sequencer( host.store_write_all(&SEQUENCER, bytes).map_err(Into::into) } -pub fn clear_events(host: &mut Host) -> anyhow::Result<()> { +pub fn clear_events>(host: &mut Host) -> anyhow::Result<()> { if host.store_has(&EVENTS)?.is_some() { host.store_delete(&EVENTS) .context("Failed to delete old events") @@ -805,14 +819,17 @@ pub fn clear_events(host: &mut Host) -> anyhow::Result<()> { } } -pub fn store_event(host: &mut Host, event: &Event) -> anyhow::Result<()> { +pub fn store_event>( + host: &mut Host, + event: &Event, +) -> anyhow::Result<()> { let index = IndexableStorage::new(&EVENTS)?; index .push_value(host, &event.rlp_bytes()) .map_err(Into::into) } -pub fn delayed_inbox_timeout(host: &Host) -> anyhow::Result { +pub fn delayed_inbox_timeout>(host: &Host) -> anyhow::Result { // The default timeout is 12 hours let default_timeout = 43200; if host.store_has(&EVM_DELAYED_INBOX_TIMEOUT)?.is_some() { @@ -839,7 +856,7 @@ pub fn delayed_inbox_timeout(host: &Host) -> anyhow::Result } } -pub fn delayed_inbox_min_levels(host: &Host) -> anyhow::Result { +pub fn delayed_inbox_min_levels>(host: &Host) -> anyhow::Result { let default_min_levels = 720; if host.store_has(&EVM_DELAYED_INBOX_MIN_LEVELS)?.is_some() { let mut buffer = [0u8; 4]; @@ -863,7 +880,7 @@ pub fn delayed_inbox_min_levels(host: &Host) -> anyhow::Result( +pub fn read_tracer_input>( host: &mut Host, ) -> anyhow::Result> { if let Some(ValueType::Value) = host.store_has(&TRACER_INPUT).map_err(Error::from)? { @@ -888,7 +905,7 @@ pub fn read_tracer_input( } } -pub fn is_enable_fa_bridge(host: &impl Runtime) -> anyhow::Result { +pub fn is_enable_fa_bridge(host: &impl Runtime) -> anyhow::Result { if let Some(ValueType::Value) = host.store_has(&ENABLE_FA_BRIDGE)? { Ok(true) } else { @@ -896,7 +913,7 @@ pub fn is_enable_fa_bridge(host: &impl Runtime) -> anyhow::Result { } } -pub fn evm_node_flag(host: &impl Runtime) -> anyhow::Result { +pub fn evm_node_flag(host: &impl Runtime) -> anyhow::Result { if let Some(ValueType::Value) = host.store_has(&EVM_NODE_FLAG)? { Ok(true) } else { @@ -904,7 +921,9 @@ pub fn evm_node_flag(host: &impl Runtime) -> anyhow::Result { } } -pub fn max_blueprint_lookahead_in_seconds(host: &impl Runtime) -> anyhow::Result { +pub fn max_blueprint_lookahead_in_seconds( + host: &impl Runtime, +) -> anyhow::Result { let bytes = host.store_read_all(&MAX_BLUEPRINT_LOOKAHEAD_IN_SECONDS)?; let bytes: [u8; 8] = bytes.as_slice().try_into()?; Ok(i64::from_le_bytes(bytes)) @@ -917,7 +936,7 @@ mod internal_for_tests { use tezos_ethereum::transaction::TransactionStatus; /// Reads status from the receipt in storage. - pub fn read_transaction_receipt_status( + pub fn read_transaction_receipt_status>( host: &mut Host, tx_hash: &TransactionHash, ) -> Result { @@ -926,7 +945,7 @@ mod internal_for_tests { } /// Reads a transaction receipt from storage. - pub fn read_transaction_receipt( + pub fn read_transaction_receipt>( host: &mut Host, tx_hash: &TransactionHash, ) -> Result { @@ -944,7 +963,7 @@ pub use internal_for_tests::*; /// /// This smart contract is used to submit transactions to the rollup /// when in sequencer mode -pub fn read_delayed_transaction_bridge( +pub fn read_delayed_transaction_bridge>( host: &Host, ) -> Option { read_b58_kt1(host, &DELAYED_BRIDGE) diff --git a/etherlink/kernel_evm/kernel/src/upgrade.rs b/etherlink/kernel_evm/kernel/src/upgrade.rs index 39b53c57e05f..689fff9063ae 100644 --- a/etherlink/kernel_evm/kernel/src/upgrade.rs +++ b/etherlink/kernel_evm/kernel/src/upgrade.rs @@ -80,7 +80,7 @@ impl Encodable for KernelUpgrade { } } -pub fn store_kernel_upgrade( +pub fn store_kernel_upgrade>( host: &mut Host, kernel_upgrade: &KernelUpgrade, ) -> anyhow::Result<()> { @@ -99,19 +99,19 @@ pub fn store_kernel_upgrade( } fn read_kernel_upgrade_at( - host: &impl Runtime, + host: &impl Runtime, path: &impl Path, ) -> anyhow::Result> { read_optional_rlp(host, path).context("Failed to decode kernel upgrade") } -pub fn read_kernel_upgrade( +pub fn read_kernel_upgrade>( host: &Host, ) -> anyhow::Result> { read_kernel_upgrade_at(host, &KERNEL_UPGRADE) } -pub fn upgrade( +pub fn upgrade>( host: &mut Host, root_hash: [u8; PREIMAGE_HASH_SIZE], ) -> anyhow::Result<()> { @@ -187,7 +187,7 @@ impl Encodable for SequencerUpgrade { } } -pub fn store_sequencer_upgrade( +pub fn store_sequencer_upgrade>( host: &mut Host, sequencer_upgrade: SequencerUpgrade, ) -> anyhow::Result<()> { @@ -205,19 +205,19 @@ pub fn store_sequencer_upgrade( .context("Failed to store sequencer upgrade") } -pub fn read_sequencer_upgrade( +pub fn read_sequencer_upgrade>( host: &Host, ) -> anyhow::Result> { let path = OwnedPath::from(SEQUENCER_UPGRADE); read_optional_rlp(host, &path).context("Failed to decode sequencer upgrade") } -fn delete_sequencer_upgrade(host: &mut Host) -> anyhow::Result<()> { +fn delete_sequencer_upgrade>(host: &mut Host) -> anyhow::Result<()> { host.store_delete(&SEQUENCER_UPGRADE) .context("Failed to delete sequencer upgrade") } -fn sequencer_upgrade( +fn sequencer_upgrade>( host: &mut Host, pool_address: H160, sequencer: &PublicKey, @@ -231,7 +231,9 @@ fn sequencer_upgrade( Ok(()) } -pub fn possible_sequencer_upgrade(host: &mut Host) -> anyhow::Result<()> { +pub fn possible_sequencer_upgrade>( + host: &mut Host, +) -> anyhow::Result<()> { let upgrade = read_sequencer_upgrade(host)?; if let Some(upgrade) = upgrade { let ipl_timestamp = storage::read_last_info_per_level_timestamp(host)?; diff --git a/etherlink/kernel_evm/runtime/src/internal_runtime.rs b/etherlink/kernel_evm/runtime/src/internal_runtime.rs index 321ebe621ee6..3e0277453dd0 100644 --- a/etherlink/kernel_evm/runtime/src/internal_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/internal_runtime.rs @@ -30,10 +30,10 @@ pub trait InternalRuntime { // to the Runtime for the Kernel to use. // The path is optional to be able to get the hash // of the root directory. -pub trait ExtendedRuntime { - fn store_get_hash>( +pub trait ExtendedRuntime { + fn store_get_hash( &mut self, - path: &T, + path: &impl Path, ) -> Result, RuntimeError>; } diff --git a/etherlink/kernel_evm/runtime/src/relative_runtime.rs b/etherlink/kernel_evm/runtime/src/relative_runtime.rs index 4e50e2135e4b..0c9df060e592 100644 --- a/etherlink/kernel_evm/runtime/src/relative_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/relative_runtime.rs @@ -29,7 +29,7 @@ impl RelativeRuntime { } } -impl InternalRuntime for RelativeRuntime<&mut Host> { +impl> InternalRuntime for RelativeRuntime<&mut Host> { fn __internal_store_get_hash>( &mut self, path: &P, @@ -38,18 +38,18 @@ impl InternalRuntime for RelativeRuntime<&mut Host> { } } -impl ExtendedRuntime for RelativeRuntime<&mut Host> { +impl> ExtendedRuntime for RelativeRuntime<&mut Host> { #[inline(always)] - fn store_get_hash>( + fn store_get_hash( &mut self, - path: &P, + path: &impl Path, ) -> Result, RuntimeError> { let path = self.absolute_path(path)?; self.__internal_store_get_hash(&path) } } -impl SdkRuntime for RelativeRuntime<&mut Host> { +impl> SdkRuntime for RelativeRuntime<&mut Host> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.write_output(from) @@ -237,13 +237,13 @@ impl SdkRuntime for RelativeRuntime<&mut Host> { } } -impl Verbosity for RelativeRuntime<&mut Host> { +impl> Verbosity for RelativeRuntime<&mut Host> { fn verbosity(&self) -> tezos_evm_logging::Level { self.host.verbosity() } } -impl WithGas for RelativeRuntime<&mut Host> { +impl> WithGas for RelativeRuntime<&mut Host> { fn add_execution_gas(&mut self, gas: u64) { self.host.add_execution_gas(gas) } diff --git a/etherlink/kernel_evm/runtime/src/runtime.rs b/etherlink/kernel_evm/runtime/src/runtime.rs index b01c618c809d..19885084a278 100644 --- a/etherlink/kernel_evm/runtime/src/runtime.rs +++ b/etherlink/kernel_evm/runtime/src/runtime.rs @@ -33,15 +33,25 @@ use tezos_smart_rollup_mock::MockHost; // Set by the node, contains the verbosity for the logs pub const VERBOSITY_PATH: RefPath = RefPath::assert_from(b"/evm/logging_verbosity"); -pub trait Runtime: - SdkRuntime + InternalRuntime + ExtendedRuntime + Verbosity + WithGas +pub trait Runtime: + SdkRuntime + + InternalRuntime + + ExtendedRuntime + + Verbosity + + WithGas { } // If a type implements the Runtime, InternalRuntime and ExtendedRuntime traits, // it also implements the kernel Runtime. -impl Runtime - for T +impl< + const IS_ABSOLUTE: bool, + T: SdkRuntime + + InternalRuntime + + ExtendedRuntime + + Verbosity + + WithGas, + > Runtime for T { } @@ -61,7 +71,7 @@ impl Ru // However it is never used in the type itself, which will be rejected by the // compiler. PhantomData associates `R` to the struct with no cost at // runtime. -pub struct KernelHost + Borrow, Internal> { +pub struct KernelHost, Host: BorrowMut + Borrow, Internal> { pub host: Host, pub internal: Internal, pub logs_verbosity: Level, @@ -69,8 +79,8 @@ pub struct KernelHost + Borrow, Internal> { pub _pd: PhantomData, } -impl + Borrow, Internal: InternalRuntime> SdkRuntime - for KernelHost +impl, Host: BorrowMut + Borrow, Internal: InternalRuntime> + SdkRuntime for KernelHost { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { @@ -259,7 +269,7 @@ impl + Borrow, Internal: InternalRuntime> S } } -impl + BorrowMut, Internal: InternalRuntime> +impl, Host: Borrow + BorrowMut, Internal: InternalRuntime> InternalRuntime for KernelHost { #[inline(always)] @@ -271,19 +281,19 @@ impl + BorrowMut, Internal: InternalRuntime> } } -impl + Borrow, Internal: InternalRuntime> - ExtendedRuntime for KernelHost +impl, Host: BorrowMut + Borrow, Internal: InternalRuntime> + ExtendedRuntime for KernelHost { #[inline(always)] - fn store_get_hash>( + fn store_get_hash( &mut self, - path: &T, + path: &impl Path, ) -> Result, RuntimeError> { self.__internal_store_get_hash(path) } } -impl + BorrowMut, Internal> +impl, Host: Borrow + BorrowMut, Internal> KernelHost where for<'a> &'a mut Host: BorrowMut, @@ -299,15 +309,15 @@ where } } -impl + Borrow, Internal: InternalRuntime> Verbosity - for KernelHost +impl, Host: BorrowMut + Borrow, Internal: InternalRuntime> + Verbosity for KernelHost { fn verbosity(&self) -> Level { self.logs_verbosity } } -pub fn read_logs_verbosity( +pub fn read_logs_verbosity>( host: &Host, ) -> Level { match host.store_read_all(&VERBOSITY_PATH) { @@ -318,15 +328,17 @@ pub fn read_logs_verbosity( } } -impl + Borrow, Internal: InternalRuntime> WithGas - for KernelHost +impl, Host: BorrowMut + Borrow, Internal: InternalRuntime> + WithGas for KernelHost { fn add_execution_gas(&mut self, gas: u64) { self.execution_gas_used += gas; } } -impl + Borrow> KernelHost { +impl, Host: BorrowMut + Borrow> + KernelHost +{ pub fn init(host: Host) -> Self { let internal_storage = InternalHost(); let logs_verbosity = read_logs_verbosity(host.borrow()); diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index e2ebc7b8a6fc..1102ecc6f4af 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -33,7 +33,7 @@ pub struct SafeStorage { pub host: Runtime, } -impl InternalRuntime for SafeStorage<&mut Host> { +impl> InternalRuntime for SafeStorage<&mut Host> { fn __internal_store_get_hash>( &mut self, path: &T, @@ -42,18 +42,18 @@ impl InternalRuntime for SafeStorage<&mut Host> { } } -impl ExtendedRuntime for SafeStorage<&mut Host> { +impl> ExtendedRuntime for SafeStorage<&mut Host> { #[inline(always)] - fn store_get_hash>( + fn store_get_hash( &mut self, - path: &P, + path: &impl Path, ) -> Result, RuntimeError> { let path = safe_path(path)?; self.__internal_store_get_hash(&path) } } -impl SdkRuntime for SafeStorage<&mut Host> { +impl> SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.write_output(from) @@ -241,13 +241,13 @@ impl SdkRuntime for SafeStorage<&mut Host> { } } -impl Verbosity for SafeStorage<&mut Host> { +impl> Verbosity for SafeStorage<&mut Host> { fn verbosity(&self) -> tezos_evm_logging::Level { self.host.verbosity() } } -impl SafeStorage<&mut Host> { +impl<'a, Host: Runtime> SafeStorage<&'a mut Host> { pub fn start(&mut self) -> Result<(), RuntimeError> { self.host .store_copy(&WORLD_STATE_PATH, &TMP_WORLD_STATE_PATH) @@ -272,7 +272,7 @@ impl SafeStorage<&mut Host> { } } -impl WithGas for SafeStorage<&mut Host> { +impl> WithGas for SafeStorage<&mut Host> { fn add_execution_gas(&mut self, gas: u64) { self.host.add_execution_gas(gas) } diff --git a/etherlink/kernel_evm/storage/src/lib.rs b/etherlink/kernel_evm/storage/src/lib.rs index aae947a3e4c1..276e3a97efaf 100644 --- a/etherlink/kernel_evm/storage/src/lib.rs +++ b/etherlink/kernel_evm/storage/src/lib.rs @@ -26,9 +26,9 @@ pub const WORD_SIZE: usize = 32usize; /// store the read slice in `buffer`. /// /// NB: Value is read starting 0. -pub fn store_read_slice( - host: &impl Runtime, - path: &impl Path, +pub fn store_read_slice( + host: &impl Runtime, + path: &impl Path, buffer: &mut [u8], expected_size: usize, ) -> Result<(), Error> { @@ -52,7 +52,10 @@ pub fn path_from_h256(index: &H256) -> Result, Error> { /// Return a 32 bytes hash from storage at the given `path`. /// /// NB: The given bytes are interpreted in big endian order. -pub fn read_h256_be(host: &impl Runtime, path: &impl Path) -> anyhow::Result { +pub fn read_h256_be( + host: &impl Runtime, + path: &impl Path, +) -> anyhow::Result { let mut buffer = [0_u8; WORD_SIZE]; store_read_slice(host, path, &mut buffer, WORD_SIZE)?; Ok(H256::from_slice(&buffer)) @@ -61,9 +64,9 @@ pub fn read_h256_be(host: &impl Runtime, path: &impl Path) -> anyhow::Resu /// Return a 32 bytes hash from storage at the given `path`. /// /// NB: The given bytes are interpreted in big endian order. -pub fn read_h256_be_opt( - host: &impl Runtime, - path: &impl Path, +pub fn read_h256_be_opt( + host: &impl Runtime, + path: &impl Path, ) -> Result, Error> { match host.store_read_all(path) { Ok(bytes) if bytes.len() == WORD_SIZE => Ok(Some(H256::from_slice(&bytes))), @@ -76,9 +79,9 @@ pub fn read_h256_be_opt( /// If the path is not found, `default` is returned. /// /// NB: The given bytes are interpreted in big endian order. -pub fn read_h256_be_default( - host: &impl Runtime, - path: &impl Path, +pub fn read_h256_be_default( + host: &impl Runtime, + path: &impl Path, default: H256, ) -> Result { match read_h256_be_opt(host, path)? { @@ -90,9 +93,9 @@ pub fn read_h256_be_default( /// Write a 32 bytes hash into storage at the given `path`. /// /// NB: The hash is stored in big endian order. -pub fn write_h256_be( - host: &mut impl Runtime, - path: &impl Path, +pub fn write_h256_be( + host: &mut impl Runtime, + path: &impl Path, hash: H256, ) -> anyhow::Result<()> { Ok(host.store_write_all(path, hash.as_bytes())?) @@ -101,7 +104,10 @@ pub fn write_h256_be( /// Return an unsigned 32 bytes value from storage at the given `path`. /// /// NB: The given bytes are interpreted in little endian order. -pub fn read_u256_le(host: &impl Runtime, path: &impl Path) -> Result { +pub fn read_u256_le( + host: &impl Runtime, + path: &impl Path, +) -> Result { let bytes = host.store_read_all(path)?; Ok(U256::from_little_endian(&bytes)) } @@ -110,9 +116,9 @@ pub fn read_u256_le(host: &impl Runtime, path: &impl Path) -> Result, +pub fn read_u256_le_default( + host: &impl Runtime, + path: &impl Path, default: U256, ) -> Result { match host.store_read_all(path) { @@ -125,9 +131,9 @@ pub fn read_u256_le_default( /// Write an unsigned 32 bytes value into storage at the given `path`. /// /// NB: The value is stored in little endian order. -pub fn write_u256_le( - host: &mut impl Runtime, - path: &impl Path, +pub fn write_u256_le( + host: &mut impl Runtime, + path: &impl Path, value: U256, ) -> Result<(), Error> { let mut bytes: [u8; WORD_SIZE] = value.into(); @@ -138,7 +144,10 @@ pub fn write_u256_le( /// Return an unsigned 8 bytes value from storage at the given `path`. /// /// NB: The given bytes are interpreted in little endian order. -pub fn read_u64_le(host: &impl SdkRuntime, path: &impl Path) -> Result { +pub fn read_u64_le( + host: &impl SdkRuntime, + path: &impl Path, +) -> Result { let mut bytes = [0; std::mem::size_of::()]; host.store_read_slice(path, 0, bytes.as_mut_slice())?; Ok(u64::from_le_bytes(bytes)) @@ -148,9 +157,9 @@ pub fn read_u64_le(host: &impl SdkRuntime, path: &impl Path) -> Result, +pub fn read_u64_le_default( + host: &impl Runtime, + path: &impl Path, default: u64, ) -> Result { match host.store_read_all(path) { @@ -169,9 +178,9 @@ pub fn read_u64_le_default( /// If the path is not found, `default` is returned. /// /// NB: The given bytes are interpreted in little endian order. -pub fn read_u16_le_default( - host: &impl Runtime, - path: &impl Path, +pub fn read_u16_le_default( + host: &impl Runtime, + path: &impl Path, default: u16, ) -> Result { // This is exactly the same function as `read_u64_le_default`, but you know @@ -191,9 +200,9 @@ pub fn read_u16_le_default( /// Write an unsigned 8 bytes value into storage at the given `path`. /// /// NB: The value is stored in little endian order. -pub fn write_u64_le( - host: &mut impl SdkRuntime, - path: &impl Path, +pub fn write_u64_le( + host: &mut impl SdkRuntime, + path: &impl Path, value: u64, ) -> Result<(), Error> { host.store_write_all(path, value.to_le_bytes().as_slice()) @@ -202,10 +211,10 @@ pub fn write_u64_le( /// Store `src` (which must be encodable) as rlp bytes into storage /// at the given `path`. -pub fn store_rlp( +pub fn store_rlp( src: &impl Encodable, - host: &mut impl Runtime, - path: &impl Path, + host: &mut impl Runtime, + path: &impl Path, ) -> Result<(), Error> { host.store_write_all(path, &src.rlp_bytes()) .map_err(Error::from) @@ -213,9 +222,9 @@ pub fn store_rlp( /// Return a decodable value from storage as rlp bytes /// at the given `path`. -pub fn read_rlp( - host: &impl Runtime, - path: &impl Path, +pub fn read_rlp( + host: &impl Runtime, + path: &impl Path, ) -> Result { let bytes = host.store_read_all(path)?; FromRlpBytes::from_rlp_bytes(&bytes).map_err(Error::from) @@ -225,9 +234,9 @@ pub fn read_rlp( /// at the given `path`. /// /// If there is no data, `None` is returned. -pub fn read_optional_rlp( - host: &impl Runtime, - path: &impl Path, +pub fn read_optional_rlp( + host: &impl Runtime, + path: &impl Path, ) -> Result, anyhow::Error> { if let Some(ValueType::Value) = host.store_has(path)? { let elt = read_rlp(host, path)?; @@ -238,9 +247,9 @@ pub fn read_optional_rlp( } /// Return a base58 contract address from storage at the given `path`. -pub fn read_b58_kt1( - host: &impl Runtime, - path: &impl Path, +pub fn read_b58_kt1( + host: &impl Runtime, + path: &impl Path, ) -> Option { let bytes = host.store_read_all(path).ok()?; let kt1_b58 = String::from_utf8(bytes).ok()?; diff --git a/src/kernel_sdk/encoding/src/dac/certificate.rs b/src/kernel_sdk/encoding/src/dac/certificate.rs index 42ff24a964bc..822cd6b2c22c 100644 --- a/src/kernel_sdk/encoding/src/dac/certificate.rs +++ b/src/kernel_sdk/encoding/src/dac/certificate.rs @@ -165,7 +165,7 @@ impl Certificate { /// If `reveal_to_store` returns an error, any content succesfully revealed /// up until the error occurred will remain in storage; use [Runtime::store_value_size] to /// determine the size of this value. - pub fn reveal_to_store( + pub fn reveal_to_store>( &self, host: &mut Host, path: &impl Path, @@ -233,7 +233,7 @@ impl Certificate { } fn fetch_page<'a>( - host: &impl Runtime, + host: &impl Runtime, hash: &[u8; PREIMAGE_HASH_SIZE], buffer: &'a mut [u8], ) -> Result<(SlicePage<'a>, &'a mut [u8]), CertificateError> { diff --git a/src/kernel_sdk/encoding/src/dac/pages.rs b/src/kernel_sdk/encoding/src/dac/pages.rs index 0b06f25260a7..6e420c2002c2 100644 --- a/src/kernel_sdk/encoding/src/dac/pages.rs +++ b/src/kernel_sdk/encoding/src/dac/pages.rs @@ -320,7 +320,7 @@ impl<'a> V0SliceHashPage<'a> { /// Fetches a page of data from file `hash` into `buffer` using [Runtime::reveal_preimage]. /// Returns a tuple of the raw page and remaining buffer. -pub fn fetch_page_raw<'a, Host: Runtime>( +pub fn fetch_page_raw<'a, Host: Runtime>( host: &Host, hash: &[u8; PREIMAGE_HASH_SIZE], buffer: &'a mut [u8], @@ -339,7 +339,7 @@ pub fn fetch_page_raw<'a, Host: Runtime>( /// however, to run into tick-limit issues while doing so, depending on what `save_content` does. /// /// Instead, it is recommended to use `DacCertificate::reveal_to_store` where possible. -pub fn reveal_loop( +pub fn reveal_loop>( host: &mut Host, level: usize, hash: &[u8; PREIMAGE_HASH_SIZE], diff --git a/src/kernel_sdk/host/src/runtime.rs b/src/kernel_sdk/host/src/runtime.rs index d7af72af67ab..a3e7d3c1f6d0 100644 --- a/src/kernel_sdk/host/src/runtime.rs +++ b/src/kernel_sdk/host/src/runtime.rs @@ -82,7 +82,7 @@ pub enum ValueType { /// - methods that take `&self` will not cause changes to the runtime state. /// - methods taking `&mut self` are expected to cause changes - either to *input*, /// *output* or *durable storage*. -pub trait Runtime { +pub trait Runtime { /// Write contents of the given slice to output. fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError>; @@ -99,11 +99,11 @@ pub trait Runtime { fn read_input(&mut self) -> Result, RuntimeError>; /// Returns whether a given path exists in storage. - fn store_has>(&self, path: &T) -> Result, RuntimeError>; + fn store_has>(&self, path: &T) -> Result, RuntimeError>; /// Read up to `max_bytes` from the given path in storage, starting `from_offset`. #[cfg(feature = "alloc")] - fn store_read>( + fn store_read>( &self, path: &T, from_offset: usize, @@ -117,7 +117,7 @@ pub trait Runtime { /// The total bytes read is returned. /// If the returned value `n` is `n < buffer.len()`, then only the first `n` /// bytes of the buffer will have been written too. - fn store_read_slice>( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -126,14 +126,14 @@ pub trait Runtime { /// Read an entire value from the given path in storage. #[cfg(feature = "alloc")] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError>; + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError>; /// Write the bytes given by `src` to storage at `path`, starting `at_offset`. /// /// Contrary to `store_write_all`, this does not replace the value (if any) /// previously stored under `path`. This allows for splicing/patching values /// directly in storage, without having to read the entire value from disk. - fn store_write>( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -144,30 +144,30 @@ pub trait Runtime { /// /// Contrary to `store_write`, this replaces the value (if any) that /// was previously stored at `path`. - fn store_write_all>( + fn store_write_all>( &mut self, path: &T, src: &[u8], ) -> Result<(), RuntimeError>; /// Delete `path` from storage. - fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError>; + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError>; /// Delete value under `path` from storage. - fn store_delete_value>(&mut self, path: &T) -> Result<(), RuntimeError>; + fn store_delete_value>(&mut self, path: &T) -> Result<(), RuntimeError>; /// Count the number of subkeys under `prefix`. /// /// See [SmartRollupCore::store_list_size]. - fn store_count_subkeys>(&self, prefix: &T) -> Result; + fn store_count_subkeys>(&self, prefix: &T) -> Result; /// Move one part of durable storage to a different location /// /// See [SmartRollupCore::store_move]. fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError>; /// Copy one part of durable storage to a different location @@ -175,8 +175,8 @@ pub trait Runtime { /// See [SmartRollupCore::store_copy]. fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError>; /// Reveal pre-image from a hash of size `PREIMAGE_HASH_SIZE` in bytes. @@ -204,7 +204,7 @@ pub trait Runtime { fn reveal_dal_parameters(&self) -> RollupDalParameters; /// Return the size of value stored at `path` - fn store_value_size(&self, path: &impl Path) -> Result; + fn store_value_size(&self, path: &impl Path) -> Result; /// Mark the kernel for reboot. /// @@ -246,7 +246,7 @@ pub trait Runtime { const REBOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/env/reboot"); -impl Runtime for Host +impl Runtime for Host where Host: SmartRollupCore, { @@ -728,7 +728,7 @@ where } fn check_path_has_value<'a>( - runtime: &'a impl Runtime, + runtime: &'a impl Runtime, path: &'a impl Path, ) -> impl FnOnce(RuntimeError) -> RuntimeError + 'a { |err| { @@ -743,7 +743,7 @@ fn check_path_has_value<'a>( } fn check_path_exists<'a, T: Path>( - runtime: &'a impl Runtime, + runtime: &'a impl Runtime, path: &'a T, ) -> impl FnOnce(RuntimeError) -> RuntimeError + 'a { |err| { diff --git a/src/kernel_sdk/installer-config/src/binary/instr.rs b/src/kernel_sdk/installer-config/src/binary/instr.rs index 85778d61b56a..9cd0aa77c4f9 100644 --- a/src/kernel_sdk/installer-config/src/binary/instr.rs +++ b/src/kernel_sdk/installer-config/src/binary/instr.rs @@ -79,7 +79,7 @@ pub mod owned { pub struct OwnedConfigProgram(pub Vec); impl OwnedConfigProgram { - pub fn evaluate(&self, host: &mut impl Runtime) -> Result<(), &'static str> { + pub fn evaluate(&self, host: &mut impl Runtime) -> Result<(), &'static str> { for instruction in self.0.iter() { eval_config_instr(host, instruction)? } @@ -149,7 +149,7 @@ pub mod evaluation { /// } /// ``` pub fn eval_config_instr, Bytes: AsRef<[u8]>>( - host: &mut impl Runtime, + host: &mut impl Runtime, config_instr: &ConfigInstruction, ) -> Result<(), &'static str> { match config_instr { diff --git a/src/kernel_sdk/installer-config/src/binary/nom.rs b/src/kernel_sdk/installer-config/src/binary/nom.rs index b3a3c7aedad7..ced462c1ed89 100644 --- a/src/kernel_sdk/installer-config/src/binary/nom.rs +++ b/src/kernel_sdk/installer-config/src/binary/nom.rs @@ -75,7 +75,7 @@ fn nom_read_ref_path(input: &[u8]) -> NomResult> { } pub fn read_size( - host: &impl Runtime, + host: &impl Runtime, path: &impl Path, offset: &mut usize, ) -> Result { diff --git a/src/kernel_sdk/installer-config/src/binary/preimage.rs b/src/kernel_sdk/installer-config/src/binary/preimage.rs index 16a1f651410e..c245cb559114 100644 --- a/src/kernel_sdk/installer-config/src/binary/preimage.rs +++ b/src/kernel_sdk/installer-config/src/binary/preimage.rs @@ -18,7 +18,7 @@ const MAX_DAC_LEVELS: usize = 4; /// This function will reveal the root hash by writing and storing the /// hash at the appropriate and intended path. pub fn reveal_root_hash_to_store( - host: &mut impl Runtime, + host: &mut impl Runtime, root_hash: &[u8; PREIMAGE_HASH_SIZE], reveal_to: &impl Path, ) -> Result<(), &'static str> { @@ -37,7 +37,7 @@ pub fn reveal_root_hash_to_store( } /// Appends the content of the page path given. -fn write_kernel_page( +fn write_kernel_page>( reveal_to: &impl Path, ) -> impl FnMut(&mut Host, V0SliceContentPage) -> Result<(), &'static str> + '_ { let mut kernel_size = 0; @@ -48,7 +48,7 @@ fn write_kernel_page( } } -fn append_content( +fn append_content>( host: &mut Host, kernel_size: usize, content: V0SliceContentPage, diff --git a/src/kernel_sdk/installer-kernel/src/instr.rs b/src/kernel_sdk/installer-kernel/src/instr.rs index bd3dbdef790b..95a348b90512 100644 --- a/src/kernel_sdk/installer-kernel/src/instr.rs +++ b/src/kernel_sdk/installer-kernel/src/instr.rs @@ -9,7 +9,7 @@ use tezos_smart_rollup::storage::path::{Path, RefPath}; use tezos_smart_rollup_installer_config::binary::read_size; pub fn read_config_program_size( - host: &impl Runtime, + host: &impl Runtime, config_interpretation_path: &RefPath, ) -> Result { let kernel_size = host @@ -25,7 +25,7 @@ pub fn read_config_program_size( } pub fn read_instruction_bytes( - host: &impl Runtime, + host: &impl Runtime, path: &impl Path, offset: &mut usize, mut buffer: &mut [u8], diff --git a/src/kernel_sdk/installer-kernel/src/lib.rs b/src/kernel_sdk/installer-kernel/src/lib.rs index d9a7906f51df..e50d74600bc0 100644 --- a/src/kernel_sdk/installer-kernel/src/lib.rs +++ b/src/kernel_sdk/installer-kernel/src/lib.rs @@ -42,7 +42,7 @@ const AUXILIARY_CONFIG_INTERPRETATION_PATH: RefPath = /// Installer. #[cfg_attr(feature = "entrypoint", entrypoint::main)] -pub fn installer(host: &mut Host) { +pub fn installer>(host: &mut Host) { if let Err(e) = install_kernel(host, KERNEL_BOOT_PATH) { Runtime::write_debug(host, e) } else { @@ -71,7 +71,7 @@ fn panic(_info: &PanicInfo) -> ! { /// was written to. // TODO: provide a concrete example (see https://gitlab.com/tezos/tezos/-/issues/5855) pub fn install_kernel( - host: &mut impl Runtime, + host: &mut impl Runtime, config_interpretation_path: RefPath, ) -> Result<(), &'static str> { if let Ok(config_program_size) = diff --git a/src/kernel_sdk/sdk/src/outbox.rs b/src/kernel_sdk/sdk/src/outbox.rs index 290869285e6e..58728d855577 100644 --- a/src/kernel_sdk/sdk/src/outbox.rs +++ b/src/kernel_sdk/sdk/src/outbox.rs @@ -146,7 +146,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { /// [`flush_queue`]: Self::flush_queue pub fn queue_message( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, message: impl Into>, ) -> Result { let (start, len) = self.read_meta(host); @@ -189,7 +189,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { /// `flush_queue` twice, on the same *durable storage state*, then a single message could be /// executed twice - leading to double spending of an L2 account's funds on L1 - this would result /// later in some accounts being unable to execute otherwise valid withdrawals on L1. - pub fn flush_queue(&self, host: &mut impl Runtime) -> usize { + pub fn flush_queue(&self, host: &mut impl Runtime) -> usize { // Consider: `store_read_extend(&mut Vec)` let mut num_flushed = 0; let (mut start, mut len) = self.read_meta(host); @@ -241,7 +241,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { } #[inline(always)] - fn read_meta(&self, host: &impl Runtime) -> (u32, u32) { + fn read_meta(&self, host: &impl Runtime) -> (u32, u32) { const BUFF_SIZE: usize = 2 * core::mem::size_of::(); let mut buffer = [0; BUFF_SIZE]; @@ -257,7 +257,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { } #[inline(always)] - fn save_meta(&self, host: &mut impl Runtime, start: u32, len: u32) { + fn save_meta(&self, host: &mut impl Runtime, start: u32, len: u32) { if len == 0 { // We only call this when we've just emptied the queue let _ = host.store_delete(self.root); diff --git a/src/kernel_sdk/storage/src/layer.rs b/src/kernel_sdk/storage/src/layer.rs index b8a0d363156c..324eae4a2e6e 100644 --- a/src/kernel_sdk/storage/src/layer.rs +++ b/src/kernel_sdk/storage/src/layer.rs @@ -20,8 +20,8 @@ use core::marker::PhantomData; use tezos_smart_rollup_host::path::{concat, OwnedPath, Path}; use tezos_smart_rollup_host::runtime::{Runtime, RuntimeError, ValueType}; -pub(crate) struct Layer>> { - pub(crate) path: OwnedPath, +pub(crate) struct Layer>> { + pub(crate) path: OwnedPath, phantom: PhantomData, } @@ -31,7 +31,7 @@ fn has_subtree_res(v: Result, RuntimeError>) -> bool { matches!(v, Ok(Some(Subtree | ValueWithSubtree))) } -impl>> Layer { +impl>> Layer { /// Create layer for the path given. /// /// Create a new layer object with all account data stored under path given, ie, @@ -39,7 +39,7 @@ impl>> Layer { /// contain all data for account with id "alpha". /// /// This function is used solely for creating the bottom layer of the storage. - pub(crate) fn with_path(name: &impl Path) -> Self { + pub(crate) fn with_path(name: &impl Path) -> Self { Self { path: OwnedPath::from(name), phantom: PhantomData, @@ -56,8 +56,8 @@ impl>> Layer { /// responsability of the caller to do so. pub(crate) fn force_make_copy( &self, - host: &mut impl Runtime, - name: &impl Path, + host: &mut impl Runtime, + name: &impl Path, ) -> Result { let copy = Self { path: OwnedPath::from(name), @@ -77,8 +77,8 @@ impl>> Layer { /// [make_copy] function. pub(crate) fn consume( &mut self, - host: &mut impl Runtime, - layer: Layer, + host: &mut impl Runtime, + layer: Layer, ) -> Result<(), StorageError> { if let Ok(Some(_)) = host.store_has(&layer.path) { // The layer we consume has content, so move it @@ -100,7 +100,7 @@ impl>> Layer { /// when the object does so. pub(crate) fn create_new( &mut self, - host: &impl Runtime, + host: &impl Runtime, id: &impl Path, ) -> Result, StorageError> { let account_path = concat(&self.path, id)?; @@ -118,7 +118,7 @@ impl>> Layer { /// that there is some data in durable storage for the object in this layer. pub(crate) fn get( &self, - host: &impl Runtime, + host: &impl Runtime, id: &impl Path, ) -> Result, StorageError> { let account_path = concat(&self.path, id)?; @@ -136,7 +136,7 @@ impl>> Layer { /// instead. (Use case). pub(crate) fn get_or_create( &self, - _host: &impl Runtime, + _host: &impl Runtime, id: &impl Path, ) -> Result { // We could get rid of the host parameter, but in the future, it would be nice @@ -151,7 +151,7 @@ impl>> Layer { /// storage. pub(crate) fn delete( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, id: &impl Path, ) -> Result<(), StorageError> { let account_path = concat(&self.path, id)?; @@ -163,7 +163,7 @@ impl>> Layer { /// /// Discard the current/self layer. This is the same as cancelling the /// current transaction. - pub(crate) fn discard(self, host: &mut impl Runtime) -> Result<(), StorageError> { + pub(crate) fn discard(self, host: &mut impl Runtime) -> Result<(), StorageError> { if let Ok(Some(_)) = host.store_has(&self.path) { host.store_delete(&self.path).map_err(StorageError::from) } else { diff --git a/src/kernel_sdk/storage/src/storage.rs b/src/kernel_sdk/storage/src/storage.rs index 7ac92b339492..96734cb1f14b 100644 --- a/src/kernel_sdk/storage/src/storage.rs +++ b/src/kernel_sdk/storage/src/storage.rs @@ -13,20 +13,20 @@ use tezos_smart_rollup_host::runtime::Runtime; extern crate alloc; /// Failsafe storage interface -pub struct Storage>> { +pub struct Storage>> { prefix: String, - layers: Vec>, + layers: Vec>, } -impl>> Storage { +impl>> Storage { /// Create the initial storage - pub fn init(name: &impl Path) -> Result { + pub fn init(name: &impl Path) -> Result { let name_bytes = name.as_bytes().to_vec(); Ok(Self { prefix: String::from_utf8(name_bytes) .map_err(|_| StorageError::InvalidAccountsPath)?, - layers: vec![Layer::::with_path(name)], + layers: vec![Layer::::with_path(name)], }) } @@ -34,7 +34,7 @@ impl>> Storage { /// state/transaction and id pub fn get( &self, - host: &impl Runtime, + host: &impl Runtime, id: &impl Path, ) -> Result, StorageError> { if let Some(top_layer) = self.layers.last() { @@ -47,7 +47,7 @@ impl>> Storage { /// Get immutable object in state before any transaction began pub fn get_original( &self, - host: &impl Runtime, + host: &impl Runtime, id: &impl Path, ) -> Result, StorageError> { if let Some(bottom_layer) = self.layers.first() { @@ -60,7 +60,7 @@ impl>> Storage { /// Create a new object as part of current storage state/transaction pub fn create_new( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, id: &impl Path, ) -> Result, StorageError> { if let Some(top_layer) = self.layers.last_mut() { @@ -72,7 +72,7 @@ impl>> Storage { pub fn get_or_create( &self, - host: &impl Runtime, + host: &impl Runtime, id: &impl Path, ) -> Result { if let Some(top_layer) = self.layers.last() { @@ -85,7 +85,7 @@ impl>> Storage { /// Delete an object as part of current storage state/transaction pub fn delete( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, id: &impl Path, ) -> Result<(), StorageError> { if let Some(top_layer) = self.layers.last_mut() { @@ -98,7 +98,7 @@ impl>> Storage { /// Begin a new transaction pub fn begin_transaction( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), StorageError> { let new_layer_index = self.layers.len() + 1; if let Some(top) = self.layers.last() { @@ -115,7 +115,7 @@ impl>> Storage { /// Commit current storage state pub fn commit_transaction( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), StorageError> { if self.layers.len() > 1 { if let (Some(top), Some(last)) = (self.layers.pop(), self.layers.last_mut()) { @@ -131,7 +131,7 @@ impl>> Storage { /// Abort current storage state pub fn rollback_transaction( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), StorageError> { if self.layers.len() > 1 { if let Some(top) = self.layers.pop() { -- GitLab From 97ad11f02aa6c6270eaae06d59e878e087a71b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 22 Oct 2024 13:08:37 +0200 Subject: [PATCH 14/31] Etherlink/Kernel: to_absolute --- etherlink/kernel_evm/evm_evaluation/src/evalhost.rs | 10 ++++++++++ etherlink/kernel_evm/runtime/src/relative_runtime.rs | 10 ++++++++++ etherlink/kernel_evm/runtime/src/runtime.rs | 10 ++++++++++ etherlink/kernel_evm/runtime/src/safe_storage.rs | 10 ++++++++++ src/kernel_sdk/host/src/runtime.rs | 9 +++++++++ 5 files changed, 49 insertions(+) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index ad81e08d90bb..265bd881fea1 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -231,6 +231,16 @@ impl<'a> SdkRuntime for EvalHost<'a> { fn runtime_version(&self) -> Result { self.host.runtime_version() } + + #[inline(always)] + fn to_absolute_ref(&self) -> &impl SdkRuntime { + self.host + } + + #[inline(always)] + fn to_absolute_mut(&mut self) -> &mut impl SdkRuntime { + self.host + } } impl<'a> InternalRuntime for EvalHost<'a> { diff --git a/etherlink/kernel_evm/runtime/src/relative_runtime.rs b/etherlink/kernel_evm/runtime/src/relative_runtime.rs index 0c9df060e592..00b6684fac6a 100644 --- a/etherlink/kernel_evm/runtime/src/relative_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/relative_runtime.rs @@ -235,6 +235,16 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { fn runtime_version(&self) -> Result { self.host.runtime_version() } + + #[inline(always)] + fn to_absolute_ref(&self) -> &impl SdkRuntime { + self.host + } + + #[inline(always)] + fn to_absolute_mut(&mut self) -> &mut impl SdkRuntime { + self.host + } } impl> Verbosity for RelativeRuntime<&mut Host> { diff --git a/etherlink/kernel_evm/runtime/src/runtime.rs b/etherlink/kernel_evm/runtime/src/runtime.rs index 19885084a278..ec93d7cd9ded 100644 --- a/etherlink/kernel_evm/runtime/src/runtime.rs +++ b/etherlink/kernel_evm/runtime/src/runtime.rs @@ -267,6 +267,16 @@ impl, Host: BorrowMut + Borrow, Internal: InternalRunt // need to modify the WASM Runtime. unimplemented!() } + + #[inline(always)] + fn to_absolute_ref(&self) -> &impl SdkRuntime { + self + } + + #[inline(always)] + fn to_absolute_mut(&mut self) -> &mut impl SdkRuntime { + self + } } impl, Host: Borrow + BorrowMut, Internal: InternalRuntime> diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index 1102ecc6f4af..ec6e24a40597 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -239,6 +239,16 @@ impl> SdkRuntime for SafeStorage<&mut Host> { fn runtime_version(&self) -> Result { self.host.runtime_version() } + + #[inline(always)] + fn to_absolute_ref(&self) -> &impl SdkRuntime { + self.host + } + + #[inline(always)] + fn to_absolute_mut(&mut self) -> &mut impl SdkRuntime { + self.host + } } impl> Verbosity for SafeStorage<&mut Host> { diff --git a/src/kernel_sdk/host/src/runtime.rs b/src/kernel_sdk/host/src/runtime.rs index a3e7d3c1f6d0..4d31f66dd184 100644 --- a/src/kernel_sdk/host/src/runtime.rs +++ b/src/kernel_sdk/host/src/runtime.rs @@ -242,6 +242,12 @@ pub trait Runtime { /// The runtime_version the kernel is using. #[cfg(feature = "alloc")] fn runtime_version(&self) -> Result; + + /// Explicit conversion to a runtime working on absolute paths + fn to_absolute_ref<'a> (&'a self) -> &'a impl Runtime; + + /// Explicit conversion to a mutable runtime working on absolute paths + fn to_absolute_mut<'a> (&'a mut self) -> &'a mut impl Runtime; } const REBOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/env/reboot"); @@ -725,6 +731,9 @@ where let version = unsafe { alloc::string::String::from_utf8_unchecked(bytes) }; Ok(version) } + + fn to_absolute_ref<'a>(&'a self) -> &'a impl Runtime {self} + fn to_absolute_mut<'a>(&'a mut self) -> &'a mut impl Runtime {self} } fn check_path_has_value<'a>( -- GitLab From 60acf8d02029bf91ce11116932b8394befbaed45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 12 Nov 2024 12:07:22 +0100 Subject: [PATCH 15/31] Kernel SDK: remove to_absolute --- etherlink/kernel_evm/evm_evaluation/src/evalhost.rs | 10 ---------- etherlink/kernel_evm/runtime/src/relative_runtime.rs | 10 ---------- etherlink/kernel_evm/runtime/src/runtime.rs | 10 ---------- etherlink/kernel_evm/runtime/src/safe_storage.rs | 10 ---------- src/kernel_sdk/host/src/runtime.rs | 9 --------- 5 files changed, 49 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index 265bd881fea1..ad81e08d90bb 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -231,16 +231,6 @@ impl<'a> SdkRuntime for EvalHost<'a> { fn runtime_version(&self) -> Result { self.host.runtime_version() } - - #[inline(always)] - fn to_absolute_ref(&self) -> &impl SdkRuntime { - self.host - } - - #[inline(always)] - fn to_absolute_mut(&mut self) -> &mut impl SdkRuntime { - self.host - } } impl<'a> InternalRuntime for EvalHost<'a> { diff --git a/etherlink/kernel_evm/runtime/src/relative_runtime.rs b/etherlink/kernel_evm/runtime/src/relative_runtime.rs index 00b6684fac6a..0c9df060e592 100644 --- a/etherlink/kernel_evm/runtime/src/relative_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/relative_runtime.rs @@ -235,16 +235,6 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { fn runtime_version(&self) -> Result { self.host.runtime_version() } - - #[inline(always)] - fn to_absolute_ref(&self) -> &impl SdkRuntime { - self.host - } - - #[inline(always)] - fn to_absolute_mut(&mut self) -> &mut impl SdkRuntime { - self.host - } } impl> Verbosity for RelativeRuntime<&mut Host> { diff --git a/etherlink/kernel_evm/runtime/src/runtime.rs b/etherlink/kernel_evm/runtime/src/runtime.rs index ec93d7cd9ded..19885084a278 100644 --- a/etherlink/kernel_evm/runtime/src/runtime.rs +++ b/etherlink/kernel_evm/runtime/src/runtime.rs @@ -267,16 +267,6 @@ impl, Host: BorrowMut + Borrow, Internal: InternalRunt // need to modify the WASM Runtime. unimplemented!() } - - #[inline(always)] - fn to_absolute_ref(&self) -> &impl SdkRuntime { - self - } - - #[inline(always)] - fn to_absolute_mut(&mut self) -> &mut impl SdkRuntime { - self - } } impl, Host: Borrow + BorrowMut, Internal: InternalRuntime> diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index ec6e24a40597..1102ecc6f4af 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -239,16 +239,6 @@ impl> SdkRuntime for SafeStorage<&mut Host> { fn runtime_version(&self) -> Result { self.host.runtime_version() } - - #[inline(always)] - fn to_absolute_ref(&self) -> &impl SdkRuntime { - self.host - } - - #[inline(always)] - fn to_absolute_mut(&mut self) -> &mut impl SdkRuntime { - self.host - } } impl> Verbosity for SafeStorage<&mut Host> { diff --git a/src/kernel_sdk/host/src/runtime.rs b/src/kernel_sdk/host/src/runtime.rs index 4d31f66dd184..a3e7d3c1f6d0 100644 --- a/src/kernel_sdk/host/src/runtime.rs +++ b/src/kernel_sdk/host/src/runtime.rs @@ -242,12 +242,6 @@ pub trait Runtime { /// The runtime_version the kernel is using. #[cfg(feature = "alloc")] fn runtime_version(&self) -> Result; - - /// Explicit conversion to a runtime working on absolute paths - fn to_absolute_ref<'a> (&'a self) -> &'a impl Runtime; - - /// Explicit conversion to a mutable runtime working on absolute paths - fn to_absolute_mut<'a> (&'a mut self) -> &'a mut impl Runtime; } const REBOOT_PATH: RefPath = RefPath::assert_from(b"/kernel/env/reboot"); @@ -731,9 +725,6 @@ where let version = unsafe { alloc::string::String::from_utf8_unchecked(bytes) }; Ok(version) } - - fn to_absolute_ref<'a>(&'a self) -> &'a impl Runtime {self} - fn to_absolute_mut<'a>(&'a mut self) -> &'a mut impl Runtime {self} } fn check_path_has_value<'a>( -- GitLab From 1e53ac9aed2198efa29f1c199eb3ae95006f4e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 14 Jan 2025 14:08:08 +0100 Subject: [PATCH 16/31] Etherlink: adapt Bifrost kernel to dev version of the Sdk --- .../evm_evaluation/src/evalhost.rs | 34 ++--- .../evm_execution/src/account_storage.rs | 76 +++++------ .../evm_execution/src/code_storage.rs | 30 ++--- .../src/fa_bridge/ticket_table.rs | 8 +- .../kernel_bifrost/evm_execution/src/lib.rs | 2 +- .../evm_execution/src/storage.rs | 22 ++-- .../evm_execution/src/withdrawal_counter.rs | 2 +- .../indexable_storage/src/lib.rs | 18 +-- etherlink/kernel_bifrost/kernel/src/apply.rs | 9 +- etherlink/kernel_bifrost/kernel/src/block.rs | 12 +- .../kernel/src/block_in_progress.rs | 16 +-- .../kernel/src/block_storage.rs | 10 +- .../kernel/src/blueprint_storage.rs | 28 ++-- .../kernel/src/delayed_inbox.rs | 2 +- .../kernel/src/evm_node_entrypoint.rs | 4 +- .../kernel/src/fallback_upgrade.rs | 4 +- etherlink/kernel_bifrost/kernel/src/lib.rs | 2 +- .../kernel_bifrost/kernel/src/linked_list.rs | 28 ++-- .../kernel/src/reveal_storage.rs | 8 +- .../kernel_bifrost/kernel/src/storage.rs | 120 +++++++++--------- .../kernel_bifrost/kernel/src/upgrade.rs | 8 +- .../runtime/src/internal_runtime.rs | 4 +- .../runtime/src/mock_internal.rs | 2 +- .../kernel_bifrost/runtime/src/runtime.rs | 82 ++++++++---- .../runtime/src/safe_storage.rs | 50 ++++---- etherlink/kernel_bifrost/storage/src/lib.rs | 30 ++--- 26 files changed, 320 insertions(+), 291 deletions(-) diff --git a/etherlink/kernel_bifrost/evm_evaluation/src/evalhost.rs b/etherlink/kernel_bifrost/evm_evaluation/src/evalhost.rs index a2973b4fa14f..57aae084ffa7 100644 --- a/etherlink/kernel_bifrost/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_bifrost/evm_evaluation/src/evalhost.rs @@ -34,7 +34,7 @@ impl EvalHost { } } -impl SdkRuntime for EvalHost { +impl SdkRuntime for EvalHost { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.write_output(from) @@ -54,12 +54,12 @@ impl SdkRuntime for EvalHost { } #[inline(always)] - fn store_has(&self, path: &T) -> Result, RuntimeError> { + fn store_has>(&self, path: &T) -> Result, RuntimeError> { self.host.store_has(path) } #[inline(always)] - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -69,7 +69,7 @@ impl SdkRuntime for EvalHost { } #[inline(always)] - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -79,12 +79,12 @@ impl SdkRuntime for EvalHost { } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { self.host.store_read_all(path) } #[inline(always)] - fn store_write( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -94,7 +94,7 @@ impl SdkRuntime for EvalHost { } #[inline(always)] - fn store_write_all( + fn store_write_all>( &mut self, path: &T, src: &[u8], @@ -103,25 +103,25 @@ impl SdkRuntime for EvalHost { } #[inline(always)] - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { self.host.store_delete(path) } #[inline(always)] - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete_value>(&mut self, path: &T) -> Result<(), RuntimeError> { self.host.store_delete_value(path) } #[inline(always)] - fn store_count_subkeys(&self, prefix: &T) -> Result { + fn store_count_subkeys>(&self, prefix: &T) -> Result { self.host.store_count_subkeys(prefix) } #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { self.host.store_move(from_path, to_path) } @@ -129,8 +129,8 @@ impl SdkRuntime for EvalHost { #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { self.host.store_copy(from_path, to_path) } @@ -145,7 +145,7 @@ impl SdkRuntime for EvalHost { } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { self.host.store_value_size(path) } @@ -203,7 +203,7 @@ impl SdkRuntime for EvalHost { } impl InternalRuntime for EvalHost { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, tezos_smart_rollup_host::runtime::RuntimeError> { @@ -212,7 +212,7 @@ impl InternalRuntime for EvalHost { } impl ExtendedRuntime for EvalHost { - fn store_get_hash( + fn store_get_hash>( &mut self, path: &T, ) -> Result, tezos_smart_rollup_host::runtime::RuntimeError> { diff --git a/etherlink/kernel_bifrost/evm_execution/src/account_storage.rs b/etherlink/kernel_bifrost/evm_execution/src/account_storage.rs index edd710855a0c..6526309ee4f1 100644 --- a/etherlink/kernel_bifrost/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_bifrost/evm_execution/src/account_storage.rs @@ -6,7 +6,7 @@ //! Ethereum account state and storage use const_decoder::Decoder; -use host::path::{concat, OwnedPath, Path, RefPath}; +use host::path::{concat, force_concat, OwnedPath, Path, RefPath}; use host::runtime::{RuntimeError, ValueType}; use primitive_types::{H160, H256, U256}; use rlp::DecoderError; @@ -120,44 +120,44 @@ pub struct StorageEffect { /// an account. We don't currently require it, and so it's omitted. #[derive(Debug, PartialEq)] pub struct EthereumAccount { - path: OwnedPath, + path: OwnedPath, } -impl From for EthereumAccount { - fn from(path: OwnedPath) -> Self { +impl From> for EthereumAccount { + fn from(path: OwnedPath) -> Self { Self { path } } } /// Path where Ethereum accounts are stored -pub const EVM_ACCOUNTS_PATH: RefPath = +pub const EVM_ACCOUNTS_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/eth_accounts"); /// Path where an account nonce is stored. This should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. -const NONCE_PATH: RefPath = RefPath::assert_from(b"/nonce"); +const NONCE_PATH: RefPath = RefPath::assert_from(b"/nonce"); /// Path where an account balance, ether held, is stored. This should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. -const BALANCE_PATH: RefPath = RefPath::assert_from(b"/balance"); +const BALANCE_PATH: RefPath = RefPath::assert_from(b"/balance"); /// "Internal" accounts - accounts with contract code have a contract code hash. /// This value is computed when the code is stored and kept for future queries. This /// path should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. -const CODE_HASH_PATH: RefPath = RefPath::assert_from(b"/code.hash"); +const CODE_HASH_PATH: RefPath = RefPath::assert_from(b"/code.hash"); /// "Internal" accounts - accounts with contract code, have their code stored here. /// This /// path should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. -const CODE_PATH: RefPath = RefPath::assert_from(b"/code"); +const CODE_PATH: RefPath = RefPath::assert_from(b"/code"); /// The contracts of "internal" accounts have their own storage area. The account /// location prefixed to this path gives the root path (prefix) to where such storage /// values are kept. Each index in durable storage gives one complete path to one /// such 256 bit integer value in storage. -const STORAGE_ROOT_PATH: RefPath = RefPath::assert_from(b"/storage"); +const STORAGE_ROOT_PATH: RefPath = RefPath::assert_from(b"/storage"); /// If a contract tries to read a value from storage and it has previously not written /// anything to this location or if it wrote the default value, then it gets this @@ -182,7 +182,7 @@ const CODE_HASH_BYTES: [u8; WORD_SIZE] = Decoder::Hex pub const CODE_HASH_DEFAULT: H256 = H256(CODE_HASH_BYTES); /// Turn an Ethereum address - a H160 - into a valid path -pub fn account_path(address: &H160) -> Result { +pub fn account_path(address: &H160) -> Result, DurableStorageError> { let path_string = alloc::format!("/{}", hex::encode(address.to_fixed_bytes())); OwnedPath::try_from(path_string).map_err(DurableStorageError::from) } @@ -211,7 +211,7 @@ impl EthereumAccount { /// Get the **nonce** for the Ethereum account. Default value is zero, so an account will /// _always_ have this **nonce**. pub fn nonce(&self, host: &impl Runtime) -> Result { - let path = concat(&self.path, &NONCE_PATH)?; + let path = force_concat(&self.path, &NONCE_PATH)?; read_u64_le_default(host, &path, NONCE_DEFAULT_VALUE) .map_err(AccountStorageError::from) } @@ -223,7 +223,7 @@ impl EthereumAccount { &mut self, host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { - let path = concat(&self.path, &NONCE_PATH)?; + let path = force_concat(&self.path, &NONCE_PATH)?; let old_value = self.nonce(host)?; @@ -241,7 +241,7 @@ impl EthereumAccount { &mut self, host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { - let path = concat(&self.path, &NONCE_PATH)?; + let path = force_concat(&self.path, &NONCE_PATH)?; let old_value = self.nonce(host)?; @@ -258,7 +258,7 @@ impl EthereumAccount { host: &mut impl Runtime, nonce: u64, ) -> Result<(), AccountStorageError> { - let path = concat(&self.path, &NONCE_PATH)?; + let path = force_concat(&self.path, &NONCE_PATH)?; let value_bytes: [u8; NONCE_ENCODING_SIZE] = nonce.to_le_bytes(); @@ -268,7 +268,7 @@ impl EthereumAccount { /// Get the **balance** of an account in Wei held by the account. pub fn balance(&self, host: &impl Runtime) -> Result { - let path = concat(&self.path, &BALANCE_PATH)?; + let path = force_concat(&self.path, &BALANCE_PATH)?; read_u256_le_default(host, &path, BALANCE_DEFAULT_VALUE) .map_err(AccountStorageError::from) } @@ -280,7 +280,7 @@ impl EthereumAccount { host: &mut impl Runtime, amount: U256, ) -> Result<(), AccountStorageError> { - let path = concat(&self.path, &BALANCE_PATH)?; + let path = force_concat(&self.path, &BALANCE_PATH)?; let value = self.balance(host)?; @@ -304,7 +304,7 @@ impl EthereumAccount { host: &mut impl Runtime, amount: U256, ) -> Result { - let path = concat(&self.path, &BALANCE_PATH)?; + let path = force_concat(&self.path, &BALANCE_PATH)?; let value = self.balance(host)?; @@ -326,7 +326,7 @@ impl EthereumAccount { host: &mut impl Runtime, new_balance: U256, ) -> Result<(), AccountStorageError> { - let path = concat(&self.path, &BALANCE_PATH)?; + let path = force_concat(&self.path, &BALANCE_PATH)?; let mut new_balance_bytes: [u8; WORD_SIZE] = [0; WORD_SIZE]; new_balance.to_little_endian(&mut new_balance_bytes); @@ -338,16 +338,16 @@ impl EthereumAccount { /// Get the path to a custom account state section, can be used by precompiles pub fn custom_path( &self, - suffix: &impl Path, - ) -> Result { - concat(&self.path, suffix).map_err(AccountStorageError::from) + suffix: &impl Path, + ) -> Result, AccountStorageError> { + force_concat(&self.path, suffix).map_err(AccountStorageError::from) } /// Get the path to an index in durable storage for an account. - fn storage_path(&self, index: &H256) -> Result { - let storage_path = concat(&self.path, &STORAGE_ROOT_PATH)?; + fn storage_path(&self, index: &H256) -> Result, AccountStorageError> { + let storage_path = force_concat(&self.path, &STORAGE_ROOT_PATH)?; let index_path = path_from_h256(index)?; - concat(&storage_path, &index_path).map_err(AccountStorageError::from) + force_concat(&storage_path, &index_path).map_err(AccountStorageError::from) } /// Clear the entire storage in durable storage for an account. @@ -355,7 +355,7 @@ impl EthereumAccount { &self, host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { - let storage_path = concat(&self.path, &STORAGE_ROOT_PATH)?; + let storage_path = force_concat(&self.path, &STORAGE_ROOT_PATH)?; if host.store_has(&storage_path)?.is_some() { host.store_delete(&storage_path) .map_err(AccountStorageError::from)? @@ -438,7 +438,7 @@ impl EthereumAccount { /// Find whether the account has any code associated with it. pub fn code_exists(&self, host: &impl Runtime) -> Result { - let path = concat(&self.path, &CODE_HASH_PATH)?; + let path = force_concat(&self.path, &CODE_HASH_PATH)?; match host.store_has(&path) { Ok(Some(ValueType::Value | ValueType::ValueWithSubtree)) => Ok(true), @@ -454,7 +454,7 @@ impl EthereumAccount { // There is a possibility here to migrate lazily all code in order // to have all legacy contract uses the new code storage. pub fn code(&self, host: &impl Runtime) -> Result, AccountStorageError> { - let path = concat(&self.path, &CODE_PATH)?; + let path = force_concat(&self.path, &CODE_PATH)?; // If we ever do the lazy migration of code for account // (i.e. moving code from account to code_storage) then this @@ -472,7 +472,7 @@ impl EthereumAccount { /// Get the hash of the code associated with an account. This value is computed and /// stored when the code of a contract is set. pub fn code_hash(&self, host: &impl Runtime) -> Result { - let path = concat(&self.path, &CODE_HASH_PATH)?; + let path = force_concat(&self.path, &CODE_HASH_PATH)?; read_h256_be_default(host, &path, CODE_HASH_DEFAULT) .map_err(AccountStorageError::from) } @@ -480,7 +480,7 @@ impl EthereumAccount { /// Get the size of a contract in number of bytes used for opcodes. This value is /// computed and stored when the code of a contract is set. pub fn code_size(&self, host: &impl Runtime) -> Result { - let path = concat(&self.path, &CODE_PATH)?; + let path = force_concat(&self.path, &CODE_PATH)?; // If we ever do the lazy migration of code for account // (i.e. moving code from account to code_storage) then this // would be dead code. @@ -507,7 +507,7 @@ impl EthereumAccount { } else { let code_hash = code_storage::CodeStorage::add(host, code)?; let code_hash_bytes: [u8; WORD_SIZE] = code_hash.into(); - let code_hash_path = concat(&self.path, &CODE_HASH_PATH)?; + let code_hash_path = force_concat(&self.path, &CODE_HASH_PATH)?; host.store_write_all(&code_hash_path, &code_hash_bytes) .map_err(AccountStorageError::from) } @@ -518,7 +518,7 @@ impl EthereumAccount { &mut self, host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { - let code_hash_path = concat(&self.path, &CODE_HASH_PATH)?; + let code_hash_path = force_concat(&self.path, &CODE_HASH_PATH)?; if let Some(ValueType::Value | ValueType::ValueWithSubtree) = host.store_has(&code_hash_path)? @@ -526,7 +526,7 @@ impl EthereumAccount { host.store_delete(&code_hash_path)? } - let code_path = concat(&self.path, &CODE_PATH)?; + let code_path = force_concat(&self.path, &CODE_PATH)?; if let Some(ValueType::Value | ValueType::ValueWithSubtree) = host.store_has(&code_path)? @@ -542,12 +542,12 @@ impl EthereumAccount { } /// The type of the storage API for accessing the Ethereum World State. -pub type EthereumAccountStorage = Storage; +pub type EthereumAccountStorage = Storage; /// Get the storage API for accessing the Ethereum World State and do transactions /// on it. pub fn init_account_storage() -> Result { - Storage::::init(&EVM_ACCOUNTS_PATH) + Storage::::init(&EVM_ACCOUNTS_PATH) .map_err(AccountStorageError::from) } @@ -1241,12 +1241,12 @@ mod test { let code_hash_bytes: [u8; WORD_SIZE] = sample_code_hash.into(); let code_hash_path = - concat(&a1.path, &CODE_HASH_PATH).expect("Could not get code hash path"); + force_concat(&a1.path, &CODE_HASH_PATH).expect("Could not get code hash path"); host.store_write_all(&code_hash_path, &code_hash_bytes) .expect("Could not write code hash into code hash path"); - let code_path = concat(&a1.path, &CODE_PATH).expect("Could not get code path"); + let code_path = force_concat(&a1.path, &CODE_PATH).expect("Could not get code path"); host.store_write_all(&code_path, &sample_code) .expect("Could not write code into code path"); @@ -1261,7 +1261,7 @@ mod test { .expect("Could not get account") .expect("Account does not exist"); - let code_path = concat(&a1.path, &CODE_PATH).expect("Could not get code path"); + let code_path = force_concat(&a1.path, &CODE_PATH).expect("Could not get code path"); let code = host .store_read_all(&code_path) diff --git a/etherlink/kernel_bifrost/evm_execution/src/code_storage.rs b/etherlink/kernel_bifrost/evm_execution/src/code_storage.rs index 6474eb67edd4..a702c2ffa667 100644 --- a/etherlink/kernel_bifrost/evm_execution/src/code_storage.rs +++ b/etherlink/kernel_bifrost/evm_execution/src/code_storage.rs @@ -5,22 +5,22 @@ //! Ethereum code storage -use host::path::{concat, OwnedPath, RefPath}; +use host::path::{force_concat, OwnedPath, RefPath}; use primitive_types::{H256, U256}; use tezos_evm_runtime::runtime::Runtime; use tezos_storage::helpers::bytes_hash; use tezos_storage::{error::Error as GenStorageError, read_u64_le, write_u64_le}; /// Path where Ethereum account's code are stored -const EVM_CODES_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/eth_codes"); +const EVM_CODES_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/eth_codes"); /// Path to the number of accounts to use a particular code -const REFERENCE_PATH: RefPath = RefPath::assert_from(b"/ref_count"); +const REFERENCE_PATH: RefPath = RefPath::assert_from(b"/ref_count"); /// Path to the code -const CODE_PATH: RefPath = RefPath::assert_from(b"/code"); +const CODE_PATH: RefPath = RefPath::assert_from(b"/code"); -fn code_hash_path(code_hash: &H256) -> Result { +fn code_hash_path(code_hash: &H256) -> Result, GenStorageError> { let code_hash_hex = hex::encode(code_hash); let code_hash_path_string = format!("/{}", code_hash_hex); OwnedPath::try_from(code_hash_path_string).map_err(Into::into) @@ -28,11 +28,11 @@ fn code_hash_path(code_hash: &H256) -> Result { #[derive(Debug, PartialEq)] pub struct CodeStorage { - path: OwnedPath, + path: OwnedPath, } -impl From for CodeStorage { - fn from(path: OwnedPath) -> Self { +impl From> for CodeStorage { + fn from(path: OwnedPath) -> Self { Self { path } } } @@ -40,7 +40,7 @@ impl From for CodeStorage { impl CodeStorage { fn new(code_hash: &H256) -> Result { let code_hash_path = code_hash_path(code_hash)?; - let path = concat(&EVM_CODES_PATH, &code_hash_path)?; + let path = force_concat(&EVM_CODES_PATH, &code_hash_path)?; Ok(Self { path }) } @@ -50,7 +50,7 @@ impl CodeStorage { } fn get_ref_count(&self, host: &mut impl Runtime) -> Result { - let reference_path = concat(&self.path, &REFERENCE_PATH)?; + let reference_path = force_concat(&self.path, &REFERENCE_PATH)?; read_u64_le(host, &reference_path).or(Ok(0u64)) } @@ -59,7 +59,7 @@ impl CodeStorage { host: &mut impl Runtime, number_ref: u64, ) -> Result<(), GenStorageError> { - let reference_path = concat(&self.path, &REFERENCE_PATH)?; + let reference_path = force_concat(&self.path, &REFERENCE_PATH)?; write_u64_le(host, &reference_path, number_ref)?; Ok(()) } @@ -90,7 +90,7 @@ impl CodeStorage { let code_hash: H256 = bytes_hash(bytecode); let code = Self::new(&code_hash)?; if !code.exists(host)? { - let code_path = concat(&code.path, &CODE_PATH)?; + let code_path = force_concat(&code.path, &CODE_PATH)?; host.store_write_all(&code_path, bytecode)?; }; code.increment_code_usage(host)?; @@ -118,7 +118,7 @@ impl CodeStorage { ) -> Result, GenStorageError> { let code = Self::new(code_hash)?; if code.exists(host)? { - let code1_path = concat(&code.path, &CODE_PATH)?; + let code1_path = force_concat(&code.path, &CODE_PATH)?; host.store_read_all(&code1_path).map_err(Into::into) } else { Ok(vec![]) @@ -131,7 +131,7 @@ impl CodeStorage { ) -> Result { let code = Self::new(code_hash)?; if code.exists(host)? { - let code_path = concat(&code.path, &CODE_PATH)?; + let code_path = force_concat(&code.path, &CODE_PATH)?; host.store_value_size(&code_path) .map(U256::from) .map_err(Into::into) @@ -178,7 +178,7 @@ mod test { CodeStorage::add(&mut host, &code).expect("Could not create code storage"); let code_storage = CodeStorage::new(&code_hash).expect("Could not find code storage"); - let ref_path = concat(&code_storage.path, &REFERENCE_PATH).unwrap(); + let ref_path = force_concat(&code_storage.path, &REFERENCE_PATH).unwrap(); let ref_count = read_u64_le(&host, &ref_path).expect("reference count not found"); assert_eq!(ref_count, 1u64); diff --git a/etherlink/kernel_bifrost/evm_execution/src/fa_bridge/ticket_table.rs b/etherlink/kernel_bifrost/evm_execution/src/fa_bridge/ticket_table.rs index 119b9fa7886f..b0a67ec936d0 100644 --- a/etherlink/kernel_bifrost/evm_execution/src/fa_bridge/ticket_table.rs +++ b/etherlink/kernel_bifrost/evm_execution/src/fa_bridge/ticket_table.rs @@ -10,11 +10,11 @@ use crate::account_storage::{account_path, AccountStorageError, EthereumAccount}; use primitive_types::{H160, H256, U256}; use tezos_evm_runtime::runtime::Runtime; -use tezos_smart_rollup_host::path::{concat, OwnedPath, RefPath}; +use tezos_smart_rollup_host::path::{concat, force_concat, OwnedPath, RefPath}; use tezos_storage::{path_from_h256, read_u256_le_default, write_u256_le}; /// Path where global ticket table is stored -const TICKET_TABLE_PATH: RefPath = RefPath::assert_from(b"/ticket_table"); +const TICKET_TABLE_PATH: RefPath = RefPath::assert_from(b"/ticket_table"); pub trait TicketTable { /// Increases ticket balance @@ -39,9 +39,9 @@ pub trait TicketTable { pub(crate) fn ticket_balance_path( ticket_hash: &H256, address: &H160, -) -> Result { +) -> Result, AccountStorageError> { let suffix = concat(&path_from_h256(ticket_hash)?, &account_path(address)?)?; - concat(&TICKET_TABLE_PATH, &suffix).map_err(Into::into) + force_concat(&TICKET_TABLE_PATH, &suffix).map_err(Into::into) } impl TicketTable for EthereumAccount { diff --git a/etherlink/kernel_bifrost/evm_execution/src/lib.rs b/etherlink/kernel_bifrost/evm_execution/src/lib.rs index efff45a85120..ca2b730f932c 100755 --- a/etherlink/kernel_bifrost/evm_execution/src/lib.rs +++ b/etherlink/kernel_bifrost/evm_execution/src/lib.rs @@ -419,7 +419,7 @@ where Ok(None) } } -pub const NATIVE_TOKEN_TICKETER_PATH: RefPath = +pub const NATIVE_TOKEN_TICKETER_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/ticketer"); /// Reads the ticketer address set by the installer, if any, encoded in b58. diff --git a/etherlink/kernel_bifrost/evm_execution/src/storage.rs b/etherlink/kernel_bifrost/evm_execution/src/storage.rs index 11f5c431bca8..dde7f349df8f 100644 --- a/etherlink/kernel_bifrost/evm_execution/src/storage.rs +++ b/etherlink/kernel_bifrost/evm_execution/src/storage.rs @@ -20,12 +20,12 @@ pub mod tracer { use crate::trace::CallTrace; use crate::trace::StructLog; - const EVM_TRACE: RefPath = RefPath::assert_from(b"/evm/trace"); + const EVM_TRACE: RefPath = RefPath::assert_from(b"/evm/trace"); - const GAS: RefPath = RefPath::assert_from(b"/gas"); - const FAILED: RefPath = RefPath::assert_from(b"/failed"); - const RETURN_VALUE: RefPath = RefPath::assert_from(b"/return_value"); - const STRUCT_LOGS: RefPath = RefPath::assert_from(b"/struct_logs"); + const GAS: RefPath = RefPath::assert_from(b"/gas"); + const FAILED: RefPath = RefPath::assert_from(b"/failed"); + const RETURN_VALUE: RefPath = RefPath::assert_from(b"/return_value"); + const STRUCT_LOGS: RefPath = RefPath::assert_from(b"/struct_logs"); #[derive(Eq, Error, Debug, PartialEq)] pub enum Error { @@ -39,8 +39,8 @@ pub mod tracer { pub fn trace_tx_path( hash: &Option, - field: &RefPath, - ) -> Result { + field: &RefPath, + ) -> Result, Error> { let trace_tx_path = match hash { None => EVM_TRACE.into(), Some(hash) => { @@ -50,7 +50,7 @@ pub mod tracer { concat(&EVM_TRACE, &tx_path)? } }; - concat(&trace_tx_path, field).map_err(Error::PathError) + force_concat(&trace_tx_path, field).map_err(Error::PathError) } pub fn store_trace_gas( @@ -101,7 +101,7 @@ pub mod tracer { Ok(()) } - const CALL_TRACE: RefPath = RefPath::assert_from(b"/call_trace"); + const CALL_TRACE: RefPath = RefPath::assert_from(b"/call_trace"); pub fn store_call_trace( host: &mut Host, @@ -167,7 +167,7 @@ pub mod blocks { /// Get block hash by block number. pub fn get_block_hash( - host: &impl Runtime, + host: &impl Runtime, block_number: U256, ) -> Result { let block_path = to_block_hash_path(block_number)?; @@ -180,7 +180,7 @@ pub mod blocks { } } - fn to_block_hash_path(block_number: U256) -> Result { + fn to_block_hash_path(block_number: U256) -> Result, EvmBlockStorageError> { let path: Vec = format!("/evm/world_state/indexes/blocks/{}", block_number).into(); let owned_path = OwnedPath::try_from(path)?; diff --git a/etherlink/kernel_bifrost/evm_execution/src/withdrawal_counter.rs b/etherlink/kernel_bifrost/evm_execution/src/withdrawal_counter.rs index d40d220b32bb..2620b6dff5ed 100644 --- a/etherlink/kernel_bifrost/evm_execution/src/withdrawal_counter.rs +++ b/etherlink/kernel_bifrost/evm_execution/src/withdrawal_counter.rs @@ -19,7 +19,7 @@ use tezos_storage::{read_u256_le_default, write_u256_le}; use crate::account_storage::{AccountStorageError, EthereumAccount}; /// Path where withdrawal counter is stored (relative to account) -pub const WITHDRAWAL_COUNTER_PATH: RefPath = RefPath::assert_from(b"/withdrawal_counter"); +pub const WITHDRAWAL_COUNTER_PATH: RefPath = RefPath::assert_from(b"/withdrawal_counter"); pub trait WithdrawalCounter { /// Returns current withdrawal ID from the storage (or 0 if it's not initialized) diff --git a/etherlink/kernel_bifrost/indexable_storage/src/lib.rs b/etherlink/kernel_bifrost/indexable_storage/src/lib.rs index 383d87337623..7a827eb34429 100644 --- a/etherlink/kernel_bifrost/indexable_storage/src/lib.rs +++ b/etherlink/kernel_bifrost/indexable_storage/src/lib.rs @@ -7,13 +7,13 @@ use rlp::DecoderError; use tezos_evm_logging::log; use tezos_evm_logging::Level::Error; use tezos_evm_runtime::runtime::Runtime; -use tezos_smart_rollup_host::path::{concat, OwnedPath, PathError, RefPath}; +use tezos_smart_rollup_host::path::{force_concat, OwnedPath, PathError, RefPath}; use tezos_smart_rollup_host::runtime::RuntimeError; use tezos_smart_rollup_storage::StorageError; use tezos_storage::{error::Error as GenStorageError, read_u64_le, write_u64_le}; use thiserror::Error; -const LENGTH: RefPath = RefPath::assert_from(b"/length"); +const LENGTH: RefPath = RefPath::assert_from(b"/length"); /// An indexable storage is a push-only mapping between increasing integers to /// bytes. It can serve as a replacement for the combination of the host @@ -22,7 +22,7 @@ pub struct IndexableStorage { /// An indexable storage is stored at a given path and consists of: /// - `/length`: the number of keys /// - `/` where keys are from `0` to `length - 1` - pub path: OwnedPath, + pub path: OwnedPath, } #[derive(Error, Debug, Eq, PartialEq)] @@ -58,20 +58,20 @@ impl From for IndexableStorageError { } impl IndexableStorage { - pub fn new(path: &RefPath<'_>) -> Result { + pub fn new(path: &RefPath<'_, true>) -> Result { Ok(Self { path: path.into() }) } - pub fn new_owned_path(path: OwnedPath) -> Self { + pub fn new_owned_path(path: OwnedPath) -> Self { Self { path } } - fn value_path(&self, index: u64) -> Result { + fn value_path(&self, index: u64) -> Result, PathError> { let index_as_path: Vec = format!("/{}", index).into(); // The key being an integer value, it will always be valid as a path, // `assert_from` cannot fail. let index_subkey = RefPath::assert_from(&index_as_path); - concat(&self.path, &index_subkey) + force_concat(&self.path, &index_subkey) } fn store_index( @@ -89,7 +89,7 @@ impl IndexableStorage { &self, host: &mut Host, ) -> Result { - let path = concat(&self.path, &LENGTH)?; + let path = force_concat(&self.path, &LENGTH)?; let length = read_u64_le(host, &path).unwrap_or(0); write_u64_le(host, &path, length + 1)?; Ok(length) @@ -102,7 +102,7 @@ impl IndexableStorage { &self, host: &Host, ) -> Result { - let path = concat(&self.path, &LENGTH)?; + let path = force_concat(&self.path, &LENGTH)?; match read_u64_le(host, &path) { Ok(l) => Ok(l), Err( diff --git a/etherlink/kernel_bifrost/kernel/src/apply.rs b/etherlink/kernel_bifrost/kernel/src/apply.rs index af0d9971a1fa..b17b6338a7ba 100644 --- a/etherlink/kernel_bifrost/kernel/src/apply.rs +++ b/etherlink/kernel_bifrost/kernel/src/apply.rs @@ -512,9 +512,12 @@ fn apply_fa_deposit( })) } -pub const WITHDRAWAL_OUTBOX_QUEUE: RefPath = +pub const WITHDRAWAL_OUTBOX_QUEUE: RefPath = RefPath::assert_from(b"/evm/world_state/__outbox_queue"); +pub const WITHDRAWAL_OUTBOX_QUEUE_META: RefPath = + RefPath::assert_from(b"/evm/world_state/__outbox_queue/meta"); + pub struct ExecutionInfo { pub receipt_info: TransactionReceiptInfo, pub object_info: TransactionObjectInfo, @@ -539,7 +542,7 @@ impl From> for ExecutionResult { #[allow(clippy::too_many_arguments)] pub fn handle_transaction_result( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, block_constants: &BlockConstants, transaction: &Transaction, index: u32, @@ -599,7 +602,7 @@ pub fn handle_transaction_result( #[allow(clippy::too_many_arguments)] pub fn apply_transaction( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, transaction: &Transaction, diff --git a/etherlink/kernel_bifrost/kernel/src/block.rs b/etherlink/kernel_bifrost/kernel/src/block.rs index 1d3e53687255..e855148db41e 100644 --- a/etherlink/kernel_bifrost/kernel/src/block.rs +++ b/etherlink/kernel_bifrost/kernel/src/block.rs @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT use crate::apply::{ - apply_transaction, ExecutionInfo, ExecutionResult, WITHDRAWAL_OUTBOX_QUEUE, + apply_transaction, ExecutionInfo, ExecutionResult, WITHDRAWAL_OUTBOX_QUEUE, WITHDRAWAL_OUTBOX_QUEUE_META, }; use crate::block_storage; use crate::blueprint_storage::{drop_blueprint, read_next_blueprint}; @@ -76,7 +76,7 @@ pub enum ComputationResult { #[allow(clippy::too_many_arguments)] fn compute( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, block_in_progress: &mut BlockInProgress, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, @@ -252,7 +252,7 @@ fn next_bip_from_blueprints( #[allow(clippy::too_many_arguments)] fn compute_bip( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, mut block_in_progress: BlockInProgress, current_block_number: &mut U256, current_block_parent_hash: &mut H256, @@ -351,7 +351,7 @@ fn clean_delayed_transactions( fn promote_block( safe_host: &mut SafeStorage<&mut Host>, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, block_in_progress: bool, number: U256, config: &mut Configuration, @@ -386,7 +386,7 @@ fn promote_block( Ok(()) } -const AT_MOST_ONE_BLOCK: RefPath = RefPath::assert_from(b"/__at_most_one_block"); +const AT_MOST_ONE_BLOCK: RefPath = RefPath::assert_from(b"/__at_most_one_block"); pub fn produce( host: &mut Host, @@ -424,7 +424,7 @@ pub fn produce( let at_most_one_block = host.store_has(&AT_MOST_ONE_BLOCK)?.is_some(); let mut safe_host = SafeStorage { host }; - let outbox_queue = OutboxQueue::new(&WITHDRAWAL_OUTBOX_QUEUE, u32::MAX)?; + let outbox_queue = OutboxQueue::new(&WITHDRAWAL_OUTBOX_QUEUE, &WITHDRAWAL_OUTBOX_QUEUE_META, u32::MAX)?; let precompiles = precompiles::precompile_set::>(config.enable_fa_bridge); diff --git a/etherlink/kernel_bifrost/kernel/src/block_in_progress.rs b/etherlink/kernel_bifrost/kernel/src/block_in_progress.rs index ea5ed9ee5ff9..a7d806b48bb0 100644 --- a/etherlink/kernel_bifrost/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_bifrost/kernel/src/block_in_progress.rs @@ -28,7 +28,7 @@ use tezos_ethereum::Bloom; use tezos_evm_logging::{log, Level::*}; use tezos_evm_runtime::runtime::Runtime; use tezos_smart_rollup_encoding::timestamp::Timestamp; -use tezos_smart_rollup_host::path::{concat, RefPath}; +use tezos_smart_rollup_host::path::{force_concat, RefPath}; #[derive(Debug, PartialEq, Clone)] /// Container for all data needed during block computation @@ -313,7 +313,7 @@ impl BlockInProgress { fn safe_store_get_hash( host: &mut Host, - path: &RefPath, + path: &RefPath, ) -> Result, anyhow::Error> { match host.store_get_hash(path) { Ok(hash) => Ok(hash), @@ -321,8 +321,8 @@ impl BlockInProgress { } } - const RECEIPTS: RefPath<'static> = RefPath::assert_from(b"/receipts"); - const RECEIPTS_PREVIOUS_ROOT: RefPath<'static> = + const RECEIPTS: RefPath<'static, true> = RefPath::assert_from(b"/receipts"); + const RECEIPTS_PREVIOUS_ROOT: RefPath<'static, true> = RefPath::assert_from(b"/receipts/previous_root"); fn receipts_root( @@ -335,7 +335,7 @@ impl BlockInProgress { } else { for hash in &self.valid_txs { let receipt_path = receipt_path(hash)?; - let new_receipt_path = concat(&Self::RECEIPTS, &receipt_path)?; + let new_receipt_path = force_concat(&Self::RECEIPTS, &receipt_path)?; host.store_copy(&receipt_path, &new_receipt_path)?; } host.store_write_all(&Self::RECEIPTS_PREVIOUS_ROOT, &previous_receipts_root)?; @@ -345,8 +345,8 @@ impl BlockInProgress { } } - const OBJECTS: RefPath<'static> = RefPath::assert_from(b"/objects"); - const OBJECTS_PREVIOUS_ROOT: RefPath<'static> = + const OBJECTS: RefPath<'static, true> = RefPath::assert_from(b"/objects"); + const OBJECTS_PREVIOUS_ROOT: RefPath<'static, true> = RefPath::assert_from(b"/objects/previous_root"); fn transactions_root( @@ -359,7 +359,7 @@ impl BlockInProgress { } else { for hash in &self.valid_txs { let object_path = object_path(hash)?; - let new_object_path = concat(&Self::OBJECTS, &object_path)?; + let new_object_path = force_concat(&Self::OBJECTS, &object_path)?; host.store_copy(&object_path, &new_object_path)?; } host.store_write_all( diff --git a/etherlink/kernel_bifrost/kernel/src/block_storage.rs b/etherlink/kernel_bifrost/kernel/src/block_storage.rs index b423f3565b24..7af312ee37c6 100644 --- a/etherlink/kernel_bifrost/kernel/src/block_storage.rs +++ b/etherlink/kernel_bifrost/kernel/src/block_storage.rs @@ -16,18 +16,18 @@ use tezos_storage::{read_h256_be, read_u256_le, write_h256_be, write_u256_le}; mod path { use super::*; - const PATH: RefPath = RefPath::assert_from(b"/evm/world_state/blocks"); + const PATH: RefPath = RefPath::assert_from(b"/evm/world_state/blocks"); - pub const CURRENT_NUMBER: RefPath = + pub const CURRENT_NUMBER: RefPath = RefPath::assert_from(b"/evm/world_state/blocks/current/number"); - pub const CURRENT_HASH: RefPath = + pub const CURRENT_HASH: RefPath = RefPath::assert_from(b"/evm/world_state/blocks/current/hash"); - pub const INDEXES: RefPath = RefPath::assert_from(b"/evm/world_state/indexes/blocks"); + pub const INDEXES: RefPath = RefPath::assert_from(b"/evm/world_state/indexes/blocks"); /// Path to the block in the storage. The path to the block is /// indexed by its hash. - pub fn path(hash: H256) -> anyhow::Result { + pub fn path(hash: H256) -> anyhow::Result> { let hash = hex::encode(hash); let raw_hash_path: Vec = format!("/{}", &hash).into(); let hash_path = OwnedPath::try_from(raw_hash_path)?; diff --git a/etherlink/kernel_bifrost/kernel/src/blueprint_storage.rs b/etherlink/kernel_bifrost/kernel/src/blueprint_storage.rs index 690213da5cc7..78bdcc658c8b 100644 --- a/etherlink/kernel_bifrost/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_bifrost/kernel/src/blueprint_storage.rs @@ -29,9 +29,9 @@ use tezos_storage::{ error::Error as GenStorageError, read_rlp, store_read_slice, store_rlp, }; -pub const EVM_BLUEPRINTS: RefPath = RefPath::assert_from(b"/evm/blueprints"); +pub const EVM_BLUEPRINTS: RefPath = RefPath::assert_from(b"/evm/blueprints"); -const EVM_BLUEPRINT_NB_CHUNKS: RefPath = RefPath::assert_from(b"/nb_chunks"); +const EVM_BLUEPRINT_NB_CHUNKS: RefPath = RefPath::assert_from(b"/nb_chunks"); /// The store representation of a blueprint. /// It's designed to support storing sequencer blueprints, @@ -87,32 +87,32 @@ impl Decodable for StoreBlueprint { } } -pub fn blueprint_path(number: U256) -> Result { +pub fn blueprint_path(number: U256) -> Result, StorageError> { let number_as_path: Vec = format!("/{}", number).into(); // The key being an integer value, it will always be valid as a path, // `assert_from` cannot fail. let number_subkey = RefPath::assert_from(&number_as_path); - concat(&EVM_BLUEPRINTS, &number_subkey).map_err(StorageError::from) + force_concat(&EVM_BLUEPRINTS, &number_subkey).map_err(StorageError::from) } fn blueprint_chunk_path( - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, chunk_index: u16, -) -> Result { +) -> Result, StorageError> { let chunk_index_as_path: Vec = format!("/{}", chunk_index).into(); let chunk_index_subkey = RefPath::assert_from(&chunk_index_as_path); - concat(blueprint_path, &chunk_index_subkey).map_err(StorageError::from) + force_concat(blueprint_path, &chunk_index_subkey).map_err(StorageError::from) } fn blueprint_nb_chunks_path( - blueprint_path: &OwnedPath, -) -> Result { - concat(blueprint_path, &EVM_BLUEPRINT_NB_CHUNKS).map_err(StorageError::from) + blueprint_path: &OwnedPath, +) -> Result, StorageError> { + force_concat(blueprint_path, &EVM_BLUEPRINT_NB_CHUNKS).map_err(StorageError::from) } fn read_blueprint_nb_chunks( host: &Host, - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, ) -> Result { let path = blueprint_nb_chunks_path(blueprint_path)?; let mut buffer = [0u8; 2]; @@ -122,7 +122,7 @@ fn read_blueprint_nb_chunks( fn store_blueprint_nb_chunks( host: &mut Host, - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, nb_chunks: u16, ) -> Result<(), Error> { let path = blueprint_nb_chunks_path(blueprint_path)?; @@ -345,7 +345,7 @@ fn parse_and_validate_blueprint( fn invalidate_blueprint( host: &mut Host, - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, error: &BlueprintValidity, ) -> Result<(), RuntimeError> { log!( @@ -361,7 +361,7 @@ fn invalidate_blueprint( fn read_all_chunks_and_validate( host: &mut Host, - blueprint_path: &OwnedPath, + blueprint_path: &OwnedPath, nb_chunks: u16, config: &mut Configuration, ) -> anyhow::Result<(Option, usize)> { diff --git a/etherlink/kernel_bifrost/kernel/src/delayed_inbox.rs b/etherlink/kernel_bifrost/kernel/src/delayed_inbox.rs index a5a97bc54cf3..d5181b793d09 100644 --- a/etherlink/kernel_bifrost/kernel/src/delayed_inbox.rs +++ b/etherlink/kernel_bifrost/kernel/src/delayed_inbox.rs @@ -24,7 +24,7 @@ use tezos_smart_rollup_host::path::RefPath; pub struct DelayedInbox(LinkedList); -pub const DELAYED_INBOX_PATH: RefPath = RefPath::assert_from(b"/evm/delayed-inbox"); +pub const DELAYED_INBOX_PATH: RefPath = RefPath::assert_from(b"/evm/delayed-inbox"); // Maximum number of transaction included in a blueprint when // forcing timed-out transactions from the delayed inbox. diff --git a/etherlink/kernel_bifrost/kernel/src/evm_node_entrypoint.rs b/etherlink/kernel_bifrost/kernel/src/evm_node_entrypoint.rs index f2910ac177aa..7bd4884e49d0 100644 --- a/etherlink/kernel_bifrost/kernel/src/evm_node_entrypoint.rs +++ b/etherlink/kernel_bifrost/kernel/src/evm_node_entrypoint.rs @@ -13,10 +13,10 @@ use tezos_ethereum::rlp_helpers::FromRlpBytes; use tezos_evm_runtime::{internal_runtime::InternalRuntime, runtime::KernelHost}; use tezos_smart_rollup_host::{path::RefPath, runtime::Runtime}; -const DELAYED_INPUT_PATH: RefPath = RefPath::assert_from(b"/__delayed_input"); +const DELAYED_INPUT_PATH: RefPath = RefPath::assert_from(b"/__delayed_input"); pub fn populate_delayed_inbox< - Host: tezos_smart_rollup_host::runtime::Runtime + InternalRuntime, + Host: tezos_smart_rollup_host::runtime::Runtime + InternalRuntime, >( sdk_host: &mut Host, ) { diff --git a/etherlink/kernel_bifrost/kernel/src/fallback_upgrade.rs b/etherlink/kernel_bifrost/kernel/src/fallback_upgrade.rs index d1a8caecfb6f..170c7fce4ac8 100644 --- a/etherlink/kernel_bifrost/kernel/src/fallback_upgrade.rs +++ b/etherlink/kernel_bifrost/kernel/src/fallback_upgrade.rs @@ -9,10 +9,10 @@ use tezos_smart_rollup_host::{path::RefPath, runtime::RuntimeError, KERNEL_BOOT_ use crate::upgrade::KERNEL_ROOT_HASH; -const BACKUP_KERNEL_BOOT_PATH: RefPath = +const BACKUP_KERNEL_BOOT_PATH: RefPath = RefPath::assert_from(b"/__backup_kernel/boot.wasm"); -const BACKUP_KERNEL_ROOT_HASH: RefPath = +const BACKUP_KERNEL_ROOT_HASH: RefPath = RefPath::assert_from(b"/__backup_kernel/root_hash"); pub fn backup_current_kernel(host: &mut impl Runtime) -> Result<(), RuntimeError> { diff --git a/etherlink/kernel_bifrost/kernel/src/lib.rs b/etherlink/kernel_bifrost/kernel/src/lib.rs index 426aaa40c4b3..0c3fedba2aee 100644 --- a/etherlink/kernel_bifrost/kernel/src/lib.rs +++ b/etherlink/kernel_bifrost/kernel/src/lib.rs @@ -305,7 +305,7 @@ pub fn main(host: &mut Host) -> Result<(), anyhow::Error> { Ok(()) } -pub fn kernel_loop( +pub fn kernel_loop + InternalRuntime>( host: &mut Host, ) { // In order to setup the temporary directory, we need to move something diff --git a/etherlink/kernel_bifrost/kernel/src/linked_list.rs b/etherlink/kernel_bifrost/kernel/src/linked_list.rs index 8ec7d95f9c9a..3a3078670768 100644 --- a/etherlink/kernel_bifrost/kernel/src/linked_list.rs +++ b/etherlink/kernel_bifrost/kernel/src/linked_list.rs @@ -22,7 +22,7 @@ where Elt: Encodable + Decodable + Clone, { /// Absolute path to queue - path: OwnedPath, + path: OwnedPath, /// None indicates an empty list pointers: Option>, _type: PhantomData<(Id, Elt)>, @@ -50,7 +50,7 @@ struct Pointer { fn decode_path( it: &mut RlpIterator, field_name: &'static str, -) -> Result { +) -> Result, rlp::DecoderError> { let path: Vec = decode_field(&next(it)?, field_name)?; OwnedPath::try_from(path).map_err(|_| DecoderError::Custom("not a path")) } @@ -150,7 +150,7 @@ where impl, Elt: Encodable + Decodable> Pointer { - fn pointer_path(id: &Id, prefix: &impl Path) -> Result { + fn pointer_path(id: &Id, prefix: &impl Path) -> Result> { let path = hex::encode(id); let path: Vec = format!("/{}/pointer", path).into(); let path = OwnedPath::try_from(path)?; @@ -161,12 +161,12 @@ impl, Elt: Encodable + Decodable> /// Path to the pointer /// /// This path is used when you want to read a pointer or to remove it. - fn path(&self, prefix: &impl Path) -> Result { + fn path(&self, prefix: &impl Path) -> Result> { Self::pointer_path(&self.id, prefix) } /// Path to the data held by the pointer. - fn data_path(&self, prefix: &impl Path) -> Result { + fn data_path(&self, prefix: &impl Path) -> Result> { let path = hex::encode(&self.id); let path: Vec = format!("/{}/data", path).into(); let path = OwnedPath::try_from(path)?; @@ -177,25 +177,25 @@ impl, Elt: Encodable + Decodable> fn save_data( &self, host: &mut impl Runtime, - prefix: &impl Path, + prefix: &impl Path, data: &Elt, ) -> Result<()> { let path = self.data_path(prefix)?; store_rlp(data, host, &path).context("cannot save the pointer's data") } - fn get_data(&self, host: &impl Runtime, prefix: &impl Path) -> Result { + fn get_data(&self, host: &impl Runtime, prefix: &impl Path) -> Result { let path = self.data_path(prefix)?; read_rlp(host, &path).context("cannot read the pointer's data") } /// Load the pointer from the durable storage - fn read(host: &impl Runtime, prefix: &impl Path, id: &Id) -> Result> { + fn read(host: &impl Runtime, prefix: &impl Path, id: &Id) -> Result> { read_optional_rlp(host, &Self::pointer_path(id, prefix)?) } /// Save the pointer in the durable storage - fn save(&self, host: &mut impl Runtime, prefix: &impl Path) -> Result<()> { + fn save(&self, host: &mut impl Runtime, prefix: &impl Path) -> Result<()> { store_rlp(self, host, &self.path(prefix)?) .context("cannot save pointer to storage") } @@ -204,7 +204,7 @@ impl, Elt: Encodable + Decodable> fn remove_with_data( &self, host: &mut impl Runtime, - prefix: &impl Path, + prefix: &impl Path, ) -> Result<()> { let path = hex::encode(&self.id); let path: Vec = format!("/{}", path).into(); @@ -224,7 +224,7 @@ where /// Load a list from the storage. /// If the list does not exist, a new empty list is created. /// Otherwise the existing list is read from the storage. - pub fn new(path: &impl Path, host: &impl Runtime) -> Result { + pub fn new(path: &impl Path, host: &impl Runtime) -> Result { let list = Self::read(host, path)?.unwrap_or(Self { path: path.into(), pointers: None, @@ -234,7 +234,7 @@ where } /// Path to the metadata that defines the list. - fn metadata_path(root: &impl Path) -> Result { + fn metadata_path(root: &impl Path) -> Result> { let meta_path: Vec = "/meta".into(); let meta_path = OwnedPath::try_from(meta_path)?; let path = concat(root, &meta_path)?; @@ -250,7 +250,7 @@ where } /// Load the LinkedList from the durable storage. - fn read(host: &impl Runtime, path: &impl Path) -> Result> { + fn read(host: &impl Runtime, path: &impl Path) -> Result> { let path = Self::metadata_path(path)?; read_optional_rlp(host, &path) } @@ -539,7 +539,7 @@ mod tests { fn traverse_f( host: &MockKernelHost, - list_path: &OwnedPath, + list_path: &OwnedPath, pointer: Pointer, f: &dyn Fn(&Pointer) -> Option, ) -> (Pointer, usize) { diff --git a/etherlink/kernel_bifrost/kernel/src/reveal_storage.rs b/etherlink/kernel_bifrost/kernel/src/reveal_storage.rs index 294670a97282..11da770422ac 100644 --- a/etherlink/kernel_bifrost/kernel/src/reveal_storage.rs +++ b/etherlink/kernel_bifrost/kernel/src/reveal_storage.rs @@ -17,11 +17,11 @@ use tezos_smart_rollup_host::runtime::ValueType; /// chain into a new deployment. It is not tick-safe, and should obviously not be used in a /// production setup. -const CONFIG_PATH: RefPath = RefPath::assert_from(b"/__tmp/reveal_config"); +const CONFIG_PATH: RefPath = RefPath::assert_from(b"/__tmp/reveal_config"); #[derive(Debug)] struct Set { - to: OwnedPath, + to: OwnedPath, value: Vec, } @@ -36,8 +36,8 @@ impl Decodable for Set { let mut it = decoder.iter(); let to: Vec = decode_field(&next(&mut it)?, "to")?; - let to: RefPath = RefPath::assert_from(&to); - let to: OwnedPath = to.into(); + let to: RefPath = RefPath::assert_from(&to); + let to: OwnedPath = to.into(); let value: Vec = decode_field(&next(&mut it)?, "value")?; Ok(Self { to, value }) diff --git a/etherlink/kernel_bifrost/kernel/src/storage.rs b/etherlink/kernel_bifrost/kernel/src/storage.rs index 4fcdc259c555..93056d88af7f 100644 --- a/etherlink/kernel_bifrost/kernel/src/storage.rs +++ b/etherlink/kernel_bifrost/kernel/src/storage.rs @@ -70,115 +70,115 @@ impl StorageVersion { pub const STORAGE_VERSION: StorageVersion = StorageVersion::V22; -pub const PRIVATE_FLAG_PATH: RefPath = RefPath::assert_from(b"/evm/remove_whitelist"); +pub const PRIVATE_FLAG_PATH: RefPath = RefPath::assert_from(b"/evm/remove_whitelist"); -pub const STORAGE_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/storage_version"); +pub const STORAGE_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/storage_version"); -const KERNEL_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/kernel_version"); +const KERNEL_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/kernel_version"); -pub const ADMIN: RefPath = RefPath::assert_from(b"/evm/admin"); -pub const SEQUENCER_GOVERNANCE: RefPath = +pub const ADMIN: RefPath = RefPath::assert_from(b"/evm/admin"); +pub const SEQUENCER_GOVERNANCE: RefPath = RefPath::assert_from(b"/evm/sequencer_governance"); -pub const KERNEL_GOVERNANCE: RefPath = RefPath::assert_from(b"/evm/kernel_governance"); -pub const KERNEL_SECURITY_GOVERNANCE: RefPath = +pub const KERNEL_GOVERNANCE: RefPath = RefPath::assert_from(b"/evm/kernel_governance"); +pub const KERNEL_SECURITY_GOVERNANCE: RefPath = RefPath::assert_from(b"/evm/kernel_security_governance"); -pub const DELAYED_BRIDGE: RefPath = RefPath::assert_from(b"/evm/delayed_bridge"); +pub const DELAYED_BRIDGE: RefPath = RefPath::assert_from(b"/evm/delayed_bridge"); -pub const MAXIMUM_ALLOWED_TICKS: RefPath = +pub const MAXIMUM_ALLOWED_TICKS: RefPath = RefPath::assert_from(b"/evm/maximum_allowed_ticks"); -pub const MAXIMUM_GAS_PER_TRANSACTION: RefPath = +pub const MAXIMUM_GAS_PER_TRANSACTION: RefPath = RefPath::assert_from(b"/evm/maximum_gas_per_transaction"); // Path to the block in progress, used between reboots -const EVM_BLOCK_IN_PROGRESS: RefPath = +const EVM_BLOCK_IN_PROGRESS: RefPath = RefPath::assert_from(b"/evm/world_state/blocks/in_progress"); -const EVENTS: RefPath = RefPath::assert_from(b"/evm/events"); +const EVENTS: RefPath = RefPath::assert_from(b"/evm/events"); -pub const EVM_TRANSACTIONS_RECEIPTS: RefPath = +pub const EVM_TRANSACTIONS_RECEIPTS: RefPath = RefPath::assert_from(b"/evm/world_state/transactions_receipts"); -pub const EVM_TRANSACTIONS_OBJECTS: RefPath = +pub const EVM_TRANSACTIONS_OBJECTS: RefPath = RefPath::assert_from(b"/evm/world_state/transactions_objects"); -const EVM_CHAIN_ID: RefPath = RefPath::assert_from(b"/evm/chain_id"); +const EVM_CHAIN_ID: RefPath = RefPath::assert_from(b"/evm/chain_id"); -pub const EVM_BASE_FEE_PER_GAS: RefPath = +pub const EVM_BASE_FEE_PER_GAS: RefPath = RefPath::assert_from(b"/evm/world_state/fees/base_fee_per_gas"); -const EVM_MINIMUM_BASE_FEE_PER_GAS: RefPath = +const EVM_MINIMUM_BASE_FEE_PER_GAS: RefPath = RefPath::assert_from(b"/evm/world_state/fees/minimum_base_fee_per_gas"); -const EVM_DA_FEE: RefPath = +const EVM_DA_FEE: RefPath = RefPath::assert_from(b"/evm/world_state/fees/da_fee_per_byte"); -const TICK_BACKLOG_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/fees/backlog"); -const TICK_BACKLOG_TIMESTAMP_PATH: RefPath = +const TICK_BACKLOG_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/fees/backlog"); +const TICK_BACKLOG_TIMESTAMP_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/fees/last_timestamp"); /// The sequencer pool is the designated account that the data-availability fees are sent to. /// /// This may be updated by the governance mechanism over time. If it is not set, the data-availability /// fees are instead burned. -pub const SEQUENCER_POOL_PATH: RefPath = +pub const SEQUENCER_POOL_PATH: RefPath = RefPath::assert_from(b"/evm/sequencer_pool_address"); /// Path to the last L1 level seen. -const EVM_L1_LEVEL: RefPath = RefPath::assert_from(b"/evm/l1_level"); +const EVM_L1_LEVEL: RefPath = RefPath::assert_from(b"/evm/l1_level"); -const EVM_BURNED_FEES: RefPath = RefPath::assert_from(b"/evm/world_state/fees/burned"); +const EVM_BURNED_FEES: RefPath = RefPath::assert_from(b"/evm/world_state/fees/burned"); /// Path to the last info per level timestamp seen. -const EVM_INFO_PER_LEVEL_TIMESTAMP: RefPath = +const EVM_INFO_PER_LEVEL_TIMESTAMP: RefPath = RefPath::assert_from(b"/evm/info_per_level/timestamp"); /// Path to the number of timestamps read, use to compute the average block time. -const EVM_INFO_PER_LEVEL_STATS_NUMBERS: RefPath = +const EVM_INFO_PER_LEVEL_STATS_NUMBERS: RefPath = RefPath::assert_from(b"/evm/info_per_level/stats/numbers"); /// Path to the sum of distance between blocks, used to compute the average block time. -const EVM_INFO_PER_LEVEL_STATS_TOTAL: RefPath = +const EVM_INFO_PER_LEVEL_STATS_TOTAL: RefPath = RefPath::assert_from(b"/evm/info_per_level/stats/total"); -pub const SIMULATION_RESULT: RefPath = RefPath::assert_from(b"/evm/simulation_result"); +pub const SIMULATION_RESULT: RefPath = RefPath::assert_from(b"/evm/simulation_result"); // Path to the number of seconds until delayed txs are timed out. -const EVM_DELAYED_INBOX_TIMEOUT: RefPath = +const EVM_DELAYED_INBOX_TIMEOUT: RefPath = RefPath::assert_from(b"/evm/delayed_inbox_timeout"); // Path to the number of l1 levels that need to pass for a // delayed tx to be timed out. -const EVM_DELAYED_INBOX_MIN_LEVELS: RefPath = +const EVM_DELAYED_INBOX_MIN_LEVELS: RefPath = RefPath::assert_from(b"/evm/delayed_inbox_min_levels"); // Path to the tz1 administrating the sequencer. If there is nothing // at this path, the kernel is in proxy mode. -pub const SEQUENCER: RefPath = RefPath::assert_from(b"/evm/sequencer"); +pub const SEQUENCER: RefPath = RefPath::assert_from(b"/evm/sequencer"); // Path to the DAL feature flag. If there is nothing at this path, DAL // is not used. -pub const ENABLE_DAL: RefPath = RefPath::assert_from(b"/evm/feature_flags/enable_dal"); +pub const ENABLE_DAL: RefPath = RefPath::assert_from(b"/evm/feature_flags/enable_dal"); // Path to the DAL slot indices to use. -pub const DAL_SLOTS: RefPath = RefPath::assert_from(b"/evm/dal_slots"); +pub const DAL_SLOTS: RefPath = RefPath::assert_from(b"/evm/dal_slots"); // Path where the input for the tracer is stored by the sequencer. -const TRACER_INPUT: RefPath = RefPath::assert_from(b"/evm/trace/input"); +const TRACER_INPUT: RefPath = RefPath::assert_from(b"/evm/trace/input"); // If this path contains a value, the fa bridge is enabled in the kernel. -pub const ENABLE_FA_BRIDGE: RefPath = +pub const ENABLE_FA_BRIDGE: RefPath = RefPath::assert_from(b"/evm/feature_flags/enable_fa_bridge"); // If the flag is set, the kernel consider that this is local evm node execution. -const EVM_NODE_FLAG: RefPath = RefPath::assert_from(b"/__evm_node"); +const EVM_NODE_FLAG: RefPath = RefPath::assert_from(b"/__evm_node"); -const MAX_BLUEPRINT_LOOKAHEAD_IN_SECONDS: RefPath = +const MAX_BLUEPRINT_LOOKAHEAD_IN_SECONDS: RefPath = RefPath::assert_from(b"/evm/max_blueprint_lookahead_in_seconds"); -pub fn receipt_path(receipt_hash: &TransactionHash) -> Result { +pub fn receipt_path(receipt_hash: &TransactionHash) -> Result, Error> { let hash = hex::encode(receipt_hash); let raw_receipt_path: Vec = format!("/{}", &hash).into(); let receipt_path = OwnedPath::try_from(raw_receipt_path)?; concat(&EVM_TRANSACTIONS_RECEIPTS, &receipt_path).map_err(Error::from) } -pub fn object_path(object_hash: &TransactionHash) -> Result { +pub fn object_path(object_hash: &TransactionHash) -> Result, Error> { let hash = hex::encode(object_hash); let raw_object_path: Vec = format!("/{}", &hash).into(); let object_path = OwnedPath::try_from(raw_object_path)?; @@ -229,11 +229,11 @@ pub fn store_transaction_object( Ok(encoded.len().try_into()?) } -const CHUNKED_TRANSACTIONS: RefPath = RefPath::assert_from(b"/chunked_transactions"); -const CHUNKED_TRANSACTION_NUM_CHUNKS: RefPath = RefPath::assert_from(b"/num_chunks"); -const CHUNKED_HASHES: RefPath = RefPath::assert_from(b"/chunk_hashes"); +const CHUNKED_TRANSACTIONS: RefPath = RefPath::assert_from(b"/chunked_transactions"); +const CHUNKED_TRANSACTION_NUM_CHUNKS: RefPath = RefPath::assert_from(b"/num_chunks"); +const CHUNKED_HASHES: RefPath = RefPath::assert_from(b"/chunk_hashes"); -pub fn chunked_transaction_path(tx_hash: &TransactionHash) -> Result { +pub fn chunked_transaction_path(tx_hash: &TransactionHash) -> Result, Error> { let hash = hex::encode(tx_hash); let raw_chunked_transaction_path: Vec = format!("/{}", hash).into(); let chunked_transaction_path = OwnedPath::try_from(raw_chunked_transaction_path)?; @@ -241,34 +241,34 @@ pub fn chunked_transaction_path(tx_hash: &TransactionHash) -> Result Result { - concat(chunked_transaction_path, &CHUNKED_TRANSACTION_NUM_CHUNKS).map_err(Error::from) + chunked_transaction_path: &OwnedPath, +) -> Result, Error> { + force_concat(chunked_transaction_path, &CHUNKED_TRANSACTION_NUM_CHUNKS).map_err(Error::from) } pub fn chunked_hash_transaction_path( chunked_hash: &[u8], - chunked_transaction_path: &OwnedPath, -) -> Result { + chunked_transaction_path: &OwnedPath, +) -> Result, Error> { let hash = hex::encode(chunked_hash); let raw_chunked_hash_key: Vec = format!("/{}", hash).into(); let chunked_hash_key = OwnedPath::try_from(raw_chunked_hash_key)?; - let chunked_hash_path = concat(&CHUNKED_HASHES, &chunked_hash_key)?; - concat(chunked_transaction_path, &chunked_hash_path).map_err(Error::from) + let chunked_hash_path = force_concat(&CHUNKED_HASHES, &chunked_hash_key)?; + force_concat(chunked_transaction_path, &chunked_hash_path).map_err(Error::from) } pub fn transaction_chunk_path( - chunked_transaction_path: &OwnedPath, + chunked_transaction_path: &OwnedPath, i: u16, -) -> Result { +) -> Result, Error> { let raw_i_path: Vec = format!("/{}", i).into(); let i_path = OwnedPath::try_from(raw_i_path)?; - concat(chunked_transaction_path, &i_path).map_err(Error::from) + force_concat(chunked_transaction_path, &i_path).map_err(Error::from) } fn is_transaction_complete( host: &mut Host, - chunked_transaction_path: &OwnedPath, + chunked_transaction_path: &OwnedPath, num_chunks: u16, ) -> Result { let n_subkeys = host.store_count_subkeys(chunked_transaction_path)? as u16; @@ -278,7 +278,7 @@ fn is_transaction_complete( fn chunked_transaction_num_chunks_by_path( host: &mut Host, - chunked_transaction_path: &OwnedPath, + chunked_transaction_path: &OwnedPath, ) -> Result { let chunked_transaction_num_chunks_path = chunked_transaction_num_chunks_path(chunked_transaction_path)?; @@ -297,7 +297,7 @@ pub fn chunked_transaction_num_chunks( fn store_transaction_chunk_data( host: &mut Host, - transaction_chunk_path: &OwnedPath, + transaction_chunk_path: &OwnedPath, data: Vec, ) -> Result<(), Error> { match host.store_has(transaction_chunk_path)? { @@ -318,7 +318,7 @@ fn store_transaction_chunk_data( pub fn read_transaction_chunk_data( host: &mut Host, - transaction_chunk_path: &OwnedPath, + transaction_chunk_path: &OwnedPath, ) -> Result, Error> { let data_size = host.store_value_size(transaction_chunk_path)?; @@ -339,7 +339,7 @@ pub fn read_transaction_chunk_data( fn get_full_transaction( host: &mut Host, - chunked_transaction_path: &OwnedPath, + chunked_transaction_path: &OwnedPath, num_chunks: u16, ) -> Result, Error> { let mut buffer = Vec::new(); @@ -353,7 +353,7 @@ fn get_full_transaction( pub fn remove_chunked_transaction_by_path( host: &mut Host, - path: &OwnedPath, + path: &OwnedPath, ) -> Result<(), Error> { host.store_delete(path).map_err(Error::from) } @@ -536,7 +536,7 @@ pub fn store_sequencer_pool_address( pub fn store_timestamp_path( host: &mut Host, - path: &OwnedPath, + path: &OwnedPath, timestamp: &Timestamp, ) -> Result<(), Error> { host.store_write(path, ×tamp.i64().to_le_bytes(), 0)?; @@ -598,7 +598,7 @@ pub fn store_last_info_per_level_timestamp( pub fn read_timestamp_path( host: &Host, - path: &OwnedPath, + path: &OwnedPath, ) -> Result { let mut buffer = [0u8; 8]; store_read_slice(host, path, &mut buffer, 8)?; diff --git a/etherlink/kernel_bifrost/kernel/src/upgrade.rs b/etherlink/kernel_bifrost/kernel/src/upgrade.rs index 32f69aa0ed42..e3b3aa17c8fd 100644 --- a/etherlink/kernel_bifrost/kernel/src/upgrade.rs +++ b/etherlink/kernel_bifrost/kernel/src/upgrade.rs @@ -34,9 +34,9 @@ use tezos_smart_rollup_host::path::RefPath; use tezos_smart_rollup_installer_config::binary::promote::upgrade_reveal_flow; use tezos_storage::read_optional_rlp; -const KERNEL_UPGRADE: RefPath = RefPath::assert_from(b"/evm/kernel_upgrade"); -pub const KERNEL_ROOT_HASH: RefPath = RefPath::assert_from(b"/evm/kernel_root_hash"); -const SEQUENCER_UPGRADE: RefPath = RefPath::assert_from(b"/evm/sequencer_upgrade"); +const KERNEL_UPGRADE: RefPath = RefPath::assert_from(b"/evm/kernel_upgrade"); +pub const KERNEL_ROOT_HASH: RefPath = RefPath::assert_from(b"/evm/kernel_root_hash"); +const SEQUENCER_UPGRADE: RefPath = RefPath::assert_from(b"/evm/sequencer_upgrade"); #[derive(Debug, PartialEq, Clone)] pub struct KernelUpgrade { @@ -99,7 +99,7 @@ pub fn store_kernel_upgrade( fn read_kernel_upgrade_at( host: &impl Runtime, - path: &impl Path, + path: &impl Path, ) -> anyhow::Result> { read_optional_rlp(host, path).context("Failed to decode kernel upgrade") } diff --git a/etherlink/kernel_bifrost/runtime/src/internal_runtime.rs b/etherlink/kernel_bifrost/runtime/src/internal_runtime.rs index f0d240c3a93c..1823d94e3c36 100644 --- a/etherlink/kernel_bifrost/runtime/src/internal_runtime.rs +++ b/etherlink/kernel_bifrost/runtime/src/internal_runtime.rs @@ -8,7 +8,7 @@ use tezos_smart_rollup_host::{path::Path, runtime::RuntimeError}; pub trait InternalRuntime { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError>; @@ -19,5 +19,5 @@ pub trait InternalRuntime { // The path is optional to be able to get the hash // of the root directory. pub trait ExtendedRuntime { - fn store_get_hash(&mut self, path: &T) -> Result, RuntimeError>; + fn store_get_hash>(&mut self, path: &T) -> Result, RuntimeError>; } diff --git a/etherlink/kernel_bifrost/runtime/src/mock_internal.rs b/etherlink/kernel_bifrost/runtime/src/mock_internal.rs index 645513f5f807..ec2fe1381145 100644 --- a/etherlink/kernel_bifrost/runtime/src/mock_internal.rs +++ b/etherlink/kernel_bifrost/runtime/src/mock_internal.rs @@ -8,7 +8,7 @@ use tezos_smart_rollup_host::path::Path; use tezos_smart_rollup_host::runtime::RuntimeError; use tezos_smart_rollup_mock::MockHost; impl InternalRuntime for MockHost { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError> { diff --git a/etherlink/kernel_bifrost/runtime/src/runtime.rs b/etherlink/kernel_bifrost/runtime/src/runtime.rs index 9d7eaef46f5f..c070591e8a3e 100644 --- a/etherlink/kernel_bifrost/runtime/src/runtime.rs +++ b/etherlink/kernel_bifrost/runtime/src/runtime.rs @@ -19,26 +19,27 @@ use crate::{ }; use tezos_evm_logging::{Level, Verbosity}; use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; +use tezos_smart_rollup_encoding::smart_rollup::SmartRollupAddress; use tezos_smart_rollup_host::{ dal_parameters::RollupDalParameters, input::Message, metadata::RollupMetadata, path::{Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, - Error, }; +use tezos_smart_rollup_mock::MockHost; // Set by the node, contains the verbosity for the logs -pub const VERBOSITY_PATH: RefPath = RefPath::assert_from(b"/evm/logging_verbosity"); +pub const VERBOSITY_PATH: RefPath = RefPath::assert_from(b"/evm/logging_verbosity"); pub trait Runtime: - SdkRuntime + InternalRuntime + ExtendedRuntime + Verbosity + WithGas + SdkRuntime + InternalRuntime + ExtendedRuntime + Verbosity + WithGas { } // If a type implements the Runtime, InternalRuntime and ExtendedRuntime traits, // it also implements the kernel Runtime. -impl Runtime +impl + InternalRuntime + ExtendedRuntime + Verbosity + WithGas> Runtime for T { } @@ -66,7 +67,7 @@ pub struct KernelHost + Borrow> { pub _pd: PhantomData, } -impl + Borrow> SdkRuntime +impl + InternalRuntime, Host: BorrowMut + Borrow> SdkRuntime for KernelHost { #[inline(always)] @@ -85,12 +86,12 @@ impl + Borrow> SdkRuntime } #[inline(always)] - fn store_has(&self, path: &T) -> Result, RuntimeError> { + fn store_has>(&self, path: &T) -> Result, RuntimeError> { self.host.borrow().store_has(path) } #[inline(always)] - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -100,7 +101,7 @@ impl + Borrow> SdkRuntime } #[inline(always)] - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -112,12 +113,12 @@ impl + Borrow> SdkRuntime } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { self.host.borrow().store_read_all(path) } #[inline(always)] - fn store_write( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -127,7 +128,7 @@ impl + Borrow> SdkRuntime } #[inline(always)] - fn store_write_all( + fn store_write_all>( &mut self, path: &T, src: &[u8], @@ -136,25 +137,25 @@ impl + Borrow> SdkRuntime } #[inline(always)] - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { self.host.borrow_mut().store_delete(path) } #[inline(always)] - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete_value>(&mut self, path: &T) -> Result<(), RuntimeError> { self.host.borrow_mut().store_delete_value(path) } #[inline(always)] - fn store_count_subkeys(&self, prefix: &T) -> Result { + fn store_count_subkeys>(&self, prefix: &T) -> Result { self.host.borrow().store_count_subkeys(prefix) } #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { self.host.borrow_mut().store_move(from_path, to_path) } @@ -162,8 +163,8 @@ impl + Borrow> SdkRuntime #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { self.host.borrow_mut().store_copy(from_path, to_path) } @@ -178,7 +179,7 @@ impl + Borrow> SdkRuntime } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { self.host.borrow().store_value_size(path) } @@ -247,11 +248,11 @@ impl + Borrow> SdkRuntime } } -impl + BorrowMut> InternalRuntime +impl + InternalRuntime, Host: Borrow + BorrowMut> InternalRuntime for KernelHost { #[inline(always)] - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError> { @@ -259,16 +260,16 @@ impl + BorrowMut> InternalRu } } -impl + Borrow> ExtendedRuntime +impl + InternalRuntime, Host: BorrowMut + Borrow> ExtendedRuntime for KernelHost { #[inline(always)] - fn store_get_hash(&mut self, path: &T) -> Result, RuntimeError> { + fn store_get_hash>(&mut self, path: &T) -> Result, RuntimeError> { self.__internal_store_get_hash(path) } } -impl + BorrowMut> KernelHost +impl + InternalRuntime, Host: Borrow + BorrowMut> KernelHost where for<'a> &'a mut Host: BorrowMut, { @@ -282,7 +283,7 @@ where } } -impl + Borrow> Verbosity +impl + InternalRuntime, Host: BorrowMut + Borrow> Verbosity for KernelHost { fn verbosity(&self) -> Level { @@ -290,7 +291,7 @@ impl + Borrow> Verbosity } } -pub fn read_logs_verbosity( +pub fn read_logs_verbosity>( host: &Host, ) -> Level { match host.store_read_all(&VERBOSITY_PATH) { @@ -301,7 +302,7 @@ pub fn read_logs_verbosity( } } -impl + Borrow> WithGas +impl + InternalRuntime, Host: BorrowMut + Borrow> WithGas for KernelHost { fn add_execution_gas(&mut self, gas: u64) { @@ -309,7 +310,7 @@ impl + Borrow> WithGas } } -impl + Borrow> +impl + InternalRuntime, Host: BorrowMut + Borrow> KernelHost { pub fn init(host: Host) -> Self { @@ -322,3 +323,28 @@ impl + Borrow> } } } + +pub type MockKernelHost = KernelHost; + +impl Default for MockKernelHost { + fn default() -> Self { + Self { + host: MockHost::default(), + logs_verbosity: Level::default(), + execution_gas_used: 0, + _pd: PhantomData, + } + } +} + +impl MockKernelHost { + pub fn with_address(address: SmartRollupAddress) -> Self { + let host = MockHost::with_address(&address); + KernelHost { + host, + logs_verbosity: Level::default(), + execution_gas_used: 0, + _pd: PhantomData, + } + } +} diff --git a/etherlink/kernel_bifrost/runtime/src/safe_storage.rs b/etherlink/kernel_bifrost/runtime/src/safe_storage.rs index d55feb706e33..4f1cb25e4a83 100644 --- a/etherlink/kernel_bifrost/runtime/src/safe_storage.rs +++ b/etherlink/kernel_bifrost/runtime/src/safe_storage.rs @@ -14,18 +14,18 @@ use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; use tezos_smart_rollup_host::{ input::Message, metadata::RollupMetadata, - path::{concat, OwnedPath, Path, RefPath}, + path::{force_concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; -pub const TMP_PATH: RefPath = RefPath::assert_from(b"/tmp"); -pub const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); -pub const TMP_WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/world_state"); -pub const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); -pub const TMP_TRACE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/trace"); +pub const TMP_PATH: RefPath = RefPath::assert_from(b"/tmp"); +pub const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); +pub const TMP_WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/world_state"); +pub const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); +pub const TMP_TRACE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/trace"); -pub fn safe_path(path: &T) -> Result { - concat(&TMP_PATH, path).map_err(|_| RuntimeError::PathNotFound) +pub fn safe_path>(path: &T) -> Result, RuntimeError> { + force_concat(&TMP_PATH, path).map_err(|_| RuntimeError::PathNotFound) } pub struct SafeStorage { @@ -33,7 +33,7 @@ pub struct SafeStorage { } impl InternalRuntime for SafeStorage<&mut Host> { - fn __internal_store_get_hash( + fn __internal_store_get_hash>( &mut self, path: &T, ) -> Result, RuntimeError> { @@ -43,13 +43,13 @@ impl InternalRuntime for SafeStorage<&mut Host> { impl ExtendedRuntime for SafeStorage<&mut Host> { #[inline(always)] - fn store_get_hash(&mut self, path: &P) -> Result, RuntimeError> { + fn store_get_hash>(&mut self, path: &P) -> Result, RuntimeError> { let path = safe_path(path)?; self.__internal_store_get_hash(&path) } } -impl SdkRuntime for SafeStorage<&mut Host> { +impl SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.write_output(from) @@ -66,13 +66,13 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_has(&self, path: &T) -> Result, RuntimeError> { + fn store_has>(&self, path: &T) -> Result, RuntimeError> { let path = safe_path(path)?; self.host.store_has(&path) } #[inline(always)] - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -83,7 +83,7 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -94,13 +94,13 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { let path = safe_path(path)?; self.host.store_read_all(&path) } #[inline(always)] - fn store_write( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -111,7 +111,7 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_write_all( + fn store_write_all>( &mut self, path: &T, src: &[u8], @@ -121,19 +121,19 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { let path = safe_path(path)?; self.host.store_delete(&path) } #[inline(always)] - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete_value>(&mut self, path: &T) -> Result<(), RuntimeError> { let path = safe_path(path)?; self.host.store_delete_value(&path) } #[inline(always)] - fn store_count_subkeys(&self, prefix: &T) -> Result { + fn store_count_subkeys>(&self, prefix: &T) -> Result { let prefix = safe_path(prefix)?; self.host.store_count_subkeys(&prefix) } @@ -141,8 +141,8 @@ impl SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = safe_path(from_path)?; let to_path = safe_path(to_path)?; @@ -152,8 +152,8 @@ impl SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = safe_path(from_path)?; let to_path = safe_path(to_path)?; @@ -170,7 +170,7 @@ impl SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { let path = safe_path(path)?; self.host.store_value_size(&path) } diff --git a/etherlink/kernel_bifrost/storage/src/lib.rs b/etherlink/kernel_bifrost/storage/src/lib.rs index a1e73354588e..9c7ecd0aa154 100644 --- a/etherlink/kernel_bifrost/storage/src/lib.rs +++ b/etherlink/kernel_bifrost/storage/src/lib.rs @@ -28,7 +28,7 @@ pub const WORD_SIZE: usize = 32usize; /// NB: Value is read starting 0. pub fn store_read_slice( host: &impl Runtime, - path: &impl Path, + path: &impl Path, buffer: &mut [u8], expected_size: usize, ) -> Result<(), Error> { @@ -44,7 +44,7 @@ pub fn store_read_slice( } /// Get the path corresponding to an index of H256. -pub fn path_from_h256(index: &H256) -> Result { +pub fn path_from_h256(index: &H256) -> Result, Error> { let path_string = format!("/{}", hex::encode(index.to_fixed_bytes())); OwnedPath::try_from(path_string).map_err(Error::from) } @@ -52,7 +52,7 @@ pub fn path_from_h256(index: &H256) -> Result { /// Return a 32 bytes hash from storage at the given `path`. /// /// NB: The given bytes are interpreted in big endian order. -pub fn read_h256_be(host: &impl Runtime, path: &impl Path) -> anyhow::Result { +pub fn read_h256_be(host: &impl Runtime, path: &impl Path) -> anyhow::Result { let mut buffer = [0_u8; WORD_SIZE]; store_read_slice(host, path, &mut buffer, WORD_SIZE)?; Ok(H256::from_slice(&buffer)) @@ -78,7 +78,7 @@ pub fn read_h256_be_opt( /// NB: The given bytes are interpreted in big endian order. pub fn read_h256_be_default( host: &impl Runtime, - path: &impl Path, + path: &impl Path, default: H256, ) -> Result { match read_h256_be_opt(host, path)? { @@ -92,7 +92,7 @@ pub fn read_h256_be_default( /// NB: The hash is stored in big endian order. pub fn write_h256_be( host: &mut impl Runtime, - path: &impl Path, + path: &impl Path, hash: H256, ) -> anyhow::Result<()> { Ok(host.store_write_all(path, hash.as_bytes())?) @@ -101,7 +101,7 @@ pub fn write_h256_be( /// Return an unsigned 32 bytes value from storage at the given `path`. /// /// NB: The given bytes are interpreted in little endian order. -pub fn read_u256_le(host: &impl Runtime, path: &impl Path) -> Result { +pub fn read_u256_le(host: &impl Runtime, path: &impl Path) -> Result { let bytes = host.store_read_all(path)?; Ok(U256::from_little_endian(&bytes)) } @@ -112,7 +112,7 @@ pub fn read_u256_le(host: &impl Runtime, path: &impl Path) -> Result, default: U256, ) -> Result { match host.store_read_all(path) { @@ -127,7 +127,7 @@ pub fn read_u256_le_default( /// NB: The value is stored in little endian order. pub fn write_u256_le( host: &mut impl Runtime, - path: &impl Path, + path: &impl Path, value: U256, ) -> Result<(), Error> { let mut bytes: [u8; WORD_SIZE] = value.into(); @@ -138,7 +138,7 @@ pub fn write_u256_le( /// Return an unsigned 8 bytes value from storage at the given `path`. /// /// NB: The given bytes are interpreted in little endian order. -pub fn read_u64_le(host: &impl Runtime, path: &impl Path) -> Result { +pub fn read_u64_le(host: &impl Runtime, path: &impl Path) -> Result { let mut bytes = [0; std::mem::size_of::()]; host.store_read_slice(path, 0, bytes.as_mut_slice())?; Ok(u64::from_le_bytes(bytes)) @@ -150,7 +150,7 @@ pub fn read_u64_le(host: &impl Runtime, path: &impl Path) -> Result /// NB: The given bytes are interpreted in little endian order. pub fn read_u64_le_default( host: &impl Runtime, - path: &impl Path, + path: &impl Path, default: u64, ) -> Result { match host.store_read_all(path) { @@ -170,7 +170,7 @@ pub fn read_u64_le_default( /// NB: The value is stored in little endian order. pub fn write_u64_le( host: &mut impl Runtime, - path: &impl Path, + path: &impl Path, value: u64, ) -> Result<(), Error> { host.store_write_all(path, value.to_le_bytes().as_slice()) @@ -182,7 +182,7 @@ pub fn write_u64_le( pub fn store_rlp( src: &T, host: &mut impl Runtime, - path: &impl Path, + path: &impl Path, ) -> Result<(), Error> { host.store_write_all(path, &src.rlp_bytes()) .map_err(Error::from) @@ -190,7 +190,7 @@ pub fn store_rlp( /// Return a decodable value from storage as rlp bytes /// at the given `path`. -pub fn read_rlp(host: &impl Runtime, path: &impl Path) -> Result { +pub fn read_rlp(host: &impl Runtime, path: &impl Path) -> Result { let bytes = host.store_read_all(path)?; FromRlpBytes::from_rlp_bytes(&bytes).map_err(Error::from) } @@ -201,7 +201,7 @@ pub fn read_rlp(host: &impl Runtime, path: &impl Path) -> Result( host: &impl Runtime, - path: &impl Path, + path: &impl Path, ) -> Result, anyhow::Error> { if let Some(ValueType::Value) = host.store_has(path)? { let elt = read_rlp(host, path)?; @@ -212,7 +212,7 @@ pub fn read_optional_rlp( } /// Return a base58 contract address from storage at the given `path`. -pub fn read_b58_kt1(host: &impl Runtime, path: &impl Path) -> Option { +pub fn read_b58_kt1(host: &impl Runtime, path: &impl Path) -> Option { let bytes = host.store_read_all(path).ok()?; let kt1_b58 = String::from_utf8(bytes).ok()?; ContractKt1Hash::from_b58check(&kt1_b58).ok() -- GitLab From f654ae4efbba2e3c13c4aaeb3d9f14a5a0836a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 14 Jan 2025 22:37:32 +0100 Subject: [PATCH 17/31] Etherlink: adapt lib_wasm_runtime to the dev version of the Sdk --- etherlink/lib_wasm_runtime/src/host.rs | 38 +++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/etherlink/lib_wasm_runtime/src/host.rs b/etherlink/lib_wasm_runtime/src/host.rs index 1126d3910bb7..605ee5a55b8c 100644 --- a/etherlink/lib_wasm_runtime/src/host.rs +++ b/etherlink/lib_wasm_runtime/src/host.rs @@ -164,13 +164,13 @@ fn from_binding_error(e: BindingsError) -> RuntimeError { } } -const REBOOT_FLAG_PATH: RefPath = RefPath::assert_from(REBOOT_FLAG.as_bytes()); +const REBOOT_FLAG_PATH: RefPath = RefPath::assert_from(REBOOT_FLAG.as_bytes()); impl Host { // Compare to its counterpart in the kernel SDK, we only check if the path exists on error. fn check_path_exists<'a>( &'a self, - path: &'a impl Path, + path: &'a impl Path, ) -> impl FnOnce(RuntimeError) -> RuntimeError + 'a { |err| { if let Ok(Some(_)) = self.store_has(path) { @@ -184,7 +184,7 @@ impl Host { // Compare to its counterpart in the kernel SDK, we only check if the path exists on error. fn check_path_has_value<'a>( &'a self, - path: &'a impl Path, + path: &'a impl Path, ) -> impl FnOnce(RuntimeError) -> RuntimeError + 'a { |err| { if let Ok(Some(ValueType::Value | ValueType::ValueWithSubtree)) = self.store_has(path) { @@ -196,7 +196,7 @@ impl Host { } } -impl Runtime for Host { +impl Runtime for Host { fn write_output(&mut self, _from: &[u8]) -> Result<(), RuntimeError> { trace!("write_output()"); // The outbox is only useful in the context of the rollup node, in order to enable @@ -221,7 +221,7 @@ impl Runtime for Host { } } - fn store_has(&self, path: &T) -> Result, RuntimeError> { + fn store_has>(&self, path: &T) -> Result, RuntimeError> { trace!("store_has({path})"); let res = bindings::store_has(self.tree(), path.as_bytes()); @@ -237,7 +237,7 @@ impl Runtime for Host { } } - fn store_read( + fn store_read>( &self, path: &T, from_offset: usize, @@ -253,7 +253,7 @@ impl Runtime for Host { Ok(res.as_bytes().to_owned()) } - fn store_read_slice( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -269,7 +269,7 @@ impl Runtime for Host { Ok(res.as_bytes().len()) } - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { trace!("store_read_all({path})"); let res = bindings::read_value(self.tree(), path.as_bytes()) .map_err(from_binding_error) @@ -277,7 +277,7 @@ impl Runtime for Host { Ok(res.as_bytes().to_owned()) } - fn store_write( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -291,7 +291,7 @@ impl Runtime for Host { Ok(()) } - fn store_write_all(&mut self, path: &T, src: &[u8]) -> Result<(), RuntimeError> { + fn store_write_all>(&mut self, path: &T, src: &[u8]) -> Result<(), RuntimeError> { trace!("store_write_all({path})"); let new_tree = bindings::store_write_all(self.tree(), path.as_bytes(), src) .map_err(from_binding_error)?; @@ -300,7 +300,7 @@ impl Runtime for Host { Ok(()) } - fn store_delete(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { trace!("store_delete({path})"); if let Ok(None) = Runtime::store_has(self, path) { return Err(RuntimeError::PathNotFound); @@ -313,7 +313,7 @@ impl Runtime for Host { Ok(()) } - fn store_delete_value(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete_value>(&mut self, path: &T) -> Result<(), RuntimeError> { trace!("store_delete_value({path})"); let new_tree = bindings::store_delete(self.tree(), path.as_bytes(), true) .map_err(from_binding_error)?; @@ -322,7 +322,7 @@ impl Runtime for Host { Ok(()) } - fn store_count_subkeys(&self, prefix: &T) -> Result { + fn store_count_subkeys>(&self, prefix: &T) -> Result { trace!("store_count_subkeys({prefix})"); let res = bindings::store_list_size(self.tree(), prefix.as_bytes()) .map_err(from_binding_error)?; @@ -332,8 +332,8 @@ impl Runtime for Host { fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { trace!("store_move({from_path}, {to_path})"); let new_tree = bindings::store_move(self.tree(), from_path.as_bytes(), to_path.as_bytes()) @@ -351,8 +351,8 @@ impl Runtime for Host { fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { trace!("store_copy({from_path}, {to_path})"); let new_tree = bindings::store_copy(self.tree(), from_path.as_bytes(), to_path.as_bytes()) @@ -416,7 +416,7 @@ impl Runtime for Host { unimplemented!() } - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { trace!("store_value_size({path})"); match self.version { RuntimeVersion::V0 => { @@ -485,7 +485,7 @@ impl Runtime for Host { } impl BifrostInternalRuntime for Host { - fn __internal_store_get_hash(&mut self, path: &T) -> Result, RuntimeError> { + fn __internal_store_get_hash>(&mut self, path: &T) -> Result, RuntimeError> { trace!("store_get_hash({path})"); let hash = bindings::store_get_hash(self.tree(), path.as_bytes()).map_err(from_binding_error)?; -- GitLab From ad9814e80b4a9e5c31471b8bac745c72fb13dad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 14:32:06 +0200 Subject: [PATCH 18/31] Etherlink/Kernel: generalize Outbox queue --- etherlink/kernel_evm/kernel/src/apply.rs | 4 ++-- etherlink/kernel_evm/kernel/src/block.rs | 6 +++--- src/kernel_sdk/sdk/src/outbox.rs | 18 ++++++++++-------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index 1c4b0bebb3c8..91a213d8c1e6 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -528,7 +528,7 @@ impl From> for ExecutionResult { #[allow(clippy::too_many_arguments)] pub fn handle_transaction_result>( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, block_constants: &BlockConstants, transaction: &Transaction, index: u32, @@ -588,7 +588,7 @@ pub fn handle_transaction_result>( #[allow(clippy::too_many_arguments)] pub fn apply_transaction>( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, transaction: &Transaction, diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index fd4aff9f0ade..31123131e71e 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -99,7 +99,7 @@ fn on_invalid_transaction>( #[allow(clippy::too_many_arguments)] fn compute>( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, block_in_progress: &mut BlockInProgress, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, @@ -283,7 +283,7 @@ fn next_bip_from_blueprints>( #[allow(clippy::too_many_arguments)] fn compute_bip>( host: &mut Host, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, mut block_in_progress: BlockInProgress, current_block_number: &mut U256, current_block_parent_hash: &mut H256, @@ -388,7 +388,7 @@ fn clean_delayed_transactions( fn promote_block>( safe_host: &mut SafeStorage<&mut Host>, - outbox_queue: &OutboxQueue<'_, impl Path>, + outbox_queue: &OutboxQueue<'_, true, impl Path>, block_in_progress: bool, number: U256, config: &mut Configuration, diff --git a/src/kernel_sdk/sdk/src/outbox.rs b/src/kernel_sdk/sdk/src/outbox.rs index 58728d855577..e9adc4e5db41 100644 --- a/src/kernel_sdk/sdk/src/outbox.rs +++ b/src/kernel_sdk/sdk/src/outbox.rs @@ -95,7 +95,7 @@ const META_SUFFIX: RefPath = RefPath::assert_from(b"/meta"); /// It is configured with a maximum queue size of 65536. If you flush the queue every /// tezos level, it will take roughly 2h45mins for a message to make its way through /// the queue, and be written to the outbox. -pub const OUTBOX_QUEUE: OutboxQueue<'static, RefPath> = OutboxQueue { +pub const OUTBOX_QUEUE: OutboxQueue<'static, true, RefPath> = OutboxQueue { root: &OUTBOX_QUEUE_ROOT, meta: &OUTBOX_QUEUE_META, max: u16::MAX as u32, @@ -105,13 +105,15 @@ pub const OUTBOX_QUEUE: OutboxQueue<'static, RefPath> = OutboxQueue { /// /// See [`OUTBOX_QUEUE`] for more information. #[derive(Debug)] -pub struct OutboxQueue<'a, P: Path> { +pub struct OutboxQueue<'a, const IS_ABSOLUTE: bool, P: Path> { root: &'a P, meta: &'a P, max: u32, } -impl<'a, P: Path> OutboxQueue<'a, P> { + + +impl<'a, const IS_ABSOLUTE: bool, P: Path> OutboxQueue<'a, IS_ABSOLUTE, P> { /// Setup the outbox queue to operate over non-default parameters. /// /// - `root` specifies the path in storage that the queue will be stored at. @@ -146,7 +148,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { /// [`flush_queue`]: Self::flush_queue pub fn queue_message( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, message: impl Into>, ) -> Result { let (start, len) = self.read_meta(host); @@ -189,7 +191,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { /// `flush_queue` twice, on the same *durable storage state*, then a single message could be /// executed twice - leading to double spending of an L2 account's funds on L1 - this would result /// later in some accounts being unable to execute otherwise valid withdrawals on L1. - pub fn flush_queue(&self, host: &mut impl Runtime) -> usize { + pub fn flush_queue(&self, host: &mut impl Runtime) -> usize { // Consider: `store_read_extend(&mut Vec)` let mut num_flushed = 0; let (mut start, mut len) = self.read_meta(host); @@ -228,7 +230,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { // if we had a 'path::append_hex_into' method, we could have an alloc free // version of this. // 'concat_into' would be useful also. - fn message_path(&self, idx: u32) -> OwnedPath { + fn message_path(&self, idx: u32) -> OwnedPath { let mut path = [b'/'; 1 + 2 * core::mem::size_of::()]; let idx = idx.to_le_bytes(); @@ -241,7 +243,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { } #[inline(always)] - fn read_meta(&self, host: &impl Runtime) -> (u32, u32) { + fn read_meta(&self, host: &impl Runtime) -> (u32, u32) { const BUFF_SIZE: usize = 2 * core::mem::size_of::(); let mut buffer = [0; BUFF_SIZE]; @@ -257,7 +259,7 @@ impl<'a, P: Path> OutboxQueue<'a, P> { } #[inline(always)] - fn save_meta(&self, host: &mut impl Runtime, start: u32, len: u32) { + fn save_meta(&self, host: &mut impl Runtime, start: u32, len: u32) { if len == 0 { // We only call this when we've just emptied the queue let _ = host.store_delete(self.root); -- GitLab From 82463f3641fe35fc899db826d860df124a4cbb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Thu, 24 Oct 2024 17:00:09 +0200 Subject: [PATCH 19/31] Etherlink/Kernel/Migration: hardcode absolute path to current block number --- etherlink/kernel_evm/kernel/src/migration.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/migration.rs b/etherlink/kernel_evm/kernel/src/migration.rs index 2cba33ebba46..8e413f2965e8 100644 --- a/etherlink/kernel_evm/kernel/src/migration.rs +++ b/etherlink/kernel_evm/kernel/src/migration.rs @@ -4,7 +4,6 @@ // // SPDX-License-Identifier: MIT -use crate::block_storage; use crate::blueprint_storage::{ blueprint_path, clear_all_blueprints, read_next_blueprint_number, }; @@ -128,7 +127,9 @@ fn migrate_to>( // // We need only the former. - let current_number = block_storage::read_current_number(host)?; + let current_number_path: RefPath = + RefPath::assert_from(b"/evm/world_state/blocks/current/number"); + let current_number = tezos_storage::read_u256_le(host, ¤t_number_path)?; let to_clean = U256::min( current_number + 1, evm_execution::storage::blocks::BLOCKS_STORED.into(), -- GitLab From 866353d073606a3497d012ab77c4a1f54518352d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 14:50:07 +0200 Subject: [PATCH 20/31] Etherlink/Kernel/Migration: use safe storage --- etherlink/kernel_evm/kernel/src/migration.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/migration.rs b/etherlink/kernel_evm/kernel/src/migration.rs index 8e413f2965e8..f4502ee99e83 100644 --- a/etherlink/kernel_evm/kernel/src/migration.rs +++ b/etherlink/kernel_evm/kernel/src/migration.rs @@ -22,7 +22,7 @@ use evm_execution::precompiles::WITHDRAWAL_ADDRESS; use evm_execution::NATIVE_TOKEN_TICKETER_PATH; use primitive_types::U256; use tezos_evm_logging::{log, Level::*}; -use tezos_evm_runtime::runtime::Runtime; +use tezos_evm_runtime::{runtime::Runtime, safe_storage::SafeStorage}; use tezos_smart_rollup::storage::path::RefPath; use tezos_smart_rollup_host::path::OwnedPath; use tezos_smart_rollup_host::runtime::RuntimeError; @@ -148,20 +148,24 @@ fn migrate_to>( // might clean the zero account by accident, and the account // must always exist as the ticket table is stored in the // zero address. + let mut host = SafeStorage { host }; let account_storage = init_account_storage()?; let account_path = account_path(&SYSTEM_ACCOUNT_ADDRESS)?; - let mut account = account_storage.get_or_create(host, &account_path)?; - account.increment_nonce(host)?; + let mut account = account_storage.get_or_create(&host, &account_path)?; + account.increment_nonce(&mut host)?; + host.promote()?; Ok(MigrationStatus::Done) } StorageVersion::V20 => { + let mut host = SafeStorage { host }; let account_storage = init_account_storage()?; let mut withdrawal_precompiled = account_storage - .get_or_create(host, &account_path(&WITHDRAWAL_ADDRESS)?)?; - let balance = withdrawal_precompiled.balance(host)?; + .get_or_create(&host, &account_path(&WITHDRAWAL_ADDRESS)?)?; + let balance = withdrawal_precompiled.balance(&host)?; if !balance.is_zero() { - withdrawal_precompiled.balance_remove(host, balance)?; + withdrawal_precompiled.balance_remove(&mut host, balance)?; } + host.promote()?; Ok(MigrationStatus::Done) } StorageVersion::V21 => { -- GitLab From 7d343b3c0a934c9045a5539a643ef0e47833fef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Thu, 9 Jan 2025 20:59:36 +0100 Subject: [PATCH 21/31] Etherlink/Kernel: use relative runtime for garbage collection of blocks --- etherlink/kernel_evm/kernel/src/inbox.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/inbox.rs b/etherlink/kernel_evm/kernel/src/inbox.rs index 1ba57a49bd48..f88796ee46ce 100644 --- a/etherlink/kernel_evm/kernel/src/inbox.rs +++ b/etherlink/kernel_evm/kernel/src/inbox.rs @@ -42,7 +42,7 @@ use tezos_ethereum::transaction::{ }; use tezos_ethereum::tx_common::EthereumTransactionCommon; use tezos_evm_logging::{log, Level::*}; -use tezos_evm_runtime::runtime::Runtime; +use tezos_evm_runtime::{relative_runtime::RelativeRuntime, runtime::Runtime}; use tezos_smart_rollup_encoding::public_key::PublicKey; #[allow(clippy::large_enum_variant)] @@ -534,7 +534,11 @@ 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)?; + let mut host = RelativeRuntime { + host: &mut *host, + root: &tezos_evm_runtime::safe_storage::WORLD_STATE_PATH, + }; + crate::block_storage::garbage_collect_blocks(&mut host)?; } store_last_info_per_level_timestamp(host, info.info.predecessor_timestamp)?; store_l1_level(host, info.level)? -- GitLab From 43c5252cf6ec9e59f1ce13761b99a3ae6b6dfb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 14:49:18 +0200 Subject: [PATCH 22/31] BROKEN TESTS: Etherlink/Kernel/Simulation: use safe storage --- etherlink/kernel_evm/kernel/src/simulation.rs | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/simulation.rs b/etherlink/kernel_evm/kernel/src/simulation.rs index 953aff1d0138..47814ea2205f 100644 --- a/etherlink/kernel_evm/kernel/src/simulation.rs +++ b/etherlink/kernel_evm/kernel/src/simulation.rs @@ -36,7 +36,9 @@ use tezos_ethereum::rlp_helpers::{ }; use tezos_ethereum::transaction::TransactionObject; use tezos_evm_logging::{log, Level::*}; -use tezos_evm_runtime::runtime::Runtime; +use tezos_evm_runtime::{ + relative_runtime::RelativeRuntime, runtime::Runtime, safe_storage::WORLD_STATE_PATH, +}; use tezos_smart_rollup::types::Timestamp; // SIMULATION/SIMPLE/RLP_ENCODED_SIMULATION @@ -371,9 +373,14 @@ impl Evaluation { enable_fa_withdrawals: bool, ) -> Result, Error> { let chain_id = retrieve_chain_id(host)?; - let minimum_base_fee_per_gas = crate::retrieve_minimum_base_fee_per_gas(host)?; - let da_fee = crate::retrieve_da_fee(host)?; let coinbase = read_sequencer_pool_address(host).unwrap_or_default(); + let mut host = RelativeRuntime { + root: &WORLD_STATE_PATH, + host, + }; + let minimum_base_fee_per_gas = + crate::retrieve_minimum_base_fee_per_gas(&mut host)?; + let da_fee = crate::retrieve_da_fee(&mut host)?; let mut evm_account_storage = account_storage::init_account_storage() .map_err(|_| Error::Storage(StorageError::AccountInitialisation))?; @@ -388,12 +395,12 @@ impl Evaluation { if let Some(value) = self.value { if from.is_zero() { let mut account = - evm_account_storage.get_or_create(host, &account_path(&from)?)?; - account.balance_add(host, value)?; + evm_account_storage.get_or_create(&host, &account_path(&from)?)?; + account.balance_add(&mut host, value)?; } } - let constants = match block_storage::read_current(host) { + let constants = match block_storage::read_current(&mut host) { Ok(block) => { // Timestamp is taken from the simulation caller if provided. // If the timestamp is missing, because of an older evm-node, @@ -427,7 +434,7 @@ impl Evaluation { .map(|timestamp| U256::from(timestamp.as_u64())) .unwrap_or_else(|| { U256::from( - read_last_info_per_level_timestamp(host) + read_last_info_per_level_timestamp(host.host) .unwrap_or(Timestamp::from(0)) .as_u64(), ) @@ -446,9 +453,9 @@ impl Evaluation { } }; - let precompiles = precompiles::precompile_set::(enable_fa_withdrawals); + let precompiles = precompiles::precompile_set(enable_fa_withdrawals); let tx_data_size = self.data.len() as u64; - let limits = fetch_limits(host); + let limits = fetch_limits(host.host); let allocated_ticks = tick_model::estimate_remaining_ticks_for_transaction_execution( limits.maximum_allowed_ticks, @@ -463,7 +470,7 @@ impl Evaluation { }; match run_transaction( - host, + &mut host, &constants, &mut evm_account_storage, &precompiles, @@ -651,7 +658,7 @@ mod tests { use primitive_types::H256; use tezos_ethereum::{block::BlockConstants, tx_signature::TxSignature}; - use tezos_evm_runtime::runtime::MockKernelHost; + use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; use crate::{retrieve_block_fees, retrieve_chain_id}; @@ -727,14 +734,14 @@ mod tests { const DUMMY_ALLOCATED_TICKS: u64 = 1_000_000_000; - fn create_contract(host: &mut Host) -> H160 + fn create_contract(host: &mut SafeStorage<&mut Host>) -> H160 where Host: Runtime, { let timestamp = - read_last_info_per_level_timestamp(host).unwrap_or(Timestamp::from(0)); + read_last_info_per_level_timestamp(host.host).unwrap_or(Timestamp::from(0)); let timestamp = U256::from(timestamp.as_u64()); - let chain_id = retrieve_chain_id(host); + let chain_id = retrieve_chain_id(host.host); assert!(chain_id.is_ok(), "chain_id should be defined"); let block_fees = retrieve_block_fees(host); assert!(chain_id.is_ok(), "chain_id should be defined"); @@ -746,7 +753,7 @@ mod tests { crate::block::GAS_LIMIT, H160::zero(), ); - let precompiles = precompiles::precompile_set::(false); + let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = account_storage::init_account_storage().unwrap(); let callee = None; @@ -790,7 +797,9 @@ mod tests { fn simulation_result() { // setup let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let new_address = create_contract(&mut host); + host.promote().unwrap(); // run evaluation num let evaluation = Evaluation { @@ -803,7 +812,7 @@ mod tests { with_da_fees: false, timestamp: None, }; - let outcome = evaluation.run(&mut host, None, false); + let outcome = evaluation.run(host.host, None, false); assert!(outcome.is_ok(), "evaluation should have succeeded"); let outcome = outcome.unwrap(); @@ -829,7 +838,7 @@ mod tests { with_da_fees: false, timestamp: None, }; - let outcome = evaluation.run(&mut host, None, false); + let outcome = evaluation.run(host.host, None, false); assert!(outcome.is_ok(), "simulation should have succeeded"); let outcome = outcome.unwrap(); @@ -848,7 +857,9 @@ mod tests { fn evaluation_result_no_gas() { // setup let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let new_address = create_contract(&mut host); + host.promote().unwrap(); // run evaluation num let evaluation = Evaluation { @@ -861,7 +872,7 @@ mod tests { with_da_fees: false, timestamp: None, }; - let outcome = evaluation.run(&mut host, None, false); + let outcome = evaluation.run(host.host, None, false); assert!(outcome.is_ok(), "evaluation should have succeeded"); let outcome = outcome.unwrap(); @@ -916,6 +927,7 @@ mod tests { fn parse_simulation2() { // setup let mut host = MockKernelHost::default(); + let mut host = SafeStorage { host: &mut host }; let new_address = create_contract(&mut host); let to = Some(new_address); -- GitLab From 41d1cad2d43c1e3cb8ad4e43d643556d6b06a628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Fri, 8 Nov 2024 11:43:59 +0100 Subject: [PATCH 23/31] BROKEN TESTS: Etherlink/Kernel: use relative runtime in promote_block --- etherlink/kernel_evm/kernel/src/block.rs | 47 +++++++++++++++++------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index 31123131e71e..bcb5db56377f 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -35,7 +35,10 @@ use primitive_types::{H160, H256, U256}; use tezos_ethereum::transaction::TransactionHash; use tezos_evm_logging::{log, Level::*, Verbosity}; use tezos_evm_runtime::runtime::Runtime; -use tezos_evm_runtime::safe_storage::SafeStorage; +use tezos_evm_runtime::{ + relative_runtime::RelativeRuntime, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, +}; use tezos_smart_rollup::outbox::OutboxQueue; use tezos_smart_rollup_host::path::{Path, RefPath}; use tick_model::estimate_remaining_ticks_for_transaction_execution; @@ -255,8 +258,12 @@ fn next_bip_from_blueprints>( return Ok(BlueprintParsing::None); } } - let gas_price = crate::gas_price::base_fee_per_gas( + let host = RelativeRuntime { + root: &WORLD_STATE_PATH, host, + }; + let gas_price = crate::gas_price::base_fee_per_gas( + &host, blueprint.timestamp, minimum_base_fee_per_gas, ); @@ -404,23 +411,28 @@ fn promote_block>( store_next_blueprint_number(safe_host.host, number.saturating_add(U256::one()))?; store_last_block_timestamp(safe_host.host, ¤t_timestamp)?; - let number = block_storage::read_current_number(safe_host.host)?; - let hash = block_storage::read_current_hash(safe_host.host)?; + let host: &mut Host = safe_host.host; + let mut relative_runtime = RelativeRuntime { + root: &WORLD_STATE_PATH, + host, + }; + let number = block_storage::read_current_number(&relative_runtime)?; + let hash = block_storage::read_current_hash(&relative_runtime)?; - Event::BlueprintApplied { number, hash }.store(safe_host.host)?; + Event::BlueprintApplied { number, hash }.store(relative_runtime.host)?; - let written = outbox_queue.flush_queue(safe_host.host); + let written = outbox_queue.flush_queue(&mut relative_runtime); // Log to Info only if we flushed messages. let level = if written > 0 { Info } else { Debug }; log!( - safe_host, + relative_runtime, level, "Flushed outbox queue messages ({} flushed)", written ); if let ConfigurationMode::Sequencer { delayed_inbox, .. } = &mut config.mode { - clean_delayed_transactions(safe_host.host, delayed_inbox, delayed_txs)?; + clean_delayed_transactions(relative_runtime.host, delayed_inbox, delayed_txs)?; } Ok(()) @@ -435,21 +447,26 @@ pub fn produce>( sequencer_pool_address: Option, tracer_input: Option, ) -> Result { - let minimum_base_fee_per_gas = crate::retrieve_minimum_base_fee_per_gas(host)?; - let da_fee_per_byte = crate::retrieve_da_fee(host)?; - let kernel_upgrade = upgrade::read_kernel_upgrade(host)?; // If there's a pool address, the coinbase in block constants and miner // in blocks is set to the pool address. let coinbase = sequencer_pool_address.unwrap_or_default(); + let mut relative_host = RelativeRuntime { + root: &WORLD_STATE_PATH, + host, + }; + let minimum_base_fee_per_gas = + crate::retrieve_minimum_base_fee_per_gas(&mut relative_host)?; + let da_fee_per_byte = crate::retrieve_da_fee(&mut relative_host)?; + let ( mut current_block_number, mut current_block_parent_hash, mut previous_receipts_root, mut previous_transactions_root, - ) = match block_storage::read_current(host) { + ) = match block_storage::read_current(&mut relative_host) { Ok(block) => ( block.number + 1, block.hash, @@ -463,9 +480,11 @@ pub fn produce>( let mut tick_counter = TickCounter::new(0u64); let mut first_block_of_reboot = true; - let at_most_one_block = host.store_has(&AT_MOST_ONE_BLOCK)?.is_some(); + let at_most_one_block = relative_host.host.store_has(&AT_MOST_ONE_BLOCK)?.is_some(); - let mut safe_host = SafeStorage { host }; + let mut safe_host = SafeStorage { + host: relative_host.host, + }; let outbox_queue = OutboxQueue::new( &WITHDRAWAL_OUTBOX_QUEUE, &WITHDRAWAL_OUTBOX_QUEUE_META, -- GitLab From ff71a2d7aab3f524383920b2dbc325ddc4be9a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 14:39:16 +0200 Subject: [PATCH 24/31] BROKEN TESTS: Etherlink/Kernel: Handle trace using relative paths --- .../kernel_evm/evm_evaluation/src/evalhost.rs | 19 ++++++++++- .../kernel_evm/evm_execution/src/storage.rs | 30 ++++++++-------- .../kernel_evm/indexable_storage/src/lib.rs | 24 ++++++++++++- .../runtime/src/relative_runtime.rs | 12 ++++++- etherlink/kernel_evm/runtime/src/runtime.rs | 34 +++++++++++++++++-- .../kernel_evm/runtime/src/safe_storage.rs | 18 +++++++++- 6 files changed, 115 insertions(+), 22 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index ad81e08d90bb..1434b6500511 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -8,7 +8,7 @@ use tezos_evm_logging::Verbosity; use tezos_evm_runtime::{ extensions::WithGas, internal_runtime::{ExtendedRuntime, InternalRuntime}, - runtime::MockKernelHost, + runtime::{MockKernelHost, TracePath, TraceRuntime}, }; use tezos_smart_rollup_host::{ dal_parameters::RollupDalParameters, @@ -37,11 +37,17 @@ impl<'a> EvalHost<'a> { } const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); +const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); fn world_state_path(p: &impl Path) -> Result, RuntimeError> { force_concat(&WORLD_STATE_PATH, p).map_err(|_| RuntimeError::PathNotFound) } +fn trace_path(p: &TracePath) -> Result, RuntimeError> { + let TracePath(p) = p; + force_concat(&TRACE_PATH, p).map_err(|_| RuntimeError::PathNotFound) +} + impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { @@ -263,3 +269,14 @@ impl<'a> WithGas for EvalHost<'a> { // evaluation fn add_execution_gas(&mut self, _gas: u64) {} } + +impl<'a> TraceRuntime for EvalHost<'a> { + fn store_write_all_trace( + &mut self, + path: &TracePath, + src: &[u8], + ) -> Result<(), RuntimeError> { + let path = trace_path(path)?; + self.host.store_write_all(&path, src) + } +} diff --git a/etherlink/kernel_evm/evm_execution/src/storage.rs b/etherlink/kernel_evm/evm_execution/src/storage.rs index d3511206776a..2450c4520752 100644 --- a/etherlink/kernel_evm/evm_execution/src/storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/storage.rs @@ -12,7 +12,7 @@ pub mod tracer { use primitive_types::H256; use tezos_evm_logging::log; use tezos_evm_logging::Level::Debug; - use tezos_evm_runtime::runtime::Runtime; + use tezos_evm_runtime::runtime::{Runtime, TracePath}; use tezos_indexable_storage::{IndexableStorage, IndexableStorageError}; use tezos_smart_rollup_host::path::*; use thiserror::Error; @@ -20,8 +20,6 @@ pub mod tracer { use crate::trace::CallTrace; use crate::trace::StructLog; - const EVM_TRACE: RefPath = RefPath::assert_from(b"/evm/trace"); - const GAS: RefPath = RefPath::assert_from(b"/gas"); const FAILED: RefPath = RefPath::assert_from(b"/failed"); const RETURN_VALUE: RefPath = RefPath::assert_from(b"/return_value"); @@ -40,17 +38,17 @@ pub mod tracer { pub fn trace_tx_path( hash: &Option, field: &RefPath, - ) -> Result, Error> { - let trace_tx_path = match hash { - None => EVM_TRACE.into(), + ) -> Result { + let path: OwnedPath = match hash { + None => concat(&RefPath::assert_from(b""), field).map_err(Error::PathError), Some(hash) => { let hash = hex::encode(hash); let raw_tx_path: Vec = format!("/{}", &hash).into(); let tx_path = OwnedPath::try_from(raw_tx_path)?; - concat(&EVM_TRACE, &tx_path)? + concat(&tx_path, field).map_err(Error::PathError) } - }; - concat(&trace_tx_path, field).map_err(Error::PathError) + }?; + Ok(TracePath(path)) } pub fn store_trace_gas>( @@ -59,7 +57,7 @@ pub mod tracer { hash: &Option, ) -> Result<(), Error> { let path = trace_tx_path(hash, &GAS)?; - host.store_write_all(&path, gas.to_le_bytes().as_slice())?; + host.store_write_all_trace(&path, gas.to_le_bytes().as_slice())?; Ok(()) } @@ -69,7 +67,7 @@ pub mod tracer { hash: &Option, ) -> Result<(), Error> { let path = trace_tx_path(hash, &FAILED)?; - host.store_write_all(&path, &[u8::from(!is_success)])?; + host.store_write_all_trace(&path, &[u8::from(!is_success)])?; log!(host, Debug, "Store trace info: is_success {}", is_success); Ok(()) } @@ -80,7 +78,7 @@ pub mod tracer { hash: &Option, ) -> Result<(), Error> { let path = trace_tx_path(hash, &RETURN_VALUE)?; - host.store_write_all(&path, value)?; + host.store_write_all_trace(&path, value)?; log!(host, Debug, "Store trace info: value {:?}", value); Ok(()) } @@ -92,10 +90,10 @@ pub mod tracer { ) -> Result<(), Error> { let logs = rlp::encode(&struct_log); - let path = trace_tx_path(hash, &STRUCT_LOGS)?; + let TracePath(path) = trace_tx_path(hash, &STRUCT_LOGS)?; let struct_logs_storage = IndexableStorage::new_owned_path(path); - struct_logs_storage.push_value(host, &logs)?; + struct_logs_storage.push_value_trace(host, &logs)?; log!(host, Debug, "Store trace info: logs {:?}", logs); Ok(()) @@ -110,10 +108,10 @@ pub mod tracer { ) -> Result<(), Error> { let encoded_call_trace = rlp::encode(&call_trace); - let path = trace_tx_path(hash, &CALL_TRACE)?; + let TracePath(path) = trace_tx_path(hash, &CALL_TRACE)?; let call_trace_storage = IndexableStorage::new_owned_path(path); - call_trace_storage.push_value(host, &encoded_call_trace)?; + call_trace_storage.push_value_trace(host, &encoded_call_trace)?; log!(host, Debug, "Store call trace: {:?}", call_trace); Ok(()) diff --git a/etherlink/kernel_evm/indexable_storage/src/lib.rs b/etherlink/kernel_evm/indexable_storage/src/lib.rs index 70bb0918ec5f..1e1ebf268e71 100644 --- a/etherlink/kernel_evm/indexable_storage/src/lib.rs +++ b/etherlink/kernel_evm/indexable_storage/src/lib.rs @@ -6,7 +6,7 @@ use rlp::DecoderError; use tezos_evm_logging::log; use tezos_evm_logging::Level::Error; -use tezos_evm_runtime::runtime::Runtime; +use tezos_evm_runtime::runtime::{Runtime, TracePath, TraceRuntime}; use tezos_smart_rollup_host::path::{concat, OwnedPath, PathError, RefPath}; use tezos_smart_rollup_host::runtime::RuntimeError; use tezos_smart_rollup_storage::StorageError; @@ -162,6 +162,28 @@ impl IndexableStorage { } } +impl IndexableStorage { + pub fn store_index_trace( + &self, + host: &mut impl TraceRuntime, + index: u64, + value_repr: &[u8], + ) -> Result<(), IndexableStorageError> { + let key_path = self.value_path(index)?; + host.store_write_all_trace(&TracePath(key_path), value_repr) + .map_err(IndexableStorageError::from) + } + + pub fn push_value_trace( + &self, + host: &mut impl Runtime, + value: &[u8], + ) -> Result<(), IndexableStorageError> { + let new_index = self.get_length_and_increment(host)?; + self.store_index_trace(host, new_index, value) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/etherlink/kernel_evm/runtime/src/relative_runtime.rs b/etherlink/kernel_evm/runtime/src/relative_runtime.rs index 0c9df060e592..36038c979589 100644 --- a/etherlink/kernel_evm/runtime/src/relative_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/relative_runtime.rs @@ -4,7 +4,7 @@ use crate::extensions::WithGas; use crate::internal_runtime::{ExtendedRuntime, InternalRuntime}; -use crate::runtime::Runtime; +use crate::runtime::{Runtime, TracePath, TraceRuntime}; use tezos_evm_logging::Verbosity; use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; @@ -248,3 +248,13 @@ impl> WithGas for RelativeRuntime<&mut Host> { self.host.add_execution_gas(gas) } } + +impl> TraceRuntime for RelativeRuntime<&mut Host> { + fn store_write_all_trace( + &mut self, + path: &TracePath, + src: &[u8], + ) -> Result<(), RuntimeError> { + self.host.store_write_all_trace(path, src) + } +} diff --git a/etherlink/kernel_evm/runtime/src/runtime.rs b/etherlink/kernel_evm/runtime/src/runtime.rs index 19885084a278..bde8f92060db 100644 --- a/etherlink/kernel_evm/runtime/src/runtime.rs +++ b/etherlink/kernel_evm/runtime/src/runtime.rs @@ -25,7 +25,7 @@ use tezos_smart_rollup_host::{ dal_parameters::RollupDalParameters, input::Message, metadata::RollupMetadata, - path::{Path, RefPath}, + path::{force_concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; use tezos_smart_rollup_mock::MockHost; @@ -33,12 +33,25 @@ use tezos_smart_rollup_mock::MockHost; // Set by the node, contains the verbosity for the logs pub const VERBOSITY_PATH: RefPath = RefPath::assert_from(b"/evm/logging_verbosity"); +const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); +pub struct TracePath(pub OwnedPath); + +pub trait TraceRuntime { + // Same as store_write_all but path is implicitely prefixed by /evm/trace/ + fn store_write_all_trace( + &mut self, + path: &TracePath, + src: &[u8], + ) -> Result<(), RuntimeError>; +} + pub trait Runtime: SdkRuntime + InternalRuntime + ExtendedRuntime + Verbosity + WithGas + + TraceRuntime { } @@ -50,7 +63,8 @@ impl< + InternalRuntime + ExtendedRuntime + Verbosity - + WithGas, + + WithGas + + TraceRuntime, > Runtime for T { } @@ -351,6 +365,22 @@ impl, Host: BorrowMut + Borrow> } } } + +impl, Host: BorrowMut + Borrow, Internal: InternalRuntime> + TraceRuntime for KernelHost +{ + fn store_write_all_trace( + &mut self, + path: &TracePath, + src: &[u8], + ) -> Result<(), RuntimeError> { + let TracePath(path) = path; + let absolute_path = + force_concat(&TRACE_PATH, path).map_err(|_| RuntimeError::PathNotFound)?; + self.store_write_all(&absolute_path, src) + } +} + pub type MockKernelHost = KernelHost; impl Default for MockKernelHost { diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index 1102ecc6f4af..d73d93b59d31 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -7,7 +7,7 @@ use crate::extensions::WithGas; use crate::internal_runtime::{ExtendedRuntime, InternalRuntime}; -use crate::runtime::Runtime; +use crate::runtime::{Runtime, TracePath, TraceRuntime}; use tezos_evm_logging::Verbosity; use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; @@ -29,6 +29,11 @@ pub fn safe_path>(path: &T) -> Result, RuntimeErro force_concat(&TMP_PATH, path).map_err(|_| RuntimeError::PathNotFound) } +pub fn safe_trace_path(path: &TracePath) -> Result, RuntimeError> { + let TracePath(path) = path; + force_concat(&TMP_TRACE_PATH, path).map_err(|_| RuntimeError::PathNotFound) +} + pub struct SafeStorage { pub host: Runtime, } @@ -277,3 +282,14 @@ impl> WithGas for SafeStorage<&mut Host> { self.host.add_execution_gas(gas) } } + +impl> TraceRuntime for SafeStorage<&mut Host> { + fn store_write_all_trace( + &mut self, + path: &TracePath, + src: &[u8], + ) -> Result<(), RuntimeError> { + let path = safe_trace_path(path)?; + self.host.store_write_all(&path, src) + } +} -- GitLab From 2432f4e81675ebbbc8c6b566c598a34f5bd077b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Thu, 24 Oct 2024 14:01:15 +0200 Subject: [PATCH 25/31] BROKEN TESTS: Etherlink/Kernel: use safe storage in main --- etherlink/kernel_evm/kernel/src/lib.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index 09eae102c4a4..52aac7b57b3b 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -28,7 +28,7 @@ use storage::{ use tezos_crypto_rs::hash::ContractKt1Hash; use tezos_evm_logging::{log, Level::*, Verbosity}; use tezos_evm_runtime::runtime::{KernelHost, Runtime}; -use tezos_evm_runtime::safe_storage::WORLD_STATE_PATH; +use tezos_evm_runtime::safe_storage::{SafeStorage, WORLD_STATE_PATH}; use tezos_smart_rollup::entrypoint; use tezos_smart_rollup::michelson::MichelsonUnit; use tezos_smart_rollup::outbox::{ @@ -290,14 +290,15 @@ pub fn main(host: &mut impl Runtime) -> Result<(), anyhow::Error> { return Ok(()); }; - let trace_input = read_tracer_input(host)?; + let host = SafeStorage { host }; + let trace_input = read_tracer_input(host.host)?; // Start processing blueprints #[cfg(not(feature = "benchmark-bypass-stage2"))] { log!(host, Debug, "Entering stage two."); if let block::ComputationResult::RebootNeeded = block::produce( - host, + host.host, chain_id, &mut configuration, sequencer_pool_address, @@ -305,7 +306,7 @@ pub fn main(host: &mut impl Runtime) -> Result<(), anyhow::Error> { ) .context("Failed during stage 2")? { - host.mark_for_reboot()?; + host.host.mark_for_reboot()?; } } -- GitLab From 40f8888134916fd951154b9b03266137d35200dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 14:53:12 +0200 Subject: [PATCH 26/31] BROKEN TESTS: Etherlink/Kernel: safe storage in config --- etherlink/kernel_evm/kernel/src/configuration.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/configuration.rs b/etherlink/kernel_evm/kernel/src/configuration.rs index 7bf0aa04eba8..c1d37f595061 100644 --- a/etherlink/kernel_evm/kernel/src/configuration.rs +++ b/etherlink/kernel_evm/kernel/src/configuration.rs @@ -13,7 +13,7 @@ use crate::{ use evm_execution::read_ticketer; use tezos_crypto_rs::hash::ContractKt1Hash; use tezos_evm_logging::{log, Level::*}; -use tezos_evm_runtime::runtime::Runtime; +use tezos_evm_runtime::{runtime::Runtime, safe_storage::SafeStorage}; use tezos_smart_rollup_encoding::public_key::PublicKey; #[derive(Debug, Clone, Default)] @@ -148,7 +148,9 @@ impl TezosContracts { fn fetch_tezos_contracts(host: &mut impl Runtime) -> TezosContracts { // 1. Fetch the kernel's ticketer, returns `None` if it is badly // encoded or absent. - let ticketer = read_ticketer(host); + let host = SafeStorage { host }; + let ticketer = read_ticketer(&host); + let host = host.host; // 2. Fetch the kernel's administrator, returns `None` if it is badly // encoded or absent. let admin = read_admin(host); -- GitLab From 80e17220310ce4ba4b15a51aaaa2453d3a4bf7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 14:53:39 +0200 Subject: [PATCH 27/31] BROKEN TESTS: Etherlink/Kernel: safe storage in blueprint storage --- etherlink/kernel_evm/kernel/src/blueprint_storage.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index 182428fcf5e8..cefbab53d1d2 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -21,8 +21,8 @@ use rlp::{Decodable, DecoderError, Encodable}; use sha3::{Digest, Keccak256}; use tezos_ethereum::rlp_helpers; use tezos_ethereum::tx_common::EthereumTransactionCommon; -use tezos_evm_logging::{log, Level::*}; -use tezos_evm_runtime::runtime::Runtime; +use tezos_evm_logging::{log, Level::*, Verbosity}; +use tezos_evm_runtime::{runtime::Runtime, safe_storage::SafeStorage}; use tezos_smart_rollup::types::Timestamp; use tezos_smart_rollup_core::MAX_INPUT_MESSAGE_SIZE; use tezos_smart_rollup_host::path::*; @@ -309,7 +309,8 @@ fn parse_and_validate_blueprint>( match rlp::decode::(bytes) { Err(e) => Ok((BlueprintValidity::DecoderError(e), bytes.len())), Ok(blueprint_with_hashes) => { - let head = block_storage::read_current(host); + let mut host = SafeStorage { host }; + let head = block_storage::read_current(&mut host); let (head_hash, head_timestamp) = match head { Ok(block) => (block.hash, block.timestamp), Err(_) => (GENESIS_PARENT_HASH, Timestamp::from(0)), @@ -340,7 +341,8 @@ fn parse_and_validate_blueprint>( // timestamps. #[cfg(not(feature = "benchmark"))] { - let last_seen_l1_timestamp = read_last_info_per_level_timestamp(host)?; + let last_seen_l1_timestamp = + read_last_info_per_level_timestamp(host.host)?; let accepted_bound = Timestamp::from( last_seen_l1_timestamp .i64() @@ -363,7 +365,7 @@ fn parse_and_validate_blueprint>( // Fetch delayed transactions fetch_delayed_txs( - host, + host.host, blueprint_with_hashes, delayed_inbox, current_blueprint_size, -- GitLab From e0c6e9a412be5446b7bac9739d778faffe86a889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Wed, 23 Oct 2024 14:31:14 +0200 Subject: [PATCH 28/31] DOES NOT COMPILE: Etherlink/Kernel: change IS_ABSOLUTE from true to false where appropriate --- .../kernel_evm/evm_evaluation/src/evalhost.rs | 34 ++++++------ .../evm_execution/src/account_storage.rs | 55 ++++++++++--------- .../evm_execution/src/code_storage.rs | 24 ++++---- .../evm_execution/src/fa_bridge/mod.rs | 12 ++-- .../evm_execution/src/fa_bridge/test_utils.rs | 18 +++--- .../evm_execution/src/fa_bridge/tests.rs | 4 ++ .../src/fa_bridge/ticket_table.rs | 8 +-- .../kernel_evm/evm_execution/src/handler.rs | 32 +++++------ etherlink/kernel_evm/evm_execution/src/lib.rs | 28 +++++----- .../evm_execution/src/precompiles/blake2.rs | 4 +- .../evm_execution/src/precompiles/ecdsa.rs | 2 +- .../src/precompiles/fa_bridge.rs | 4 +- .../evm_execution/src/precompiles/hash.rs | 4 +- .../evm_execution/src/precompiles/identity.rs | 2 +- .../evm_execution/src/precompiles/mod.rs | 18 +++--- .../evm_execution/src/precompiles/modexp.rs | 2 +- .../evm_execution/src/precompiles/revert.rs | 2 +- .../src/precompiles/withdrawal.rs | 2 +- .../src/precompiles/zero_knowledge.rs | 12 ++-- .../kernel_evm/evm_execution/src/storage.rs | 12 ++-- .../evm_execution/src/withdrawal_counter.rs | 4 +- .../kernel_evm/indexable_storage/src/lib.rs | 4 +- etherlink/kernel_evm/kernel/src/apply.rs | 28 ++++++---- etherlink/kernel_evm/kernel/src/block.rs | 22 ++++---- .../kernel/src/block_in_progress.rs | 12 ++-- .../kernel_evm/kernel/src/block_storage.rs | 28 +++++----- etherlink/kernel_evm/kernel/src/bridge.rs | 2 +- etherlink/kernel_evm/kernel/src/fees.rs | 6 +- etherlink/kernel_evm/kernel/src/gas_price.rs | 10 ++-- etherlink/kernel_evm/kernel/src/lib.rs | 10 ++-- etherlink/kernel_evm/kernel/src/storage.rs | 38 ++++++------- .../runtime/src/relative_runtime.rs | 40 +++++++------- .../kernel_evm/runtime/src/safe_storage.rs | 34 ++++++------ 33 files changed, 264 insertions(+), 253 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index 1434b6500511..091adba99331 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -48,7 +48,7 @@ fn trace_path(p: &TracePath) -> Result, RuntimeError> { force_concat(&TRACE_PATH, p).map_err(|_| RuntimeError::PathNotFound) } -impl<'a> SdkRuntime for EvalHost<'a> { +impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.host.write_output(from) @@ -68,7 +68,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_has>( + fn store_has>( &self, path: &T, ) -> Result, RuntimeError> { @@ -77,7 +77,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_read>( + fn store_read>( &self, path: &T, from_offset: usize, @@ -88,7 +88,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_read_slice>( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -99,13 +99,13 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { let path = world_state_path(path)?; self.host.store_read_all(&path) } #[inline(always)] - fn store_write>( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -116,7 +116,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_write_all>( + fn store_write_all>( &mut self, path: &T, src: &[u8], @@ -126,13 +126,13 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { let path = world_state_path(path)?; self.host.store_delete(&path) } #[inline(always)] - fn store_delete_value>( + fn store_delete_value>( &mut self, path: &T, ) -> Result<(), RuntimeError> { @@ -141,7 +141,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_count_subkeys>( + fn store_count_subkeys>( &self, prefix: &T, ) -> Result { @@ -152,8 +152,8 @@ impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = world_state_path(from_path)?; let to_path = world_state_path(to_path)?; @@ -163,8 +163,8 @@ impl<'a> SdkRuntime for EvalHost<'a> { #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = world_state_path(from_path)?; let to_path = world_state_path(to_path)?; @@ -181,7 +181,7 @@ impl<'a> SdkRuntime for EvalHost<'a> { } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { let path = world_state_path(path)?; self.host.store_value_size(&path) } @@ -248,10 +248,10 @@ impl<'a> InternalRuntime for EvalHost<'a> { } } -impl<'a> ExtendedRuntime for EvalHost<'a> { +impl<'a> ExtendedRuntime for EvalHost<'a> { fn store_get_hash( &mut self, - path: &impl Path, + path: &impl Path, ) -> Result, tezos_smart_rollup_host::runtime::RuntimeError> { let path = world_state_path(path)?; self.host.store_get_hash(&path) diff --git a/etherlink/kernel_evm/evm_execution/src/account_storage.rs b/etherlink/kernel_evm/evm_execution/src/account_storage.rs index c2c0626b3123..caf9e0e36560 100644 --- a/etherlink/kernel_evm/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/account_storage.rs @@ -120,11 +120,11 @@ pub struct StorageEffect { /// an account. We don't currently require it, and so it's omitted. #[derive(Debug, PartialEq)] pub struct EthereumAccount { - path: OwnedPath, + path: OwnedPath, } -impl From> for EthereumAccount { - fn from(path: OwnedPath) -> Self { +impl From> for EthereumAccount { + fn from(path: OwnedPath) -> Self { Self { path } } } @@ -210,7 +210,7 @@ impl EthereumAccount { /// Get the **nonce** for the Ethereum account. Default value is zero, so an account will /// _always_ have this **nonce**. - pub fn nonce(&self, host: &impl Runtime) -> Result { + pub fn nonce(&self, host: &impl Runtime) -> Result { let path = concat(&self.path, &NONCE_PATH)?; read_u64_le_default(host, &path, NONCE_DEFAULT_VALUE) .map_err(AccountStorageError::from) @@ -221,7 +221,7 @@ impl EthereumAccount { /// integer. pub fn increment_nonce( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &NONCE_PATH)?; @@ -239,7 +239,7 @@ impl EthereumAccount { pub fn decrement_nonce( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &NONCE_PATH)?; @@ -255,7 +255,7 @@ impl EthereumAccount { pub fn set_nonce( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, nonce: u64, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &NONCE_PATH)?; @@ -269,7 +269,7 @@ impl EthereumAccount { /// Get the **balance** of an account in Wei held by the account. pub fn balance( &self, - host: &impl Runtime, + host: &impl Runtime, ) -> Result { let path = concat(&self.path, &BALANCE_PATH)?; read_u256_le_default(host, &path, BALANCE_DEFAULT_VALUE) @@ -280,7 +280,7 @@ impl EthereumAccount { /// final amount exceeds the range of a a 256 bit unsigned integer. pub fn balance_add( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, amount: U256, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &BALANCE_PATH)?; @@ -304,7 +304,7 @@ impl EthereumAccount { /// ie the account held enough funds, the function returns `Ok(true)`. pub fn balance_remove( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, amount: U256, ) -> Result { let path = concat(&self.path, &BALANCE_PATH)?; @@ -326,7 +326,7 @@ impl EthereumAccount { /// Set the balance of an account to an amount in Wei pub fn set_balance( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, new_balance: U256, ) -> Result<(), AccountStorageError> { let path = concat(&self.path, &BALANCE_PATH)?; @@ -342,12 +342,15 @@ impl EthereumAccount { pub fn custom_path( &self, suffix: &impl Path, - ) -> Result, AccountStorageError> { + ) -> Result, AccountStorageError> { concat(&self.path, suffix).map_err(AccountStorageError::from) } /// Get the path to an index in durable storage for an account. - fn storage_path(&self, index: &H256) -> Result, AccountStorageError> { + fn storage_path( + &self, + index: &H256, + ) -> Result, AccountStorageError> { let storage_path = concat(&self.path, &STORAGE_ROOT_PATH)?; let index_path = path_from_h256(index)?; concat(&storage_path, &index_path).map_err(AccountStorageError::from) @@ -356,7 +359,7 @@ impl EthereumAccount { /// Clear the entire storage in durable storage for an account. pub fn clear_storage( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { let storage_path = concat(&self.path, &STORAGE_ROOT_PATH)?; if host.store_has(&storage_path)?.is_some() { @@ -369,7 +372,7 @@ impl EthereumAccount { /// Get the value stored in contract permanent storage at a given index for an account. pub fn get_storage( &self, - host: &impl Runtime, + host: &impl Runtime, index: &H256, ) -> Result { let path = self.storage_path(index)?; @@ -379,7 +382,7 @@ impl EthereumAccount { pub fn read_storage( &self, - host: &impl Runtime, + host: &impl Runtime, index: &H256, ) -> Result { let path = self.storage_path(index)?; @@ -396,7 +399,7 @@ impl EthereumAccount { /// non-default to default, et.c. This is for the purpose of calculating gas cost. pub fn set_storage_checked( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, index: &H256, value: &H256, ) -> Result { @@ -427,7 +430,7 @@ impl EthereumAccount { /// values being stored. This function does no tracking for the purpose of gas cost. pub fn set_storage( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, index: &H256, value: &H256, ) -> Result<(), AccountStorageError> { @@ -442,7 +445,7 @@ impl EthereumAccount { /// Find whether the account has any code associated with it. pub fn code_exists( &self, - host: &impl Runtime, + host: &impl Runtime, ) -> Result { let path = concat(&self.path, &CODE_HASH_PATH)?; @@ -461,7 +464,7 @@ impl EthereumAccount { // to have all legacy contract uses the new code storage. pub fn code( &self, - host: &impl Runtime, + host: &impl Runtime, ) -> Result, AccountStorageError> { let path = concat(&self.path, &CODE_PATH)?; @@ -482,7 +485,7 @@ impl EthereumAccount { /// stored when the code of a contract is set. pub fn code_hash( &self, - host: &impl Runtime, + host: &impl Runtime, ) -> Result { let path = concat(&self.path, &CODE_HASH_PATH)?; read_h256_be_default(host, &path, CODE_HASH_DEFAULT) @@ -493,7 +496,7 @@ impl EthereumAccount { /// computed and stored when the code of a contract is set. pub fn code_size( &self, - host: &impl Runtime, + host: &impl Runtime, ) -> Result { let path = concat(&self.path, &CODE_PATH)?; // If we ever do the lazy migration of code for account @@ -514,7 +517,7 @@ impl EthereumAccount { /// not before. pub fn set_code( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, code: &[u8], ) -> Result<(), AccountStorageError> { if self.code_exists(host)? { @@ -531,7 +534,7 @@ impl EthereumAccount { /// Delete all code associated with a contract. Also sets code length and size accordingly pub fn delete_code( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), AccountStorageError> { let code_hash_path = concat(&self.path, &CODE_HASH_PATH)?; @@ -557,12 +560,12 @@ impl EthereumAccount { } /// The type of the storage API for accessing the Ethereum World State. -pub type EthereumAccountStorage = Storage; +pub type EthereumAccountStorage = Storage; /// Get the storage API for accessing the Ethereum World State and do transactions /// on it. pub fn init_account_storage() -> Result { - Storage::::init(&EVM_ACCOUNTS_PATH) + Storage::::init(&EVM_ACCOUNTS_PATH) .map_err(AccountStorageError::from) } diff --git a/etherlink/kernel_evm/evm_execution/src/code_storage.rs b/etherlink/kernel_evm/evm_execution/src/code_storage.rs index c97ad081735b..28c5c3e23ada 100644 --- a/etherlink/kernel_evm/evm_execution/src/code_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/code_storage.rs @@ -28,11 +28,11 @@ fn code_hash_path(code_hash: &H256) -> Result, GenStorageError> #[derive(Debug, PartialEq)] pub struct CodeStorage { - path: OwnedPath, + path: OwnedPath, } -impl From> for CodeStorage { - fn from(path: OwnedPath) -> Self { +impl From> for CodeStorage { + fn from(path: OwnedPath) -> Self { Self { path } } } @@ -44,14 +44,14 @@ impl CodeStorage { Ok(Self { path }) } - fn exists(&self, host: &impl Runtime) -> Result { + fn exists(&self, host: &impl Runtime) -> Result { let store_has_code = host.store_has(&self.path)?; Ok(store_has_code.is_some()) } fn get_ref_count( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result { let reference_path = concat(&self.path, &REFERENCE_PATH)?; read_u64_le(host, &reference_path).or(Ok(0u64)) @@ -59,7 +59,7 @@ impl CodeStorage { fn set_ref_count( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, number_ref: u64, ) -> Result<(), GenStorageError> { let reference_path = concat(&self.path, &REFERENCE_PATH)?; @@ -69,7 +69,7 @@ impl CodeStorage { fn increment_code_usage( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result<(), GenStorageError> { let number_reference = self.get_ref_count(host)?; let number_reference = number_reference.saturating_add(1u64); @@ -78,7 +78,7 @@ impl CodeStorage { fn decrement_code_usage( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result { let number_reference = self.get_ref_count(host)?; let number_reference = number_reference.saturating_sub(1u64); @@ -87,7 +87,7 @@ impl CodeStorage { } pub fn add( - host: &mut impl Runtime, + host: &mut impl Runtime, bytecode: &[u8], ) -> Result { let code_hash: H256 = bytes_hash(bytecode); @@ -101,7 +101,7 @@ impl CodeStorage { } pub fn delete( - host: &mut impl Runtime, + host: &mut impl Runtime, code_hash: &H256, ) -> Result<(), GenStorageError> { let code = Self::new(code_hash)?; @@ -116,7 +116,7 @@ impl CodeStorage { } pub fn get_code( - host: &impl Runtime, + host: &impl Runtime, code_hash: &H256, ) -> Result, GenStorageError> { let code = Self::new(code_hash)?; @@ -129,7 +129,7 @@ impl CodeStorage { } pub fn code_size( - host: &impl Runtime, + host: &impl Runtime, code_hash: &H256, ) -> Result { let code = Self::new(code_hash)?; diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/mod.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/mod.rs index d5aa0a67c88c..d00227ddd52b 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/mod.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/mod.rs @@ -124,7 +124,7 @@ macro_rules! create_outcome_error { /// account storage transaction, and we can open one. #[allow(clippy::too_many_arguments)] #[cfg_attr(feature = "benchmark", inline(never))] -pub fn execute_fa_deposit<'a, Host: Runtime>( +pub fn execute_fa_deposit<'a, Host: Runtime>( host: &'a mut Host, block: &'a BlockConstants, evm_account_storage: &'a mut EthereumAccountStorage, @@ -193,7 +193,7 @@ pub fn execute_fa_deposit<'a, Host: Runtime>( /// on errors and the caller is responsible of cleaning up intermediate layer in /// case of errors (i.e. using `end_inter_transaction`). It also can return the /// withdrawal if it was succesful. -fn execute_layered_fa_withdrawal>( +fn execute_layered_fa_withdrawal>( handler: &mut EvmHandler, caller: H160, withdrawal: FaWithdrawal, @@ -226,7 +226,7 @@ fn execute_layered_fa_withdrawal>( /// another smart contract. /// /// We assume there is an open account storage transaction. -pub fn execute_fa_withdrawal>( +pub fn execute_fa_withdrawal>( handler: &mut EvmHandler, caller: H160, withdrawal: FaWithdrawal, @@ -311,7 +311,7 @@ pub fn execute_fa_withdrawal>( /// Updates ticket table according to the deposit and actual ticket owner. /// Assuming there is an open account storage transaction. -fn inner_execute_deposit>( +fn inner_execute_deposit>( handler: &mut EvmHandler, ticket_owner: H160, deposit: &FaDeposit, @@ -344,7 +344,7 @@ fn inner_execute_deposit>( /// Updates ticket ledger and outbox counter according to the withdrawal. /// Assuming there is an open account storage transaction. -fn inner_execute_withdrawal>( +fn inner_execute_withdrawal>( handler: &mut EvmHandler, withdrawal: &FaWithdrawal, ) -> Result { @@ -378,7 +378,7 @@ fn inner_execute_withdrawal>( /// Invokes proxy (ERC wrapper) contract from within a deposit or /// withdrawal handling function. /// Assuming there is an open account storage transaction. -fn inner_execute_proxy>( +fn inner_execute_proxy>( handler: &mut EvmHandler, caller: H160, proxy: H160, diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs index 39b2709d41a2..a0e912207129 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/test_utils.rs @@ -59,7 +59,7 @@ const REENTRANCY_TESTER_BYTECODE: &[u8] = /// Create a smart contract in the storage with the mocked token code pub fn deploy_mock_wrapper( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, ticket: &FA2_1Ticket, caller: &H160, @@ -102,7 +102,7 @@ pub fn deploy_mock_wrapper( /// Create a smart contract in the storage with the mocked token code pub fn deploy_reentrancy_tester( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, ticket: &FA2_1Ticket, caller: &H160, @@ -149,7 +149,7 @@ pub fn deploy_reentrancy_tester( /// Execute FA deposit pub fn run_fa_deposit( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, deposit: &FaDeposit, caller: &H160, @@ -198,7 +198,7 @@ pub fn dummy_fa_deposit(ticket: FA2_1Ticket, proxy: Option) -> FaDeposit { /// } /// } pub fn get_storage_flag( - host: &impl Runtime, + host: &impl Runtime, evm_account_storage: &EthereumAccountStorage, proxy: H160, ) -> u32 { @@ -232,7 +232,7 @@ pub fn dummy_block_constants() -> BlockConstants { /// Provision ticket balance for a specified account pub fn ticket_balance_add( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, ticket_hash: &H256, address: &H160, @@ -248,7 +248,7 @@ pub fn ticket_balance_add( /// Get ticket balance for a specified account pub fn ticket_balance_get( - host: &impl Runtime, + host: &impl Runtime, evm_account_storage: &EthereumAccountStorage, ticket_hash: &H256, address: &H160, @@ -266,7 +266,7 @@ pub fn ticket_balance_get( /// Get next withdrawal counter value pub fn withdrawal_counter_next( - host: &impl Runtime, + host: &impl Runtime, evm_account_storage: &EthereumAccountStorage, ) -> Option { let system = evm_account_storage @@ -282,7 +282,7 @@ pub fn withdrawal_counter_next( /// Provision TEZ balance for a specified account pub fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -381,7 +381,7 @@ pub fn dummy_fa_withdrawal( /// Execute FA withdrawal directly without going through the precompile pub fn fa_bridge_precompile_call_withdraw( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, withdrawal: FaWithdrawal, caller: H160, diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs index 006e731fbe58..03af83bdffdf 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs @@ -491,6 +491,10 @@ fn fa_withdrawal_fails_due_to_insufficient_balance() { #[test] fn fa_deposit_cannot_call_fa_withdrawal_precompile() { let mut mock_runtime = MockKernelHost::default(); + let mut mock_runtime = SafeStorage { + host: &mut mock_runtime, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = init_account_storage().unwrap(); let caller = H160::zero(); diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs index 2397652a21ae..da4c6215e53e 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs @@ -20,7 +20,7 @@ pub trait TicketTable { /// Increases ticket balance fn ticket_balance_add( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ticket_hash: &H256, address: &H160, amount: U256, @@ -29,7 +29,7 @@ pub trait TicketTable { /// Decreases ticket balance fn ticket_balance_remove( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ticket_hash: &H256, address: &H160, amount: U256, @@ -47,7 +47,7 @@ pub(crate) fn ticket_balance_path( impl TicketTable for EthereumAccount { fn ticket_balance_add( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ticket_hash: &H256, owner: &H160, amount: U256, @@ -65,7 +65,7 @@ impl TicketTable for EthereumAccount { fn ticket_balance_remove( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ticket_hash: &H256, owner: &H160, amount: U256, diff --git a/etherlink/kernel_evm/evm_execution/src/handler.rs b/etherlink/kernel_evm/evm_execution/src/handler.rs index 7ef642ef0cc1..9fcf9f688aaa 100644 --- a/etherlink/kernel_evm/evm_execution/src/handler.rs +++ b/etherlink/kernel_evm/evm_execution/src/handler.rs @@ -236,7 +236,7 @@ mod benchmarks { *b"__wasm_debugger__::start_section(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0)"; #[inline(always)] - pub fn start_opcode_section>(host: &mut Host, opcode: &Opcode) { + pub fn start_opcode_section>(host: &mut Host, opcode: &Opcode) { unsafe { START_OPCODE_SECTION_MSG[33] = opcode.as_u8(); host.write_debug(core::str::from_utf8_unchecked(&START_OPCODE_SECTION_MSG)); @@ -244,7 +244,7 @@ mod benchmarks { } #[inline(always)] - pub fn start_precompile_section>( + pub fn start_precompile_section>( host: &mut Host, address: H160, input: &Vec, @@ -272,7 +272,7 @@ mod benchmarks { *b"__wasm_debugger__::end_section()"; #[inline(always)] - pub fn end_opcode_section, T>( + pub fn end_opcode_section, T>( host: &mut Host, gas: u64, step_result: &Result<(), Capture>, @@ -285,7 +285,7 @@ mod benchmarks { } #[inline(always)] - pub fn end_precompile_section>(host: &mut Host) { + pub fn end_precompile_section>(host: &mut Host) { unsafe { host.write_debug(core::str::from_utf8_unchecked(&END_PRECOMPILE_SECTION_MSG)); } @@ -329,7 +329,7 @@ pub type LayerCache = HashMap; pub type StorageCache = HashMap; /// The implementation of the SputnikVM [Handler] trait -pub struct EvmHandler<'a, Host: Runtime> { +pub struct EvmHandler<'a, Host: Runtime> { /// The host pub host: &'a mut Host, /// The ethereum accounts storage @@ -369,7 +369,7 @@ pub struct EvmHandler<'a, Host: Runtime> { reentrancy_guard: ReentrancyGuard, } -impl<'a, Host: Runtime> EvmHandler<'a, Host> { +impl<'a, Host: Runtime> EvmHandler<'a, Host> { /// Create a new handler to suit a new, initial EVM call context #[allow(clippy::too_many_arguments)] pub fn new( @@ -2129,7 +2129,7 @@ impl<'a, Host: Runtime> EvmHandler<'a, Host> { } } -fn update_cache>( +fn update_cache>( handler: &mut EvmHandler<'_, Host>, address: H160, index: H256, @@ -2145,7 +2145,7 @@ fn update_cache>( } } -fn find_storage_key>( +fn find_storage_key>( handler: &mut EvmHandler<'_, Host>, address: H160, index: H256, @@ -2163,7 +2163,7 @@ fn find_storage_key>( /// Committing the storage cache means that the current layer changes /// are propagated to the previous one and the current layer is popped. -fn commit_storage_cache>( +fn commit_storage_cache>( handler: &mut EvmHandler<'_, Host>, current_layer: usize, ) { @@ -2177,7 +2177,7 @@ fn commit_storage_cache>( } } -fn cached_storage_access>( +fn cached_storage_access>( handler: &mut EvmHandler<'_, Host>, address: H160, index: H256, @@ -2209,7 +2209,7 @@ fn cached_storage_access>( } #[allow(unused_variables)] -impl<'a, Host: Runtime> Handler for EvmHandler<'a, Host> { +impl<'a, Host: Runtime> Handler for EvmHandler<'a, Host> { type CreateInterrupt = Infallible; type CreateFeedback = Infallible; type CallInterrupt = Infallible; @@ -2822,7 +2822,7 @@ mod test { const DUMMY_ALLOCATED_TICKS: u64 = 1_000_000_000; fn set_code( - handler: &mut EvmHandler<'_, impl Runtime>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, code: Vec, ) { @@ -2832,7 +2832,7 @@ mod test { } fn set_nonce( - handler: &mut EvmHandler<'_, impl Runtime>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, nonce: u64, ) { @@ -2841,7 +2841,7 @@ mod test { } fn get_balance( - handler: &mut EvmHandler<'_, impl Runtime>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, ) -> U256 { let account = handler.get_or_create_account(*address).unwrap(); @@ -2849,7 +2849,7 @@ mod test { } fn set_balance( - handler: &mut EvmHandler<'_, impl Runtime>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, new_balance: U256, ) { @@ -2873,7 +2873,7 @@ mod test { } fn get_durable_slot( - handler: &mut EvmHandler<'_, impl Runtime>, + handler: &mut EvmHandler<'_, impl Runtime>, address: &H160, index: &H256, ) -> H256 { diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index 52a6db3e9028..449d2d939bcf 100755 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -134,7 +134,7 @@ pub enum EthereumError { Tracer(#[from] tracer::Error), } -fn trace_outcome>( +fn trace_outcome>( handler: EvmHandler, is_success: bool, output: Option<&[u8]>, @@ -150,7 +150,7 @@ fn trace_outcome>( } #[allow(clippy::too_many_arguments)] -fn call_trace_outcome>( +fn call_trace_outcome>( handler: EvmHandler, base_call_type: &str, call_data: Vec, @@ -204,7 +204,7 @@ fn call_trace_outcome>( } #[allow(clippy::too_many_arguments)] -fn call_trace_error>( +fn call_trace_error>( handler: EvmHandler, base_call_type: &str, call_data: Vec, @@ -266,7 +266,7 @@ pub fn run_transaction<'a, Host>( tracer: Option, ) -> Result, EthereumError> where - Host: Runtime, + Host: Runtime, { fn do_refund(outcome: &handler::ExecutionOutcome, pay_for_gas: bool) -> bool { match outcome.result { @@ -423,7 +423,7 @@ pub const NATIVE_TOKEN_TICKETER_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/ticketer"); /// Reads the ticketer address set by the installer, if any, encoded in b58. -pub fn read_ticketer(host: &impl Runtime) -> Option { +pub fn read_ticketer(host: &impl Runtime) -> Option { let ticketer = host.store_read_all(&NATIVE_TOKEN_TICKETER_PATH).ok()?; let kt1_b58 = String::from_utf8(ticketer.to_vec()).ok()?; @@ -475,7 +475,7 @@ mod test { const DUMMY_ALLOCATED_TICKS: u64 = 1_000_000_000; fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -496,7 +496,7 @@ mod test { } fn set_storage( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, index: &H256, @@ -509,7 +509,7 @@ mod test { } fn get_storage( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, index: &H256, @@ -521,7 +521,7 @@ mod test { } fn get_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> U256 { @@ -533,7 +533,7 @@ mod test { // Simple utility function to set some code for an account fn set_account_code( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, code: &[u8], @@ -544,7 +544,7 @@ mod test { } fn get_code( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> Vec { @@ -555,7 +555,7 @@ mod test { } fn bump_nonce( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) { @@ -565,7 +565,7 @@ mod test { } fn get_nonce( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, ) -> u64 { @@ -3563,7 +3563,7 @@ mod test { } fn out_of_tick_scenario( - host: &mut impl Runtime, + host: &mut impl Runtime, retriable: bool, ) -> ( Result, EthereumError>, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs index f1953ae58159..ed0edbf304ee 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/blake2.rs @@ -112,7 +112,7 @@ fn blake2f_output_for_wrong_input() -> EthereumError { }) } -fn blake2f_precompile_without_gas_draining>( +fn blake2f_precompile_without_gas_draining>( handler: &mut EvmHandler, input: &[u8], ) -> Result { @@ -193,7 +193,7 @@ fn blake2f_precompile_without_gas_draining>( }) } -pub fn blake2f_precompile>( +pub fn blake2f_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs index b05be8a5d8f3..c39fcd536da1 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/ecdsa.rs @@ -52,7 +52,7 @@ fn erec_parse_inputs(input: &[u8]) -> ([u8; 32], [u8; 32], [u8; 64]) { } // Implementation of 0x01 ECDSA recover -pub fn ecrecover_precompile>( +pub fn ecrecover_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs index 0915f73b445d..d5cd5f9fa3dc 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs @@ -80,7 +80,7 @@ macro_rules! precompile_outcome_error { /// FA bridge precompile entrypoint. #[allow(unused)] -pub fn fa_bridge_precompile>( +pub fn fa_bridge_precompile>( handler: &mut EvmHandler, input: &[u8], context: &Context, @@ -184,7 +184,7 @@ mod tests { #[allow(clippy::too_many_arguments)] fn execute_precompile( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, caller: H160, value: U256, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs index e1e3f4e4ac38..6f51701f194b 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/hash.rs @@ -14,7 +14,7 @@ use tezos_evm_logging::Level::Debug; use tezos_evm_runtime::runtime::Runtime; // Implementation of 0x03 precompiled (sha256) -pub fn sha256_precompile>( +pub fn sha256_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, @@ -49,7 +49,7 @@ pub fn sha256_precompile>( } // Implementation of 0x04 precompiled (ripemd160) -pub fn ripemd160_precompile>( +pub fn ripemd160_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/identity.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/identity.rs index b38f9f1a6675..dc262d8e78a9 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/identity.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/identity.rs @@ -13,7 +13,7 @@ use tezos_evm_logging::Level::Debug; use tezos_evm_runtime::runtime::Runtime; // Implementation of 0x02 precompiled (identity) -pub fn identity_precompile>( +pub fn identity_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs index 1ff66c90ea1c..e54093da4de7 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs @@ -84,7 +84,7 @@ pub type PrecompileFn = fn( /// This is adapted from SputnikVM trait with same name. It has been /// modified to take the Host into account, so that precompiles can /// interact with log and durable storage and the rest of the kernel. -pub trait PrecompileSet> { +pub trait PrecompileSet> { /// Execute a single contract call to a precompiled contract. Should /// return None (and have no effect), if there is no precompiled contract /// at the address given. @@ -106,7 +106,7 @@ pub trait PrecompileSet> { /// One implementation for PrecompileSet above. Adapted from SputnikVM. pub type PrecompileBTreeMap = BTreeMap>; -impl> PrecompileSet for PrecompileBTreeMap { +impl> PrecompileSet for PrecompileBTreeMap { fn execute( &self, handler: &mut EvmHandler, @@ -117,7 +117,7 @@ impl> PrecompileSet for PrecompileBTreeMap { transfer: Option, ) -> Option> where - Host: Runtime, + Host: Runtime, { self.get(&address) .map(|precompile| (*precompile)(handler, input, context, is_static, transfer)) @@ -134,7 +134,7 @@ impl> PrecompileSet for PrecompileBTreeMap { type PrecompileWithoutGasDrainFn = fn(_: &mut EvmHandler, _: &[u8]) -> Result; -pub fn call_precompile_with_gas_draining>( +pub fn call_precompile_with_gas_draining>( handler: &mut EvmHandler, input: &[u8], precompile_contract_without_gas: PrecompileWithoutGasDrainFn, @@ -162,7 +162,7 @@ pub const WITHDRAWAL_ADDRESS: H160 = H160([ 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ]); -pub fn evm_precompile_set>() -> PrecompileBTreeMap { +pub fn evm_precompile_set>() -> PrecompileBTreeMap { BTreeMap::from([ ( H160::from_low_u64_be(1u64), @@ -204,7 +204,7 @@ pub fn evm_precompile_set>() -> PrecompileBTreeMap { } /// Factory function for generating the precompileset that the EVM kernel uses. -pub fn precompile_set>( +pub fn precompile_set>( enable_fa_withdrawals: bool, ) -> PrecompileBTreeMap { let mut precompiles = evm_precompile_set(); @@ -223,7 +223,7 @@ pub fn precompile_set>( precompiles } -pub fn precompile_set_with_revert_withdrawals>( +pub fn precompile_set_with_revert_withdrawals>( enable_fa_withdrawals: bool, ) -> PrecompileBTreeMap { let mut precompiles = evm_precompile_set(); @@ -301,7 +301,7 @@ mod test_helpers { pub const DUMMY_TICKETER: &str = "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5"; pub fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, @@ -390,7 +390,7 @@ mod test_helpers { ) } - fn set_ticketer(host: &mut impl Runtime, address: &str) { + fn set_ticketer(host: &mut impl Runtime, address: &str) { host.store_write(&NATIVE_TOKEN_TICKETER_PATH, address.as_bytes(), 0) .unwrap(); } diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs index 862dbc9382cc..0ea7608b945a 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/modexp.rs @@ -75,7 +75,7 @@ fn modexp_mod_overflow_exit(reason: &'static str) -> PrecompileOutcome { // to be taken up by the next value const HEADER_LENGTH: usize = 96; -pub fn modexp_precompile>( +pub fn modexp_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/revert.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/revert.rs index c87f23d4a1cb..873e06931137 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/revert.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/revert.rs @@ -12,7 +12,7 @@ use crate::{handler::EvmHandler, EthereumError}; use super::PrecompileOutcome; -pub fn revert_precompile>( +pub fn revert_precompile>( _handler: &mut EvmHandler, _input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs index b6f772623fa0..3703f8151e55 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/withdrawal.rs @@ -92,7 +92,7 @@ fn prepare_message( } /// Implementation of Etherlink specific withdrawals precompiled contract. -pub fn withdrawal_precompile>( +pub fn withdrawal_precompile>( handler: &mut EvmHandler, input: &[u8], context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs index f9fa04fe1f36..5360b7c04cb2 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/zero_knowledge.rs @@ -60,7 +60,7 @@ fn read_point(input: &[u8], pos: usize) -> Result { } } -fn ecadd_precompile_without_gas_draining>( +fn ecadd_precompile_without_gas_draining>( handler: &mut EvmHandler, input: &[u8], ) -> Result { @@ -103,7 +103,7 @@ fn ecadd_precompile_without_gas_draining>( }) } -pub fn ecadd_precompile>( +pub fn ecadd_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, @@ -117,7 +117,7 @@ pub fn ecadd_precompile>( ) } -fn ecmul_precompile_without_gas_draining>( +fn ecmul_precompile_without_gas_draining>( handler: &mut EvmHandler, input: &[u8], ) -> Result { @@ -158,7 +158,7 @@ fn ecmul_precompile_without_gas_draining>( }) } -pub fn ecmul_precompile>( +pub fn ecmul_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, @@ -172,7 +172,7 @@ pub fn ecmul_precompile>( ) } -fn ecpairing_precompile_without_gas_draining>( +fn ecpairing_precompile_without_gas_draining>( handler: &mut EvmHandler, input: &[u8], ) -> Result { @@ -281,7 +281,7 @@ fn ecpairing_precompile_without_gas_draining>( }) } -pub fn ecpairing_precompile>( +pub fn ecpairing_precompile>( handler: &mut EvmHandler, input: &[u8], _context: &Context, diff --git a/etherlink/kernel_evm/evm_execution/src/storage.rs b/etherlink/kernel_evm/evm_execution/src/storage.rs index 2450c4520752..7413fcf7f9b1 100644 --- a/etherlink/kernel_evm/evm_execution/src/storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/storage.rs @@ -51,7 +51,7 @@ pub mod tracer { Ok(TracePath(path)) } - pub fn store_trace_gas>( + pub fn store_trace_gas>( host: &mut Host, gas: u64, hash: &Option, @@ -61,7 +61,7 @@ pub mod tracer { Ok(()) } - pub fn store_trace_failed>( + pub fn store_trace_failed>( host: &mut Host, is_success: bool, hash: &Option, @@ -72,7 +72,7 @@ pub mod tracer { Ok(()) } - pub fn store_return_value>( + pub fn store_return_value>( host: &mut Host, value: &[u8], hash: &Option, @@ -83,7 +83,7 @@ pub mod tracer { Ok(()) } - pub fn store_struct_log>( + pub fn store_struct_log>( host: &mut Host, struct_log: StructLog, hash: &Option, @@ -101,7 +101,7 @@ pub mod tracer { const CALL_TRACE: RefPath = RefPath::assert_from(b"/call_trace"); - pub fn store_call_trace>( + pub fn store_call_trace>( host: &mut Host, call_trace: CallTrace, hash: &Option, @@ -165,7 +165,7 @@ pub mod blocks { /// Get block hash by block number. pub fn get_block_hash( - host: &impl Runtime, + host: &impl Runtime, block_number: U256, ) -> Result { let block_path = to_block_hash_path(block_number)?; diff --git a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs index 70243a238e75..f7ba7d01ae86 100644 --- a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs +++ b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs @@ -27,14 +27,14 @@ pub trait WithdrawalCounter { /// and increments & store the new value (will fail in case of overflow). fn withdrawal_counter_get_and_increment( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result; } impl WithdrawalCounter for EthereumAccount { fn withdrawal_counter_get_and_increment( &mut self, - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> Result { let path = self.custom_path(&WITHDRAWAL_COUNTER_PATH)?; let old_value = read_u256_le_default(host, &path, U256::zero())?; diff --git a/etherlink/kernel_evm/indexable_storage/src/lib.rs b/etherlink/kernel_evm/indexable_storage/src/lib.rs index 1e1ebf268e71..8a83012e4b96 100644 --- a/etherlink/kernel_evm/indexable_storage/src/lib.rs +++ b/etherlink/kernel_evm/indexable_storage/src/lib.rs @@ -162,7 +162,7 @@ impl IndexableStorage { } } -impl IndexableStorage { +impl IndexableStorage { pub fn store_index_trace( &self, host: &mut impl TraceRuntime, @@ -176,7 +176,7 @@ impl IndexableStorage { pub fn push_value_trace( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, value: &[u8], ) -> Result<(), IndexableStorageError> { let new_index = self.get_length_and_increment(host)?; diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index 91a213d8c1e6..da85e358fc81 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -175,7 +175,7 @@ fn make_object_info( }) } -fn account>( +fn account>( host: &mut Host, caller: H160, evm_account_storage: &mut EthereumAccountStorage, @@ -200,7 +200,7 @@ pub enum Validity { // TODO: https://gitlab.com/tezos/tezos/-/issues/6812 // arguably, effective_gas_price should be set on EthereumTransactionCommon // directly - initialised when constructed. -fn is_valid_ethereum_transaction_common>( +fn is_valid_ethereum_transaction_common>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, transaction: &EthereumTransactionCommon, @@ -288,7 +288,11 @@ pub struct TransactionResult { /// Technically incorrect: it is possible to do a call without sending any data, /// however it's done for benchmarking only, and benchmarking doesn't include /// such a scenario -fn log_transaction_type>(host: &Host, to: Option, data: &[u8]) { +fn log_transaction_type>( + host: &Host, + to: Option, + data: &[u8], +) { if to.is_none() { log!(host, Benchmarking, "Transaction type: CREATE"); } else if data.is_empty() { @@ -299,7 +303,7 @@ fn log_transaction_type>(host: &Host, to: Option, data } #[allow(clippy::too_many_arguments)] -fn apply_ethereum_transaction_common>( +fn apply_ethereum_transaction_common>( host: &mut Host, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, @@ -388,7 +392,7 @@ fn apply_ethereum_transaction_common>( } } -fn trace_deposit>( +fn trace_deposit>( host: &mut Host, amount: U256, receiver: Option, @@ -420,7 +424,7 @@ fn trace_deposit>( } } -fn apply_deposit>( +fn apply_deposit>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, deposit: &Deposit, @@ -448,7 +452,7 @@ fn apply_deposit>( } #[allow(clippy::too_many_arguments)] -fn apply_fa_deposit>( +fn apply_fa_deposit>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, fa_deposit: &FaDeposit, @@ -526,9 +530,9 @@ impl From> for ExecutionResult { } #[allow(clippy::too_many_arguments)] -pub fn handle_transaction_result>( +pub fn handle_transaction_result>( host: &mut Host, - outbox_queue: &OutboxQueue<'_, true, impl Path>, + outbox_queue: &OutboxQueue<'_, false, impl Path>, block_constants: &BlockConstants, transaction: &Transaction, index: u32, @@ -586,9 +590,9 @@ pub fn handle_transaction_result>( } #[allow(clippy::too_many_arguments)] -pub fn apply_transaction>( +pub fn apply_transaction>( host: &mut Host, - outbox_queue: &OutboxQueue<'_, true, impl Path>, + outbox_queue: &OutboxQueue<'_, false, impl Path>, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, transaction: &Transaction, @@ -724,7 +728,7 @@ mod tests { } fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: &H160, balance: U256, diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index bcb5db56377f..9bb73178f63e 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -80,7 +80,7 @@ pub enum ComputationResult { Finished, } -fn on_invalid_transaction>( +fn on_invalid_transaction>( host: &mut Host, transaction: &Transaction, block_in_progress: &mut BlockInProgress, @@ -100,9 +100,9 @@ fn on_invalid_transaction>( } #[allow(clippy::too_many_arguments)] -fn compute>( +fn compute>( host: &mut Host, - outbox_queue: &OutboxQueue<'_, true, impl Path>, + outbox_queue: &OutboxQueue<'_, false, impl Path>, block_in_progress: &mut BlockInProgress, block_constants: &BlockConstants, precompiles: &PrecompileBTreeMap, @@ -288,9 +288,9 @@ fn next_bip_from_blueprints>( } #[allow(clippy::too_many_arguments)] -fn compute_bip>( +fn compute_bip>( host: &mut Host, - outbox_queue: &OutboxQueue<'_, true, impl Path>, + outbox_queue: &OutboxQueue<'_, false, impl Path>, mut block_in_progress: BlockInProgress, current_block_number: &mut U256, current_block_parent_hash: &mut H256, @@ -395,7 +395,7 @@ fn clean_delayed_transactions( fn promote_block>( safe_host: &mut SafeStorage<&mut Host>, - outbox_queue: &OutboxQueue<'_, true, impl Path>, + outbox_queue: &OutboxQueue<'_, false, impl Path>, block_in_progress: bool, number: U256, config: &mut Configuration, @@ -694,7 +694,7 @@ mod tests { Some(H160::from_slice(data)) } - fn set_balance>( + fn set_balance>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, address: &H160, @@ -715,7 +715,7 @@ mod tests { } } - fn get_balance>( + fn get_balance>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, address: &H160, @@ -860,7 +860,7 @@ mod tests { } } - fn store_block_fees>( + fn store_block_fees>( host: &mut Host, block_fees: &BlockFees, ) -> anyhow::Result<()> { @@ -920,7 +920,7 @@ mod tests { .expect("The block production failed."); } - fn assert_current_block_reading_validity>(host: &mut Host) { + fn assert_current_block_reading_validity>(host: &mut Host) { match block_storage::read_current(host) { Ok(_) => (), Err(e) => { @@ -1565,7 +1565,7 @@ mod tests { blueprint(transactions) } - fn check_current_block_number>(host: &mut Host, nb: usize) { + fn check_current_block_number>(host: &mut Host, nb: usize) { let current_nb = block_storage::read_current_number(host) .expect("Should have manage to check block number"); assert_eq!(current_nb, U256::from(nb), "Incorrect block number"); diff --git a/etherlink/kernel_evm/kernel/src/block_in_progress.rs b/etherlink/kernel_evm/kernel/src/block_in_progress.rs index d78d6612b92b..bbc0b3f1b9ef 100644 --- a/etherlink/kernel_evm/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_evm/kernel/src/block_in_progress.rs @@ -286,7 +286,7 @@ impl BlockInProgress { self.delayed_txs.push(hash); } - pub fn register_valid_transaction>( + pub fn register_valid_transaction>( &mut self, transaction: &Transaction, object_info: TransactionObjectInfo, @@ -347,9 +347,9 @@ impl BlockInProgress { self.add_ticks(tick_model::ticks_of_invalid_transaction(tx_data_size)); } - fn safe_store_get_hash>( + fn safe_store_get_hash>( host: &mut Host, - path: &RefPath, + path: &RefPath, ) -> Result, anyhow::Error> { match host.store_get_hash(path) { Ok(hash) => Ok(hash), @@ -364,7 +364,7 @@ impl BlockInProgress { fn receipts_root( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, previous_receipts_root: Vec, ) -> anyhow::Result> { if self.valid_txs.is_empty() { @@ -389,7 +389,7 @@ impl BlockInProgress { fn transactions_root( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, previous_transactions_root: Vec, ) -> anyhow::Result> { if self.valid_txs.is_empty() { @@ -411,7 +411,7 @@ impl BlockInProgress { } #[cfg_attr(feature = "benchmark", inline(never))] - pub fn finalize_and_store>( + pub fn finalize_and_store>( self, host: &mut Host, block_constants: &BlockConstants, diff --git a/etherlink/kernel_evm/kernel/src/block_storage.rs b/etherlink/kernel_evm/kernel/src/block_storage.rs index 3155fcd1b211..5a2a04b8ccb0 100644 --- a/etherlink/kernel_evm/kernel/src/block_storage.rs +++ b/etherlink/kernel_evm/kernel/src/block_storage.rs @@ -36,7 +36,7 @@ mod path { /// Path to the block in the storage. The path to the block is /// indexed by its hash. - pub fn path(hash: H256) -> anyhow::Result> { + pub fn path(hash: H256) -> anyhow::Result> { let hash = hex::encode(hash); let raw_hash_path: Vec = format!("/{}", &hash).into(); let hash_path = OwnedPath::try_from(raw_hash_path)?; @@ -45,18 +45,18 @@ mod path { } fn store_current_number( - host: &mut impl Runtime, + host: &mut impl Runtime, number: U256, ) -> anyhow::Result<()> { Ok(write_u256_le(host, &path::CURRENT_NUMBER, number)?) } -fn store_current_hash(host: &mut impl Runtime, hash: H256) -> anyhow::Result<()> { +fn store_current_hash(host: &mut impl Runtime, hash: H256) -> anyhow::Result<()> { write_h256_be(host, &path::CURRENT_HASH, hash) } fn store_block( - host: &mut impl Runtime, + host: &mut impl Runtime, block: &L2Block, index_block: bool, ) -> anyhow::Result<()> { @@ -72,7 +72,7 @@ fn store_block( } fn store_current_index_or_not( - host: &mut impl Runtime, + host: &mut impl Runtime, block: &L2Block, index_block: bool, ) -> anyhow::Result<()> { @@ -92,28 +92,28 @@ fn store_current_index_or_not( } pub fn store_current( - host: &mut impl Runtime, + host: &mut impl Runtime, block: &L2Block, ) -> anyhow::Result<()> { store_current_index_or_not(host, block, true) } pub fn restore_current( - host: &mut impl Runtime, + host: &mut impl Runtime, block: &L2Block, ) -> anyhow::Result<()> { store_current_index_or_not(host, block, false) } -pub fn read_current_number(host: &impl Runtime) -> anyhow::Result { +pub fn read_current_number(host: &impl Runtime) -> anyhow::Result { Ok(read_u256_le(host, &path::CURRENT_NUMBER)?) } -pub fn read_current_hash(host: &impl Runtime) -> anyhow::Result { +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) -> anyhow::Result { let hash = read_current_hash(host)?; let block_path = path::path(hash)?; let bytes = &host.store_read_all(&block_path)?; @@ -122,13 +122,13 @@ pub fn read_current(host: &mut impl Runtime) -> anyhow::Result { } pub fn read_current_timestamp( - host: &mut impl Runtime, + host: &mut impl Runtime, ) -> anyhow::Result { let block = read_current(host)?; Ok(block.timestamp) } -pub fn garbage_collect_blocks(host: &mut impl Runtime) -> anyhow::Result<()> { +pub fn garbage_collect_blocks(host: &mut impl Runtime) -> anyhow::Result<()> { log!(host, Debug, "Garbage collecting blocks."); if let Ok(block) = read_current(host) { // The kernel needs the current block to process the next one. Therefore @@ -146,12 +146,12 @@ pub fn garbage_collect_blocks(host: &mut impl Runtime) -> anyhow::Result<( pub mod internal_for_tests { use super::*; - pub fn init_blocks_index() -> anyhow::Result> { + pub fn init_blocks_index() -> anyhow::Result> { Ok(IndexableStorage::new(&path::INDEXES)?) } pub fn store_current_number( - host: &mut impl Runtime, + host: &mut impl Runtime, number: U256, ) -> anyhow::Result<()> { super::store_current_number(host, number) diff --git a/etherlink/kernel_evm/kernel/src/bridge.rs b/etherlink/kernel_evm/kernel/src/bridge.rs index 841514e3803d..a7adbb515530 100644 --- a/etherlink/kernel_evm/kernel/src/bridge.rs +++ b/etherlink/kernel_evm/kernel/src/bridge.rs @@ -177,7 +177,7 @@ impl Decodable for Deposit { } } -pub fn execute_deposit>( +pub fn execute_deposit>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, deposit: &Deposit, diff --git a/etherlink/kernel_evm/kernel/src/fees.rs b/etherlink/kernel_evm/kernel/src/fees.rs index f02dbeefae7a..e79ff723cbd3 100644 --- a/etherlink/kernel_evm/kernel/src/fees.rs +++ b/etherlink/kernel_evm/kernel/src/fees.rs @@ -167,7 +167,7 @@ impl FeeUpdates { pub fn apply( &self, - host: &mut impl Runtime, + host: &mut impl Runtime, accounts: &mut EthereumAccountStorage, caller: H160, sequencer_pool_address: Option, @@ -513,7 +513,7 @@ mod tests { } fn get_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: H160, ) -> U256 { @@ -524,7 +524,7 @@ mod tests { } fn set_balance( - host: &mut impl Runtime, + host: &mut impl Runtime, evm_account_storage: &mut EthereumAccountStorage, address: H160, balance: U256, diff --git a/etherlink/kernel_evm/kernel/src/gas_price.rs b/etherlink/kernel_evm/kernel/src/gas_price.rs index a62f2e1fc06a..640936ad6b6d 100644 --- a/etherlink/kernel_evm/kernel/src/gas_price.rs +++ b/etherlink/kernel_evm/kernel/src/gas_price.rs @@ -23,7 +23,7 @@ const ALPHA: F64 = softfloat::f64!(0.000_000_000_007); /// Register a completed block into the tick backlog pub fn register_block( - host: &mut impl Runtime, + host: &mut impl Runtime, bip: &BlockInProgress, ) -> anyhow::Result<()> { if bip.queue_length() > 0 { @@ -37,7 +37,7 @@ pub fn register_block( /// Retrieve *base fee per gas*, according to the current timestamp. pub fn base_fee_per_gas( - host: &impl Runtime, + host: &impl Runtime, timestamp: Timestamp, minimum_gas_price: U256, ) -> U256 { @@ -53,7 +53,7 @@ pub fn base_fee_per_gas( } fn backlog_with_time_elapsed( - host: &impl Runtime, + host: &impl Runtime, extra_ticks: u64, current_timestamp: u64, last_timestamp: u64, @@ -69,7 +69,7 @@ fn backlog_with_time_elapsed( } fn update_tick_backlog( - host: &mut impl Runtime, + host: &mut impl Runtime, ticks_in_block: u64, timestamp: Timestamp, ) -> anyhow::Result<()> { @@ -242,7 +242,7 @@ mod test { ); } - fn load_gas_price(host: &mut impl Runtime) -> (U256, U256) { + fn load_gas_price(host: &mut impl Runtime) -> (U256, U256) { let bf = crate::retrieve_block_fees(host).unwrap(); (bf.minimum_base_fee_per_gas(), bf.base_fee_per_gas()) diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index 52aac7b57b3b..f0260598aa2d 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -159,7 +159,7 @@ fn retrieve_chain_id(host: &mut impl Runtime) -> Result { } } -fn retrieve_minimum_base_fee_per_gas>( +fn retrieve_minimum_base_fee_per_gas>( host: &mut Host, ) -> Result { match read_minimum_base_fee_per_gas(host) { @@ -173,7 +173,7 @@ fn retrieve_minimum_base_fee_per_gas>( } #[cfg(test)] -fn retrieve_base_fee_per_gas>( +fn retrieve_base_fee_per_gas>( host: &mut Host, minimum_base_fee_per_gas: U256, ) -> U256 { @@ -190,7 +190,7 @@ fn retrieve_base_fee_per_gas>( } } -fn retrieve_da_fee>(host: &mut Host) -> Result { +fn retrieve_da_fee>(host: &mut Host) -> Result { match read_da_fee(host) { Ok(da_fee) => Ok(da_fee), Err(_) => { @@ -202,7 +202,7 @@ fn retrieve_da_fee>(host: &mut Host) -> Result } #[cfg(test)] -fn retrieve_block_fees>( +fn retrieve_block_fees>( host: &mut Host, ) -> Result { let minimum_base_fee_per_gas = retrieve_minimum_base_fee_per_gas(host)?; @@ -445,7 +445,7 @@ mod tests { ) } - fn set_balance>( + fn set_balance>( host: &mut Host, evm_account_storage: &mut EthereumAccountStorage, address: &H160, diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index 4b98e5832c99..1a6a5e741c77 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -179,14 +179,14 @@ const EVM_NODE_FLAG: RefPath = RefPath::assert_from(b"/__evm_node"); const MAX_BLUEPRINT_LOOKAHEAD_IN_SECONDS: RefPath = RefPath::assert_from(b"/evm/max_blueprint_lookahead_in_seconds"); -pub fn receipt_path(receipt_hash: &TransactionHash) -> Result, Error> { +pub fn receipt_path(receipt_hash: &TransactionHash) -> Result, Error> { let hash = hex::encode(receipt_hash); let raw_receipt_path: Vec = format!("/{}", &hash).into(); let receipt_path = OwnedPath::try_from(raw_receipt_path)?; concat(&EVM_TRANSACTIONS_RECEIPTS, &receipt_path).map_err(Error::from) } -pub fn object_path(object_hash: &TransactionHash) -> Result, Error> { +pub fn object_path(object_hash: &TransactionHash) -> Result, Error> { let hash = hex::encode(object_hash); let raw_object_path: Vec = format!("/{}", &hash).into(); let object_path = OwnedPath::try_from(raw_object_path)?; @@ -206,7 +206,7 @@ pub fn store_simulation_result, T: Decodable + Encodable>( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn store_transaction_receipt>( +pub fn store_transaction_receipt>( host: &mut Host, receipt: &TransactionReceipt, ) -> Result { @@ -221,7 +221,7 @@ pub fn store_transaction_receipt>( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn store_transaction_object>( +pub fn store_transaction_object>( host: &mut Host, object: &TransactionObject, ) -> Result { @@ -457,36 +457,36 @@ pub fn read_chain_id>(host: &Host) -> Result { read_u256_le(host, &EVM_CHAIN_ID).map_err(Error::from) } -pub fn read_minimum_base_fee_per_gas>( +pub fn read_minimum_base_fee_per_gas>( host: &Host, ) -> Result { read_u256_le(host, &EVM_MINIMUM_BASE_FEE_PER_GAS).map_err(Error::from) } -pub fn read_tick_backlog(host: &impl Runtime) -> Result { +pub fn read_tick_backlog(host: &impl Runtime) -> Result { read_u64_le(host, &TICK_BACKLOG_PATH).map_err(Error::from) } pub fn store_tick_backlog( - host: &mut impl Runtime, + host: &mut impl Runtime, value: u64, ) -> Result<(), Error> { write_u64_le(host, &TICK_BACKLOG_PATH, value).map_err(Error::from) } -pub fn read_tick_backlog_timestamp(host: &impl Runtime) -> Result { +pub fn read_tick_backlog_timestamp(host: &impl Runtime) -> Result { read_u64_le(host, &TICK_BACKLOG_TIMESTAMP_PATH).map_err(Error::from) } pub fn store_tick_backlog_timestamp( - host: &mut impl Runtime, + host: &mut impl Runtime, value: u64, ) -> Result<(), Error> { write_u64_le(host, &TICK_BACKLOG_TIMESTAMP_PATH, value)?; Ok(()) } -pub fn store_minimum_base_fee_per_gas>( +pub fn store_minimum_base_fee_per_gas>( host: &mut Host, price: U256, ) -> Result<(), Error> { @@ -494,18 +494,18 @@ pub fn store_minimum_base_fee_per_gas>( } pub fn store_da_fee( - host: &mut impl Runtime, + host: &mut impl Runtime, base_fee_per_gas: U256, ) -> Result<(), Error> { write_u256_le(host, &EVM_DA_FEE, base_fee_per_gas).map_err(Error::from) } -pub fn read_da_fee(host: &impl Runtime) -> Result { +pub fn read_da_fee(host: &impl Runtime) -> Result { read_u256_le(host, &EVM_DA_FEE).map_err(Error::from) } pub fn update_burned_fees( - host: &mut impl Runtime, + host: &mut impl Runtime, burned_fee: U256, ) -> Result<(), Error> { let path = &EVM_BURNED_FEES; @@ -515,7 +515,7 @@ pub fn update_burned_fees( } #[cfg(test)] -pub fn read_burned_fees(host: &mut impl Runtime) -> U256 { +pub fn read_burned_fees(host: &mut impl Runtime) -> U256 { let path = &EVM_BURNED_FEES; read_u256_le(host, path).unwrap_or_else(|_| U256::zero()) } @@ -712,7 +712,7 @@ pub fn store_kernel_version>( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn store_block_in_progress>( +pub fn store_block_in_progress>( host: &mut Host, bip: &BlockInProgress, ) -> anyhow::Result<()> { @@ -732,7 +732,7 @@ pub fn store_block_in_progress>( // Never inlined when the kernel is compiled for benchmarks, to ensure the // function is visible in the profiling results. #[cfg_attr(feature = "benchmark", inline(never))] -pub fn read_block_in_progress>( +pub fn read_block_in_progress>( host: &Host, ) -> anyhow::Result> { let path = OwnedPath::from(EVM_BLOCK_IN_PROGRESS); @@ -755,7 +755,7 @@ pub fn read_block_in_progress>( } } -pub fn delete_block_in_progress>( +pub fn delete_block_in_progress>( host: &mut Host, ) -> anyhow::Result<()> { host.store_delete(&EVM_BLOCK_IN_PROGRESS) @@ -936,7 +936,7 @@ mod internal_for_tests { use tezos_ethereum::transaction::TransactionStatus; /// Reads status from the receipt in storage. - pub fn read_transaction_receipt_status>( + pub fn read_transaction_receipt_status>( host: &mut Host, tx_hash: &TransactionHash, ) -> Result { @@ -945,7 +945,7 @@ mod internal_for_tests { } /// Reads a transaction receipt from storage. - pub fn read_transaction_receipt>( + pub fn read_transaction_receipt>( host: &mut Host, tx_hash: &TransactionHash, ) -> Result { diff --git a/etherlink/kernel_evm/runtime/src/relative_runtime.rs b/etherlink/kernel_evm/runtime/src/relative_runtime.rs index 36038c979589..9df2a42f6b0a 100644 --- a/etherlink/kernel_evm/runtime/src/relative_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/relative_runtime.rs @@ -11,7 +11,7 @@ use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; use tezos_smart_rollup_host::{ input::Message, metadata::RollupMetadata, - path::{force_concat, OwnedPath, Path, RefPath}, + path::{concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; @@ -23,9 +23,9 @@ pub struct RelativeRuntime { impl RelativeRuntime { pub fn absolute_path( &self, - path: &impl Path, + path: &impl Path, ) -> Result, RuntimeError> { - force_concat(self.root, path).map_err(|_| RuntimeError::PathNotFound) + concat(self.root, path).map_err(|_| RuntimeError::PathNotFound) } } @@ -38,18 +38,18 @@ impl> InternalRuntime for RelativeRuntime<&mut Host> { } } -impl> ExtendedRuntime for RelativeRuntime<&mut Host> { +impl> ExtendedRuntime for RelativeRuntime<&mut Host> { #[inline(always)] fn store_get_hash( &mut self, - path: &impl Path, + path: &impl Path, ) -> Result, RuntimeError> { let path = self.absolute_path(path)?; self.__internal_store_get_hash(&path) } } -impl> SdkRuntime for RelativeRuntime<&mut Host> { +impl> SdkRuntime for RelativeRuntime<&mut Host> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.write_output(from) @@ -66,7 +66,7 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_has>( + fn store_has>( &self, path: &P, ) -> Result, RuntimeError> { @@ -75,7 +75,7 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_read>( + fn store_read>( &self, path: &P, from_offset: usize, @@ -86,7 +86,7 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_read_slice>( + fn store_read_slice>( &self, path: &P, from_offset: usize, @@ -97,13 +97,13 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { let path = self.absolute_path(path)?; self.host.store_read_all(&path) } #[inline(always)] - fn store_write>( + fn store_write>( &mut self, path: &P, src: &[u8], @@ -114,7 +114,7 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_write_all>( + fn store_write_all>( &mut self, path: &P, src: &[u8], @@ -124,13 +124,13 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_delete>(&mut self, path: &P) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &P) -> Result<(), RuntimeError> { let path = self.absolute_path(path)?; self.host.store_delete(&path) } #[inline(always)] - fn store_delete_value>( + fn store_delete_value>( &mut self, path: &P, ) -> Result<(), RuntimeError> { @@ -139,7 +139,7 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_count_subkeys>( + fn store_count_subkeys>( &self, prefix: &P, ) -> Result { @@ -150,8 +150,8 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = self.absolute_path(from_path)?; let to_path = self.absolute_path(to_path)?; @@ -161,8 +161,8 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = self.absolute_path(from_path)?; let to_path = self.absolute_path(to_path)?; @@ -179,7 +179,7 @@ impl> SdkRuntime for RelativeRuntime<&mut Host> { } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { let path = self.absolute_path(path)?; self.host.store_value_size(&path) } diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index d73d93b59d31..8dc8cf48f60f 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -47,18 +47,18 @@ impl> InternalRuntime for SafeStorage<&mut Host> { } } -impl> ExtendedRuntime for SafeStorage<&mut Host> { +impl> ExtendedRuntime for SafeStorage<&mut Host> { #[inline(always)] fn store_get_hash( &mut self, - path: &impl Path, + path: &impl Path, ) -> Result, RuntimeError> { let path = safe_path(path)?; self.__internal_store_get_hash(&path) } } -impl> SdkRuntime for SafeStorage<&mut Host> { +impl> SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { self.host.write_output(from) @@ -75,7 +75,7 @@ impl> SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_has>( + fn store_has>( &self, path: &T, ) -> Result, RuntimeError> { @@ -84,7 +84,7 @@ impl> SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_read>( + fn store_read>( &self, path: &T, from_offset: usize, @@ -95,7 +95,7 @@ impl> SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_read_slice>( + fn store_read_slice>( &self, path: &T, from_offset: usize, @@ -106,13 +106,13 @@ impl> SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { + fn store_read_all(&self, path: &impl Path) -> Result, RuntimeError> { let path = safe_path(path)?; self.host.store_read_all(&path) } #[inline(always)] - fn store_write>( + fn store_write>( &mut self, path: &T, src: &[u8], @@ -123,7 +123,7 @@ impl> SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_write_all>( + fn store_write_all>( &mut self, path: &T, src: &[u8], @@ -133,13 +133,13 @@ impl> SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { + fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { let path = safe_path(path)?; self.host.store_delete(&path) } #[inline(always)] - fn store_delete_value>( + fn store_delete_value>( &mut self, path: &T, ) -> Result<(), RuntimeError> { @@ -148,7 +148,7 @@ impl> SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_count_subkeys>( + fn store_count_subkeys>( &self, prefix: &T, ) -> Result { @@ -159,8 +159,8 @@ impl> SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn store_move( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = safe_path(from_path)?; let to_path = safe_path(to_path)?; @@ -170,8 +170,8 @@ impl> SdkRuntime for SafeStorage<&mut Host> { #[inline(always)] fn store_copy( &mut self, - from_path: &impl Path, - to_path: &impl Path, + from_path: &impl Path, + to_path: &impl Path, ) -> Result<(), RuntimeError> { let from_path = safe_path(from_path)?; let to_path = safe_path(to_path)?; @@ -188,7 +188,7 @@ impl> SdkRuntime for SafeStorage<&mut Host> { } #[inline(always)] - fn store_value_size(&self, path: &impl Path) -> Result { + fn store_value_size(&self, path: &impl Path) -> Result { let path = safe_path(path)?; self.host.store_value_size(&path) } -- GitLab From 2b07756abd7c7eb2fec6dcfe4377eb10aabb32a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 22 Oct 2024 13:29:32 +0200 Subject: [PATCH 29/31] DOES NOT COMPILE: Etherlink/Kernel: remove world state prefix in constants --- .../evm_execution/src/account_storage.rs | 3 +- .../evm_execution/src/code_storage.rs | 2 +- .../src/fa_bridge/ticket_table.rs | 22 +++++++++----- etherlink/kernel_evm/evm_execution/src/lib.rs | 3 +- .../kernel_evm/evm_execution/src/storage.rs | 7 ++--- .../evm_execution/src/withdrawal_counter.rs | 21 +++++++++----- etherlink/kernel_evm/kernel/src/apply.rs | 8 ++--- .../kernel/src/block_in_progress.rs | 14 ++++----- .../kernel_evm/kernel/src/block_storage.rs | 13 ++++----- etherlink/kernel_evm/kernel/src/lib.rs | 3 +- etherlink/kernel_evm/kernel/src/storage.rs | 29 +++++++++---------- 11 files changed, 64 insertions(+), 61 deletions(-) diff --git a/etherlink/kernel_evm/evm_execution/src/account_storage.rs b/etherlink/kernel_evm/evm_execution/src/account_storage.rs index caf9e0e36560..5c8f8e5d0d15 100644 --- a/etherlink/kernel_evm/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/account_storage.rs @@ -130,8 +130,7 @@ impl From> for EthereumAccount { } /// Path where Ethereum accounts are stored -pub const EVM_ACCOUNTS_PATH: RefPath = - RefPath::assert_from(b"/evm/world_state/eth_accounts"); +pub const EVM_ACCOUNTS_PATH: RefPath = RefPath::assert_from(b"/eth_accounts"); /// Path where an account nonce is stored. This should be prefixed with the path to /// where the account is stored for the world state or for the current transaction. diff --git a/etherlink/kernel_evm/evm_execution/src/code_storage.rs b/etherlink/kernel_evm/evm_execution/src/code_storage.rs index 28c5c3e23ada..f75d4eb1f705 100644 --- a/etherlink/kernel_evm/evm_execution/src/code_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/code_storage.rs @@ -12,7 +12,7 @@ use tezos_storage::helpers::bytes_hash; use tezos_storage::{error::Error as GenStorageError, read_u64_le, write_u64_le}; /// Path where Ethereum account's code are stored -const EVM_CODES_PATH: RefPath = RefPath::assert_from(b"/evm/world_state/eth_codes"); +const EVM_CODES_PATH: RefPath = RefPath::assert_from(b"/eth_codes"); /// Path to the number of accounts to use a particular code const REFERENCE_PATH: RefPath = RefPath::assert_from(b"/ref_count"); diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs index da4c6215e53e..611b44dd0d39 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs @@ -110,12 +110,15 @@ mod tests { .unwrap(); let path = b"\ - /evm/world_state/eth_accounts/0000000000000000000000000000000000000000/ticket_table\ + /eth_accounts/0000000000000000000000000000000000000000/ticket_table\ /0101010101010101010101010101010101010101010101010101010101010101\ /0202020202020202020202020202020202020202"; - let balance = - read_u256_le_default(&host, &RefPath::assert_from(path), U256::zero()) - .unwrap(); + let balance = read_u256_le_default( + &host, + &RefPath::::assert_from(path), + U256::zero(), + ) + .unwrap(); assert_eq!(U256::from(84), balance); } @@ -140,12 +143,15 @@ mod tests { assert!(!res); let path = b"\ - /evm/world_state/eth_accounts/0000000000000000000000000000000000000000/ticket_table\ + /eth_accounts/0000000000000000000000000000000000000000/ticket_table\ /0101010101010101010101010101010101010101010101010101010101010101\ /0202020202020202020202020202020202020202"; - let balance = - read_u256_le_default(&host, &RefPath::assert_from(path), U256::zero()) - .unwrap(); + let balance = read_u256_le_default( + &host, + &RefPath::::assert_from(path), + U256::zero(), + ) + .unwrap(); assert_eq!(U256::MAX, balance); } diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index 449d2d939bcf..75a59f064ce0 100755 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -419,8 +419,7 @@ where Ok(None) } } -pub const NATIVE_TOKEN_TICKETER_PATH: RefPath = - RefPath::assert_from(b"/evm/world_state/ticketer"); +pub const NATIVE_TOKEN_TICKETER_PATH: RefPath = RefPath::assert_from(b"/ticketer"); /// Reads the ticketer address set by the installer, if any, encoded in b58. pub fn read_ticketer(host: &impl Runtime) -> Option { diff --git a/etherlink/kernel_evm/evm_execution/src/storage.rs b/etherlink/kernel_evm/evm_execution/src/storage.rs index 7413fcf7f9b1..c6ae2e4bb9ac 100644 --- a/etherlink/kernel_evm/evm_execution/src/storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/storage.rs @@ -180,10 +180,9 @@ pub mod blocks { fn to_block_hash_path( block_number: U256, - ) -> Result, EvmBlockStorageError> { - let path: Vec = - format!("/evm/world_state/indexes/blocks/{}", block_number).into(); - let owned_path = OwnedPath::try_from(path)?; + ) -> Result, EvmBlockStorageError> { + let path: Vec = format!("/indexes/blocks/{}", block_number).into(); + let owned_path = OwnedPath::::try_from(path)?; Ok(owned_path) } diff --git a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs index f7ba7d01ae86..55458627bbf0 100644 --- a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs +++ b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs @@ -66,16 +66,20 @@ mod tests { }; let mut account = EthereumAccount::from_address(&SYSTEM_ACCOUNT_ADDRESS).unwrap(); - let path = b"/evm/world_state/eth_accounts/0000000000000000000000000000000000000000/withdrawal_counter"; + let path = + b"/eth_accounts/0000000000000000000000000000000000000000/withdrawal_counter"; let id = account .withdrawal_counter_get_and_increment(&mut mock_host) .unwrap(); assert_eq!(U256::zero(), id); - let next_id = - read_u256_le_default(&mock_host, &RefPath::assert_from(path), U256::zero()) - .unwrap(); + let next_id = read_u256_le_default( + &mock_host, + &RefPath::::assert_from(path), + U256::zero(), + ) + .unwrap(); assert_eq!(U256::one(), next_id); let id = account @@ -83,9 +87,12 @@ mod tests { .unwrap(); assert_eq!(U256::one(), id); - let next_id = - read_u256_le_default(&mock_host, &RefPath::assert_from(path), U256::zero()) - .unwrap(); + let next_id = read_u256_le_default( + &mock_host, + &RefPath::::assert_from(path), + U256::zero(), + ) + .unwrap(); assert_eq!(U256::from(2), next_id); } } diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index da85e358fc81..b9966b193c32 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -502,11 +502,11 @@ fn apply_fa_deposit>( })) } -pub const WITHDRAWAL_OUTBOX_QUEUE: RefPath = - RefPath::assert_from(b"/evm/world_state/__outbox_queue"); +pub const WITHDRAWAL_OUTBOX_QUEUE: RefPath = + RefPath::assert_from(b"/__outbox_queue"); -pub const WITHDRAWAL_OUTBOX_QUEUE_META: RefPath = - RefPath::assert_from(b"/evm/world_state/__outbox_queue/meta"); +pub const WITHDRAWAL_OUTBOX_QUEUE_META: RefPath = + RefPath::assert_from(b"/__outbox_queue/meta"); pub struct ExecutionInfo { pub receipt_info: TransactionReceiptInfo, diff --git a/etherlink/kernel_evm/kernel/src/block_in_progress.rs b/etherlink/kernel_evm/kernel/src/block_in_progress.rs index bbc0b3f1b9ef..5dc83dd2ed87 100644 --- a/etherlink/kernel_evm/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_evm/kernel/src/block_in_progress.rs @@ -357,10 +357,9 @@ impl BlockInProgress { } } - const RECEIPTS: RefPath<'static, true> = - RefPath::assert_from(b"/evm/world_state/__receipts"); - const RECEIPTS_PREVIOUS_ROOT: RefPath<'static, true> = - RefPath::assert_from(b"/evm/world_state/__receipts/previous_root"); + const RECEIPTS: RefPath<'static, false> = RefPath::assert_from(b"/__receipts"); + const RECEIPTS_PREVIOUS_ROOT: RefPath<'static, false> = + RefPath::assert_from(b"/__receipts/previous_root"); fn receipts_root( &self, @@ -382,10 +381,9 @@ impl BlockInProgress { } } - const OBJECTS: RefPath<'static, true> = - RefPath::assert_from(b"/evm/world_state/__objects"); - const OBJECTS_PREVIOUS_ROOT: RefPath<'static, true> = - RefPath::assert_from(b"/evm/world_state/__objects/previous_root"); + const OBJECTS: RefPath<'static, false> = RefPath::assert_from(b"/__objects"); + const OBJECTS_PREVIOUS_ROOT: RefPath<'static, false> = + RefPath::assert_from(b"/__objects/previous_root"); fn transactions_root( &self, diff --git a/etherlink/kernel_evm/kernel/src/block_storage.rs b/etherlink/kernel_evm/kernel/src/block_storage.rs index 5a2a04b8ccb0..c753ff5ca0c9 100644 --- a/etherlink/kernel_evm/kernel/src/block_storage.rs +++ b/etherlink/kernel_evm/kernel/src/block_storage.rs @@ -24,15 +24,14 @@ use crate::storage::EVM_TRANSACTIONS_RECEIPTS; mod path { use super::*; - pub const PATH: RefPath = RefPath::assert_from(b"/evm/world_state/blocks"); + pub const PATH: RefPath = RefPath::assert_from(b"/blocks"); - pub const CURRENT_NUMBER: RefPath = - RefPath::assert_from(b"/evm/world_state/blocks/current/number"); - pub const CURRENT_HASH: RefPath = - RefPath::assert_from(b"/evm/world_state/blocks/current/hash"); + pub const CURRENT_NUMBER: RefPath = + RefPath::assert_from(b"/blocks/current/number"); + pub const CURRENT_HASH: RefPath = + RefPath::assert_from(b"/blocks/current/hash"); - pub const INDEXES: RefPath = - RefPath::assert_from(b"/evm/world_state/indexes/blocks"); + pub const INDEXES: RefPath = RefPath::assert_from(b"/indexes/blocks"); /// Path to the block in the storage. The path to the block is /// indexed by its hash. diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index f0260598aa2d..575f0d19efc3 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -662,8 +662,7 @@ mod tests { #[test] fn load_min_block_fees() { - let min_path = - RefPath::assert_from(b"/evm/world_state/fees/minimum_base_fee_per_gas"); + let min_path = RefPath::::assert_from(b"/fees/minimum_base_fee_per_gas"); // Arrange let mut host = MockKernelHost::default(); diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index 1a6a5e741c77..22573715da99 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -97,27 +97,25 @@ pub const MAXIMUM_GAS_PER_TRANSACTION: RefPath = RefPath::assert_from(b"/evm/maximum_gas_per_transaction"); // Path to the block in progress, used between reboots -const EVM_BLOCK_IN_PROGRESS: RefPath = - RefPath::assert_from(b"/evm/world_state/blocks/in_progress"); +const EVM_BLOCK_IN_PROGRESS: RefPath = + RefPath::assert_from(b"/blocks/in_progress"); const EVENTS: RefPath = RefPath::assert_from(b"/evm/events"); -pub const EVM_TRANSACTIONS_RECEIPTS: RefPath = - RefPath::assert_from(b"/evm/world_state/transactions_receipts"); +pub const EVM_TRANSACTIONS_RECEIPTS: RefPath = + RefPath::assert_from(b"/transactions_receipts"); -pub const EVM_TRANSACTIONS_OBJECTS: RefPath = - RefPath::assert_from(b"/evm/world_state/transactions_objects"); +pub const EVM_TRANSACTIONS_OBJECTS: RefPath = + RefPath::assert_from(b"/transactions_objects"); const EVM_CHAIN_ID: RefPath = RefPath::assert_from(b"/evm/chain_id"); -const EVM_MINIMUM_BASE_FEE_PER_GAS: RefPath = - RefPath::assert_from(b"/evm/world_state/fees/minimum_base_fee_per_gas"); -const EVM_DA_FEE: RefPath = - RefPath::assert_from(b"/evm/world_state/fees/da_fee_per_byte"); -const TICK_BACKLOG_PATH: RefPath = - RefPath::assert_from(b"/evm/world_state/fees/backlog"); -const TICK_BACKLOG_TIMESTAMP_PATH: RefPath = - RefPath::assert_from(b"/evm/world_state/fees/last_timestamp"); +const EVM_MINIMUM_BASE_FEE_PER_GAS: RefPath = + RefPath::assert_from(b"/fees/minimum_base_fee_per_gas"); +const EVM_DA_FEE: RefPath = RefPath::assert_from(b"/fees/da_fee_per_byte"); +const TICK_BACKLOG_PATH: RefPath = RefPath::assert_from(b"/fees/backlog"); +const TICK_BACKLOG_TIMESTAMP_PATH: RefPath = + RefPath::assert_from(b"/fees/last_timestamp"); /// The sequencer pool is the designated account that the data-availability fees are sent to. /// @@ -129,8 +127,7 @@ pub const SEQUENCER_POOL_PATH: RefPath = /// Path to the last L1 level seen. const EVM_L1_LEVEL: RefPath = RefPath::assert_from(b"/evm/l1_level"); -const EVM_BURNED_FEES: RefPath = - RefPath::assert_from(b"/evm/world_state/fees/burned"); +const EVM_BURNED_FEES: RefPath = RefPath::assert_from(b"/fees/burned"); /// Path to the last info per level timestamp seen. const EVM_INFO_PER_LEVEL_TIMESTAMP: RefPath = -- GitLab From d2447639ea20282dd629f93d397e9782ea0add3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Thu, 24 Oct 2024 17:40:25 +0200 Subject: [PATCH 30/31] Etherlink/Kernel: Adapt kernel to relative paths --- etherlink/kernel_evm/evm_evaluation/src/evalhost.rs | 8 ++++---- .../kernel_evm/evm_execution/src/fa_bridge/tests.rs | 1 - etherlink/kernel_evm/evm_execution/src/storage.rs | 4 ++-- etherlink/kernel_evm/kernel/src/block_in_progress.rs | 6 +++--- etherlink/kernel_evm/kernel/src/migration.rs | 11 ++++++++--- etherlink/kernel_evm/runtime/src/runtime.rs | 6 +++--- etherlink/kernel_evm/runtime/src/safe_storage.rs | 8 ++++---- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index 091adba99331..05c7cdb25ad0 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -14,7 +14,7 @@ use tezos_smart_rollup_host::{ dal_parameters::RollupDalParameters, input::Message, metadata::RollupMetadata, - path::{force_concat, OwnedPath, Path, RefPath}, + path::{concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; @@ -39,13 +39,13 @@ impl<'a> EvalHost<'a> { const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state"); const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); -fn world_state_path(p: &impl Path) -> Result, RuntimeError> { - force_concat(&WORLD_STATE_PATH, p).map_err(|_| RuntimeError::PathNotFound) +fn world_state_path(p: &impl Path) -> Result, RuntimeError> { + concat(&WORLD_STATE_PATH, p).map_err(|_| RuntimeError::PathNotFound) } fn trace_path(p: &TracePath) -> Result, RuntimeError> { let TracePath(p) = p; - force_concat(&TRACE_PATH, p).map_err(|_| RuntimeError::PathNotFound) + concat(&TRACE_PATH, p).map_err(|_| RuntimeError::PathNotFound) } impl<'a> SdkRuntime for EvalHost<'a> { diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs index 03af83bdffdf..99002b16073f 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs @@ -493,7 +493,6 @@ fn fa_deposit_cannot_call_fa_withdrawal_precompile() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, - root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); diff --git a/etherlink/kernel_evm/evm_execution/src/storage.rs b/etherlink/kernel_evm/evm_execution/src/storage.rs index c6ae2e4bb9ac..020266982d54 100644 --- a/etherlink/kernel_evm/evm_execution/src/storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/storage.rs @@ -39,8 +39,8 @@ pub mod tracer { hash: &Option, field: &RefPath, ) -> Result { - let path: OwnedPath = match hash { - None => concat(&RefPath::assert_from(b""), field).map_err(Error::PathError), + let path: OwnedPath = match hash { + None => Ok(field.into()), Some(hash) => { let hash = hex::encode(hash); let raw_tx_path: Vec = format!("/{}", &hash).into(); diff --git a/etherlink/kernel_evm/kernel/src/block_in_progress.rs b/etherlink/kernel_evm/kernel/src/block_in_progress.rs index 5dc83dd2ed87..10d374285e88 100644 --- a/etherlink/kernel_evm/kernel/src/block_in_progress.rs +++ b/etherlink/kernel_evm/kernel/src/block_in_progress.rs @@ -28,7 +28,7 @@ use tezos_ethereum::Bloom; use tezos_evm_logging::{log, Level::*}; use tezos_evm_runtime::runtime::Runtime; use tezos_smart_rollup_encoding::timestamp::Timestamp; -use tezos_smart_rollup_host::path::{force_concat, RefPath}; +use tezos_smart_rollup_host::path::{concat, RefPath}; #[derive(Debug, PartialEq, Clone)] /// Container for all data needed during block computation @@ -371,7 +371,7 @@ impl BlockInProgress { } else { for hash in &self.valid_txs { let receipt_path = receipt_path(hash)?; - let new_receipt_path = force_concat(&Self::RECEIPTS, &receipt_path)?; + let new_receipt_path = concat(&Self::RECEIPTS, &receipt_path)?; host.store_copy(&receipt_path, &new_receipt_path)?; } host.store_write_all(&Self::RECEIPTS_PREVIOUS_ROOT, &previous_receipts_root)?; @@ -395,7 +395,7 @@ impl BlockInProgress { } else { for hash in &self.valid_txs { let object_path = object_path(hash)?; - let new_object_path = force_concat(&Self::OBJECTS, &object_path)?; + let new_object_path = concat(&Self::OBJECTS, &object_path)?; host.store_copy(&object_path, &new_object_path)?; } host.store_write_all( diff --git a/etherlink/kernel_evm/kernel/src/migration.rs b/etherlink/kernel_evm/kernel/src/migration.rs index f4502ee99e83..ad1d495cfd97 100644 --- a/etherlink/kernel_evm/kernel/src/migration.rs +++ b/etherlink/kernel_evm/kernel/src/migration.rs @@ -22,8 +22,11 @@ use evm_execution::precompiles::WITHDRAWAL_ADDRESS; use evm_execution::NATIVE_TOKEN_TICKETER_PATH; use primitive_types::U256; use tezos_evm_logging::{log, Level::*}; -use tezos_evm_runtime::{runtime::Runtime, safe_storage::SafeStorage}; -use tezos_smart_rollup::storage::path::RefPath; +use tezos_evm_runtime::{ + runtime::Runtime, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, +}; +use tezos_smart_rollup::storage::path::{concat, RefPath}; use tezos_smart_rollup_host::path::OwnedPath; use tezos_smart_rollup_host::runtime::RuntimeError; @@ -80,7 +83,9 @@ fn migrate_to>( StorageVersion::V12 => { let legacy_ticketer_path = RefPath::assert_from(b"/evm/ticketer"); if host.store_has(&legacy_ticketer_path)?.is_some() { - host.store_move(&legacy_ticketer_path, &NATIVE_TOKEN_TICKETER_PATH)?; + let native_token_ticketer_path = + concat(&WORLD_STATE_PATH, &NATIVE_TOKEN_TICKETER_PATH)?; + host.store_move(&legacy_ticketer_path, &native_token_ticketer_path)?; } Ok(MigrationStatus::Done) diff --git a/etherlink/kernel_evm/runtime/src/runtime.rs b/etherlink/kernel_evm/runtime/src/runtime.rs index bde8f92060db..1617b1d41ef4 100644 --- a/etherlink/kernel_evm/runtime/src/runtime.rs +++ b/etherlink/kernel_evm/runtime/src/runtime.rs @@ -25,7 +25,7 @@ use tezos_smart_rollup_host::{ dal_parameters::RollupDalParameters, input::Message, metadata::RollupMetadata, - path::{force_concat, OwnedPath, Path, RefPath}, + path::{concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; use tezos_smart_rollup_mock::MockHost; @@ -34,7 +34,7 @@ use tezos_smart_rollup_mock::MockHost; pub const VERBOSITY_PATH: RefPath = RefPath::assert_from(b"/evm/logging_verbosity"); const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); -pub struct TracePath(pub OwnedPath); +pub struct TracePath(pub OwnedPath); pub trait TraceRuntime { // Same as store_write_all but path is implicitely prefixed by /evm/trace/ @@ -376,7 +376,7 @@ impl, Host: BorrowMut + Borrow, Internal: InternalRunt ) -> Result<(), RuntimeError> { let TracePath(path) = path; let absolute_path = - force_concat(&TRACE_PATH, path).map_err(|_| RuntimeError::PathNotFound)?; + concat(&TRACE_PATH, path).map_err(|_| RuntimeError::PathNotFound)?; self.store_write_all(&absolute_path, src) } } diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index 8dc8cf48f60f..ac871199375c 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -14,7 +14,7 @@ use tezos_smart_rollup_host::dal_parameters::RollupDalParameters; use tezos_smart_rollup_host::{ input::Message, metadata::RollupMetadata, - path::{force_concat, OwnedPath, Path, RefPath}, + path::{concat, OwnedPath, Path, RefPath}, runtime::{Runtime as SdkRuntime, RuntimeError, ValueType}, }; @@ -25,13 +25,13 @@ pub const TMP_WORLD_STATE_PATH: RefPath = pub const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); pub const TMP_TRACE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/trace"); -pub fn safe_path>(path: &T) -> Result, RuntimeError> { - force_concat(&TMP_PATH, path).map_err(|_| RuntimeError::PathNotFound) +pub fn safe_path(path: &impl Path) -> Result, RuntimeError> { + concat(&TMP_WORLD_STATE_PATH, path).map_err(|_| RuntimeError::PathNotFound) } pub fn safe_trace_path(path: &TracePath) -> Result, RuntimeError> { let TracePath(path) = path; - force_concat(&TMP_TRACE_PATH, path).map_err(|_| RuntimeError::PathNotFound) + concat(&TMP_TRACE_PATH, path).map_err(|_| RuntimeError::PathNotFound) } pub struct SafeStorage { -- GitLab From 45739c0ccb643b592acf5ce98ceafc36183af8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Thu, 9 Jan 2025 17:44:53 +0100 Subject: [PATCH 31/31] Etherlink/Kernel/SafeStorage: add a root argument This represents the directory from which the safe storage started and to which data will be moved at promotion. The prefix on which the safe storage operates is still fixed to /tmp/evm/world_state --- .../evm_execution/src/account_storage.rs | 87 ++++++++++++++---- .../evm_execution/src/code_storage.rs | 25 ++++-- .../evm_execution/src/fa_bridge/tests.rs | 13 ++- .../src/fa_bridge/ticket_table.rs | 15 +++- .../kernel_evm/evm_execution/src/handler.rs | 42 ++++++++- etherlink/kernel_evm/evm_execution/src/lib.rs | 89 ++++++++++++++++--- .../src/precompiles/fa_bridge.rs | 10 ++- .../evm_execution/src/precompiles/mod.rs | 3 +- .../evm_execution/src/withdrawal_counter.rs | 6 +- etherlink/kernel_evm/kernel/src/apply.rs | 37 ++++++-- etherlink/kernel_evm/kernel/src/block.rs | 86 ++++++++++++++---- .../kernel/src/blueprint_storage.rs | 10 ++- etherlink/kernel_evm/kernel/src/bridge.rs | 15 +++- .../kernel_evm/kernel/src/configuration.rs | 10 ++- etherlink/kernel_evm/kernel/src/fees.rs | 20 ++++- etherlink/kernel_evm/kernel/src/gas_price.rs | 7 +- etherlink/kernel_evm/kernel/src/lib.rs | 29 ++++-- etherlink/kernel_evm/kernel/src/migration.rs | 10 ++- etherlink/kernel_evm/kernel/src/simulation.rs | 15 +++- etherlink/kernel_evm/kernel/src/stage_one.rs | 10 ++- etherlink/kernel_evm/kernel/src/storage.rs | 10 ++- .../kernel_evm/runtime/src/safe_storage.rs | 7 +- 22 files changed, 455 insertions(+), 101 deletions(-) diff --git a/etherlink/kernel_evm/evm_execution/src/account_storage.rs b/etherlink/kernel_evm/evm_execution/src/account_storage.rs index 5c8f8e5d0d15..1d6184618061 100644 --- a/etherlink/kernel_evm/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/account_storage.rs @@ -574,7 +574,7 @@ mod test { use host::path::RefPath; use primitive_types::U256; use tezos_evm_runtime::runtime::MockKernelHost; - use tezos_evm_runtime::safe_storage::SafeStorage; + use tezos_evm_runtime::safe_storage::{SafeStorage, WORLD_STATE_PATH}; use tezos_smart_rollup_host::runtime::Runtime as SdkRuntime; // Used for use tezos_storage::helpers::bytes_hash; use tezos_storage::write_u256_le; @@ -582,7 +582,10 @@ mod test { #[test] fn test_account_nonce_update() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -619,7 +622,10 @@ mod test { #[test] fn test_zero_account_balance_for_new_accounts() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -658,7 +664,10 @@ mod test { #[test] fn test_account_balance_add() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -703,7 +712,10 @@ mod test { #[test] fn test_account_balance_sub() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -748,7 +760,10 @@ mod test { #[test] fn test_account_balance_underflow() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -791,7 +806,10 @@ mod test { #[test] fn test_account_storage_zero_default() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -819,7 +837,10 @@ mod test { #[test] fn test_account_storage_update() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -861,7 +882,10 @@ mod test { #[test] fn test_account_storage_update_checked() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -943,7 +967,10 @@ mod test { #[test] fn test_account_code_storage_initial_code_is_zero() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -992,7 +1019,10 @@ mod test { fn test_account_code_storage_write_code_aux(sample_code: Vec) { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1053,7 +1083,10 @@ mod test { #[test] fn test_account_code_storage_cant_be_overwritten() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1106,7 +1139,10 @@ mod test { #[test] fn test_account_code_storage_delete_code() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1161,7 +1197,10 @@ mod test { #[test] fn test_empty_contract_hash_matches_default() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1211,7 +1250,10 @@ mod test { #[test] fn test_read_u256_le_default_le() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let path = RefPath::assert_from(b"/value"); assert_eq!( read_u256_le_default(&host, &path, U256::from(128)).unwrap(), @@ -1241,7 +1283,10 @@ mod test { #[test] fn test_write_u256_le_le() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let path = RefPath::assert_from(b"/value"); write_u256_le(&mut host, &path, U256::from(255)).unwrap(); @@ -1257,7 +1302,10 @@ mod test { let sample_code_hash: H256 = bytes_hash(&sample_code); let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); @@ -1325,7 +1373,10 @@ mod test { let sample_code_hash: H256 = bytes_hash(&sample_code); let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut storage = init_account_storage().expect("Could not create EVM accounts storage API"); diff --git a/etherlink/kernel_evm/evm_execution/src/code_storage.rs b/etherlink/kernel_evm/evm_execution/src/code_storage.rs index f75d4eb1f705..65501f4f061e 100644 --- a/etherlink/kernel_evm/evm_execution/src/code_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/code_storage.rs @@ -147,14 +147,20 @@ impl CodeStorage { #[cfg(test)] mod test { use crate::account_storage; - use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; + use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, + }; use super::*; #[test] fn test_empty_contract_hash_matches_default() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let empty_code: Vec = vec![]; let empty_code_hash: H256 = account_storage::CODE_HASH_DEFAULT; @@ -167,7 +173,10 @@ mod test { #[test] fn test_get_code_matches_given() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let code: Vec = (0..100).collect(); let code_hash = CodeStorage::add(&mut host, &code).expect("Could not create code storage"); @@ -178,7 +187,10 @@ mod test { #[test] fn test_code_ref_is_incremented() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let code: Vec = (0..100).collect(); let code_hash = CodeStorage::add(&mut host, &code).expect("Could not create code storage"); @@ -207,7 +219,10 @@ mod test { #[test] fn test_code_is_deleted() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let code_hash: H256 = account_storage::CODE_HASH_DEFAULT; let code_storage = diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs index 99002b16073f..1c3456956e60 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/tests.rs @@ -6,7 +6,10 @@ use alloy_primitives::FixedBytes; use alloy_sol_types::SolEvent; use evm::ExitError; use primitive_types::{H160, U256}; -use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; +use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, +}; use crate::{ account_storage::{account_path, init_account_storage}, @@ -29,6 +32,7 @@ fn fa_deposit_reached_wrapper_contract() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -114,6 +118,7 @@ fn fa_deposit_refused_due_non_existing_contract() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -176,6 +181,7 @@ fn fa_deposit_refused_non_compatible_interface() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -245,6 +251,7 @@ fn fa_deposit_proxy_state_reverted_if_ticket_balance_overflows() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -311,6 +318,7 @@ fn fa_withdrawal_executed_via_l2_proxy_contract() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -402,6 +410,7 @@ fn fa_withdrawal_fails_due_to_faulty_l2_proxy() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -458,6 +467,7 @@ fn fa_withdrawal_fails_due_to_insufficient_balance() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -493,6 +503,7 @@ fn fa_deposit_cannot_call_fa_withdrawal_precompile() { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); diff --git a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs index 611b44dd0d39..97e67bcb45d7 100644 --- a/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs +++ b/etherlink/kernel_evm/evm_execution/src/fa_bridge/ticket_table.rs @@ -84,7 +84,10 @@ impl TicketTable for EthereumAccount { #[cfg(test)] mod tests { - use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; + use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, + }; use tezos_smart_rollup_host::path::RefPath; use tezos_storage::read_u256_le_default; @@ -95,7 +98,10 @@ mod tests { #[test] fn ticket_table_balance_add_succeeds() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut account = EthereumAccount::from_address(&SYSTEM_ACCOUNT_ADDRESS).unwrap(); @@ -126,7 +132,10 @@ mod tests { #[test] fn ticket_table_balance_add_overflows() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut account = EthereumAccount::from_address(&SYSTEM_ACCOUNT_ADDRESS).unwrap(); diff --git a/etherlink/kernel_evm/evm_execution/src/handler.rs b/etherlink/kernel_evm/evm_execution/src/handler.rs index 9fcf9f688aaa..22b8cfeb920a 100644 --- a/etherlink/kernel_evm/evm_execution/src/handler.rs +++ b/etherlink/kernel_evm/evm_execution/src/handler.rs @@ -2817,7 +2817,10 @@ mod test { use std::str::FromStr; use std::vec; use tezos_ethereum::block::BlockFees; - use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; + use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, + }; const DUMMY_ALLOCATED_TICKS: u64 = 1_000_000_000; @@ -2901,6 +2904,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2947,6 +2951,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2992,6 +2997,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3041,6 +3047,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3109,6 +3116,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3206,6 +3214,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3304,6 +3313,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3400,6 +3410,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3475,6 +3486,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3535,6 +3547,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3604,6 +3617,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3670,6 +3684,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3735,6 +3750,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3809,6 +3825,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3840,6 +3857,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3904,6 +3922,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3959,6 +3978,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4030,6 +4050,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4102,6 +4123,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4148,6 +4170,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4227,6 +4250,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4259,6 +4283,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4306,6 +4331,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4392,6 +4418,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4495,6 +4522,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4564,6 +4592,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4639,7 +4668,10 @@ mod test { #[test] fn precompile_failure_are_not_fatal() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_account_storage().unwrap(); @@ -4701,6 +4733,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4786,6 +4819,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4829,6 +4863,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4874,6 +4909,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -4955,6 +4991,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -5030,6 +5067,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index 75a59f064ce0..4d43795004d5 100755 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -448,7 +448,7 @@ mod test { use tezos_ethereum::tx_common::EthereumTransactionCommon; use tezos_evm_runtime::runtime::MockKernelHost; use tezos_evm_runtime::runtime::Runtime; - use tezos_evm_runtime::safe_storage::SafeStorage; + use tezos_evm_runtime::safe_storage::{SafeStorage, WORLD_STATE_PATH}; // The compiled initialization code for the Ethereum demo contract given // as an example in kernel_evm/solidity_examples/storage.sol @@ -594,6 +594,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -662,6 +663,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -731,6 +733,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -788,6 +791,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -952,6 +956,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1011,6 +1016,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1072,6 +1078,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1212,6 +1219,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1277,6 +1285,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1349,6 +1358,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1404,6 +1414,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1472,6 +1483,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1530,6 +1542,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1595,6 +1608,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1700,6 +1714,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1797,6 +1812,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -1894,6 +1910,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2018,6 +2035,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2127,6 +2145,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2240,6 +2259,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2362,6 +2382,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let chain_id = U256::from(42); let mut chain_id_bytes = [0u8; 32]; @@ -2450,6 +2471,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let base_fee_per_gas = U256::from(23000); let mut base_fee_per_gas_bytes = [0u8; 32]; @@ -2559,6 +2581,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2610,6 +2633,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2672,6 +2696,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -2733,6 +2758,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let base_fee_per_gas = U256::from(23000); let block_fees = BlockFees::new( @@ -2806,6 +2832,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let base_fee_per_gas = U256::from(23000); let block_fees = BlockFees::new( @@ -2897,6 +2924,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = first_block(); let precompiles = precompiles::precompile_set(false); @@ -2980,6 +3008,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3056,6 +3085,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3159,6 +3189,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3270,6 +3301,7 @@ mod test { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); @@ -3336,7 +3368,10 @@ mod test { #[test] fn created_contract_start_at_nonce_one() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); @@ -3382,7 +3417,10 @@ mod test { #[test] fn call_contract_create_contract_with_insufficient_funds() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); @@ -3448,7 +3486,10 @@ mod test { #[test] fn nested_create_check_nonce_start_at_one() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); @@ -3619,7 +3660,10 @@ mod test { #[test] fn transaction_has_no_impact_if_retriable() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let (result, caller, initial_caller_balance, initial_caller_nonce) = out_of_tick_scenario(&mut host, true); let caller_balance = caller.balance(&host).unwrap(); @@ -3643,7 +3687,10 @@ mod test { #[test] fn non_retriable_transaction_pays_for_exhausted_ticks() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let (result, caller, initial_caller_balance, initial_caller_nonce) = out_of_tick_scenario(&mut host, false); let caller_balance = caller.balance(&host).unwrap(); @@ -3673,7 +3720,10 @@ mod test { #[ignore] fn multiple_call_all_the_way_to_1024() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); @@ -3761,7 +3811,10 @@ mod test { #[test] fn multiple_call_fails_right_after_1024() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); @@ -3847,7 +3900,10 @@ mod test { #[ignore] fn call_too_deep_not_revert() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); @@ -3899,7 +3955,10 @@ mod test { // The test was a bit tweaked so that the called contract transfer 1 WEI to the called contract. let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); @@ -4005,7 +4064,10 @@ mod test { // with the second data. let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); @@ -4083,7 +4145,10 @@ mod test { #[test] fn nonce_bump_before_tx() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block = dummy_first_block(); let precompiles = precompiles::precompile_set(false); let mut evm_account_storage = init_evm_account_storage().unwrap(); diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs index d5cd5f9fa3dc..8344fd26b90d 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/fa_bridge.rs @@ -163,7 +163,7 @@ mod tests { use tezos_data_encoding::enc::BinWriter; use tezos_evm_runtime::{ runtime::{MockKernelHost, Runtime}, - safe_storage::SafeStorage, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, }; use crate::{ @@ -226,6 +226,7 @@ mod tests { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -250,6 +251,7 @@ mod tests { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -275,6 +277,7 @@ mod tests { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -307,6 +310,7 @@ mod tests { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -332,6 +336,7 @@ mod tests { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -377,6 +382,7 @@ mod tests { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -401,6 +407,7 @@ mod tests { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -472,6 +479,7 @@ mod tests { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let mut evm_account_storage = init_account_storage().unwrap(); diff --git a/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs b/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs index e54093da4de7..e78b3bf094f4 100644 --- a/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs +++ b/etherlink/kernel_evm/evm_execution/src/precompiles/mod.rs @@ -293,7 +293,7 @@ mod test_helpers { use tezos_ethereum::block::BlockFees; use tezos_evm_runtime::{ runtime::{MockKernelHost, Runtime}, - safe_storage::SafeStorage, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, }; use super::precompile_set; @@ -332,6 +332,7 @@ mod test_helpers { let mut mock_runtime = MockKernelHost::default(); let mut mock_runtime = SafeStorage { host: &mut mock_runtime, + root: WORLD_STATE_PATH, }; let block_fees = BlockFees::new( U256::from(21000), diff --git a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs index 55458627bbf0..f68d52ca6e28 100644 --- a/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs +++ b/etherlink/kernel_evm/evm_execution/src/withdrawal_counter.rs @@ -50,7 +50,10 @@ impl WithdrawalCounter for EthereumAccount { #[cfg(test)] mod tests { use primitive_types::U256; - use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; + use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, + }; use tezos_smart_rollup_host::path::RefPath; use tezos_storage::read_u256_le_default; @@ -63,6 +66,7 @@ mod tests { let mut mock_host = MockKernelHost::default(); let mut mock_host = SafeStorage { host: &mut mock_host, + root: WORLD_STATE_PATH, }; let mut account = EthereumAccount::from_address(&SYSTEM_ACCOUNT_ADDRESS).unwrap(); diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index b9966b193c32..29dcc93876b6 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -699,7 +699,7 @@ mod tests { }; use tezos_evm_runtime::{ runtime::{MockKernelHost, Runtime}, - safe_storage::SafeStorage, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, }; use tezos_smart_rollup_encoding::timestamp::Timestamp; @@ -788,7 +788,10 @@ mod tests { #[test] fn test_tx_is_valid() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -821,7 +824,10 @@ mod tests { #[test] fn test_tx_is_invalid_cannot_prepay() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -856,7 +862,10 @@ mod tests { #[test] fn test_tx_is_invalid_signature() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -891,7 +900,10 @@ mod tests { #[test] fn test_tx_is_invalid_wrong_nonce() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -928,7 +940,10 @@ mod tests { #[test] fn test_tx_is_invalid_wrong_chain_id() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -963,7 +978,10 @@ mod tests { #[test] fn test_tx_is_invalid_max_fee_less_than_base_fee() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); @@ -998,7 +1016,10 @@ mod tests { #[test] fn test_tx_invalid_not_enough_gas_for_fee() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); let block_constants = mock_block_constants(); diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index 9bb73178f63e..9eca2932c0eb 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -483,6 +483,7 @@ pub fn produce>( let at_most_one_block = relative_host.host.store_has(&AT_MOST_ONE_BLOCK)?.is_some(); let mut safe_host = SafeStorage { + root: WORLD_STATE_PATH, host: relative_host.host, }; let outbox_queue = OutboxQueue::new( @@ -933,7 +934,10 @@ mod tests { // Test if the invalid transactions are producing receipts fn test_invalid_transactions_receipt_status() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -983,7 +987,10 @@ mod tests { // Test if a valid transaction is producing a receipt with a success status fn test_valid_transactions_receipt_status() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1033,7 +1040,10 @@ mod tests { // Test if a valid transaction is producing a receipt with a contract address fn test_valid_transactions_receipt_contract_address() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1094,7 +1104,10 @@ mod tests { // Test if several valid transactions can be performed fn test_several_valid_transactions() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1120,7 +1133,10 @@ mod tests { // Test if several valid proposals can produce valid blocks fn test_several_valid_proposals() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1191,7 +1207,10 @@ mod tests { // Test transfers gas consumption consistency fn test_cumulative_transfers_gas_consumption() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let base_gas = U256::from(21000); crate::storage::store_minimum_base_fee_per_gas(&mut host, base_gas).unwrap(); @@ -1260,7 +1279,10 @@ mod tests { // a block production fn test_read_storage_current_block_after_block_production_with_filled_queue() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -1275,7 +1297,10 @@ mod tests { // Test that the same transaction can not be replayed twice fn test_replay_attack() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1338,7 +1363,10 @@ mod tests { #[test] fn test_blocks_are_indexed() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1413,7 +1441,10 @@ mod tests { fn test_stop_computation() { // init host let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block_constants = first_block(&mut host); let precompiles = precompiles::precompile_set(false); @@ -1501,7 +1532,10 @@ mod tests { #[test] fn invalid_transaction_should_bump_nonce() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = init_account_storage().unwrap(); @@ -1574,7 +1608,10 @@ mod tests { #[test] fn test_first_blocks() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; store_block_fees(&mut host, &dummy_block_fees()).unwrap(); host.promote().unwrap(); @@ -1693,7 +1730,10 @@ mod tests { fn test_reboot_many_tx_one_proposal() { // init host let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -1778,7 +1818,10 @@ mod tests { fn test_reboot_many_tx_many_proposal() { // init host let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, @@ -1892,7 +1935,10 @@ mod tests { // init host let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; // see // https://basescan.org/tx/0x07471adfe8f4ec553c1199f495be97fc8be8e0626ae307281c22534460184ed1 @@ -1957,7 +2003,10 @@ mod tests { fn test_non_retriable_transaction_are_marked_as_failed() { // init host let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), @@ -2075,7 +2124,10 @@ mod tests { // Test if a valid transaction is producing a receipt with a success status fn test_type_propagation() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; crate::storage::store_minimum_base_fee_per_gas( &mut host, DUMMY_BASE_FEE_PER_GAS.into(), diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index cefbab53d1d2..b94cc9759bb1 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -22,7 +22,10 @@ use sha3::{Digest, Keccak256}; use tezos_ethereum::rlp_helpers; use tezos_ethereum::tx_common::EthereumTransactionCommon; use tezos_evm_logging::{log, Level::*, Verbosity}; -use tezos_evm_runtime::{runtime::Runtime, safe_storage::SafeStorage}; +use tezos_evm_runtime::{ + runtime::Runtime, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, +}; use tezos_smart_rollup::types::Timestamp; use tezos_smart_rollup_core::MAX_INPUT_MESSAGE_SIZE; use tezos_smart_rollup_host::path::*; @@ -309,7 +312,10 @@ fn parse_and_validate_blueprint>( match rlp::decode::(bytes) { Err(e) => Ok((BlueprintValidity::DecoderError(e), bytes.len())), Ok(blueprint_with_hashes) => { - let mut host = SafeStorage { host }; + let mut host = SafeStorage { + root: WORLD_STATE_PATH, + host, + }; let head = block_storage::read_current(&mut host); let (head_hash, head_timestamp) = match head { Ok(block) => (block.hash, block.timestamp), diff --git a/etherlink/kernel_evm/kernel/src/bridge.rs b/etherlink/kernel_evm/kernel/src/bridge.rs index a7adbb515530..ee23ae46dd60 100644 --- a/etherlink/kernel_evm/kernel/src/bridge.rs +++ b/etherlink/kernel_evm/kernel/src/bridge.rs @@ -223,7 +223,10 @@ mod tests { use evm_execution::account_storage::init_account_storage; use primitive_types::{H160, U256}; use rlp::Decodable; - use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; + use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, + }; use crate::{bridge::DEPOSIT_EVENT_TOPIC, CONFIG}; @@ -275,7 +278,10 @@ mod tests { #[test] fn deposit_execution_outcome_contains_event() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = init_account_storage().unwrap(); let deposit = dummy_deposit(); @@ -303,7 +309,10 @@ mod tests { #[test] fn deposit_execution_fails_due_to_balance_overflow() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = init_account_storage().unwrap(); let mut deposit = dummy_deposit(); diff --git a/etherlink/kernel_evm/kernel/src/configuration.rs b/etherlink/kernel_evm/kernel/src/configuration.rs index c1d37f595061..596055fdaba2 100644 --- a/etherlink/kernel_evm/kernel/src/configuration.rs +++ b/etherlink/kernel_evm/kernel/src/configuration.rs @@ -13,7 +13,10 @@ use crate::{ use evm_execution::read_ticketer; use tezos_crypto_rs::hash::ContractKt1Hash; use tezos_evm_logging::{log, Level::*}; -use tezos_evm_runtime::{runtime::Runtime, safe_storage::SafeStorage}; +use tezos_evm_runtime::{ + runtime::Runtime, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, +}; use tezos_smart_rollup_encoding::public_key::PublicKey; #[derive(Debug, Clone, Default)] @@ -148,7 +151,10 @@ impl TezosContracts { fn fetch_tezos_contracts(host: &mut impl Runtime) -> TezosContracts { // 1. Fetch the kernel's ticketer, returns `None` if it is badly // encoded or absent. - let host = SafeStorage { host }; + let host = SafeStorage { + host, + root: WORLD_STATE_PATH, + }; let ticketer = read_ticketer(&host); let host = host.host; // 2. Fetch the kernel's administrator, returns `None` if it is badly diff --git a/etherlink/kernel_evm/kernel/src/fees.rs b/etherlink/kernel_evm/kernel/src/fees.rs index e79ff723cbd3..48510641d472 100644 --- a/etherlink/kernel_evm/kernel/src/fees.rs +++ b/etherlink/kernel_evm/kernel/src/fees.rs @@ -311,7 +311,10 @@ mod tests { use evm::ExitSucceed; use evm_execution::account_storage::{account_path, EthereumAccountStorage}; use primitive_types::{H160, U256}; - use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; + use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, + }; use proptest::prelude::*; @@ -363,7 +366,10 @@ mod tests { fn apply_updates_balances_no_sequencer() { // Arrange let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); @@ -401,7 +407,10 @@ mod tests { fn apply_updates_balances_with_sequencer() { // Arrange let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let sequencer_address = address_from_str("0123456789ABCDEF0123456789ABCDEF01234567"); @@ -459,7 +468,10 @@ mod tests { fn apply_fails_user_charge_too_large() { // Arrange let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let mut evm_account_storage = evm_execution::account_storage::init_account_storage().unwrap(); diff --git a/etherlink/kernel_evm/kernel/src/gas_price.rs b/etherlink/kernel_evm/kernel/src/gas_price.rs index 640936ad6b6d..a7e88088f92a 100644 --- a/etherlink/kernel_evm/kernel/src/gas_price.rs +++ b/etherlink/kernel_evm/kernel/src/gas_price.rs @@ -157,7 +157,7 @@ mod test { use tezos_ethereum::block::BlockConstants; use tezos_evm_runtime::{ runtime::{MockKernelHost, Runtime}, - safe_storage::SafeStorage, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, }; proptest! { @@ -189,7 +189,10 @@ mod test { #[test] fn gas_price_responds_to_load() { let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let timestamp = 0_i64; let block_fees = crate::retrieve_block_fees(&mut host).unwrap(); let dummy_block_constants = BlockConstants::first_block( diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index 575f0d19efc3..13729e10e69e 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -290,7 +290,10 @@ pub fn main(host: &mut impl Runtime) -> Result<(), anyhow::Error> { return Ok(()); }; - let host = SafeStorage { host }; + let host = SafeStorage { + host, + root: WORLD_STATE_PATH, + }; let trace_input = read_tracer_input(host.host)?; // Start processing blueprints @@ -416,7 +419,7 @@ mod tests { tx_common::EthereumTransactionCommon, }; use tezos_evm_runtime::runtime::MockKernelHost; - use tezos_evm_runtime::safe_storage::SafeStorage; + use tezos_evm_runtime::safe_storage::{SafeStorage, WORLD_STATE_PATH}; use tezos_evm_runtime::runtime::Runtime; use tezos_smart_rollup::michelson::ticket::FA2_1Ticket; @@ -536,7 +539,10 @@ mod tests { fn test_reboot_during_block_production() { // init host let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let block_fees = dummy_block_fees(); crate::storage::store_minimum_base_fee_per_gas( @@ -644,7 +650,10 @@ mod tests { fn load_block_fees_new() { // Arrange let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; // Act let result = crate::retrieve_block_fees(&mut host); @@ -666,7 +675,10 @@ mod tests { // Arrange let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let min_base_fee = U256::from(17); tezos_storage::write_u256_le(&mut host, &min_path, min_base_fee).unwrap(); @@ -686,7 +698,10 @@ mod tests { fn test_xtz_withdrawal_applied() { // init host let mut host = MockKernelHost::default(); - let mut safe_storage = SafeStorage { host: &mut host }; + let mut safe_storage = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; safe_storage .store_write_all( &NATIVE_TOKEN_TICKETER_PATH, @@ -890,6 +905,7 @@ mod tests { // read transaction receipt let mut safe_storage = SafeStorage { host: &mut mock_host, + root: WORLD_STATE_PATH, }; safe_storage.start().unwrap(); let res = read_transaction_receipt_status(&mut safe_storage, &tx_hash.0).ok(); @@ -927,6 +943,7 @@ mod tests { let mut evm_account_storage = account_storage::init_account_storage().unwrap(); let mut safe_storage = SafeStorage { host: &mut mock_host, + root: WORLD_STATE_PATH, }; set_balance( &mut safe_storage, diff --git a/etherlink/kernel_evm/kernel/src/migration.rs b/etherlink/kernel_evm/kernel/src/migration.rs index ad1d495cfd97..a748a6364173 100644 --- a/etherlink/kernel_evm/kernel/src/migration.rs +++ b/etherlink/kernel_evm/kernel/src/migration.rs @@ -153,7 +153,10 @@ fn migrate_to>( // might clean the zero account by accident, and the account // must always exist as the ticket table is stored in the // zero address. - let mut host = SafeStorage { host }; + let mut host = SafeStorage { + host, + root: WORLD_STATE_PATH, + }; let account_storage = init_account_storage()?; let account_path = account_path(&SYSTEM_ACCOUNT_ADDRESS)?; let mut account = account_storage.get_or_create(&host, &account_path)?; @@ -162,7 +165,10 @@ fn migrate_to>( Ok(MigrationStatus::Done) } StorageVersion::V20 => { - let mut host = SafeStorage { host }; + let mut host = SafeStorage { + host, + root: WORLD_STATE_PATH, + }; let account_storage = init_account_storage()?; let mut withdrawal_precompiled = account_storage .get_or_create(&host, &account_path(&WITHDRAWAL_ADDRESS)?)?; diff --git a/etherlink/kernel_evm/kernel/src/simulation.rs b/etherlink/kernel_evm/kernel/src/simulation.rs index 47814ea2205f..f49599f3f1bf 100644 --- a/etherlink/kernel_evm/kernel/src/simulation.rs +++ b/etherlink/kernel_evm/kernel/src/simulation.rs @@ -797,7 +797,10 @@ mod tests { fn simulation_result() { // setup let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let new_address = create_contract(&mut host); host.promote().unwrap(); @@ -857,7 +860,10 @@ mod tests { fn evaluation_result_no_gas() { // setup let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let new_address = create_contract(&mut host); host.promote().unwrap(); @@ -927,7 +933,10 @@ mod tests { fn parse_simulation2() { // setup let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let new_address = create_contract(&mut host); let to = Some(new_address); diff --git a/etherlink/kernel_evm/kernel/src/stage_one.rs b/etherlink/kernel_evm/kernel/src/stage_one.rs index 861414100847..88477b8691b0 100644 --- a/etherlink/kernel_evm/kernel/src/stage_one.rs +++ b/etherlink/kernel_evm/kernel/src/stage_one.rs @@ -191,7 +191,10 @@ mod tests { use rlp::Encodable; use tezos_crypto_rs::hash::{HashTrait, SecretKeyEd25519, UnknownSignature}; use tezos_data_encoding::types::Bytes; - use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; + use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, + }; use tezos_smart_rollup::{ michelson::{ ticket::FA2_1Ticket, MichelsonBytes, MichelsonOption, MichelsonOr, @@ -551,7 +554,10 @@ mod tests { }; // The dummy chunk in the inbox is registered at block 10 - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; store_current_number(&mut host, U256::from(9)).unwrap(); if read_next_blueprint(host.host, &mut conf) .expect("Blueprint reading shouldn't fail") diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index 22573715da99..46780d1bc2b2 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -968,13 +968,19 @@ pub fn read_delayed_transaction_bridge>( #[cfg(test)] mod tests { - use tezos_evm_runtime::{runtime::MockKernelHost, safe_storage::SafeStorage}; + use tezos_evm_runtime::{ + runtime::MockKernelHost, + safe_storage::{SafeStorage, WORLD_STATE_PATH}, + }; #[test] fn update_burned_fees() { // Arrange let mut host = MockKernelHost::default(); - let mut host = SafeStorage { host: &mut host }; + let mut host = SafeStorage { + host: &mut host, + root: WORLD_STATE_PATH, + }; let fst = 17.into(); let snd = 19.into(); diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index ac871199375c..05980f7fe1c7 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -35,6 +35,7 @@ pub fn safe_trace_path(path: &TracePath) -> Result, RuntimeError } pub struct SafeStorage { + pub root: RefPath<'static, true>, pub host: Runtime, } @@ -254,13 +255,11 @@ impl> Verbosity for SafeStorage<&mut Host> { impl<'a, Host: Runtime> SafeStorage<&'a mut Host> { pub fn start(&mut self) -> Result<(), RuntimeError> { - self.host - .store_copy(&WORLD_STATE_PATH, &TMP_WORLD_STATE_PATH) + self.host.store_copy(&self.root, &TMP_WORLD_STATE_PATH) } pub fn promote(&mut self) -> Result<(), RuntimeError> { - self.host - .store_move(&TMP_WORLD_STATE_PATH, &WORLD_STATE_PATH) + self.host.store_move(&TMP_WORLD_STATE_PATH, &self.root) } // Only used in tracing mode, so that the trace doesn't polute the world -- GitLab