From 188bd7646c79ab890a183f12b106233d5645c02c Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Fri, 9 May 2025 23:42:50 +0200 Subject: [PATCH] =?UTF-8?q?EVM=20Node:=20Enable=20executing=20Dionysus=20n?= =?UTF-8?q?atively=20=F0=9F=8D=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch introduces the necessary adjustment on Dionysus so that it can be natively executed. There is currently two changes that are required for the native execution to be possible: 1. The `populate_delayed_inbox` signature needs to be changed, because it is no longer called as a `unit -> unit` WASM function, but instead as a regular Rust function. This means we can remove the `extern "C"` annotation (required for exposing the function as a WASM function) and we can pass it explicitely the runtime host. 2. We cannot rely on the `InternalRuntime` implementation hard-coded in the kernel to use the WASM host function for getting Irmin root hashes. Instead, we say the `host` passed as an argument of `kernel_loop` actually implements `InternalRuntime`. Basically, it is a way to inject the implementation of our choice. As a consequence, the `KernelHost` struct is simplified: it does no longer contain an implementor of `InternalRuntime`, as its `Runtime` implementor also implements `InternalRuntime`. The kernel could be changed to make this updates unnecessary. But in the meantime, this patch does the necessary job. --- etherlink/CHANGES_NODE.md | 2 + etherlink/kernel_dionysus/kernel/Cargo.toml | 2 +- .../kernel/src/evm_node_entrypoint.rs | 10 ++--- etherlink/kernel_dionysus/kernel/src/lib.rs | 15 +++---- .../kernel_dionysus/runtime/src/runtime.rs | 43 ++++++++----------- etherlink/lib_wasm_runtime/src/host.rs | 11 +++++ etherlink/lib_wasm_runtime/src/runtime/mod.rs | 15 +++++++ 7 files changed, 55 insertions(+), 43 deletions(-) diff --git a/etherlink/CHANGES_NODE.md b/etherlink/CHANGES_NODE.md index e617fe7894be..96be88b86c6f 100644 --- a/etherlink/CHANGES_NODE.md +++ b/etherlink/CHANGES_NODE.md @@ -17,6 +17,8 @@ ### Execution changes +- Supports executing Dionysus natively. (!17975 !17976 !17977) + ### Command-line interface changes - Renames `--bootstrap-account` and `--bootstrap-balance` to diff --git a/etherlink/kernel_dionysus/kernel/Cargo.toml b/etherlink/kernel_dionysus/kernel/Cargo.toml index 2ef3edb7ec7e..be62dfdf4c97 100644 --- a/etherlink/kernel_dionysus/kernel/Cargo.toml +++ b/etherlink/kernel_dionysus/kernel/Cargo.toml @@ -13,7 +13,7 @@ build = "build.rs" license = "MIT" [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "rlib"] [dependencies] thiserror.workspace = true diff --git a/etherlink/kernel_dionysus/kernel/src/evm_node_entrypoint.rs b/etherlink/kernel_dionysus/kernel/src/evm_node_entrypoint.rs index 8488474170a4..48b416b198f1 100644 --- a/etherlink/kernel_dionysus/kernel/src/evm_node_entrypoint.rs +++ b/etherlink/kernel_dionysus/kernel/src/evm_node_entrypoint.rs @@ -10,17 +10,13 @@ use crate::{delayed_inbox::DelayedInbox, transaction::Transaction}; use tezos_ethereum::rlp_helpers::FromRlpBytes; -use tezos_evm_runtime::runtime::KernelHost; -use tezos_smart_rollup_core::rollup_host::RollupHost; +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"); -#[allow(dead_code)] -#[no_mangle] -pub extern "C" fn populate_delayed_inbox() { - let sdk_host = unsafe { RollupHost::new() }; - let mut host = KernelHost::init(sdk_host); +pub fn populate_delayed_inbox(sdk_host: &mut Host) { + let mut host: KernelHost = KernelHost::init(sdk_host); let payload = host.store_read_all(&DELAYED_INPUT_PATH).unwrap(); let transaction = Transaction::from_rlp_bytes(&payload).unwrap(); let mut delayed_inbox = DelayedInbox::new(&mut host).unwrap(); diff --git a/etherlink/kernel_dionysus/kernel/src/lib.rs b/etherlink/kernel_dionysus/kernel/src/lib.rs index 1b96f4c94436..b7d02d2a6fc0 100644 --- a/etherlink/kernel_dionysus/kernel/src/lib.rs +++ b/etherlink/kernel_dionysus/kernel/src/lib.rs @@ -28,9 +28,9 @@ use storage::{ }; use tezos_crypto_rs::hash::ContractKt1Hash; use tezos_evm_logging::{log, Level::*, Verbosity}; +use tezos_evm_runtime::internal_runtime::InternalRuntime; use tezos_evm_runtime::runtime::{KernelHost, Runtime}; use tezos_evm_runtime::safe_storage::WORLD_STATE_PATH; -use tezos_smart_rollup::entrypoint; use tezos_smart_rollup::michelson::MichelsonUnit; use tezos_smart_rollup::outbox::{ OutboxMessage, OutboxMessageWhitelistUpdate, OUTBOX_QUEUE, @@ -52,7 +52,7 @@ mod dal_slot_import_signal; mod delayed_inbox; mod error; mod event; -mod evm_node_entrypoint; +pub mod evm_node_entrypoint; mod fallback_upgrade; mod fees; mod gas_price; @@ -331,8 +331,9 @@ pub fn main(host: &mut Host) -> Result<(), anyhow::Error> { Ok(()) } -#[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. @@ -340,11 +341,7 @@ pub fn kernel_loop(host: &mut H // The kernel host is initialized as soon as possible. `kernel_loop` // shouldn't be called in tests as it won't use `MockInternal` for the // internal runtime. - let mut host: KernelHost< - Host, - &mut Host, - tezos_evm_runtime::internal_runtime::InternalHost, - > = KernelHost::init(host); + let mut host: KernelHost = KernelHost::init(host); let reboot_counter = host .host diff --git a/etherlink/kernel_dionysus/runtime/src/runtime.rs b/etherlink/kernel_dionysus/runtime/src/runtime.rs index e9f97776571c..84ae166fa9bc 100644 --- a/etherlink/kernel_dionysus/runtime/src/runtime.rs +++ b/etherlink/kernel_dionysus/runtime/src/runtime.rs @@ -15,8 +15,7 @@ use std::{ use crate::{ extensions::WithGas, - internal_runtime::{ExtendedRuntime, InternalHost, InternalRuntime}, - mock_internal::MockInternal, + internal_runtime::{ExtendedRuntime, InternalRuntime}, }; use tezos_evm_logging::{Level, Verbosity}; use tezos_smart_rollup_core::PREIMAGE_HASH_SIZE; @@ -61,16 +60,15 @@ 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 + Borrow> { pub host: Host, - pub internal: Internal, pub logs_verbosity: Level, pub execution_gas_used: u64, pub _pd: PhantomData, } -impl + Borrow, Internal: InternalRuntime> SdkRuntime - for KernelHost +impl + Borrow> SdkRuntime + for KernelHost { #[inline(always)] fn write_output(&mut self, from: &[u8]) -> Result<(), RuntimeError> { @@ -250,20 +248,20 @@ impl + Borrow, Internal: InternalRuntime> S } } -impl + BorrowMut, Internal: InternalRuntime> - InternalRuntime for KernelHost +impl + BorrowMut> InternalRuntime + for KernelHost { #[inline(always)] fn __internal_store_get_hash( &mut self, path: &T, ) -> Result, RuntimeError> { - self.internal.__internal_store_get_hash(path) + self.host.borrow_mut().__internal_store_get_hash(path) } } -impl + Borrow, Internal: InternalRuntime> - ExtendedRuntime for KernelHost +impl + Borrow> ExtendedRuntime + for KernelHost { #[inline(always)] fn store_get_hash(&mut self, path: &T) -> Result, RuntimeError> { @@ -271,15 +269,13 @@ impl + Borrow, Internal: InternalRuntime> } } -impl + BorrowMut, Internal> - KernelHost +impl + BorrowMut> KernelHost where for<'a> &'a mut Host: BorrowMut, { - pub fn to_ref_host(&mut self) -> KernelHost { + pub fn to_ref_host(&mut self) -> KernelHost { KernelHost { host: &mut self.host, - internal: &mut self.internal, logs_verbosity: self.logs_verbosity, execution_gas_used: self.execution_gas_used, _pd: PhantomData, @@ -287,8 +283,8 @@ where } } -impl + Borrow, Internal: InternalRuntime> Verbosity - for KernelHost +impl + Borrow> Verbosity + for KernelHost { fn verbosity(&self) -> Level { self.logs_verbosity @@ -306,8 +302,8 @@ pub fn read_logs_verbosity( } } -impl + Borrow, Internal: InternalRuntime> WithGas - for KernelHost +impl + Borrow> WithGas + for KernelHost { fn add_execution_gas(&mut self, gas: u64) { self.execution_gas_used += gas; @@ -318,26 +314,23 @@ impl + Borrow, Internal: InternalRuntime> W } } -impl + Borrow> KernelHost { +impl + Borrow> KernelHost { pub fn init(host: Host) -> Self { - let internal_storage = InternalHost(); let logs_verbosity = read_logs_verbosity(host.borrow()); Self { host, - internal: internal_storage, logs_verbosity, execution_gas_used: 0, _pd: PhantomData, } } } -pub type MockKernelHost = KernelHost; +pub type MockKernelHost = KernelHost; impl Default for MockKernelHost { fn default() -> Self { Self { host: MockHost::default(), - internal: MockInternal(), logs_verbosity: Level::default(), execution_gas_used: 0, _pd: PhantomData, @@ -348,10 +341,8 @@ impl Default for MockKernelHost { impl MockKernelHost { pub fn with_address(address: SmartRollupAddress) -> Self { let host = MockHost::with_address(&address); - let internal = MockInternal(); KernelHost { host, - internal, logs_verbosity: Level::default(), execution_gas_used: 0, _pd: PhantomData, diff --git a/etherlink/lib_wasm_runtime/src/host.rs b/etherlink/lib_wasm_runtime/src/host.rs index 73967cc89d02..4f5164e88a6e 100644 --- a/etherlink/lib_wasm_runtime/src/host.rs +++ b/etherlink/lib_wasm_runtime/src/host.rs @@ -10,6 +10,7 @@ use ocaml::Error; use runtime_bifrost::internal_runtime::InternalRuntime as BifrostInternalRuntime; use runtime_calypso::internal_runtime::InternalRuntime as CalypsoInternalRuntime; use runtime_calypso2::internal_runtime::InternalRuntime as Calypso2InternalRuntime; +use runtime_dionysus::internal_runtime::InternalRuntime as DionysusInternalRuntime; use tezos_smart_rollup_core::MAX_FILE_CHUNK_SIZE; use tezos_smart_rollup_host::{ input::Message, @@ -515,3 +516,13 @@ impl Calypso2InternalRuntime for Host { Ok(hash.as_bytes().to_vec()) } } + +impl DionysusInternalRuntime for Host { + 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)?; + + Ok(hash.as_bytes().to_vec()) + } +} diff --git a/etherlink/lib_wasm_runtime/src/runtime/mod.rs b/etherlink/lib_wasm_runtime/src/runtime/mod.rs index 130f7120139c..2e955e9804c4 100644 --- a/etherlink/lib_wasm_runtime/src/runtime/mod.rs +++ b/etherlink/lib_wasm_runtime/src/runtime/mod.rs @@ -109,6 +109,7 @@ enum NativeKernel { Bifrost, Calypso, Calypso2, + Dionysus, } impl NativeKernel { @@ -117,6 +118,7 @@ impl NativeKernel { Self::Bifrost => RuntimeVersion::V0, Self::Calypso => RuntimeVersion::V1, Self::Calypso2 => RuntimeVersion::V1, + Self::Dionysus => RuntimeVersion::V1, } } } @@ -127,6 +129,8 @@ const CALYPSO_ROOT_HASH_HEX: &'static str = "96114bf7a28e617a3788d8554aa24711b4b11f9c54cd0b12c00bc358beb814a7"; const CALYPSO2_ROOT_HASH_HEX: &'static str = "7b42577597504d6a705cdd56e59c770125223a0ffda471d70b463a2dc2d5f84f"; +const DIONYSUS_ROOT_HASH_HEX: &'static str = + "2214b77edf321b0ed41cc3a1028934299c4b94e0687b06e5239cc0b4eb31417f"; impl NativeKernel { fn of_root_hash(root_hash: &ContextHash) -> Option { @@ -137,6 +141,7 @@ impl NativeKernel { BIFROST_ROOT_HASH_HEX => Some(NativeKernel::Bifrost), CALYPSO_ROOT_HASH_HEX => Some(NativeKernel::Calypso), CALYPSO2_ROOT_HASH_HEX => Some(NativeKernel::Calypso2), + DIONYSUS_ROOT_HASH_HEX => Some(NativeKernel::Dionysus), _ => None, } } @@ -189,6 +194,16 @@ impl Runtime for NativeRuntime { kernel_calypso2::evm_node_entrypoint::populate_delayed_inbox(self.mut_host()); Ok(()) } + ("kernel_run", NativeKernel::Dionysus) => { + trace!("dionysus::kernel_loop"); + kernel_dionysus::kernel_loop(self.mut_host()); + Ok(()) + } + ("populate_delayed_inbox", NativeKernel::Dionysus) => { + trace!("dionysus::populate_delayed_inbox"); + kernel_dionysus::evm_node_entrypoint::populate_delayed_inbox(self.mut_host()); + Ok(()) + } (missing_entrypoint, _) => todo!("entrypoint {missing_entrypoint} not covered yet"), } } -- GitLab