From a3ef5686d957383a32570730ea3e19965efe93ce Mon Sep 17 00:00:00 2001 From: David Edey Date: Sun, 15 Sep 2024 23:55:49 +0100 Subject: [PATCH] tweak: Make SystemLogicVersion a generic for performance --- .../tests/kernel/kernel_open_substate.rs | 6 +- radix-engine-tests/tests/kernel/panics.rs | 4 +- radix-engine-tests/tests/vm/native_vm.rs | 4 +- radix-engine/src/kernel/kernel.rs | 2 +- .../src/kernel/kernel_callback_api.rs | 2 +- radix-engine/src/system/module.rs | 19 +- radix-engine/src/system/system.rs | 9 +- radix-engine/src/system/system_callback.rs | 288 ++++++++++-------- .../src/system/system_callback_api.rs | 2 +- .../system_modules/execution_trace/module.rs | 8 +- .../src/transaction/transaction_executor.rs | 65 +++- scrypto-test/src/environment/builder.rs | 2 +- scrypto-test/src/environment/types.rs | 2 +- .../ledger_simulator/inject_costing_err.rs | 26 +- .../src/ledger_simulator/ledger_simulator.rs | 17 +- 15 files changed, 276 insertions(+), 180 deletions(-) diff --git a/radix-engine-tests/tests/kernel/kernel_open_substate.rs b/radix-engine-tests/tests/kernel/kernel_open_substate.rs index 1a7abe51fd4..f4c6e1be283 100644 --- a/radix-engine-tests/tests/kernel/kernel_open_substate.rs +++ b/radix-engine-tests/tests/kernel/kernel_open_substate.rs @@ -4,7 +4,7 @@ use radix_engine::kernel::call_frame::OpenSubstateError; use radix_engine::kernel::id_allocator::IdAllocator; use radix_engine::kernel::kernel::Kernel; use radix_engine::kernel::kernel_api::KernelSubstateApi; -use radix_engine::system::system_callback::{System, SystemLockData, VersionedSystemLogic}; +use radix_engine::system::system_callback::{System, SystemLockData}; use radix_engine::system::system_modules::auth::AuthModule; use radix_engine::system::system_modules::costing::{ CostingModule, CostingModuleConfig, FeeTable, SystemLoanFeeReserve, @@ -26,7 +26,7 @@ use radix_substate_store_queries::typed_substate_layout::{ BlueprintVersionKey, PACKAGE_AUTH_TEMPLATE_PARTITION_OFFSET, }; use radix_transactions::prelude::*; -use scrypto_test::prelude::UniqueTransaction; +use scrypto_test::prelude::{LatestSystemLogicVersion, UniqueTransaction}; #[test] pub fn test_open_substate_of_invisible_package_address() { @@ -48,7 +48,7 @@ pub fn test_open_substate_of_invisible_package_address() { // Create kernel let mut system = System { - versioned_system_logic: VersionedSystemLogic::V1, + versioned_system_logic: LatestSystemLogicVersion::default(), blueprint_cache: NonIterMap::new(), auth_cache: NonIterMap::new(), schema_cache: NonIterMap::new(), diff --git a/radix-engine-tests/tests/kernel/panics.rs b/radix-engine-tests/tests/kernel/panics.rs index 9625fbfdedb..c44f493f51e 100644 --- a/radix-engine-tests/tests/kernel/panics.rs +++ b/radix-engine-tests/tests/kernel/panics.rs @@ -39,7 +39,7 @@ macro_rules! panic1 { pub struct MockKernel(PhantomData); impl KernelApi for MockKernel { - type CallbackObject = System; + type CallbackObject = System; } impl KernelStackApi for MockKernel { @@ -190,7 +190,7 @@ impl KernelInvokeApi for MockKernel { } impl KernelInternalApi for MockKernel { - type System = System; + type System = System; fn kernel_get_system_state(&mut self) -> SystemState<'_, Self::System> { panic1!() diff --git a/radix-engine-tests/tests/vm/native_vm.rs b/radix-engine-tests/tests/vm/native_vm.rs index babed4b38ef..ed60164e7df 100644 --- a/radix-engine-tests/tests/vm/native_vm.rs +++ b/radix-engine-tests/tests/vm/native_vm.rs @@ -67,7 +67,7 @@ fn panics_can_be_caught_in_the_native_vm_and_converted_into_results() { let intent_hash = Hash([0; 32]); let mut system = System { - versioned_system_logic: VersionedSystemLogic::V1, + versioned_system_logic: LatestSystemLogicVersion::default(), blueprint_cache: NonIterMap::new(), auth_cache: NonIterMap::new(), schema_cache: NonIterMap::new(), @@ -138,7 +138,7 @@ fn any_panics_can_be_caught_in_the_native_vm_and_converted_into_results() { let intent_hash = Hash([0; 32]); let mut system = System { - versioned_system_logic: VersionedSystemLogic::V1, + versioned_system_logic: LatestSystemLogicVersion::default(), blueprint_cache: NonIterMap::new(), auth_cache: NonIterMap::new(), schema_cache: NonIterMap::new(), diff --git a/radix-engine/src/kernel/kernel.rs b/radix-engine/src/kernel/kernel.rs index 313d030f00b..cdc63842830 100644 --- a/radix-engine/src/kernel/kernel.rs +++ b/radix-engine/src/kernel/kernel.rs @@ -93,7 +93,7 @@ impl<'h, M: KernelTransactionCallbackObject, S: SubstateDatabase> BootLoader<'h, .unwrap_or(KernelBoot::babylon()); // Upper Layer Initialization - let system_init_result = M::init(&mut self.track, &executable, self.init.clone()); + let system_init_result = M::init(&mut self.track, &executable, self.init); let (mut system, call_frame_inits) = match system_init_result { Ok(success) => success, diff --git a/radix-engine/src/kernel/kernel_callback_api.rs b/radix-engine/src/kernel/kernel_callback_api.rs index b2629490f6d..ec6872d6c9b 100644 --- a/radix-engine/src/kernel/kernel_callback_api.rs +++ b/radix-engine/src/kernel/kernel_callback_api.rs @@ -140,7 +140,7 @@ pub trait ExecutionReceipt { pub trait KernelTransactionCallbackObject: KernelCallbackObject { /// Initialization object - type Init: Clone; + type Init; /// The transaction object type Executable; /// Output to be returned at the end of execution diff --git a/radix-engine/src/system/module.rs b/radix-engine/src/system/module.rs index d6854ea0ce5..4e0764d9b18 100644 --- a/radix-engine/src/system/module.rs +++ b/radix-engine/src/system/module.rs @@ -36,19 +36,27 @@ impl<'a, K: KernelInternalApi + ?Sized> SystemModuleApiImpl<'a, K> { } pub trait SystemModuleApi { + type SystemLogicVersion: SystemLogicVersion; type SystemCallback: SystemCallbackObject; - fn system(&mut self) -> &mut System; + fn system(&mut self) -> &mut System; - fn system_state(&mut self) -> SystemState<'_, System>; + fn system_state( + &mut self, + ) -> SystemState<'_, System>; /// Gets the number of call frames that are currently in the call frame stack fn current_stack_depth(&self) -> usize; } -impl<'a, V: SystemCallbackObject, K: KernelInternalApi> + ?Sized> SystemModuleApi - for SystemModuleApiImpl<'a, K> +impl< + 'a, + L: SystemLogicVersion, + V: SystemCallbackObject, + K: KernelInternalApi> + ?Sized, + > SystemModuleApi for SystemModuleApiImpl<'a, K> { + type SystemLogicVersion = L; type SystemCallback = V; fn system(&mut self) -> &mut K::System { @@ -76,8 +84,9 @@ pub trait SystemModuleApiFor: SystemModuleAp impl< 'a, + L: SystemLogicVersion, V: SystemCallbackObject, - K: KernelInternalApi> + ?Sized, + K: KernelInternalApi> + ?Sized, M: ResolvableSystemModule + ?Sized, > SystemModuleApiFor for SystemModuleApiImpl<'a, K> { diff --git a/radix-engine/src/system/system.rs b/radix-engine/src/system/system.rs index 3e806bd3142..1ba8ff15b48 100644 --- a/radix-engine/src/system/system.rs +++ b/radix-engine/src/system/system.rs @@ -108,7 +108,7 @@ impl<'a, Y: SystemBasedKernelApi + ?Sized> SystemService<'a, Y> { self.api } - pub fn system(&mut self) -> &mut System { + pub fn system(&mut self) -> &mut System { self.api.kernel_get_system() } @@ -2168,12 +2168,7 @@ impl<'a, Y: SystemBasedKernelApi> SystemCostingApi for SystemServi &mut self, costing_entry: ClientCostingEntry, ) -> Result<(), RuntimeError> { - let system_logic = self - .api - .kernel_get_system_state() - .system - .versioned_system_logic; - if !system_logic.should_consume_cost_units(self.api) { + if !Y::SystemLogicVersion::should_consume_cost_units(self.api) { return Ok(()); } diff --git a/radix-engine/src/system/system_callback.rs b/radix-engine/src/system/system_callback.rs index 5cdb80f4096..6a095baf006 100644 --- a/radix-engine/src/system/system_callback.rs +++ b/radix-engine/src/system/system_callback.rs @@ -66,7 +66,20 @@ pub enum SystemBoot { } impl SystemBoot { - fn system_logic(&self) -> VersionedSystemLogic { + pub fn fallback_or_panic(execution_config: &ExecutionConfig) -> Self { + SystemBoot::V1(SystemParameters { + network_definition: execution_config + .system_overrides + .as_ref() + .and_then(|config| config.network_definition.clone()) + .expect("If no SystemBoot exists, a network_definition override must be provided"), + costing_parameters: CostingParameters::babylon_genesis(), + costing_module_config: CostingModuleConfig::babylon_genesis(), + limit_parameters: LimitParameters::babylon_genesis(), + }) + } + + pub fn system_logic_version(&self) -> VersionedSystemLogic { match self { Self::V1(..) => VersionedSystemLogic::V1, Self::V2(logic, _) => *logic, @@ -81,89 +94,116 @@ pub enum VersionedSystemLogic { V2, } -impl VersionedSystemLogic { +pub type LatestSystemLogicVersion = SystemLogicVersion2; + +pub trait SystemLogicVersion: Default + Sized + 'static { + fn execute_transaction( + api: &mut Y, + executable: ExecutableTransaction, + global_address_reservations: Vec, + ) -> Result, RuntimeError>; + + fn should_consume_cost_units(api: &mut Y) -> bool; + + fn create_auth_module( + &self, + executable: &ExecutableTransaction, + ) -> Result; +} + +#[derive(Default)] +pub struct SystemLogicVersion1; + +impl SystemLogicVersion for SystemLogicVersion1 { + fn execute_transaction( + api: &mut Y, + executable: ExecutableTransaction, + global_address_reservations: Vec, + ) -> Result, RuntimeError> { + let mut system_service = SystemService::new(api); + let intent = executable + .intents() + .get(0) + .expect("This should have been checked in init"); + let rtn = system_service.call_function( + TRANSACTION_PROCESSOR_PACKAGE, + TRANSACTION_PROCESSOR_BLUEPRINT, + TRANSACTION_PROCESSOR_RUN_IDENT, + scrypto_encode(&TransactionProcessorRunInputEfficientEncodable { + manifest_encoded_instructions: intent.encoded_instructions.clone(), + global_address_reservations, + references: Rc::new(intent.references.clone()), + blobs: intent.blobs.clone(), + }) + .unwrap(), + )?; + let output: Vec = scrypto_decode(&rtn).unwrap(); + Ok(output) + } + + fn should_consume_cost_units(api: &mut Y) -> bool { + // Skip client-side costing requested by TransactionProcessor + if api.kernel_get_current_depth() == 1 { + return false; + } + + true + } + fn create_auth_module( &self, executable: &ExecutableTransaction, ) -> Result { - let auth_module = match self { - VersionedSystemLogic::V1 => { - // This isn't exactly a necessary check as node logic should protect against this - // but keep it here for sanity - let intent = if executable.intents().len() != 1 { - return Err(RejectionReason::TransactionNotYetSupported); - } else { - executable.intents().get(0).unwrap() - }; - AuthModule::new_with_transaction_processor_auth_zone(intent.auth_zone_init.clone()) - } - VersionedSystemLogic::V2 => AuthModule::new(), + // This isn't exactly a necessary check as node logic should protect against this + // but keep it here for sanity + let intent = if executable.intents().len() != 1 { + return Err(RejectionReason::TransactionNotYetSupported); + } else { + executable.intents().get(0).unwrap() }; + let auth_module = + AuthModule::new_with_transaction_processor_auth_zone(intent.auth_zone_init.clone()); + Ok(auth_module) } +} +#[derive(Default)] +pub struct SystemLogicVersion2; + +impl SystemLogicVersion for SystemLogicVersion2 { fn execute_transaction( - &self, api: &mut Y, executable: ExecutableTransaction, global_address_reservations: Vec, ) -> Result, RuntimeError> { - let output = match self { - VersionedSystemLogic::V1 => { - let mut system_service = SystemService::new(api); - let intent = executable - .intents() - .get(0) - .expect("This should have been checked in init"); - let rtn = system_service.call_function( - TRANSACTION_PROCESSOR_PACKAGE, - TRANSACTION_PROCESSOR_BLUEPRINT, - TRANSACTION_PROCESSOR_RUN_IDENT, - scrypto_encode(&TransactionProcessorRunInputEfficientEncodable { - manifest_encoded_instructions: intent.encoded_instructions.clone(), - global_address_reservations, - references: Rc::new(intent.references.clone()), - blobs: intent.blobs.clone(), - }) - .unwrap(), - )?; - let output: Vec = scrypto_decode(&rtn).unwrap(); - output - } - VersionedSystemLogic::V2 => { - let mut txn_threads = - MultiThreadedTxnProcessor::init(executable, global_address_reservations, api)?; - txn_threads.execute(api)?; - let output = txn_threads - .threads - .get_mut(0) - .unwrap() - .0 - .outputs - .drain(..) - .collect(); - txn_threads.cleanup(api)?; - output - } - }; + let mut txn_threads = + MultiThreadedTxnProcessor::init(executable, global_address_reservations, api)?; + txn_threads.execute(api)?; + let output = txn_threads + .threads + .get_mut(0) + .unwrap() + .0 + .outputs + .drain(..) + .collect(); + txn_threads.cleanup(api)?; Ok(output) } - pub fn should_consume_cost_units(&self, api: &mut Y) -> bool { - match self { - VersionedSystemLogic::V1 => { - // Skip client-side costing requested by TransactionProcessor - if api.kernel_get_current_depth() == 1 { - return false; - } - } - VersionedSystemLogic::V2 => {} - } - + fn should_consume_cost_units(_api: &mut Y) -> bool { true } + + fn create_auth_module( + &self, + _executable: &ExecutableTransaction, + ) -> Result { + Ok(AuthModule::new()) + } } #[derive(Clone)] @@ -215,7 +255,10 @@ impl SystemLockData { } /// Effectively a trait alias for `KernelApi>` -pub trait SystemBasedKernelApi: KernelApi> { +pub trait SystemBasedKernelApi: + KernelApi> +{ + type SystemLogicVersion: SystemLogicVersion; type SystemCallback: SystemCallbackObject; fn system_service(&mut self) -> SystemService<'_, Self> { @@ -223,14 +266,21 @@ pub trait SystemBasedKernelApi: KernelApi>> SystemBasedKernelApi for K { +impl< + L: SystemLogicVersion, + V: SystemCallbackObject, + K: KernelApi>, + > SystemBasedKernelApi for K +{ + type SystemLogicVersion = L; type SystemCallback = V; } /// Effectively a trait alias for `KernelInternalApi>` pub trait SystemBasedKernelInternalApi: - KernelInternalApi> + KernelInternalApi> { + type SystemLogicVersion: SystemLogicVersion; type SystemCallback: SystemCallbackObject; fn system_module_api(&mut self) -> SystemModuleApiImpl { @@ -238,30 +288,38 @@ pub trait SystemBasedKernelInternalApi: } } -impl>> SystemBasedKernelInternalApi - for K +impl< + L: SystemLogicVersion, + V: SystemCallbackObject, + K: KernelInternalApi>, + > SystemBasedKernelInternalApi for K { + type SystemLogicVersion = L; type SystemCallback = V; } -#[derive(Clone)] -pub struct SystemInit { +pub struct SystemInit { + pub self_init: SystemSelfInit, + pub callback_init: V, +} + +pub struct SystemSelfInit { // These fields only affect side effects and do not affect ledger state execution pub enable_kernel_trace: bool, pub enable_cost_breakdown: bool, pub execution_trace: Option, pub enable_debug_information: bool, - // Higher layer initialization object - pub callback_init: C, + pub versioned_logic: L, + pub system_boot: SystemBoot, // An override of system configuration pub system_overrides: Option, } -pub struct System { - pub versioned_system_logic: VersionedSystemLogic, - pub callback: C, +pub struct System { + pub versioned_system_logic: L, + pub callback: V, pub blueprint_cache: NonIterMap>, pub schema_cache: NonIterMap>, pub auth_cache: NonIterMap, @@ -273,7 +331,7 @@ pub trait HasModules { fn modules_mut(&mut self) -> &mut SystemModuleMixer; } -impl HasModules for System { +impl HasModules for System { #[inline] fn modules_mut(&mut self) -> &mut SystemModuleMixer { &mut self.modules @@ -285,7 +343,7 @@ pub struct SystemFinalization { intent_nullifications: Vec, } -impl System { +impl System { fn on_move_node( node_id: &NodeId, is_moving_down: bool, @@ -334,7 +392,7 @@ impl System { } } -impl System { +impl System { #[cfg(not(feature = "alloc"))] fn print_executable(executable: &ExecutableTransaction) { println!("{:-^120}", "Executable"); @@ -1248,30 +1306,15 @@ impl System { } fn resolve_modules( - store: &mut impl BootStore, executable: &ExecutableTransaction, - init_input: &SystemInit, - ) -> Result<(VersionedSystemLogic, SystemModuleMixer), TransactionReceiptV1> { - let system_boot = store - .read_boot_substate( - TRANSACTION_TRACKER.as_node_id(), - BOOT_LOADER_PARTITION, - &SubstateKey::Field(BOOT_LOADER_SYSTEM_SUBSTATE_FIELD_KEY), - ) - .map(|v| scrypto_decode(v.as_slice()).unwrap()) - .unwrap_or(SystemBoot::V1(SystemParameters { - network_definition: NetworkDefinition::mainnet(), - costing_parameters: CostingParameters::babylon_genesis(), - costing_module_config: CostingModuleConfig::babylon_genesis(), - limit_parameters: LimitParameters::babylon_genesis(), - })); - - let system_logic_version = system_boot.system_logic(); - let mut system_parameters = match system_boot { + init_input: SystemSelfInit, + ) -> Result<(L, SystemModuleMixer), TransactionReceiptV1> { + let mut system_parameters = match init_input.system_boot { SystemBoot::V1(system_parameters) | SystemBoot::V2(_, system_parameters) => { system_parameters } }; + let logic = init_input.versioned_logic; let mut enabled_modules = { let mut enabled_modules = EnabledModules::AUTH | EnabledModules::TRANSACTION_RUNTIME; @@ -1340,17 +1383,14 @@ impl System { on_apply_cost: Default::default(), }; - let auth_module = system_logic_version - .create_auth_module(&executable) - .map_err(|reason| { - let print_execution_summary = - enabled_modules.contains(EnabledModules::KERNEL_TRACE); - Self::create_non_commit_receipt( - TransactionResult::Reject(RejectResult { reason }), - print_execution_summary, - costing_module.clone(), - ) - })?; + let auth_module = logic.create_auth_module(&executable).map_err(|reason| { + let print_execution_summary = enabled_modules.contains(EnabledModules::KERNEL_TRACE); + Self::create_non_commit_receipt( + TransactionResult::Reject(RejectResult { reason }), + print_execution_summary, + costing_module.clone(), + ) + })?; let module_mixer = SystemModuleMixer::new( enabled_modules, @@ -1364,12 +1404,14 @@ impl System { costing_module, ExecutionTraceModule::new(init_input.execution_trace.unwrap_or(0)), ); - Ok((system_logic_version, module_mixer)) + Ok((logic, module_mixer)) } } -impl KernelTransactionCallbackObject for System { - type Init = SystemInit; +impl KernelTransactionCallbackObject + for System +{ + type Init = SystemInit; type Executable = ExecutableTransaction; type ExecutionOutput = Vec; type Receipt = TransactionReceiptV1; @@ -1377,18 +1419,18 @@ impl KernelTransactionCallbackObject for System { fn init( store: &mut S, executable: &ExecutableTransaction, - init_input: SystemInit, + init_input: SystemInit, ) -> Result<(Self, Vec>), Self::Receipt> { // Dump executable #[cfg(not(feature = "alloc"))] - if init_input.enable_kernel_trace { + if init_input.self_init.enable_kernel_trace { Self::print_executable(executable); } - let (logic_version, mut modules) = Self::resolve_modules(store, executable, &init_input)?; + let (logic_version, mut modules) = Self::resolve_modules(executable, init_input.self_init)?; // NOTE: Have to use match pattern rather than map_err to appease the borrow checker - let callback = match C::init(store, init_input.callback_init) { + let callback = match V::init(store, init_input.callback_init) { Ok(callback) => callback, Err(error) => return Err(Self::create_rejection_receipt(error, modules)), }; @@ -1502,13 +1544,7 @@ impl KernelTransactionCallbackObject for System { global_address_reservations.push(global_address_reservation); } - let system_logic_version = system_service.system().versioned_system_logic; - - let output = system_logic_version.execute_transaction( - api, - executable, - global_address_reservations, - )?; + let output = L::execute_transaction(api, executable, global_address_reservations)?; Ok(output) } @@ -1598,7 +1634,7 @@ impl KernelTransactionCallbackObject for System { } } -impl KernelCallbackObject for System { +impl KernelCallbackObject for System { type LockData = SystemLockData; type CallFrameData = Actor; @@ -1804,7 +1840,7 @@ impl KernelCallbackObject for System { .expect("Schema should have validated this exists") .clone(); let output = - { C::invoke(&blueprint_id.package_address, export, input, &mut system)? }; + { V::invoke(&blueprint_id.package_address, export, input, &mut system)? }; // Validate output system.validate_blueprint_payload( @@ -1834,7 +1870,7 @@ impl KernelCallbackObject for System { // Input is not validated as they're created by system. // Invoke the export - let output = C::invoke( + let output = V::invoke( &blueprint_id.package_address, export.clone(), &input, diff --git a/radix-engine/src/system/system_callback_api.rs b/radix-engine/src/system/system_callback_api.rs index a029482dbb6..c7d32c30887 100644 --- a/radix-engine/src/system/system_callback_api.rs +++ b/radix-engine/src/system/system_callback_api.rs @@ -9,7 +9,7 @@ use radix_engine_interface::blueprints::package::PackageExport; /// Callback object invoked by the system layer pub trait SystemCallbackObject: Sized { /// Initialization Object - type Init: Clone; + type Init; /// Initialize and create the callback object above the system fn init(store: &S, init_input: Self::Init) -> Result; diff --git a/radix-engine/src/system/system_modules/execution_trace/module.rs b/radix-engine/src/system/system_modules/execution_trace/module.rs index c17dfdc9990..41339084e4b 100644 --- a/radix-engine/src/system/system_modules/execution_trace/module.rs +++ b/radix-engine/src/system/system_modules/execution_trace/module.rs @@ -103,8 +103,12 @@ trait SystemModuleApiResourceSnapshotExtension { fn read_proof_uncosted(&self, proof_id: &NodeId) -> Option; } -impl<'a, V: SystemCallbackObject, K: KernelInternalApi>> - SystemModuleApiResourceSnapshotExtension for SystemModuleApiImpl<'a, K> +impl< + 'a, + L: SystemLogicVersion, + V: SystemCallbackObject, + K: KernelInternalApi>, + > SystemModuleApiResourceSnapshotExtension for SystemModuleApiImpl<'a, K> { fn read_bucket_uncosted(&self, bucket_id: &NodeId) -> Option { let (is_fungible_bucket, resource_address) = if let Some(substate) = diff --git a/radix-engine/src/transaction/transaction_executor.rs b/radix-engine/src/transaction/transaction_executor.rs index 57a79302e82..7e05fc98de4 100644 --- a/radix-engine/src/transaction/transaction_executor.rs +++ b/radix-engine/src/transaction/transaction_executor.rs @@ -3,14 +3,14 @@ use crate::internal_prelude::*; use crate::kernel::id_allocator::IdAllocator; use crate::kernel::kernel::BootLoader; use crate::kernel::kernel_callback_api::*; -use crate::system::system_callback::{System, SystemInit}; +use crate::system::system_callback::*; use crate::system::system_callback_api::SystemCallbackObject; use crate::track::Track; use crate::transaction::*; use crate::vm::*; use radix_common::constants::*; use radix_engine_interface::blueprints::transaction_processor::InstructionOutput; -use radix_substate_store_interface::{db_key_mapper::SpreadPrefixKeyMapper, interface::*}; +use radix_substate_store_interface::{db_key_mapper::*, interface::*}; use radix_transactions::model::*; /// Protocol-defined costing parameters @@ -296,11 +296,11 @@ where } } - pub fn execute(&mut self, executable: V::Executable) -> V::Receipt { + pub fn execute(self, executable: V::Executable) -> V::Receipt { let kernel_boot = BootLoader { id_allocator: IdAllocator::new(executable.unique_seed_for_id_allocator()), track: Track::<_, SpreadPrefixKeyMapper>::new(self.substate_db), - init: self.system_init.clone(), + init: self.system_init, phantom: PhantomData::::default(), }; @@ -313,16 +313,61 @@ pub fn execute_transaction_with_configuration TransactionReceipt { + let system_boot = { + let db_partition_key = SpreadPrefixKeyMapper::to_db_partition_key( + TRANSACTION_TRACKER.as_node_id(), + BOOT_LOADER_PARTITION, + ); + let db_sort_key = SpreadPrefixKeyMapper::to_db_sort_key(&SubstateKey::Field( + BOOT_LOADER_SYSTEM_SUBSTATE_FIELD_KEY, + )); + substate_db + .get_substate(&db_partition_key, &db_sort_key) + .map(|v| scrypto_decode(v.as_slice()).unwrap()) + .unwrap_or_else(|| SystemBoot::fallback_or_panic(&execution_config)) + }; + match system_boot.system_logic_version() { + VersionedSystemLogic::V1 => execute_internal::( + substate_db, + vm_init, + SystemLogicVersion1, + system_boot, + execution_config, + executable, + ), + VersionedSystemLogic::V2 => execute_internal::( + substate_db, + vm_init, + SystemLogicVersion2, + system_boot, + execution_config, + executable, + ), + } +} + +fn execute_internal( + substate_db: &impl SubstateDatabase, + vm_init: V::Init, + versioned_logic: impl SystemLogicVersion, + system_boot: SystemBoot, + execution_config: &ExecutionConfig, + executable: ExecutableTransaction, ) -> TransactionReceipt { let system_init = SystemInit { - enable_kernel_trace: execution_config.enable_kernel_trace, - enable_cost_breakdown: execution_config.enable_cost_breakdown, - enable_debug_information: execution_config.enable_debug_information, - execution_trace: execution_config.execution_trace, + self_init: SystemSelfInit { + enable_kernel_trace: execution_config.enable_kernel_trace, + enable_cost_breakdown: execution_config.enable_cost_breakdown, + enable_debug_information: execution_config.enable_debug_information, + execution_trace: execution_config.execution_trace, + versioned_logic, + system_overrides: execution_config.system_overrides.clone(), + system_boot, + }, callback_init: vm_init, - system_overrides: execution_config.system_overrides.clone(), }; - TransactionExecutor::<_, System>::new(substate_db, system_init).execute(executable) + TransactionExecutor::<_, System<_, V>>::new(substate_db, system_init).execute(executable) } pub fn execute_transaction<'s, V: VmInitialize>( diff --git a/scrypto-test/src/environment/builder.rs b/scrypto-test/src/environment/builder.rs index eced465acad..043bd18942d 100644 --- a/scrypto-test/src/environment/builder.rs +++ b/scrypto-test/src/environment/builder.rs @@ -246,7 +246,7 @@ where }; System { - versioned_system_logic: VersionedSystemLogic::V1, + versioned_system_logic: LatestSystemLogicVersion::default(), blueprint_cache: NonIterMap::new(), auth_cache: NonIterMap::new(), schema_cache: NonIterMap::new(), diff --git a/scrypto-test/src/environment/types.rs b/scrypto-test/src/environment/types.rs index 64ac8db8f98..281063a97ef 100644 --- a/scrypto-test/src/environment/types.rs +++ b/scrypto-test/src/environment/types.rs @@ -5,6 +5,6 @@ use crate::prelude::*; pub type TestVm<'g> = Vm<'g, DefaultWasmEngine, NoExtension>; pub type TestTrack<'g, D> = Track<'g, D, SpreadPrefixKeyMapper>; -pub type TestSystemConfig<'g> = System>; +pub type TestSystemConfig<'g> = System>; pub type TestKernel<'g, D> = Kernel<'g, TestSystemConfig<'g>, TestTrack<'g, D>>; pub type TestSystemService<'g, D> = SystemService<'g, TestKernel<'g, D>>; diff --git a/scrypto-test/src/ledger_simulator/inject_costing_err.rs b/scrypto-test/src/ledger_simulator/inject_costing_err.rs index ca1f53fe588..bd9ecd5bbdf 100644 --- a/scrypto-test/src/ledger_simulator/inject_costing_err.rs +++ b/scrypto-test/src/ledger_simulator/inject_costing_err.rs @@ -4,7 +4,9 @@ use radix_engine::kernel::call_frame::{CallFrameInit, CallFrameMessage, NodeVisi use radix_engine::kernel::kernel_api::*; use radix_engine::kernel::kernel_callback_api::*; use radix_engine::system::actor::Actor; -use radix_engine::system::system_callback::{System, SystemInit, SystemLockData}; +use radix_engine::system::system_callback::{ + LatestSystemLogicVersion, System, SystemInit, SystemLockData, +}; use radix_engine::system::system_callback_api::SystemCallbackObject; use radix_engine::system::system_modules::costing::{CostingError, FeeReserveError, OnApplyCost}; use radix_engine::track::*; @@ -27,7 +29,7 @@ pub struct InjectCostingErrorInput { pub struct InjectCostingError { fail_after: Rc>, - system: System, + system: System, } impl InjectCostingError { @@ -65,8 +67,10 @@ macro_rules! wrapped_internal_api { }; } +type InternalSystem = System; + impl KernelTransactionCallbackObject for InjectCostingError { - type Init = InjectCostingErrorInput>; + type Init = InjectCostingErrorInput>; type Executable = ExecutableTransaction; type ExecutionOutput = Vec; type Receipt = TransactionReceipt; @@ -77,7 +81,7 @@ impl KernelTransactionCallbackObject for InjectCostingE init_input: Self::Init, ) -> Result<(Self, Vec>), Self::Receipt> { let (mut system, call_frame_inits) = - System::::init(store, executable, init_input.system_input)?; + InternalSystem::::init(store, executable, init_input.system_input)?; let fail_after = Rc::new(RefCell::new(init_input.error_after_count)); system.modules.costing_mut().unwrap().on_apply_cost = OnApplyCost::ForceFailOnCount { @@ -92,7 +96,7 @@ impl KernelTransactionCallbackObject for InjectCostingE executable: ExecutableTransaction, ) -> Result, RuntimeError> { let mut api = wrapped_api!(api); - System::start(&mut api, executable) + InternalSystem::::start(&mut api, executable) } fn finish(&mut self, store_commit_info: StoreCommitInfo) -> Result<(), RuntimeError> { @@ -109,8 +113,6 @@ impl KernelTransactionCallbackObject for InjectCostingE } } -type InternalSystem = System; - impl KernelCallbackObject for InjectCostingError { type LockData = SystemLockData; type CallFrameData = Actor; @@ -517,9 +519,9 @@ impl<'a, M: SystemCallbackObject, K: KernelApi>> KernelInternalApi for WrappedKernelApi<'a, M, K> { - type System = System; + type System = InternalSystem; - fn kernel_get_system_state(&mut self) -> SystemState<'_, System> { + fn kernel_get_system_state(&mut self) -> SystemState<'_, InternalSystem> { let state = self.api.kernel_get_system_state(); SystemState { system: &mut state.system.system, @@ -550,7 +552,7 @@ impl<'a, M: SystemCallbackObject, K: KernelApi>> KernelApi for WrappedKernelApi<'a, M, K> { - type CallbackObject = System; + type CallbackObject = InternalSystem; } pub struct WrappedKernelInternalApi< @@ -564,9 +566,9 @@ pub struct WrappedKernelInternalApi< impl<'a, M: SystemCallbackObject, K: KernelInternalApi>> KernelInternalApi for WrappedKernelInternalApi<'a, M, K> { - type System = System; + type System = InternalSystem; - fn kernel_get_system_state(&mut self) -> SystemState<'_, System> { + fn kernel_get_system_state(&mut self) -> SystemState<'_, InternalSystem> { let state = self.api.kernel_get_system_state(); SystemState { system: &mut state.system.system, diff --git a/scrypto-test/src/ledger_simulator/ledger_simulator.rs b/scrypto-test/src/ledger_simulator/ledger_simulator.rs index 849497d9263..5c3e5739343 100644 --- a/scrypto-test/src/ledger_simulator/ledger_simulator.rs +++ b/scrypto-test/src/ledger_simulator/ledger_simulator.rs @@ -1215,16 +1215,21 @@ impl LedgerSimulator { let execution_config = ExecutionConfig::for_test_transaction().with_kernel_trace(self.with_kernel_trace); - let mut executor = TransactionExecutor::<_, InjectSystemCostingError<'_, E>>::new( + let system_boot = SystemBoot::fallback_or_panic(&execution_config); + let executor = TransactionExecutor::<_, InjectSystemCostingError<'_, E>>::new( &self.database, InjectCostingErrorInput { system_input: SystemInit { - enable_kernel_trace: execution_config.enable_kernel_trace, - enable_cost_breakdown: execution_config.enable_cost_breakdown, - enable_debug_information: execution_config.enable_debug_information, - execution_trace: execution_config.execution_trace, + self_init: SystemSelfInit { + enable_kernel_trace: execution_config.enable_kernel_trace, + enable_cost_breakdown: execution_config.enable_cost_breakdown, + enable_debug_information: execution_config.enable_debug_information, + execution_trace: execution_config.execution_trace, + system_overrides: execution_config.system_overrides.clone(), + versioned_logic: LatestSystemLogicVersion::default(), + system_boot, + }, callback_init: vm_init, - system_overrides: execution_config.system_overrides.clone(), }, error_after_count, },