diff --git a/fvm/src/call_manager/default.rs b/fvm/src/call_manager/default.rs index a0727e8c2..fb210563a 100644 --- a/fvm/src/call_manager/default.rs +++ b/fvm/src/call_manager/default.rs @@ -25,7 +25,6 @@ use crate::engine::Engine; use crate::gas::{Gas, GasTracker}; use crate::kernel::{ Block, BlockRegistry, ClassifyResult, ExecutionError, Kernel, Result, SyscallError, - SyscallHandler, }; use crate::machine::limiter::MemoryLimiter; use crate::machine::Machine; @@ -181,7 +180,7 @@ where read_only: bool, ) -> Result where - K: Kernel + SyscallHandler, + K: Kernel, { if self.machine.context().tracing { self.trace(ExecutionEvent::Call { @@ -549,7 +548,7 @@ where /// 2. Initializes it by calling the constructor. fn create_account_actor_from_send(&mut self, addr: &Address) -> Result where - K: Kernel + SyscallHandler, + K: Kernel, { if addr.is_bls_zero_address() { return Err( @@ -608,7 +607,7 @@ where read_only: bool, ) -> Result where - K: Kernel + SyscallHandler, + K: Kernel, { // Get the receiver; this will resolve the address. let to = match self.resolve_address(&to)? { @@ -654,7 +653,7 @@ where read_only: bool, ) -> Result where - K: Kernel + SyscallHandler, + K: Kernel, { // Lookup the actor. let state = self diff --git a/fvm/src/call_manager/mod.rs b/fvm/src/call_manager/mod.rs index 80f2dff69..680c8ecda 100644 --- a/fvm/src/call_manager/mod.rs +++ b/fvm/src/call_manager/mod.rs @@ -10,7 +10,7 @@ use fvm_shared::{ActorID, MethodNum}; use crate::engine::Engine; use crate::gas::{Gas, GasCharge, GasTimer, GasTracker, PriceList}; -use crate::kernel::{self, BlockRegistry, ClassifyResult, Context, Result, SyscallHandler}; +use crate::kernel::{self, BlockRegistry, ClassifyResult, Context, Result}; use crate::machine::{Machine, MachineContext}; use crate::state_tree::ActorState; use crate::Kernel; @@ -65,7 +65,7 @@ pub trait CallManager: 'static { /// Calls an actor at the given address and entrypoint. The type parameter `K` specifies the the _kernel_ on top of which the target /// actor should execute. #[allow(clippy::too_many_arguments)] - fn call_actor + SyscallHandler>( + fn call_actor>( &mut self, from: ActorID, to: Address, diff --git a/fvm/src/engine/mod.rs b/fvm/src/engine/mod.rs index 3267f0859..f342a7305 100644 --- a/fvm/src/engine/mod.rs +++ b/fvm/src/engine/mod.rs @@ -23,7 +23,6 @@ use wasmtime::{ }; use crate::gas::{Gas, GasTimer, WasmGasPrices}; -use crate::kernel::SyscallHandler; use crate::machine::limiter::MemoryLimiter; use crate::machine::{Machine, NetworkConfig}; use crate::syscalls::error::Abort; @@ -498,7 +497,7 @@ impl Engine { /// linker, syscalls, etc. /// /// This returns an `Abort` as it may need to execute initialization code, charge gas, etc. - pub fn instantiate>( + pub fn instantiate( &self, store: &mut wasmtime::Store>, k: &Cid, @@ -516,12 +515,7 @@ impl Engine { .insert({ let mut linker = Linker::new(&self.inner.engine); linker.allow_shadowing(true); - - store - .data() - .kernel - .bind_syscalls(&mut linker) - .map_err(Abort::Fatal)?; + K::bind_syscalls(&mut linker).map_err(Abort::Fatal)?; Box::new(Cache { linker }) }) diff --git a/fvm/src/executor/default.rs b/fvm/src/executor/default.rs index 579b29ef4..554dea015 100644 --- a/fvm/src/executor/default.rs +++ b/fvm/src/executor/default.rs @@ -20,7 +20,7 @@ use crate::call_manager::{backtrace, Backtrace, CallManager, Entrypoint, Invocat use crate::eam_actor::EAM_ACTOR_ID; use crate::engine::EnginePool; use crate::gas::{Gas, GasCharge, GasOutputs}; -use crate::kernel::{Block, ClassifyResult, Context as _, ExecutionError, Kernel, SyscallHandler}; +use crate::kernel::{Block, ClassifyResult, Context as _, ExecutionError, Kernel}; use crate::machine::{Machine, BURNT_FUNDS_ACTOR_ID, REWARD_ACTOR_ID}; use crate::trace::ExecutionTrace; @@ -53,7 +53,7 @@ impl DerefMut for DefaultExecutor { impl Executor for DefaultExecutor where - K: Kernel + SyscallHandler, + K: Kernel, { type Kernel = K; diff --git a/fvm/src/kernel/default.rs b/fvm/src/kernel/default.rs index d47740e4a..da10bb5df 100644 --- a/fvm/src/kernel/default.rs +++ b/fvm/src/kernel/default.rs @@ -427,7 +427,7 @@ where impl CallOps for DefaultKernel where - K: Kernel + SyscallHandler, + K: Kernel, { fn send( &mut self, @@ -437,10 +437,7 @@ where value: &TokenAmount, gas_limit: Option, flags: SendFlags, - ) -> Result - where - K: SyscallHandler + Kernel, - { + ) -> Result { let from = self.actor_id; let read_only = self.read_only || flags.read_only(); @@ -506,10 +503,7 @@ where }) } - fn upgrade_actor(&mut self, new_code_cid: Cid, params_id: BlockId) -> Result - where - K: SyscallHandler + Kernel, - { + fn upgrade_actor(&mut self, new_code_cid: Cid, params_id: BlockId) -> Result { if self.read_only { return Err( syscall_error!(ReadOnly, "upgrade_actor cannot be called while read-only").into(), diff --git a/fvm/src/kernel/filecoin.rs b/fvm/src/kernel/filecoin.rs index e07a2ab6f..1cc2347ef 100644 --- a/fvm/src/kernel/filecoin.rs +++ b/fvm/src/kernel/filecoin.rs @@ -86,7 +86,7 @@ pub trait FilecoinKernel: Kernel { #[derive(Delegate)] #[delegate(IpldBlockOps, where = "C: CallManager")] #[delegate(ActorOps, where = "C: CallManager")] -#[delegate(CallOps, generics = "K", where = "C: CallManager, K: SyscallHandler + Kernel")] +#[delegate(CallOps, generics = "K", where = "C: CallManager, K: Kernel")] #[delegate(CryptoOps, where = "C: CallManager")] #[delegate(DebugOps, where = "C: CallManager")] #[delegate(SystemOps, where = "C: CallManager")] diff --git a/fvm/src/kernel/mod.rs b/fvm/src/kernel/mod.rs index 959882b2a..bc688e935 100644 --- a/fvm/src/kernel/mod.rs +++ b/fvm/src/kernel/mod.rs @@ -48,9 +48,11 @@ pub struct CallResult { pub exit_code: ExitCode, } -pub trait Kernel: 'static { - /// The [`Kernel`]'s [`CallManager`] is +/// The base [`Kernel`] trait implemented by all kernels. +pub trait Kernel: SyscallHandler + 'static { + /// The [`Kernel`]'s [`CallManager`]. type CallManager: CallManager; + /// The [`Kernel`]'s memory allocation tracker. type Limiter: MemoryLimiter; /// Construct a new [`Kernel`] from the given [`CallManager`]. @@ -83,6 +85,7 @@ pub trait Kernel: 'static { fn into_inner(self) -> (Self::CallManager, BlockRegistry) where Self: Sized; + /// The kernel's underlying "machine". fn machine(&self) -> &::Machine; @@ -90,14 +93,18 @@ pub trait Kernel: 'static { /// `name` provides information about gas charging point. fn charge_gas(&self, name: &str, compute: Gas) -> Result; - /// XXX Returns the remaining gas for the transaction. + // XXX: Move these somewhere else? + + /// Returns the remaining gas for the transaction. fn gas_available(&self) -> Gas; + /// XXX: Testing only! fn gas_used(&self) -> Gas; } +/// This trait links the kernel to a wasm module via wasm "host" calls (syscalls). pub trait SyscallHandler: Sized { - fn bind_syscalls(&self, linker: &mut Linker>) -> anyhow::Result<()>; + fn bind_syscalls(linker: &mut Linker>) -> anyhow::Result<()>; } #[delegatable_trait] diff --git a/fvm/src/syscalls/actor.rs b/fvm/src/syscalls/actor.rs index c328b9b38..1e7237fe5 100644 --- a/fvm/src/syscalls/actor.rs +++ b/fvm/src/syscalls/actor.rs @@ -6,9 +6,7 @@ use fvm_shared::{sys, ActorID}; use super::bind::ControlFlow; use super::error::Abort; use super::Context; -use crate::kernel::{ - ActorOps, CallOps, CallResult, ClassifyResult, Result, SyscallHandler, SystemOps, -}; +use crate::kernel::{ActorOps, CallOps, CallResult, ClassifyResult, Result, SystemOps}; use crate::{syscall_error, Kernel}; pub fn resolve_address( @@ -113,7 +111,7 @@ pub fn create_actor( context.kernel.create_actor(typ, actor_id, addr) } -pub fn upgrade_actor( +pub fn upgrade_actor( context: Context<'_, K>, new_code_cid_off: u32, params_id: u32, diff --git a/fvm/src/syscalls/mod.rs b/fvm/src/syscalls/mod.rs index 268715e57..894ee58ed 100644 --- a/fvm/src/syscalls/mod.rs +++ b/fvm/src/syscalls/mod.rs @@ -4,9 +4,9 @@ use anyhow::{anyhow, Context as _}; use num_traits::Zero; use wasmtime::{AsContextMut, ExternType, Global, Linker, Memory, Module, Val}; -use crate::call_manager::{backtrace, CallManager}; +use crate::call_manager::backtrace; use crate::gas::{Gas, GasInstant, GasTimer}; -use crate::kernel::filecoin::DefaultFilecoinKernel; +use crate::kernel::filecoin::{DefaultFilecoinKernel, FilecoinKernel}; use crate::kernel::{ ActorOps, CallOps, ChainOps, CryptoOps, DebugOps, ExecutionError, IpldBlockOps, SyscallHandler, SystemOps, @@ -241,20 +241,9 @@ use self::error::Abort; impl SyscallHandler for DefaultKernel where - K: ChainOps - + ActorOps - + CryptoOps - + SystemOps - + IpldBlockOps - + DebugOps - + CallOps - + SyscallHandler - + Kernel, + K: Kernel + ChainOps + ActorOps + CryptoOps + SystemOps + IpldBlockOps + DebugOps + CallOps, { - fn bind_syscalls( - &self, - linker: &mut wasmtime::Linker>, - ) -> anyhow::Result<()> { + fn bind_syscalls(linker: &mut wasmtime::Linker>) -> anyhow::Result<()> { linker.bind("vm", "exit", vm::exit)?; linker.bind("vm", "message_context", vm::message_context)?; @@ -330,15 +319,13 @@ where } } -impl SyscallHandler> for DefaultFilecoinKernel +impl SyscallHandler for DefaultFilecoinKernel where - C: CallManager, + K: FilecoinKernel, + DefaultKernel: SyscallHandler, { - fn bind_syscalls( - &self, - linker: &mut Linker>>, - ) -> anyhow::Result<()> { - self.0.bind_syscalls(linker)?; + fn bind_syscalls(linker: &mut Linker>) -> anyhow::Result<()> { + DefaultKernel::bind_syscalls(linker)?; // Now bind the crypto syscalls. linker.bind( diff --git a/fvm/src/syscalls/send.rs b/fvm/src/syscalls/send.rs index 93c2ca9f4..3c1c0b7b1 100644 --- a/fvm/src/syscalls/send.rs +++ b/fvm/src/syscalls/send.rs @@ -7,13 +7,13 @@ use fvm_shared::sys::{self, SendFlags}; use super::Context; use crate::gas::Gas; -use crate::kernel::{CallOps, CallResult, ClassifyResult, Result, SyscallHandler}; +use crate::kernel::{CallOps, CallResult, ClassifyResult, Result}; use crate::Kernel; /// Send a message to another actor. The result is placed as a CBOR-encoded /// receipt in the block registry, and can be retrieved by the returned BlockId. #[allow(clippy::too_many_arguments)] -pub fn send( +pub fn send( context: Context<'_, K>, recipient_off: u32, recipient_len: u32, diff --git a/fvm/tests/dummy.rs b/fvm/tests/dummy.rs index 88f0d8187..1faf483c0 100644 --- a/fvm/tests/dummy.rs +++ b/fvm/tests/dummy.rs @@ -10,7 +10,6 @@ use fvm::call_manager::{Backtrace, CallManager, Entrypoint, FinishRet, Invocatio use fvm::engine::Engine; use fvm::externs::{Chain, Consensus, Externs, Rand}; use fvm::gas::{Gas, GasCharge, GasTimer, GasTracker}; -use fvm::kernel::SyscallHandler; use fvm::machine::limiter::MemoryLimiter; use fvm::machine::{Machine, MachineContext, Manifest, NetworkConfig}; use fvm::state_tree::StateTree; @@ -275,7 +274,7 @@ impl CallManager for DummyCallManager { } } - fn call_actor + SyscallHandler>( + fn call_actor>( &mut self, _from: fvm_shared::ActorID, _to: Address, diff --git a/testing/conformance/src/vm.rs b/testing/conformance/src/vm.rs index ff0a09278..a1ff077da 100644 --- a/testing/conformance/src/vm.rs +++ b/testing/conformance/src/vm.rs @@ -195,18 +195,11 @@ impl Kernel for TestKernel where M: Machine, C: CallManager>, - K: Kernel, + K: Kernel + SyscallHandler, { type CallManager = K::CallManager; type Limiter = K::Limiter; - fn into_inner(self) -> (Self::CallManager, BlockRegistry) - where - Self: Sized, - { - self.0.into_inner() - } - fn new( mgr: C, blocks: BlockRegistry, @@ -236,6 +229,13 @@ where ) } + fn into_inner(self) -> (Self::CallManager, BlockRegistry) + where + Self: Sized, + { + self.0.into_inner() + } + fn machine(&self) -> &::Machine { self.0.machine() } @@ -261,12 +261,11 @@ where } } -impl CallOps for TestKernel +impl CallOps for TestKernel where M: Machine, C: CallManager>, K: Kernel + CallOps, - KK: SyscallHandler + Kernel, { /// Sends a message to another actor. /// The method type parameter K is the type of the kernel to instantiate for @@ -293,17 +292,14 @@ where } } -impl SyscallHandler> for TestKernel +impl SyscallHandler for TestKernel where M: Machine, C: CallManager>, - K: Kernel, + K: Kernel + SyscallHandler, { - fn bind_syscalls( - &self, - _linker: &mut Linker>>, - ) -> anyhow::Result<()> { - Ok(()) + fn bind_syscalls(linker: &mut Linker>) -> anyhow::Result<()> { + K::bind_syscalls(linker) } } @@ -311,7 +307,7 @@ impl FilecoinKernel for TestKernel where M: Machine, C: CallManager>, - K: FilecoinKernel, + K: FilecoinKernel + SyscallHandler, { fn compute_unsealed_sector_cid( &self,