From d998e0169a69adabfaf65852f06641d011d60b77 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 8 Dec 2023 11:50:54 +0900 Subject: [PATCH] feat: delegate implementation of conformance kernel (#1938) --- Cargo.lock | 1 + testing/conformance/Cargo.toml | 1 + testing/conformance/src/vm.rs | 270 +++------------------------------ 3 files changed, 22 insertions(+), 250 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23fe3ae9e..0f33bd95e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2366,6 +2366,7 @@ dependencies = [ name = "fvm_conformance_tests" version = "0.1.0" dependencies = [ + "ambassador", "anyhow", "async-std", "base64 0.21.4", diff --git a/testing/conformance/Cargo.toml b/testing/conformance/Cargo.toml index 8e2f9c4ee..1b22be67b 100644 --- a/testing/conformance/Cargo.toml +++ b/testing/conformance/Cargo.toml @@ -37,6 +37,7 @@ ittapi-rs = { version = "0.3.0", optional = true } libipld-core = { version = "0.16.0", features = ["serde-codec"] } tar = { version = "0.4.38", default-features = false } zstd = { version = "0.12.3", default-features = false } +ambassador = "0.3.5" [dependencies.fvm] version = "4.0.0" diff --git a/testing/conformance/src/vm.rs b/testing/conformance/src/vm.rs index dda590f7c..3ad92cfca 100644 --- a/testing/conformance/src/vm.rs +++ b/testing/conformance/src/vm.rs @@ -3,6 +3,7 @@ use std::convert::TryFrom; use std::sync::{Arc, Mutex}; +use ambassador::Delegate; use anyhow::anyhow; use cid::Cid; use fvm::kernel::filecoin::{DefaultFilecoinKernel, FilecoinKernel}; @@ -11,11 +12,9 @@ use multihash::MultihashGeneric; use fvm::call_manager::{CallManager, DefaultCallManager}; use fvm::gas::{price_list_by_network_version, Gas, GasTimer, PriceList}; -use fvm::kernel::*; use fvm::machine::limiter::MemoryLimiter; use fvm::machine::{DefaultMachine, Machine, MachineContext, Manifest, NetworkConfig}; use fvm::state_tree::StateTree; -use fvm::DefaultKernel; use fvm_ipld_blockstore::MemoryBlockstore; use fvm_shared::address::Address; use fvm_shared::clock::ChainEpoch; @@ -29,11 +28,17 @@ use fvm_shared::randomness::RANDOMNESS_LENGTH; use fvm_shared::sector::{ AggregateSealVerifyProofAndInfos, RegisteredSealProof, ReplicaUpdateInfo, SealVerifyInfo, }; -use fvm_shared::sys::{EventEntry, SendFlags}; +use fvm_shared::sys::out::network::NetworkContext; +use fvm_shared::sys::out::vm::MessageContext; +use fvm_shared::sys::SendFlags; use fvm_shared::version::NetworkVersion; use fvm_shared::{ActorID, MethodNum}; use wasmtime::Linker; +// We have glob imports here because delegation doesn't work well without it. +use fvm::*; +use kernel::*; + use crate::externs::TestExterns; use crate::vector::{MessageVector, Variant}; @@ -168,6 +173,18 @@ where /// A kernel for intercepting syscalls. // TestKernel is coupled to TestMachine because it needs to use that to plumb the // TestData through when it's destroyed into a CallManager then recreated by that CallManager. +#[derive(Delegate)] +#[delegate(IpldBlockOps)] +#[delegate(ActorOps)] +#[delegate(CryptoOps)] +#[delegate(DebugOps)] +#[delegate(EventOps)] +#[delegate(GasOps)] +#[delegate(MessageOps)] +#[delegate(NetworkOps)] +#[delegate(RandomnessOps)] +#[delegate(SelfOps)] +#[delegate(LimiterOps)] pub struct TestKernel>>>( pub K, ); @@ -250,81 +267,6 @@ where } } -impl ActorOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn resolve_address(&self, address: &Address) -> Result { - self.0.resolve_address(address) - } - - fn get_actor_code_cid(&self, id: ActorID) -> Result { - self.0.get_actor_code_cid(id) - } - - fn next_actor_address(&self) -> Result
{ - self.0.next_actor_address() - } - - fn create_actor( - &mut self, - code_id: Cid, - actor_id: ActorID, - delegated_address: Option
, - ) -> Result<()> { - self.0.create_actor(code_id, actor_id, delegated_address) - } - - fn install_actor(&mut self, _code_id: Cid) -> Result<()> { - Ok(()) - } - - fn get_builtin_actor_type(&self, code_cid: &Cid) -> Result { - self.0.get_builtin_actor_type(code_cid) - } - - fn get_code_cid_for_type(&self, typ: u32) -> Result { - self.0.get_code_cid_for_type(typ) - } - - fn balance_of(&self, actor_id: ActorID) -> Result { - self.0.balance_of(actor_id) - } - - fn lookup_delegated_address(&self, actor_id: ActorID) -> Result> { - self.0.lookup_delegated_address(actor_id) - } -} - -impl IpldBlockOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn block_open(&mut self, cid: &Cid) -> Result<(BlockId, BlockStat)> { - self.0.block_open(cid) - } - - fn block_create(&mut self, codec: u64, data: &[u8]) -> Result { - self.0.block_create(codec, data) - } - - fn block_link(&mut self, id: BlockId, hash_fun: u64, hash_len: u32) -> Result { - self.0.block_link(id, hash_fun, hash_len) - } - - fn block_read(&self, id: BlockId, offset: u32, buf: &mut [u8]) -> Result { - self.0.block_read(id, offset, buf) - } - - fn block_stat(&self, id: BlockId) -> Result { - self.0.block_stat(id) - } -} - impl FilecoinKernel for TestKernel where M: Machine, @@ -382,178 +324,6 @@ where } } -impl CryptoOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - // forwarded - fn hash(&self, code: u64, data: &[u8]) -> Result> { - self.0.hash(code, data) - } - - // forwarded - fn verify_signature( - &self, - sig_type: SignatureType, - signature: &[u8], - signer: &Address, - plaintext: &[u8], - ) -> Result { - self.0 - .verify_signature(sig_type, signature, signer, plaintext) - } - - // forwarded - fn recover_secp_public_key( - &self, - hash: &[u8; SECP_SIG_MESSAGE_HASH_SIZE], - signature: &[u8; SECP_SIG_LEN], - ) -> Result<[u8; SECP_PUB_LEN]> { - self.0.recover_secp_public_key(hash, signature) - } -} - -impl DebugOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn log(&self, msg: String) { - self.0.log(msg) - } - - fn debug_enabled(&self) -> bool { - self.0.debug_enabled() - } - - fn store_artifact(&self, name: &str, data: &[u8]) -> Result<()> { - self.0.store_artifact(name, data) - } -} - -impl GasOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn gas_used(&self) -> Gas { - self.0.gas_used() - } - - fn charge_gas(&self, name: &str, compute: Gas) -> Result { - self.0.charge_gas(name, compute) - } - - fn price_list(&self) -> &PriceList { - self.0.price_list() - } - - fn gas_available(&self) -> Gas { - self.0.gas_available() - } -} - -impl MessageOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn msg_context(&self) -> Result { - self.0.msg_context() - } -} - -impl NetworkOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn network_context(&self) -> Result { - self.0.network_context() - } - - fn tipset_cid(&self, epoch: ChainEpoch) -> Result { - self.0.tipset_cid(epoch) - } -} - -impl RandomnessOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn get_randomness_from_tickets( - &self, - rand_epoch: ChainEpoch, - ) -> Result<[u8; RANDOMNESS_LENGTH]> { - self.0.get_randomness_from_tickets(rand_epoch) - } - - fn get_randomness_from_beacon( - &self, - rand_epoch: ChainEpoch, - ) -> Result<[u8; RANDOMNESS_LENGTH]> { - self.0.get_randomness_from_beacon(rand_epoch) - } -} - -impl SelfOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn root(&mut self) -> Result { - self.0.root() - } - - fn set_root(&mut self, root: Cid) -> Result<()> { - self.0.set_root(root) - } - - fn current_balance(&self) -> Result { - self.0.current_balance() - } - - fn self_destruct(&mut self, burn_unspent: bool) -> Result<()> { - self.0.self_destruct(burn_unspent) - } -} - -impl LimiterOps for TestKernel -where - K: LimiterOps, -{ - type Limiter = K::Limiter; - - fn limiter_mut(&mut self) -> &mut Self::Limiter { - self.0.limiter_mut() - } -} - -impl EventOps for TestKernel -where - M: Machine, - C: CallManager>, - K: Kernel, -{ - fn emit_event( - &mut self, - event_headers: &[EventEntry], - key_evt: &[u8], - val_evt: &[u8], - ) -> Result<()> { - self.0.emit_event(event_headers, key_evt, val_evt) - } -} - /// Wrap a `ResourceLimiter` and collect statistics. pub struct TestLimiter { inner: L,