From dd8076b376a7c007465aa2420c35fabf0691ef84 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 15 Jan 2024 17:21:06 +0100 Subject: [PATCH 1/3] EVM/Kernel: move KernelUpgrade to upgrade module --- etherlink/kernel_evm/kernel/src/inbox.rs | 25 ++-------------------- etherlink/kernel_evm/kernel/src/lib.rs | 6 +++--- etherlink/kernel_evm/kernel/src/parsing.rs | 3 ++- etherlink/kernel_evm/kernel/src/storage.rs | 2 +- etherlink/kernel_evm/kernel/src/upgrade.rs | 25 ++++++++++++++++++++++ 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/inbox.rs b/etherlink/kernel_evm/kernel/src/inbox.rs index 039b692b8a3e..fcdb7487546e 100644 --- a/etherlink/kernel_evm/kernel/src/inbox.rs +++ b/etherlink/kernel_evm/kernel/src/inbox.rs @@ -14,6 +14,7 @@ use crate::storage::{ get_and_increment_deposit_nonce, remove_chunked_transaction, store_last_info_per_level_timestamp, store_transaction_chunk, }; +use crate::upgrade::*; use crate::Error; use primitive_types::{H160, U256}; use rlp::{Decodable, DecoderError, Encodable}; @@ -23,7 +24,6 @@ use tezos_ethereum::rlp_helpers::{decode_field, decode_tx_hash, next}; use tezos_ethereum::transaction::{TransactionHash, TRANSACTION_HASH_SIZE}; use tezos_ethereum::tx_common::EthereumTransactionCommon; use tezos_evm_logging::{log, Level::*}; -use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; use tezos_smart_rollup_encoding::public_key::PublicKey; use tezos_smart_rollup_host::runtime::Runtime; @@ -147,28 +147,6 @@ impl Decodable for Transaction { } } -#[derive(Debug, PartialEq, Clone)] -pub struct KernelUpgrade { - pub preimage_hash: [u8; PREIMAGE_HASH_SIZE], -} - -impl Decodable for KernelUpgrade { - fn decode(decoder: &rlp::Rlp) -> Result { - let hash: Vec = decoder.as_val()?; - let preimage_hash: [u8; PREIMAGE_HASH_SIZE] = hash - .try_into() - .map_err(|_| DecoderError::RlpInvalidLength)?; - - Ok(Self { preimage_hash }) - } -} - -impl Encodable for KernelUpgrade { - fn rlp_append(&self, stream: &mut rlp::RlpStream) { - stream.append_iter(self.preimage_hash); - } -} - #[derive(Debug, PartialEq)] pub struct InboxContent { pub kernel_upgrade: Option, @@ -376,6 +354,7 @@ mod tests { use tezos_crypto_rs::hash::SmartRollupHash; use tezos_data_encoding::types::Bytes; use tezos_ethereum::transaction::TRANSACTION_HASH_SIZE; + use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; use tezos_smart_rollup_encoding::contract::Contract; use tezos_smart_rollup_encoding::inbox::ExternalMessageFrame; use tezos_smart_rollup_encoding::michelson::{MichelsonBytes, MichelsonOr}; diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index 6203b66866ce..a7706361f4bd 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -7,12 +7,11 @@ use crate::error::Error; use crate::error::UpgradeProcessError::Fallback; -use crate::inbox::KernelUpgrade; use crate::migration::storage_migration; use crate::safe_storage::{InternalStorage, KernelRuntime, SafeStorage, TMP_PATH}; use crate::stage_one::{fetch, Configuration}; use crate::storage::{read_smart_rollup_address, store_smart_rollup_address}; -use crate::upgrade::upgrade_kernel; +use crate::upgrade::{upgrade_kernel, KernelUpgrade}; use crate::Error::UpgradeError; use anyhow::Context; use block::ComputationResult; @@ -373,8 +372,9 @@ mod tests { use crate::safe_storage::{KernelRuntime, SafeStorage}; use crate::{ blueprint::Blueprint, - inbox::{KernelUpgrade, Transaction, TransactionContent}, + inbox::{Transaction, TransactionContent}, stage_two, storage, + upgrade::KernelUpgrade, }; use evm_execution::account_storage::{self, EthereumAccountStorage}; use primitive_types::{H160, U256}; diff --git a/etherlink/kernel_evm/kernel/src/parsing.rs b/etherlink/kernel_evm/kernel/src/parsing.rs index 65c7d6a865c5..540a41d8a4f7 100644 --- a/etherlink/kernel_evm/kernel/src/parsing.rs +++ b/etherlink/kernel_evm/kernel/src/parsing.rs @@ -6,8 +6,9 @@ // SPDX-License-Identifier: MIT use crate::{ - inbox::{Deposit, KernelUpgrade, Transaction, TransactionContent}, + inbox::{Deposit, Transaction, TransactionContent}, sequencer_blueprint::{SequencerBlueprint, UnsignedSequencerBlueprint}, + upgrade::KernelUpgrade, }; use primitive_types::{H160, U256}; use rlp::Encodable; diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index 97ee31cfc7fb..225ba4a7c15b 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -5,8 +5,8 @@ // SPDX-License-Identifier: MIT use crate::block_in_progress::BlockInProgress; -use crate::inbox::KernelUpgrade; use crate::indexable_storage::IndexableStorage; +use crate::upgrade::KernelUpgrade; use anyhow::Context; use evm_execution::account_storage::EthereumAccount; use tezos_crypto_rs::hash::{ContractKt1Hash, HashTrait}; diff --git a/etherlink/kernel_evm/kernel/src/upgrade.rs b/etherlink/kernel_evm/kernel/src/upgrade.rs index 376d20232758..2a2361e181b0 100644 --- a/etherlink/kernel_evm/kernel/src/upgrade.rs +++ b/etherlink/kernel_evm/kernel/src/upgrade.rs @@ -6,11 +6,36 @@ use crate::error::Error; use crate::error::UpgradeProcessError; +use rlp::Decodable; +use rlp::DecoderError; +use rlp::Encodable; use tezos_evm_logging::{log, Level::*}; use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; use tezos_smart_rollup_host::runtime::Runtime; use tezos_smart_rollup_installer_config::binary::promote::upgrade_reveal_flow; +#[derive(Debug, PartialEq, Clone)] +pub struct KernelUpgrade { + pub preimage_hash: [u8; PREIMAGE_HASH_SIZE], +} + +impl Decodable for KernelUpgrade { + fn decode(decoder: &rlp::Rlp) -> Result { + let hash: Vec = decoder.as_val()?; + let preimage_hash: [u8; PREIMAGE_HASH_SIZE] = hash + .try_into() + .map_err(|_| DecoderError::RlpInvalidLength)?; + + Ok(Self { preimage_hash }) + } +} + +impl Encodable for KernelUpgrade { + fn rlp_append(&self, stream: &mut rlp::RlpStream) { + stream.append_iter(self.preimage_hash); + } +} + pub fn upgrade_kernel( host: &mut Host, root_hash: [u8; PREIMAGE_HASH_SIZE], -- GitLab From 0e9306dfbbeac33e0275ab76b741e62fdc3fa591 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 15 Jan 2024 17:26:27 +0100 Subject: [PATCH 2/3] EVM/Kernel: move storage related functions to upgrade module --- etherlink/kernel_evm/kernel/src/lib.rs | 6 ++--- etherlink/kernel_evm/kernel/src/stage_one.rs | 2 +- etherlink/kernel_evm/kernel/src/storage.rs | 25 ----------------- etherlink/kernel_evm/kernel/src/upgrade.rs | 28 ++++++++++++++++++++ 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index a7706361f4bd..d8a3efda48c2 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -140,7 +140,7 @@ fn upgrade( // reboot before upgrade just in case upgrade_kernel(host, kernel_upgrade.preimage_hash) .context("Failed to upgrade kernel")?; - storage::delete_kernel_upgrade(host) + upgrade::delete_kernel_upgrade(host) } pub fn stage_two( @@ -149,7 +149,7 @@ pub fn stage_two( base_fee_per_gas: U256, ) -> Result<(), anyhow::Error> { log!(host, Info, "Entering stage two."); - if let Some(kernel_upgrade) = storage::read_kernel_upgrade(host)? { + if let Some(kernel_upgrade) = upgrade::read_kernel_upgrade(host)? { produce_and_upgrade(host, kernel_upgrade, chain_id, base_fee_per_gas) } else { block::produce(host, chain_id, base_fee_per_gas).map(|_| ()) @@ -524,7 +524,7 @@ mod tests { let broken_kernel_upgrade = KernelUpgrade { preimage_hash: [0u8; PREIMAGE_HASH_SIZE], }; - storage::store_kernel_upgrade(&mut host, &broken_kernel_upgrade) + crate::upgrade::store_kernel_upgrade(&mut host, &broken_kernel_upgrade) .expect("Should be able to store kernel upgrade"); // If the upgrade is started, it should raise an error diff --git a/etherlink/kernel_evm/kernel/src/stage_one.rs b/etherlink/kernel_evm/kernel/src/stage_one.rs index eb3f78c4f5f7..5bda2ee4ee38 100644 --- a/etherlink/kernel_evm/kernel/src/stage_one.rs +++ b/etherlink/kernel_evm/kernel/src/stage_one.rs @@ -8,7 +8,7 @@ use crate::current_timestamp; use crate::delayed_inbox::DelayedInbox; use crate::inbox::read_inbox; use crate::inbox::InboxContent; -use crate::storage::store_kernel_upgrade; +use crate::upgrade::store_kernel_upgrade; use anyhow::Ok; use tezos_crypto_rs::hash::ContractKt1Hash; use tezos_evm_logging::{log, Level::*}; diff --git a/etherlink/kernel_evm/kernel/src/storage.rs b/etherlink/kernel_evm/kernel/src/storage.rs index 225ba4a7c15b..9fa561a1f1dd 100644 --- a/etherlink/kernel_evm/kernel/src/storage.rs +++ b/etherlink/kernel_evm/kernel/src/storage.rs @@ -6,7 +6,6 @@ use crate::block_in_progress::BlockInProgress; use crate::indexable_storage::IndexableStorage; -use crate::upgrade::KernelUpgrade; use anyhow::Context; use evm_execution::account_storage::EthereumAccount; use tezos_crypto_rs::hash::{ContractKt1Hash, HashTrait}; @@ -89,8 +88,6 @@ const TRANSACTIONS_INDEX: RefPath = RefPath::assert_from(b"/transactions"); /// The size of one 256 bit word. Size in bytes pub const WORD_SIZE: usize = 32usize; -const KERNEL_UPGRADE: RefPath = RefPath::assert_from(b"/kernel_upgrade"); - // Path to the tz1 administrating the sequencer. If there is nothing // at this path, the kernel is in proxy mode. const SEQUENCER: RefPath = RefPath::assert_from(b"/sequencer"); @@ -812,28 +809,6 @@ pub fn delete_block_in_progress(host: &mut Host) -> anyhow::Resul .context("Failed to delete block in progress") } -pub fn store_kernel_upgrade( - host: &mut Host, - kernel_upgrade: &KernelUpgrade, -) -> Result<(), anyhow::Error> { - let path = OwnedPath::from(KERNEL_UPGRADE); - let bytes = &kernel_upgrade.rlp_bytes(); - host.store_write_all(&path, bytes) - .context("Failed to store kernel upgrade") -} - -pub fn read_kernel_upgrade( - host: &Host, -) -> Result, anyhow::Error> { - let path = OwnedPath::from(KERNEL_UPGRADE); - read_optional_rlp(host, &path).context("Failed to decode kernel upgrade") -} - -pub fn delete_kernel_upgrade(host: &mut Host) -> anyhow::Result<()> { - host.store_delete(&KERNEL_UPGRADE) - .context("Failed to delete kernel upgrade") -} - pub fn sequencer(host: &Host) -> anyhow::Result> { if host.store_has(&SEQUENCER)?.is_some() { let bytes = host.store_read_all(&SEQUENCER)?; diff --git a/etherlink/kernel_evm/kernel/src/upgrade.rs b/etherlink/kernel_evm/kernel/src/upgrade.rs index 2a2361e181b0..c03be33022fc 100644 --- a/etherlink/kernel_evm/kernel/src/upgrade.rs +++ b/etherlink/kernel_evm/kernel/src/upgrade.rs @@ -6,11 +6,15 @@ use crate::error::Error; use crate::error::UpgradeProcessError; +use crate::storage::read_optional_rlp; +use anyhow::Context; use rlp::Decodable; use rlp::DecoderError; use rlp::Encodable; use tezos_evm_logging::{log, Level::*}; use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; +use tezos_smart_rollup_host::path::OwnedPath; +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; @@ -36,6 +40,30 @@ impl Encodable for KernelUpgrade { } } +const KERNEL_UPGRADE: RefPath = RefPath::assert_from(b"/kernel_upgrade"); + +pub fn store_kernel_upgrade( + host: &mut Host, + kernel_upgrade: &KernelUpgrade, +) -> Result<(), anyhow::Error> { + let path = OwnedPath::from(KERNEL_UPGRADE); + let bytes = &kernel_upgrade.rlp_bytes(); + host.store_write_all(&path, bytes) + .context("Failed to store kernel upgrade") +} + +pub fn read_kernel_upgrade( + host: &Host, +) -> Result, anyhow::Error> { + let path = OwnedPath::from(KERNEL_UPGRADE); + read_optional_rlp(host, &path).context("Failed to decode kernel upgrade") +} + +fn delete_kernel_upgrade(host: &mut Host) -> anyhow::Result<()> { + host.store_delete(&KERNEL_UPGRADE) + .context("Failed to delete kernel upgrade") +} + pub fn upgrade_kernel( host: &mut Host, root_hash: [u8; PREIMAGE_HASH_SIZE], -- GitLab From e62fdb39db5b163a1e192edcbc0c25eb8564a80e Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 15 Jan 2024 17:29:44 +0100 Subject: [PATCH 3/3] EVM/Kernel: self contained upgrade function in module --- etherlink/kernel_evm/kernel/src/lib.rs | 17 +++-------------- etherlink/kernel_evm/kernel/src/upgrade.rs | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/etherlink/kernel_evm/kernel/src/lib.rs b/etherlink/kernel_evm/kernel/src/lib.rs index d8a3efda48c2..11017021d397 100644 --- a/etherlink/kernel_evm/kernel/src/lib.rs +++ b/etherlink/kernel_evm/kernel/src/lib.rs @@ -11,7 +11,7 @@ use crate::migration::storage_migration; use crate::safe_storage::{InternalStorage, KernelRuntime, SafeStorage, TMP_PATH}; use crate::stage_one::{fetch, Configuration}; use crate::storage::{read_smart_rollup_address, store_smart_rollup_address}; -use crate::upgrade::{upgrade_kernel, KernelUpgrade}; +use crate::upgrade::{upgrade, KernelUpgrade}; use crate::Error::UpgradeError; use anyhow::Context; use block::ComputationResult; @@ -126,23 +126,12 @@ fn produce_and_upgrade( Error, "{:?} happened during block production but a kernel upgrade was detected.", e); - upgrade(host, kernel_upgrade) + upgrade(host, kernel_upgrade.preimage_hash) } - Ok(ComputationResult::Finished) => upgrade(host, kernel_upgrade), + Ok(ComputationResult::Finished) => upgrade(host, kernel_upgrade.preimage_hash), } } -fn upgrade( - host: &mut Host, - kernel_upgrade: KernelUpgrade, -) -> anyhow::Result<()> { - // TODO: #5873 - // reboot before upgrade just in case - upgrade_kernel(host, kernel_upgrade.preimage_hash) - .context("Failed to upgrade kernel")?; - upgrade::delete_kernel_upgrade(host) -} - pub fn stage_two( host: &mut Host, chain_id: U256, diff --git a/etherlink/kernel_evm/kernel/src/upgrade.rs b/etherlink/kernel_evm/kernel/src/upgrade.rs index c03be33022fc..86b0fc91106f 100644 --- a/etherlink/kernel_evm/kernel/src/upgrade.rs +++ b/etherlink/kernel_evm/kernel/src/upgrade.rs @@ -4,7 +4,6 @@ // // SPDX-License-Identifier: MIT -use crate::error::Error; use crate::error::UpgradeProcessError; use crate::storage::read_optional_rlp; use anyhow::Context; @@ -64,10 +63,10 @@ fn delete_kernel_upgrade(host: &mut Host) -> anyhow::Result<()> { .context("Failed to delete kernel upgrade") } -pub fn upgrade_kernel( +pub fn upgrade( host: &mut Host, root_hash: [u8; PREIMAGE_HASH_SIZE], -) -> Result<(), Error> { +) -> anyhow::Result<()> { log!(host, Info, "Kernel upgrade initialisation."); let config = upgrade_reveal_flow(root_hash); @@ -75,6 +74,8 @@ pub fn upgrade_kernel( .evaluate(host) .map_err(UpgradeProcessError::InternalUpgrade)?; + delete_kernel_upgrade(host)?; + // Mark for reboot, the upgrade/migration will happen at next // kernel run, it doesn't matter if it is within the Tezos level // or not. @@ -115,9 +116,14 @@ mod tests { // the debug kernel one from `tests/resources/debug_kernel.wasm`. fn test_kernel_upgrade() { let mut host = MockHost::default(); - let (root_hash, original_kernel) = preliminary_upgrade(&mut host); - upgrade_kernel(&mut host, root_hash.into()) - .expect("Kernel upgrade must succeed."); + let (preimage_hash, original_kernel) = preliminary_upgrade(&mut host); + let preimage_hash = preimage_hash.into(); + + let kernel_upgrade = KernelUpgrade { preimage_hash }; + store_kernel_upgrade(&mut host, &kernel_upgrade) + .expect("It should be able to store"); + + upgrade(&mut host, preimage_hash).expect("Kernel upgrade must succeed."); let boot_kernel = host.store_read_all(&KERNEL_BOOT_PATH).unwrap(); assert_eq!(original_kernel, boot_kernel); -- GitLab