From 93c31402ce3de9d9c98ef7e1c35d758f242cde92 Mon Sep 17 00:00:00 2001 From: steelgeek091 Date: Tue, 24 Dec 2024 17:05:14 +0800 Subject: [PATCH] implement CodeStorage and ModuleStorage --- Cargo.lock | 9 + Cargo.toml | 1 + crates/rooch-executor/Cargo.toml | 1 + crates/rooch-executor/src/actor/executor.rs | 11 +- .../src/actor/reader_executor.rs | 9 +- crates/rooch-genesis/src/lib.rs | 9 +- .../rooch-integration-test-runner/src/lib.rs | 5 +- crates/rooch/src/tx_runner.rs | 6 +- moveos/moveos-store/Cargo.toml | 5 + moveos/moveos-store/src/lib.rs | 200 +++++++++++++++++- moveos/moveos-types/Cargo.toml | 1 + moveos/moveos-types/src/state_resolver.rs | 13 +- moveos/moveos/Cargo.toml | 2 + moveos/moveos/src/moveos.rs | 40 ++-- moveos/moveos/src/vm/moveos_vm.rs | 21 +- .../src/vm/unit_tests/vm_arguments_tests.rs | 10 +- 16 files changed, 293 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b5a012520..ed82de1c82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6947,6 +6947,7 @@ dependencies = [ name = "moveos" version = "0.8.4" dependencies = [ + "ambassador", "anyhow 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", "clap 4.5.17", "codespan", @@ -6954,6 +6955,7 @@ dependencies = [ "itertools 0.13.0", "move-binary-format", "move-bytecode-source-map", + "move-bytecode-verifier", "move-command-line-common", "move-compiler", "move-core-types", @@ -7097,12 +7099,17 @@ name = "moveos-store" version = "0.8.4" dependencies = [ "accumulator", + "ambassador", "anyhow 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", "bcs 0.1.6", + "bytes", "chrono", "function_name", "metrics", + "move-binary-format", "move-core-types", + "move-vm-runtime", + "move-vm-types", "moveos-config", "moveos-types", "once_cell", @@ -7127,6 +7134,7 @@ dependencies = [ "move-binary-format", "move-core-types", "move-resource-viewer", + "move-vm-runtime", "move-vm-types", "once_cell", "primitive-types 0.12.2", @@ -9554,6 +9562,7 @@ dependencies = [ "metrics", "move-core-types", "move-resource-viewer", + "move-vm-runtime", "moveos", "moveos-eventbus", "moveos-store", diff --git a/Cargo.toml b/Cargo.toml index f441ac5d9c..eba54e6d27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -358,6 +358,7 @@ vergen-pretty = "0.3.6" crossbeam-channel = "0.5.13" inferno = "0.11.21" handlebars = "4.2.2" +ambassador = "0.4.1" # Note: the BEGIN and END comments below are required for external tooling. Do not remove. # BEGIN MOVE DEPENDENCIES diff --git a/crates/rooch-executor/Cargo.toml b/crates/rooch-executor/Cargo.toml index 03961e3868..dd20d124c5 100644 --- a/crates/rooch-executor/Cargo.toml +++ b/crates/rooch-executor/Cargo.toml @@ -23,6 +23,7 @@ function_name = { workspace = true } move-core-types = { workspace = true } move-resource-viewer = { workspace = true } +move-vm-runtime = { workspace = true } moveos = { workspace = true } moveos-store = { workspace = true } diff --git a/crates/rooch-executor/src/actor/executor.rs b/crates/rooch-executor/src/actor/executor.rs index 1c9bc8a2a8..0f12f4e2ab 100644 --- a/crates/rooch-executor/src/actor/executor.rs +++ b/crates/rooch-executor/src/actor/executor.rs @@ -46,6 +46,7 @@ use rooch_types::transaction::{ }; use std::str::FromStr; use std::sync::Arc; +use move_vm_runtime::RuntimeEnvironment; pub struct ExecutorActor { root: ObjectMeta, @@ -69,10 +70,11 @@ impl ExecutorActor { let resolver = RootObjectResolver::new(root.clone(), &moveos_store); let gas_parameters = FrameworksGasParameters::load_from_chain(&resolver)?; + let runtime_environment = RuntimeEnvironment::new(gas_parameters.all_natives()); + let moveos = MoveOS::new( + &runtime_environment, moveos_store.clone(), - gas_parameters.all_natives(), - MoveOSConfig::default(), system_pre_execute_functions(), system_post_execute_functions(), )?; @@ -521,10 +523,11 @@ impl Handler for ExecutorActor { let resolver = RootObjectResolver::new(self.root.clone(), &self.moveos_store); let gas_parameters = FrameworksGasParameters::load_from_chain(&resolver)?; + let runtime_environment = RuntimeEnvironment::new(gas_parameters.all_natives()); + self.moveos = MoveOS::new( + &runtime_environment, self.moveos_store.clone(), - gas_parameters.all_natives(), - MoveOSConfig::default(), system_pre_execute_functions(), system_post_execute_functions(), )?; diff --git a/crates/rooch-executor/src/actor/reader_executor.rs b/crates/rooch-executor/src/actor/reader_executor.rs index f7990da613..817aabf628 100644 --- a/crates/rooch-executor/src/actor/reader_executor.rs +++ b/crates/rooch-executor/src/actor/reader_executor.rs @@ -14,6 +14,7 @@ use anyhow::Result; use async_trait::async_trait; use coerce::actor::{context::ActorContext, message::Handler, Actor, LocalActorRef}; use move_resource_viewer::MoveValueAnnotator; +use move_vm_runtime::RuntimeEnvironment; use moveos::moveos::MoveOS; use moveos::moveos::MoveOSConfig; use moveos_eventbus::bus::EventData; @@ -51,10 +52,10 @@ impl ReaderExecutorActor { ) -> Result { let resolver = RootObjectResolver::new(root.clone(), &moveos_store); let gas_parameters = FrameworksGasParameters::load_from_chain(&resolver)?; + let runtime_environment = RuntimeEnvironment::new(gas_parameters.all_natives()); let moveos = MoveOS::new( + &runtime_environment, moveos_store.clone(), - gas_parameters.all_natives(), - MoveOSConfig::default(), system_pre_execute_functions(), system_post_execute_functions(), )?; @@ -321,11 +322,11 @@ impl Handler for ReaderExecutorActor { let resolver = RootObjectResolver::new(self.root.clone(), &self.moveos_store); let gas_parameters = FrameworksGasParameters::load_from_chain(&resolver)?; + let runtime_environment = RuntimeEnvironment::new(gas_parameters.all_natives()); self.moveos = MoveOS::new( + &runtime_environment, self.moveos_store.clone(), - gas_parameters.all_natives(), - MoveOSConfig::default(), system_pre_execute_functions(), system_post_execute_functions(), )?; diff --git a/crates/rooch-genesis/src/lib.rs b/crates/rooch-genesis/src/lib.rs index f296388e9f..b32ae4bf26 100644 --- a/crates/rooch-genesis/src/lib.rs +++ b/crates/rooch-genesis/src/lib.rs @@ -49,6 +49,7 @@ use std::collections::BTreeMap; use std::path::PathBuf; use std::str::FromStr; use std::{fs::File, io::Write, path::Path}; +use move_vm_runtime::RuntimeEnvironment; pub static ROOCH_LOCAL_GENESIS: Lazy = Lazy::new(|| { let network: RoochNetwork = BuiltinChainID::Local.into(); @@ -311,10 +312,10 @@ impl RoochGenesis { let vm_config = MoveOSConfig::default(); let (moveos_store, _temp_dir) = MoveOSStore::mock_moveos_store()?; + let runtime_environment = RuntimeEnvironment::new(gas_parameter.all_natives()); let moveos = MoveOS::new( + &runtime_environment, moveos_store, - gas_parameter.all_natives(), - vm_config, vec![], vec![], )?; @@ -412,10 +413,10 @@ impl RoochGenesis { self.initial_gas_config.max_gas_amount, self.initial_gas_config.entries.clone(), )?; + let runtime_environment = RuntimeEnvironment::new(genesis_gas_parameter.all_natives()); let moveos = MoveOS::new( + &runtime_environment, rooch_db.moveos_store.clone(), - genesis_gas_parameter.all_natives(), - MoveOSConfig::default(), vec![], vec![], )?; diff --git a/crates/rooch-integration-test-runner/src/lib.rs b/crates/rooch-integration-test-runner/src/lib.rs index aca267e7d1..f45acee332 100644 --- a/crates/rooch-integration-test-runner/src/lib.rs +++ b/crates/rooch-integration-test-runner/src/lib.rs @@ -45,6 +45,7 @@ use rooch_types::framework::auth_validator::TxValidateResult; use rooch_types::function_arg::FunctionArg; use std::path::PathBuf; use std::{collections::BTreeMap, path::Path}; +use move_vm_runtime::RuntimeEnvironment; use tracing::debug; pub struct MoveOSTestRunner<'a> { @@ -117,10 +118,10 @@ impl<'a> MoveOSTestAdapter<'a> for MoveOSTestRunner<'a> { let moveos_store = MoveOSStore::new(temp_dir.path(), ®istry).unwrap(); let genesis_gas_parameter = FrameworksGasParameters::initial(); let genesis: &RoochGenesis = &rooch_genesis::ROOCH_LOCAL_GENESIS; + let runtime_environment = RuntimeEnvironment::new(genesis_gas_parameter.all_natives()); let moveos = MoveOS::new( + &runtime_environment, moveos_store.clone(), - genesis_gas_parameter.all_natives(), - MoveOSConfig::default(), rooch_types::framework::system_pre_execute_functions(), rooch_types::framework::system_post_execute_functions(), ) diff --git a/crates/rooch/src/tx_runner.rs b/crates/rooch/src/tx_runner.rs index 50bc67e320..bef4ea36c0 100644 --- a/crates/rooch/src/tx_runner.rs +++ b/crates/rooch/src/tx_runner.rs @@ -37,6 +37,7 @@ use rooch_types::framework::system_pre_execute_functions; use rooch_types::transaction::RoochTransactionData; use std::rc::Rc; use std::str::FromStr; +use move_vm_runtime::RuntimeEnvironment; pub fn execute_tx_locally( state_root_bytes: Vec, @@ -214,9 +215,10 @@ pub fn prepare_execute_env( client_resolver, ))); + let runtime_environment = RuntimeEnvironment::new(gas_parameters.all_natives()); + let vm = MoveOSVM::new( - gas_parameters.all_natives(), - MoveOSConfig::default().vm_config, + &runtime_environment, ) .expect("create MoveVM failed"); diff --git a/moveos/moveos-store/Cargo.toml b/moveos/moveos-store/Cargo.toml index 605f6856b8..a003bf546a 100644 --- a/moveos/moveos-store/Cargo.toml +++ b/moveos/moveos-store/Cargo.toml @@ -24,8 +24,13 @@ prometheus = { workspace = true } tokio = { workspace = true } function_name = { workspace = true } tracing = { workspace = true } +ambassador = { workspace = true } +bytes = { workspace = true } move-core-types = { workspace = true } +move-vm-types = { workspace = true } +move-binary-format = { workspace = true } +move-vm-runtime = { workspace = true } moveos-types = { workspace = true } raw-store = { workspace = true } diff --git a/moveos/moveos-store/src/lib.rs b/moveos/moveos-store/src/lib.rs index 82a06892ba..331a4b577e 100644 --- a/moveos/moveos-store/src/lib.rs +++ b/moveos/moveos-store/src/lib.rs @@ -12,7 +12,7 @@ use crate::transaction_store::{TransactionDBStore, TransactionStore}; use accumulator::inmemory::InMemoryAccumulator; use anyhow::{Error, Result}; use bcs::to_bytes; -use move_core_types::language_storage::StructTag; +use move_core_types::language_storage::{ModuleId, StructTag}; use moveos_config::store_config::{MoveOSStoreConfig, RocksdbConfig}; use moveos_config::DataDirPath; use moveos_types::genesis_info::GenesisInfo; @@ -37,6 +37,13 @@ use smt::NodeReader; use std::fmt::{Debug, Display, Formatter}; use std::path::Path; use std::sync::Arc; +use ambassador::delegate_to_methods; +use bytes::Bytes; +use move_binary_format::CompiledModule; +use move_binary_format::file_format::CompiledScript; +use move_vm_runtime::{Module, Script}; +use move_vm_types::code::{ModuleCache, ScriptCache, UnsyncModuleCache, UnsyncScriptCache, WithBytes, WithHash}; +use move_vm_types::sha3_256; pub mod config_store; pub mod event_store; @@ -67,6 +74,8 @@ static VEC_COLUMN_FAMILY_NAME: Lazy> = Lazy::new(|| { ] }); +pub type TxnIndex = u32; + #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct StoreMeta {} @@ -83,6 +92,28 @@ pub struct MoveOSStore { pub transaction_store: TransactionDBStore, pub config_store: ConfigDBStore, pub state_store: StateDBStore, + pub script_cache: UnsyncScriptCache<[u8; 32], CompiledScript, Script>, + pub module_cache: UnsyncModuleCache>, +} + +#[delegate_to_methods] +#[delegate(ScriptCache, target_ref = "as_script_cache")] +impl MoveOSStore { + pub fn as_script_cache(&self) -> &dyn ScriptCache { + &self.script_cache + } + + fn as_module_cache( + &self, + ) -> &dyn ModuleCache< + Key = ModuleId, + Deserialized = CompiledModule, + Verified = Module, + Extension = RoochModuleExtension, + Version = Option, + > { + &self.module_cache + } } impl MoveOSStore { @@ -111,6 +142,8 @@ impl MoveOSStore { transaction_store: TransactionDBStore::new(instance.clone()), config_store: ConfigDBStore::new(instance), state_store, + script_cache: UnsyncScriptCache::empty(), + module_cache: UnsyncModuleCache::empty(), }; Ok(store) } @@ -398,3 +431,168 @@ pub fn load_feature_store_object( } } } + +/// Additional data stored alongside deserialized or verified modules. +pub struct RoochModuleExtension { + /// Serialized representation of the module. + bytes: Bytes, + /// Module's hash. + hash: [u8; 32], + /// The state value metadata associated with the module, when read from or + /// written to storage. + state_value_metadata: StateValueMetadata, +} + +impl RoochModuleExtension { + /* + /// Creates new extension based on [StateValue]. + pub fn new(state_value: StateValue) -> Self { + let (state_value_metadata, bytes) = state_value.unpack(); + let hash = sha3_256(&bytes); + Self { + bytes, + hash, + state_value_metadata, + } + } + */ + + /// Returns the state value metadata stored in extension. + pub fn state_value_metadata(&self) -> &StateValueMetadata { + &self.state_value_metadata + } +} + +impl WithBytes for RoochModuleExtension { + fn bytes(&self) -> &Bytes { + &self.bytes + } +} + +impl WithHash for RoochModuleExtension { + fn hash(&self) -> &[u8; 32] { + &self.hash + } +} + +#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +struct StateValueMetadataInner { + slot_deposit: u64, + bytes_deposit: u64, + creation_time_usecs: u64, +} + +#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct StateValueMetadata { + inner: Option, +} + +impl StateValueMetadata { + /* + pub fn into_persistable(self) -> Option { + self.inner.map(|inner| { + let StateValueMetadataInner { + slot_deposit, + bytes_deposit, + creation_time_usecs, + } = inner; + if bytes_deposit == 0 { + PersistedStateValueMetadata::V0 { + deposit: slot_deposit, + creation_time_usecs, + } + } else { + PersistedStateValueMetadata::V1 { + slot_deposit, + bytes_deposit, + creation_time_usecs, + } + } + }) + } + */ + + pub fn new( + slot_deposit: u64, + bytes_deposit: u64, + creation_time_usecs: &CurrentTimeMicroseconds, + ) -> Self { + Self::new_impl( + slot_deposit, + bytes_deposit, + creation_time_usecs.microseconds, + ) + } + + pub fn legacy(slot_deposit: u64, creation_time_usecs: &CurrentTimeMicroseconds) -> Self { + Self::new(slot_deposit, 0, creation_time_usecs) + } + + pub fn placeholder(creation_time_usecs: &CurrentTimeMicroseconds) -> Self { + Self::legacy(0, creation_time_usecs) + } + + pub fn none() -> Self { + Self { inner: None } + } + + fn new_impl(slot_deposit: u64, bytes_deposit: u64, creation_time_usecs: u64) -> Self { + Self { + inner: Some(StateValueMetadataInner { + slot_deposit, + bytes_deposit, + creation_time_usecs, + }), + } + } + + pub fn is_none(&self) -> bool { + self.inner.is_none() + } + + fn inner(&self) -> Option<&StateValueMetadataInner> { + self.inner.as_ref() + } + + pub fn creation_time_usecs(&self) -> u64 { + self.inner().map_or(0, |v1| v1.creation_time_usecs) + } + + pub fn slot_deposit(&self) -> u64 { + self.inner().map_or(0, |v1| v1.slot_deposit) + } + + pub fn bytes_deposit(&self) -> u64 { + self.inner().map_or(0, |v1| v1.bytes_deposit) + } + + pub fn total_deposit(&self) -> u64 { + self.slot_deposit() + self.bytes_deposit() + } + + pub fn maybe_upgrade(&mut self) -> &mut Self { + *self = Self::new_impl( + self.slot_deposit(), + self.bytes_deposit(), + self.creation_time_usecs(), + ); + self + } + + fn expect_upgraded(&mut self) -> &mut StateValueMetadataInner { + self.inner.as_mut().expect("State metadata is None.") + } + + pub fn set_slot_deposit(&mut self, amount: u64) { + self.expect_upgraded().slot_deposit = amount; + } + + pub fn set_bytes_deposit(&mut self, amount: u64) { + self.expect_upgraded().bytes_deposit = amount; + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CurrentTimeMicroseconds { + pub microseconds: u64, +} \ No newline at end of file diff --git a/moveos/moveos-types/Cargo.toml b/moveos/moveos-types/Cargo.toml index 4f1e433de9..c71df0e138 100644 --- a/moveos/moveos-types/Cargo.toml +++ b/moveos/moveos-types/Cargo.toml @@ -36,6 +36,7 @@ move-core-types = { workspace = true } move-vm-types = { workspace = true } move-resource-viewer = { workspace = true } move-binary-format = { workspace = true } +move-vm-runtime = { workspace = true } smt = { workspace = true } diff --git a/moveos/moveos-types/src/state_resolver.rs b/moveos/moveos-types/src/state_resolver.rs index 6112f2c7cc..a449903d23 100644 --- a/moveos/moveos-types/src/state_resolver.rs +++ b/moveos/moveos-types/src/state_resolver.rs @@ -12,7 +12,12 @@ use crate::{ }; use anyhow::{ensure, Error, Result}; use bytes::Bytes; -use move_binary_format::errors::{PartialVMError, PartialVMResult}; +use move_binary_format::errors::{ + BinaryLoaderResult, Location, PartialVMError, PartialVMResult, VMResult, +}; +use move_binary_format::file_format::CompiledScript; +use move_binary_format::CompiledModule; +use move_core_types::identifier::{IdentStr, Identifier}; use move_core_types::metadata::Metadata; use move_core_types::value::MoveTypeLayout; use move_core_types::vm_status::StatusCode; @@ -21,7 +26,13 @@ use move_core_types::{ language_storage::{ModuleId, StructTag, TypeTag}, }; use move_resource_viewer::{AnnotatedMoveStruct, AnnotatedMoveValue, MoveValueAnnotator}; +use move_vm_runtime::{ + CodeStorage, Module, ModuleStorage, RuntimeEnvironment, Script, WithRuntimeEnvironment, +}; +use move_vm_types::code::Code; use move_vm_types::resolver::{ModuleResolver, MoveResolver, ResourceResolver}; +use std::env::temp_dir; +use std::sync::Arc; pub type StateKV = (FieldKey, ObjectState); pub type AnnotatedStateKV = (FieldKey, AnnotatedState); diff --git a/moveos/moveos/Cargo.toml b/moveos/moveos/Cargo.toml index 7d0851cd2f..802050dea3 100644 --- a/moveos/moveos/Cargo.toml +++ b/moveos/moveos/Cargo.toml @@ -27,6 +27,7 @@ regex = { workspace = true } parking_lot = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true } +ambassador = { workspace = true } move-binary-format = { workspace = true } move-core-types = { workspace = true } @@ -41,6 +42,7 @@ move-compiler = { workspace = true } move-symbol-pool = { workspace = true } move-model = { workspace = true } move-vm-runtime = { workspace = true, features = ["stacktrace", "debugging", "testing"] } +move-bytecode-verifier = { workspace = true } moveos-types = { workspace = true } moveos-store = { workspace = true } diff --git a/moveos/moveos/src/moveos.rs b/moveos/moveos/src/moveos.rs index 6c81fea705..3586ad4a5a 100644 --- a/moveos/moveos/src/moveos.rs +++ b/moveos/moveos/src/moveos.rs @@ -10,7 +10,7 @@ use anyhow::{bail, format_err, Error, Result}; use move_binary_format::binary_views::BinaryIndexedView; use move_binary_format::errors::VMError; use move_binary_format::errors::{vm_status_of_result, Location, PartialVMError, VMResult}; -use move_binary_format::file_format::FunctionDefinitionIndex; +use move_binary_format::file_format::{CompiledScript, FunctionDefinitionIndex}; use move_binary_format::CompiledModule; use move_core_types::identifier::IdentStr; use move_core_types::language_storage::ModuleId; @@ -19,7 +19,7 @@ use move_core_types::vm_status::{KeptVMStatus, VMStatus}; use move_core_types::{ account_address::AccountAddress, ident_str, identifier::Identifier, vm_status::StatusCode, }; -use move_vm_runtime::config::VMConfig; +use move_vm_runtime::config::{VMConfig, DEFAULT_MAX_VALUE_NEST_DEPTH}; use move_vm_runtime::data_cache::TransactionCache; use move_vm_runtime::native_functions::NativeFunction; use moveos_common::types::ClassifiedGasMeter; @@ -43,6 +43,12 @@ use moveos_types::transaction::{ use parking_lot::RwLock; use serde::{Deserialize, Serialize}; use std::sync::Arc; +use ambassador::delegate_to_methods; +use move_binary_format::deserializer::DeserializerConfig; +use move_bytecode_verifier::VerifierConfig; +use move_vm_runtime::{RuntimeEnvironment, Script}; +use move_vm_types::code::{ScriptCache, UnsyncScriptCache}; +use move_vm_types::loaded_data::runtime_types::TypeBuilder; #[derive(thiserror::Error, Debug)] pub enum VMPanicError { @@ -81,10 +87,6 @@ pub struct MoveOSConfig { impl std::fmt::Debug for MoveOSConfig { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("MoveOSConfig") - .field( - "vm_config.max_binary_format_version", - &self.vm_config.max_binary_format_version, - ) .field( "vm_config.paranoid_type_checks", &self.vm_config.paranoid_type_checks, @@ -98,12 +100,19 @@ impl Clone for MoveOSConfig { fn clone(&self) -> Self { Self { vm_config: VMConfig { - verifier: self.vm_config.verifier.clone(), - max_binary_format_version: self.vm_config.max_binary_format_version, - paranoid_type_checks: self.vm_config.paranoid_type_checks, - enable_invariant_violation_check_in_swap_loc: false, - type_size_limit: false, - max_value_nest_depth: None, + verifier_config: VerifierConfig::default(), + deserializer_config: DeserializerConfig::default(), + paranoid_type_checks: false, + check_invariant_in_swap_loc: true, + max_value_nest_depth: Some(DEFAULT_MAX_VALUE_NEST_DEPTH), + type_max_cost: 0, + type_base_cost: 0, + type_byte_cost: 0, + delayed_field_optimization_enabled: false, + ty_builder: TypeBuilder::with_limits(128, 20), + disallow_dispatch_for_native: true, + use_compatibility_checker_v2: true, + use_loader_v2: true, }, } } @@ -122,15 +131,14 @@ pub struct MoveOS { impl MoveOS { pub fn new( + runtime_environment: &RuntimeEnvironment, db: MoveOSStore, - natives: impl IntoIterator, - config: MoveOSConfig, system_pre_execute_functions: Vec, system_post_execute_functions: Vec, ) -> Result { //TODO load the gas table from argument, and remove the cost_table lock. - let vm = MoveOSVM::new(natives, config.vm_config)?; + let vm = MoveOSVM::new(runtime_environment)?; Ok(Self { vm, db, @@ -239,7 +247,7 @@ impl MoveOS { gas_meter.set_metering(false); let resolver = RootObjectResolver::new(root.clone(), &self.db); - let session = self + let mut session = self .vm .new_readonly_session(&resolver, ctx.clone(), gas_meter); diff --git a/moveos/moveos/src/vm/moveos_vm.rs b/moveos/moveos/src/vm/moveos_vm.rs index 67b08f010b..bbfe737ee6 100644 --- a/moveos/moveos/src/vm/moveos_vm.rs +++ b/moveos/moveos/src/vm/moveos_vm.rs @@ -20,13 +20,7 @@ use move_core_types::{ }; use move_model::script_into_module; use move_vm_runtime::data_cache::TransactionCache; -use move_vm_runtime::{ - config::VMConfig, - move_vm::MoveVM, - native_extensions::NativeContextExtensions, - native_functions::NativeFunction, - session::{LoadedFunctionInstantiation, Session}, -}; +use move_vm_runtime::{config::VMConfig, move_vm::MoveVM, native_extensions::NativeContextExtensions, native_functions::NativeFunction, session::{LoadedFunctionInstantiation, Session}, CodeStorage, ModuleStorage, RuntimeEnvironment, Script}; use move_vm_types::gas::UnmeteredGasMeter; use move_vm_types::loaded_data::runtime_types::{CachedStructIndex, StructType, Type}; use moveos_common::types::{ClassifiedGasMeter, SwitchableGasMeter}; @@ -53,6 +47,7 @@ use parking_lot::RwLock; use std::collections::BTreeSet; use std::rc::Rc; use std::{borrow::Borrow, sync::Arc}; +use move_vm_types::code::UnsyncScriptCache; /// MoveOSVM is a wrapper of MoveVM with MoveOS specific features. pub struct MoveOSVM { @@ -61,11 +56,10 @@ pub struct MoveOSVM { impl MoveOSVM { pub fn new( - natives: impl IntoIterator, - vm_config: VMConfig, + runtime_environment: &RuntimeEnvironment, ) -> VMResult { Ok(Self { - inner: MoveVM::new_with_config(natives, vm_config)?, + inner: MoveVM::new_with_runtime_environment(runtime_environment), }) } @@ -135,7 +129,7 @@ impl MoveOSVM { /// MoveOSSession is a wrapper of MoveVM session with MoveOS specific features. /// It is used to execute a transaction, every transaction should be executed in a new session. /// Every session has a TxContext, if the transaction have multiple actions, the TxContext is shared. -pub struct MoveOSSession<'r, 'l, S, G> { +pub struct MoveOSSession<'r, 'l, S: CodeStorage + ModuleStorage, G> { pub(crate) vm: &'l MoveVM, pub(crate) remote: &'r S, pub(crate) session: Session<'r, 'l, MoveosDataCache<'r, 'l, S>>, @@ -213,12 +207,12 @@ where /// Verify a move action. /// The caller should call this function when validate a transaction. /// If the result is error, the transaction should be rejected. - pub fn verify_move_action(&self, action: MoveAction) -> VMResult { + pub fn verify_move_action(&mut self, action: MoveAction) -> VMResult { match action { MoveAction::Script(call) => { let loaded_function = self .session - .load_script(call.code.as_slice(), call.ty_args.clone())?; + .load_script(self.remote, call.code.as_slice(), call.ty_args.clone())?; let location = Location::Script; moveos_verifier::verifier::verify_entry_function(&loaded_function, &self.session) .map_err(|e| e.finish(location.clone()))?; @@ -242,6 +236,7 @@ where } MoveAction::Function(call) => { let loaded_function = self.session.load_function( + self.remote, &call.function_id.module_id, &call.function_id.function_name, call.ty_args.as_slice(), diff --git a/moveos/moveos/src/vm/unit_tests/vm_arguments_tests.rs b/moveos/moveos/src/vm/unit_tests/vm_arguments_tests.rs index 7d4af02da3..f47ce0d0c4 100644 --- a/moveos/moveos/src/vm/unit_tests/vm_arguments_tests.rs +++ b/moveos/moveos/src/vm/unit_tests/vm_arguments_tests.rs @@ -38,6 +38,7 @@ use moveos_types::{ state_resolver::StateResolver, transaction::MoveAction, }; use std::collections::HashMap; +use move_vm_runtime::RuntimeEnvironment; // make a script with a given signature for main. fn make_script(parameters: Signature) -> Vec { @@ -342,7 +343,8 @@ fn call_script_with_args_ty_args_signers( ty_args: Vec, signers: Vec, ) -> VMResult<()> { - let moveos_vm = MoveOSVM::new(vec![], VMConfig::default()).unwrap(); + let runtime_environment = RuntimeEnvironment::new(vec![]); + let moveos_vm = MoveOSVM::new(&runtime_environment).unwrap(); let remote_view = RemoteStore::new(); let ctx = TxContext::random_for_testing_only(); let cost_table = initial_cost_schedule(None); @@ -370,7 +372,8 @@ fn call_script_function_with_args_ty_args_signers( ty_args: Vec, signers: Vec, ) -> VMResult<()> { - let moveos_vm = MoveOSVM::new(vec![], VMConfig::default()).unwrap(); + let runtime_environment = RuntimeEnvironment::new(vec![]); + let moveos_vm = MoveOSVM::new(&runtime_environment).unwrap(); let mut remote_view = RemoteStore::new(); let id = module.self_id(); remote_view.add_module(module); @@ -852,7 +855,8 @@ fn call_missing_item() { let id = &module.self_id(); let function_name = IdentStr::new("foo").unwrap(); // missing module - let moveos_vm = MoveOSVM::new(vec![], VMConfig::default()).unwrap(); + let runtime_environment = RuntimeEnvironment::new(vec![]); + let moveos_vm = MoveOSVM::new(&runtime_environment).unwrap(); let mut remote_view = RemoteStore::new(); let ctx = TxContext::random_for_testing_only(); let cost_table = initial_cost_schedule(None);