Skip to content

Commit

Permalink
refactor: System is versioned at the type layer
Browse files Browse the repository at this point in the history
  • Loading branch information
dhedey committed Sep 20, 2024
1 parent 9d47e54 commit b31ba81
Show file tree
Hide file tree
Showing 19 changed files with 446 additions and 453 deletions.
40 changes: 6 additions & 34 deletions radix-engine-tests/tests/kernel/kernel_open_substate.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,7 @@
use radix_common::prelude::*;
use radix_engine::errors::{CallFrameError, KernelError, RuntimeError};
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_modules::auth::AuthModule;
use radix_engine::system::system_modules::costing::{
CostingModule, CostingModuleConfig, FeeTable, SystemLoanFeeReserve,
};
use radix_engine::system::system_modules::execution_trace::ExecutionTraceModule;
use radix_engine::system::system_modules::kernel_trace::KernelTraceModule;
use radix_engine::system::system_modules::limits::LimitsModule;
use radix_engine::system::system_modules::transaction_runtime::TransactionRuntimeModule;
use radix_engine::system::system_modules::{EnabledModules, SystemModuleMixer};
use radix_engine::track::Track;
use radix_engine::updates::ProtocolBuilder;
use radix_engine::vm::wasm::DefaultWasmEngine;
use radix_engine::vm::*;
use radix_engine_interface::api::LockFlags;
use radix_engine_interface::prelude::*;
use radix_substate_store_impls::memory_db::InMemorySubstateDatabase;
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::*;

#[test]
pub fn test_open_substate_of_invisible_package_address() {
Expand All @@ -46,17 +22,13 @@ pub fn test_open_substate_of_invisible_package_address() {
.commit_each_protocol_update(&mut database);

// Create kernel
let mut system = System {
versioned_system_logic: VersionedSystemLogic::V1,
blueprint_cache: NonIterMap::new(),
auth_cache: NonIterMap::new(),
schema_cache: NonIterMap::new(),
callback: Vm {
let mut system = LatestSystem::new(
Vm {
scrypto_vm: &scrypto_vm,
native_vm,
vm_boot: VmBoot::latest(),
},
modules: SystemModuleMixer::new(
SystemModuleMixer::new(
EnabledModules::for_test_transaction(),
KernelTraceModule,
TransactionRuntimeModule::new(
Expand All @@ -78,8 +50,8 @@ pub fn test_open_substate_of_invisible_package_address() {
},
ExecutionTraceModule::new(MAX_EXECUTION_TRACE_DEPTH),
),
finalization: Default::default(),
};
SystemFinalization::no_nullifications(),
);
let mut track = Track::new(&database);
let mut id_allocator = IdAllocator::new(executable.unique_seed_for_id_allocator());
let mut kernel = Kernel::new_no_refs(&mut track, &mut id_allocator, &mut system);
Expand Down
18 changes: 9 additions & 9 deletions radix-engine-tests/tests/kernel/panics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ macro_rules! panic1 {
};
}

pub struct MockKernel<M: SystemCallbackObject>(PhantomData<M>);
pub struct MockKernel<V: SystemCallbackObject>(PhantomData<V>);

impl<M: SystemCallbackObject> KernelApi for MockKernel<M> {
type CallbackObject = System<M>;
impl<V: SystemCallbackObject> KernelApi for MockKernel<V> {
type CallbackObject = LatestSystem<V>;
}

impl<M: SystemCallbackObject> KernelStackApi for MockKernel<M> {
impl<V: SystemCallbackObject> KernelStackApi for MockKernel<V> {
type CallFrameData = Actor;

fn kernel_get_stack_id(&self) -> usize {
Expand All @@ -62,7 +62,7 @@ impl<M: SystemCallbackObject> KernelStackApi for MockKernel<M> {
}
}

impl<M: SystemCallbackObject> KernelNodeApi for MockKernel<M> {
impl<V: SystemCallbackObject> KernelNodeApi for MockKernel<V> {
fn kernel_pin_node(&mut self, _: NodeId) -> Result<(), RuntimeError> {
panic1!()
}
Expand All @@ -88,7 +88,7 @@ impl<M: SystemCallbackObject> KernelNodeApi for MockKernel<M> {
}
}

impl<M: SystemCallbackObject> KernelSubstateApi<SystemLockData> for MockKernel<M> {
impl<V: SystemCallbackObject> KernelSubstateApi<SystemLockData> for MockKernel<V> {
fn kernel_mark_substate_as_transient(
&mut self,
_: NodeId,
Expand Down Expand Up @@ -180,7 +180,7 @@ impl<M: SystemCallbackObject> KernelSubstateApi<SystemLockData> for MockKernel<M
}
}

impl<M: SystemCallbackObject> KernelInvokeApi<Actor> for MockKernel<M> {
impl<V: SystemCallbackObject> KernelInvokeApi<Actor> for MockKernel<V> {
fn kernel_invoke(
&mut self,
_: Box<KernelInvocation<Actor>>,
Expand All @@ -189,8 +189,8 @@ impl<M: SystemCallbackObject> KernelInvokeApi<Actor> for MockKernel<M> {
}
}

impl<M: SystemCallbackObject> KernelInternalApi for MockKernel<M> {
type System = System<M>;
impl<V: SystemCallbackObject> KernelInternalApi for MockKernel<V> {
type System = LatestSystem<V>;

fn kernel_get_system_state(&mut self) -> SystemState<'_, Self::System> {
panic1!()
Expand Down
28 changes: 10 additions & 18 deletions radix-engine-tests/tests/vm/native_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,13 @@ fn panics_can_be_caught_in_the_native_vm_and_converted_into_results() {
let native_vm = NativeVm::new_with_extension(Extension);

let intent_hash = Hash([0; 32]);
let mut system = System {
versioned_system_logic: VersionedSystemLogic::V1,
blueprint_cache: NonIterMap::new(),
auth_cache: NonIterMap::new(),
schema_cache: NonIterMap::new(),
callback: Vm {
let mut system = LatestSystem::new(
Vm {
scrypto_vm: &scrypto_vm,
native_vm,
vm_boot: VmBoot::latest(),
},
modules: SystemModuleMixer::new(
SystemModuleMixer::new(
EnabledModules::for_notarized_transaction(),
KernelTraceModule,
TransactionRuntimeModule::new(NetworkDefinition::simulator(), intent_hash),
Expand All @@ -94,8 +90,8 @@ fn panics_can_be_caught_in_the_native_vm_and_converted_into_results() {
},
ExecutionTraceModule::new(MAX_EXECUTION_TRACE_DEPTH),
),
finalization: Default::default(),
};
SystemFinalization::no_nullifications(),
);

let mut id_allocator = IdAllocator::new(intent_hash);
let mut kernel = Kernel::new_no_refs(&mut track, &mut id_allocator, &mut system);
Expand Down Expand Up @@ -136,17 +132,13 @@ fn any_panics_can_be_caught_in_the_native_vm_and_converted_into_results() {
let native_vm = NativeVm::new_with_extension(NonStringPanicExtension);

let intent_hash = Hash([0; 32]);
let mut system = System {
versioned_system_logic: VersionedSystemLogic::V1,
blueprint_cache: NonIterMap::new(),
auth_cache: NonIterMap::new(),
schema_cache: NonIterMap::new(),
callback: Vm {
let mut system = LatestSystem::new(
Vm {
scrypto_vm: &scrypto_vm,
native_vm,
vm_boot: VmBoot::latest(),
},
modules: SystemModuleMixer::new(
SystemModuleMixer::new(
EnabledModules::for_notarized_transaction(),
KernelTraceModule,
TransactionRuntimeModule::new(NetworkDefinition::simulator(), intent_hash),
Expand All @@ -165,8 +157,8 @@ fn any_panics_can_be_caught_in_the_native_vm_and_converted_into_results() {
},
ExecutionTraceModule::new(MAX_EXECUTION_TRACE_DEPTH),
),
finalization: Default::default(),
};
SystemFinalization::no_nullifications(),
);

let mut id_allocator = IdAllocator::new(intent_hash);
let mut kernel = Kernel::new_no_refs(&mut track, &mut id_allocator, &mut system);
Expand Down
61 changes: 41 additions & 20 deletions radix-engine/src/kernel/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use radix_engine_interface::api::field_api::LockFlags;
use radix_engine_profiling_derive::trace_resources;
use radix_substate_store_interface::db_key_mapper::SubstateKeyContent;
use radix_substate_store_interface::interface::SubstateDatabase;
use radix_transactions::model::ExecutableTransaction;
use sbor::rust::mem;

macro_rules! as_read_only {
Expand Down Expand Up @@ -42,39 +43,59 @@ impl KernelBoot {
}
}

/// A transaction which has a unique id, useful for creating an IdAllocator which
/// requires a unique input
pub trait UniqueSeed {
fn unique_seed_for_id_allocator(&self) -> Hash;
}

impl UniqueSeed for ExecutableTransaction {
fn unique_seed_for_id_allocator(&self) -> Hash {
*self.unique_hash()
}
}

/// Organizes the radix engine stack to make a function entrypoint available for execution
pub struct BootLoader<'h, M: KernelTransactionCallbackObject, S: SubstateDatabase> {
pub id_allocator: IdAllocator,
pub track: Track<'h, S>,
pub init: M::Init,
pub phantom: PhantomData<M>,
pub struct BootLoader<'h, E: KernelTransactionExecutor, S: SubstateDatabase> {
id_allocator: IdAllocator,
track: Track<'h, S>,
system_init: E::Init,
phantom: PhantomData<E>,
}

impl<'h, M: KernelTransactionCallbackObject, S: SubstateDatabase> BootLoader<'h, M, S> {
impl<'s, E: KernelTransactionExecutor<Executable: UniqueSeed>, S: SubstateDatabase>
BootLoader<'s, E, S>
{
/// Executes a transaction
pub fn execute(self, executable: M::Executable) -> M::Receipt {
// Start hardware resource usage tracker
#[cfg(all(target_os = "linux", feature = "std", feature = "cpu_ram_metrics"))]
let mut resources_tracker =
crate::kernel::resources_tracker::ResourcesTracker::start_measurement();
pub fn execute(
substate_db: &'s S,
system_init: E::Init,
executable: E::Executable,
) -> E::Receipt {
let boot_loader = Self {
id_allocator: IdAllocator::new(executable.unique_seed_for_id_allocator()),
track: Track::new(substate_db),
system_init,
phantom: PhantomData,
};

#[cfg(not(all(target_os = "linux", feature = "std", feature = "cpu_ram_metrics")))]
{
self.execute_internal(executable)
boot_loader.execute_internal(executable)
}

#[cfg(all(target_os = "linux", feature = "std", feature = "cpu_ram_metrics"))]
{
let mut receipt = self.execute_internal(executable);
use crate::kernel::resources_tracker::ResourcesTracker;

// Stop hardware resource usage tracker
let mut resources_tracker = ResourcesTracker::start_measurement();
let mut receipt = boot_loader.execute_internal(executable);
receipt.set_resource_usage(resources_tracker.end_measurement());

receipt
}
}

fn execute_internal(mut self, executable: M::Executable) -> M::Receipt {
fn execute_internal(mut self, executable: E::Executable) -> E::Receipt {
#[cfg(feature = "resource_tracker")]
radix_engine_profiling::QEMU_PLUGIN_CALIBRATOR.with(|v| {
v.borrow_mut();
Expand All @@ -93,7 +114,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);
let system_init_result = E::init(&mut self.track, &executable, self.system_init);

let (mut system, call_frame_inits) = match system_init_result {
Ok(success) => success,
Expand All @@ -109,9 +130,9 @@ impl<'h, M: KernelTransactionCallbackObject, S: SubstateDatabase> BootLoader<'h,
);

// Execution
let result = || -> Result<M::ExecutionOutput, RuntimeError> {
let result = || -> Result<E::ExecutionOutput, RuntimeError> {
// Invoke transaction processor
let output = M::start(&mut kernel, executable)?;
let output = E::execute(&mut kernel, executable)?;

// Sanity check call frame
for stack in &kernel.stacks.stacks {
Expand All @@ -123,7 +144,7 @@ impl<'h, M: KernelTransactionCallbackObject, S: SubstateDatabase> BootLoader<'h,

// Finalize state updates based on what has occurred
let commit_info = kernel.substate_io.store.get_commit_info();
kernel.callback.finish(commit_info)?;
kernel.callback.finalize(commit_info)?;

Ok(output)
}()
Expand Down
6 changes: 3 additions & 3 deletions radix-engine/src/kernel/kernel_callback_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ pub trait ExecutionReceipt {
fn set_resource_usage(&mut self, resources_usage: ResourcesUsage);
}

pub trait KernelTransactionCallbackObject: KernelCallbackObject {
pub trait KernelTransactionExecutor: KernelCallbackObject {
/// Initialization object
type Init;
/// The transaction object
Expand All @@ -155,13 +155,13 @@ pub trait KernelTransactionCallbackObject: KernelCallbackObject {
) -> Result<(Self, Vec<CallFrameInit<Self::CallFrameData>>), Self::Receipt>;

/// Start execution
fn start<Y: KernelApi<CallbackObject = Self>>(
fn execute<Y: KernelApi<CallbackObject = Self>>(
api: &mut Y,
executable: Self::Executable,
) -> Result<Self::ExecutionOutput, RuntimeError>;

/// Finish execution
fn finish(&mut self, store_commit_info: StoreCommitInfo) -> Result<(), RuntimeError>;
fn finalize(&mut self, store_commit_info: StoreCommitInfo) -> Result<(), RuntimeError>;

/// Create final receipt
fn create_receipt<S: SubstateDatabase>(
Expand Down
19 changes: 14 additions & 5 deletions radix-engine/src/system/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,27 @@ impl<'a, K: KernelInternalApi + ?Sized> SystemModuleApiImpl<'a, K> {
}

pub trait SystemModuleApi {
type SystemVersionLogic: SystemVersionLogic;
type SystemCallback: SystemCallbackObject;

fn system(&mut self) -> &mut System<Self::SystemCallback>;
fn system(&mut self) -> &mut System<Self::SystemVersionLogic, Self::SystemCallback>;

fn system_state(&mut self) -> SystemState<'_, System<Self::SystemCallback>>;
fn system_state(
&mut self,
) -> SystemState<'_, System<Self::SystemVersionLogic, Self::SystemCallback>>;

/// 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<System = System<V>> + ?Sized> SystemModuleApi
for SystemModuleApiImpl<'a, K>
impl<
'a,
L: SystemVersionLogic,
V: SystemCallbackObject,
K: KernelInternalApi<System = System<L, V>> + ?Sized,
> SystemModuleApi for SystemModuleApiImpl<'a, K>
{
type SystemVersionLogic = L;
type SystemCallback = V;

fn system(&mut self) -> &mut K::System {
Expand Down Expand Up @@ -76,8 +84,9 @@ pub trait SystemModuleApiFor<M: ResolvableSystemModule + ?Sized>: SystemModuleAp

impl<
'a,
L: SystemVersionLogic,
V: SystemCallbackObject,
K: KernelInternalApi<System = System<V>> + ?Sized,
K: KernelInternalApi<System = System<L, V>> + ?Sized,
M: ResolvableSystemModule + ?Sized,
> SystemModuleApiFor<M> for SystemModuleApiImpl<'a, K>
{
Expand Down
9 changes: 2 additions & 7 deletions radix-engine/src/system/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl<'a, Y: SystemBasedKernelApi + ?Sized> SystemService<'a, Y> {
self.api
}

pub fn system(&mut self) -> &mut System<Y::SystemCallback> {
pub fn system(&mut self) -> &mut System<Y::SystemVersionLogic, Y::SystemCallback> {
self.api.kernel_get_system()
}

Expand Down Expand Up @@ -2168,12 +2168,7 @@ impl<'a, Y: SystemBasedKernelApi> SystemCostingApi<RuntimeError> 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::SystemVersionLogic::should_consume_cost_units(self.api) {
return Ok(());
}

Expand Down
Loading

0 comments on commit b31ba81

Please sign in to comment.