From ca09474d16fb8687355d505acd4a5a0bef1a08bd Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 28 Feb 2024 11:30:52 +0100 Subject: [PATCH 1/2] EVM/Kernel: failsafe storage in /tmp/evm and not /tmp --- etherlink/kernel_evm/kernel/src/lib.rs | 11 ++++++----- etherlink/kernel_evm/kernel/src/safe_storage.rs | 10 ++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index e02cdfb5ff21..f1f29ad4ccbc 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -10,7 +10,7 @@ use crate::configuration::{fetch_configuration, Configuration}; use crate::error::Error; use crate::error::UpgradeProcessError::Fallback; use crate::migration::storage_migration; -use crate::safe_storage::{KernelRuntime, SafeStorage, TMP_PATH}; +use crate::safe_storage::{KernelRuntime, SafeStorage}; use crate::stage_one::fetch; use crate::Error::UpgradeError; use anyhow::Context; @@ -239,20 +239,21 @@ pub fn kernel_loop(host: &mut Host) { ); } - host.store_copy(&EVM_PATH, &TMP_PATH) - .expect("The kernel failed to create the temporary directory"); - let mut internal_storage = InternalStorage(); let mut safe_host = SafeStorage { host, internal: &mut internal_storage, }; + safe_host + .start() + .expect("The kernel failed to create the temporary directory"); + match main(&mut safe_host) { Ok(()) => { promote_upgrade(&mut safe_host) .expect("Potential kernel upgrade promotion failed"); safe_host - .promote(&EVM_PATH) + .promote() .expect("The kernel failed to promote the temporary directory"); // The kernel run went fine, it won't be retried, we can safely diff --git a/etherlink/kernel_evm/kernel/src/safe_storage.rs b/etherlink/kernel_evm/kernel/src/safe_storage.rs index 2e04bd5bc3ac..d4712bdddadc 100644 --- a/etherlink/kernel_evm/kernel/src/safe_storage.rs +++ b/etherlink/kernel_evm/kernel/src/safe_storage.rs @@ -17,6 +17,8 @@ use tezos_smart_rollup_host::{ }; pub const TMP_PATH: RefPath = RefPath::assert_from(b"/tmp"); +pub const EVM_PATH: RefPath = RefPath::assert_from(b"/evm"); +pub const TMP_EVM_PATH: RefPath = RefPath::assert_from(b"/tmp/evm"); // The kernel runtime requires both the standard Runtime and the // new Extended one. @@ -220,8 +222,12 @@ impl Runtime for SafeStorage<&mut Host, &mut Intern } impl SafeStorage<&mut Host, &mut Internal> { - pub fn promote(&mut self, path: &impl Path) -> Result<(), RuntimeError> { - self.host.store_move(&TMP_PATH, path) + pub fn start(&mut self) -> Result<(), RuntimeError> { + self.host.store_copy(&EVM_PATH, &TMP_EVM_PATH) + } + + pub fn promote(&mut self) -> Result<(), RuntimeError> { + self.host.store_move(&TMP_EVM_PATH, &EVM_PATH) } pub fn revert(&mut self) -> Result<(), RuntimeError> { -- GitLab From 3d1ff2e614d0328c3f48707e47fed1115d332b0f Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 28 Feb 2024 11:32:40 +0100 Subject: [PATCH 2/2] EVM/Kernel: add /evm prefix manually --- .../evm_execution/src/account_storage.rs | 3 +- .../kernel_evm/evm_execution/src/storage.rs | 3 +- etherlink/kernel_evm/kernel/src/apply.rs | 2 +- .../kernel/src/blueprint_storage.rs | 2 +- .../kernel_evm/kernel/src/delayed_inbox.rs | 2 +- etherlink/kernel_evm/kernel/src/lib.rs | 9 ++- etherlink/kernel_evm/kernel/src/migration.rs | 2 +- .../kernel_evm/kernel/src/reveal_storage.rs | 13 ++-- etherlink/kernel_evm/kernel/src/storage.rs | 65 ++++++++++--------- etherlink/kernel_evm/kernel/src/upgrade.rs | 4 +- 10 files changed, 52 insertions(+), 53 deletions(-) diff --git a/etherlink/kernel_evm/evm_execution/src/account_storage.rs b/etherlink/kernel_evm/evm_execution/src/account_storage.rs index 6bebe67f2149..ff8845fc35ec 100644 --- a/etherlink/kernel_evm/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/account_storage.rs @@ -102,7 +102,8 @@ impl From for EthereumAccount { } /// Path where Ethereum accounts are stored -pub const EVM_ACCOUNTS_PATH: RefPath = RefPath::assert_from(b"/world_state/eth_accounts"); +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. diff --git a/etherlink/kernel_evm/evm_execution/src/storage.rs b/etherlink/kernel_evm/evm_execution/src/storage.rs index 3e25a15e9ab5..d48e1d5b8b08 100644 --- a/etherlink/kernel_evm/evm_execution/src/storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/storage.rs @@ -88,7 +88,8 @@ pub mod blocks { } fn to_block_hash_path(block_number: U256) -> Result { - let path: Vec = format!("/world_state/blocks/{}/hash", block_number).into(); + let path: Vec = + format!("/evm/world_state/blocks/{}/hash", block_number).into(); let owned_path = OwnedPath::try_from(path)?; Ok(owned_path) } diff --git a/etherlink/kernel_evm/kernel/src/apply.rs b/etherlink/kernel_evm/kernel/src/apply.rs index 56b3b899ed27..7e6f76b77137 100644 --- a/etherlink/kernel_evm/kernel/src/apply.rs +++ b/etherlink/kernel_evm/kernel/src/apply.rs @@ -407,7 +407,7 @@ fn apply_deposit( } pub const WITHDRAWAL_OUTBOX_QUEUE: RefPath = - RefPath::assert_from(b"/world_state/__outbox_queue"); + RefPath::assert_from(b"/evm/world_state/__outbox_queue"); fn post_withdrawals( host: &mut Host, diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index 2e5aec7c8148..24d5da75a87d 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -17,7 +17,7 @@ use tezos_evm_logging::{log, Level::*}; use tezos_smart_rollup_host::path::*; use tezos_smart_rollup_host::runtime::{Runtime, RuntimeError}; -const EVM_BLUEPRINTS: RefPath = RefPath::assert_from(b"/blueprints"); +const EVM_BLUEPRINTS: RefPath = RefPath::assert_from(b"/evm/blueprints"); const EVM_BLUEPRINT_NB_CHUNKS: RefPath = RefPath::assert_from(b"/nb_chunks"); diff --git a/etherlink/kernel_evm/kernel/src/delayed_inbox.rs b/etherlink/kernel_evm/kernel/src/delayed_inbox.rs index 9ed7fffadbec..9df72d1273ad 100644 --- a/etherlink/kernel_evm/kernel/src/delayed_inbox.rs +++ b/etherlink/kernel_evm/kernel/src/delayed_inbox.rs @@ -18,7 +18,7 @@ use tezos_smart_rollup_host::{path::RefPath, runtime::Runtime}; pub struct DelayedInbox(LinkedList); -pub const DELAYED_INBOX_PATH: RefPath = RefPath::assert_from(b"/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_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index f1f29ad4ccbc..f72d8e28eced 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -33,7 +33,7 @@ use tezos_smart_rollup::outbox::OutboxQueue; use tezos_smart_rollup_encoding::public_key::PublicKey; use tezos_smart_rollup_encoding::timestamp::Timestamp; use tezos_smart_rollup_entrypoint::kernel_entry; -use tezos_smart_rollup_host::path::{concat, RefPath}; +use tezos_smart_rollup_host::path::RefPath; use tezos_smart_rollup_host::runtime::Runtime; mod apply; @@ -258,9 +258,7 @@ pub fn kernel_loop(host: &mut Host) { // The kernel run went fine, it won't be retried, we can safely // flush the outbox queue: - let path = concat(&EVM_PATH, &WITHDRAWAL_OUTBOX_QUEUE) - .expect("Failed to concat path"); - let outbox_queue = OutboxQueue::new(&path, u32::MAX) + let outbox_queue = OutboxQueue::new(&WITHDRAWAL_OUTBOX_QUEUE, u32::MAX) .expect("Failed to create the outbox queue"); let written = outbox_queue.flush_queue(safe_host.host); @@ -551,7 +549,8 @@ mod tests { #[test] fn load_block_fees_with_minimum() { let min_path = - RefPath::assert_from(b"/world_state/fees/minimum_base_fee_per_gas").into(); + RefPath::assert_from(b"/evm/world_state/fees/minimum_base_fee_per_gas") + .into(); // Arrange let mut host = MockHost::default(); diff --git a/etherlink/kernel_evm/kernel/src/migration.rs b/etherlink/kernel_evm/kernel/src/migration.rs index d2d7cf314757..a7473e084eda 100644 --- a/etherlink/kernel_evm/kernel/src/migration.rs +++ b/etherlink/kernel_evm/kernel/src/migration.rs @@ -46,7 +46,7 @@ fn migration(host: &mut Host) -> anyhow::Result if STORAGE_VERSION == current_version + 1 { // MIGRATION CODE - START allow_path_not_found( - host.store_delete(&RefPath::assert_from(b"/blueprints/last")), + host.store_delete(&RefPath::assert_from(b"/evm/blueprints/last")), )?; // MIGRATION CODE - END store_storage_version(host, STORAGE_VERSION)?; diff --git a/etherlink/kernel_evm/kernel/src/reveal_storage.rs b/etherlink/kernel_evm/kernel/src/reveal_storage.rs index e2521352c9fa..081b978f9b7b 100644 --- a/etherlink/kernel_evm/kernel/src/reveal_storage.rs +++ b/etherlink/kernel_evm/kernel/src/reveal_storage.rs @@ -2,17 +2,14 @@ // // SPDX-License-Identifier: MIT -use crate::{ - storage::{ADMIN, SEQUENCER}, - EVM_PATH, -}; +use crate::storage::{ADMIN, SEQUENCER}; use rlp::{Decodable, DecoderError, Rlp}; use tezos_crypto_rs::hash::ContractKt1Hash; use tezos_ethereum::rlp_helpers::{decode_field, next, FromRlpBytes}; use tezos_evm_logging::{log, Level::*}; use tezos_smart_rollup_debug::Runtime; use tezos_smart_rollup_encoding::public_key::PublicKey; -use tezos_smart_rollup_host::path::{concat, OwnedPath, RefPath}; +use tezos_smart_rollup_host::path::{OwnedPath, RefPath}; use tezos_smart_rollup_host::runtime::ValueType; /// This module is a testing device, allowing to replicate the state of an existing EVM rollup @@ -93,18 +90,16 @@ pub fn reveal_storage( // Change the sequencer if asked: if let Some(sequencer) = sequencer { - let sequencer_path = concat(&EVM_PATH, &SEQUENCER).unwrap(); let pk_b58 = PublicKey::to_b58check(&sequencer); let bytes = String::as_bytes(&pk_b58); - host.store_write_all(&sequencer_path, bytes).unwrap(); + host.store_write_all(&SEQUENCER, bytes).unwrap(); } // Change the admin if asked: if let Some(admin) = admin { - let sequencer_path = concat(&EVM_PATH, &ADMIN).unwrap(); let kt1_b58 = admin.to_base58_check(); let bytes = String::as_bytes(&kt1_b58); - host.store_write_all(&sequencer_path, bytes).unwrap(); + host.store_write_all(&ADMIN, bytes).unwrap(); } log!(host, Info, "Done revealing") diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index b18201ff8676..a1ed73cfb2ed 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -32,71 +32,74 @@ use tezos_ethereum::wei::Wei; use primitive_types::{H160, H256, U256}; pub const STORAGE_VERSION: u64 = 8; -pub const STORAGE_VERSION_PATH: RefPath = RefPath::assert_from(b"/storage_version"); +pub const STORAGE_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/storage_version"); -const KERNEL_VERSION_PATH: RefPath = RefPath::assert_from(b"/kernel_version"); +const KERNEL_VERSION_PATH: RefPath = RefPath::assert_from(b"/evm/kernel_version"); -const TICKETER: RefPath = RefPath::assert_from(b"/ticketer"); -pub const ADMIN: RefPath = RefPath::assert_from(b"/admin"); -pub const SEQUENCER_ADMIN: RefPath = RefPath::assert_from(b"/sequencer_admin"); -const KERNEL_GOVERNANCE: RefPath = RefPath::assert_from(b"/kernel_governance"); -const DELAYED_BRIDGE: RefPath = RefPath::assert_from(b"/delayed_bridge"); +const TICKETER: RefPath = RefPath::assert_from(b"/evm/ticketer"); +pub const ADMIN: RefPath = RefPath::assert_from(b"/evm/admin"); +pub const SEQUENCER_ADMIN: RefPath = RefPath::assert_from(b"/evm/sequencer_admin"); +const KERNEL_GOVERNANCE: RefPath = RefPath::assert_from(b"/evm/kernel_governance"); +const DELAYED_BRIDGE: RefPath = RefPath::assert_from(b"/evm/delayed_bridge"); // Path to the block in progress, used between reboots const EVM_BLOCK_IN_PROGRESS: RefPath = - RefPath::assert_from(b"/world_state/blocks/in_progress"); + RefPath::assert_from(b"/evm/world_state/blocks/in_progress"); -const EVM_CURRENT_BLOCK: RefPath = RefPath::assert_from(b"/world_state/blocks/current"); -pub const EVM_BLOCKS: RefPath = RefPath::assert_from(b"/world_state/blocks"); +const EVM_CURRENT_BLOCK: RefPath = + RefPath::assert_from(b"/evm/world_state/blocks/current"); +pub const EVM_BLOCKS: RefPath = RefPath::assert_from(b"/evm/world_state/blocks"); const BLOCK_NUMBER: RefPath = RefPath::assert_from(b"/number"); const BLOCK_HASH: RefPath = RefPath::assert_from(b"/hash"); -const EVENTS: RefPath = RefPath::assert_from(b"/events"); +const EVENTS: RefPath = RefPath::assert_from(b"/evm/events"); pub const EVM_TRANSACTIONS_RECEIPTS: RefPath = - RefPath::assert_from(b"/world_state/transactions_receipts"); + RefPath::assert_from(b"/evm/world_state/transactions_receipts"); pub const EVM_TRANSACTIONS_OBJECTS: RefPath = - RefPath::assert_from(b"/world_state/transactions_objects"); + RefPath::assert_from(b"/evm/world_state/transactions_objects"); -const EVM_CHAIN_ID: RefPath = RefPath::assert_from(b"/chain_id"); +const EVM_CHAIN_ID: RefPath = RefPath::assert_from(b"/evm/chain_id"); pub const EVM_BASE_FEE_PER_GAS: RefPath = - RefPath::assert_from(b"/world_state/fees/base_fee_per_gas"); + RefPath::assert_from(b"/evm/world_state/fees/base_fee_per_gas"); const EVM_MINIMUM_BASE_FEE_PER_GAS: RefPath = - RefPath::assert_from(b"/world_state/fees/minimum_base_fee_per_gas"); -const EVM_DA_FEE: RefPath = RefPath::assert_from(b"/world_state/fees/da_fee_per_byte"); -const TICK_BACKLOG_PATH: RefPath = RefPath::assert_from(b"/world_state/fees/backlog"); + 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"/world_state/fees/last_timestamp"); + 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 = RefPath::assert_from(b"/sequencer_pool_address"); +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"/l1_level"); +const EVM_L1_LEVEL: RefPath = RefPath::assert_from(b"/evm/l1_level"); -const EVM_BURNED_FEES: RefPath = RefPath::assert_from(b"/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 = - RefPath::assert_from(b"/info_per_level/timestamp"); + 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 = - RefPath::assert_from(b"/info_per_level/stats/numbers"); + 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 = - RefPath::assert_from(b"/info_per_level/stats/total"); + RefPath::assert_from(b"/evm/info_per_level/stats/total"); -pub const SIMULATION_RESULT: RefPath = RefPath::assert_from(b"/simulation_result"); +pub const SIMULATION_RESULT: RefPath = RefPath::assert_from(b"/evm/simulation_result"); -pub const DEPOSIT_NONCE: RefPath = RefPath::assert_from(b"/deposit_nonce"); +pub const DEPOSIT_NONCE: RefPath = RefPath::assert_from(b"/evm/deposit_nonce"); /// Path where all indexes are stored. -pub const EVM_INDEXES: RefPath = RefPath::assert_from(b"/world_state/indexes"); +pub const EVM_INDEXES: RefPath = RefPath::assert_from(b"/evm/world_state/indexes"); /// Path where Ethereum accounts are stored. const ACCOUNTS_INDEX: RefPath = RefPath::assert_from(b"/accounts"); @@ -109,19 +112,19 @@ const TRANSACTIONS_INDEX: RefPath = RefPath::assert_from(b"/transactions"); // Path to the number of seconds until delayed txs are timed out. const EVM_DELAYED_INBOX_TIMEOUT: RefPath = - RefPath::assert_from(b"/delayed_inbox_timeout"); + 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 = - RefPath::assert_from(b"/delayed_inbox_min_levels"); + RefPath::assert_from(b"/evm/delayed_inbox_min_levels"); /// The size of one 256 bit word. Size in bytes pub const WORD_SIZE: usize = 32usize; // 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"/sequencer"); +pub const SEQUENCER: RefPath = RefPath::assert_from(b"/evm/sequencer"); pub fn store_read_slice( host: &Host, diff --git a/etherlink/kernel_evm/kernel/src/upgrade.rs b/etherlink/kernel_evm/kernel/src/upgrade.rs index 2cf32ce47b72..e14332e5e034 100644 --- a/etherlink/kernel_evm/kernel/src/upgrade.rs +++ b/etherlink/kernel_evm/kernel/src/upgrade.rs @@ -35,8 +35,8 @@ use tezos_smart_rollup_host::path::RefPath; use tezos_smart_rollup_host::runtime::Runtime; use tezos_smart_rollup_installer_config::binary::promote::upgrade_reveal_flow; -const KERNEL_UPGRADE: RefPath = RefPath::assert_from(b"/kernel_upgrade"); -const SEQUENCER_UPGRADE: RefPath = RefPath::assert_from(b"/sequencer_upgrade"); +const KERNEL_UPGRADE: RefPath = RefPath::assert_from(b"/evm/kernel_upgrade"); +const SEQUENCER_UPGRADE: RefPath = RefPath::assert_from(b"/evm/sequencer_upgrade"); #[derive(Debug, PartialEq, Clone)] pub struct KernelUpgrade { -- GitLab