From b6aae0c953c4d7f8d8d3d71c1fe08ccb3a933a0e Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Thu, 19 Jan 2023 12:05:56 -0800 Subject: [PATCH] feat: allow calling InvokeEVM on accounts Additionally, use the same dispatch mechanism for the universal receiver hook. Given #1076, CBOR encoding should no longer be a compatibility hazard for us. --- actors/account/src/lib.rs | 14 +++----------- actors/ethaccount/src/lib.rs | 14 +++----------- runtime/src/dispatch.rs | 26 ++++++++++++++++++++++---- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/actors/account/src/lib.rs b/actors/account/src/lib.rs index af87aaf86..1b4986c18 100644 --- a/actors/account/src/lib.rs +++ b/actors/account/src/lib.rs @@ -1,7 +1,6 @@ // Copyright 2019-2022 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use fvm_actor_utils::receiver::UniversalReceiverParams; use fvm_shared::address::{Address, Protocol}; use fvm_shared::crypto::signature::SignatureType::{Secp256k1, BLS}; use fvm_shared::crypto::signature::{Signature, SignatureType}; @@ -36,6 +35,7 @@ pub enum Method { // AuthenticateMessage = 3, AuthenticateMessageExported = frc42_dispatch::method_hash!("AuthenticateMessage"), UniversalReceiverHook = frc42_dispatch::method_hash!("Receive"), + InvokeEVM = frc42_dispatch::method_hash!("InvokeEVM"), } /// Account Actor @@ -91,15 +91,6 @@ impl Actor { Ok(()) } - - // Always succeeds, accepting any transfers. - pub fn universal_receiver_hook( - rt: &mut impl Runtime, - _params: UniversalReceiverParams, - ) -> Result<(), ActorError> { - rt.validate_immediate_caller_accept_any()?; - Ok(()) - } } impl ActorCode for Actor { @@ -108,6 +99,7 @@ impl ActorCode for Actor { Constructor => constructor, PubkeyAddress => pubkey_address, AuthenticateMessageExported => authenticate_message, - UniversalReceiverHook => universal_receiver_hook, + UniversalReceiverHook => (), + InvokeEVM => (), } } diff --git a/actors/ethaccount/src/lib.rs b/actors/ethaccount/src/lib.rs index 2690ba82d..ad755e73e 100644 --- a/actors/ethaccount/src/lib.rs +++ b/actors/ethaccount/src/lib.rs @@ -1,6 +1,5 @@ pub mod types; -use fvm_actor_utils::receiver::UniversalReceiverParams; use fvm_shared::address::{Payload, Protocol}; use fvm_shared::crypto::hash::SupportedHashes::Keccak256; use fvm_shared::error::ExitCode; @@ -25,6 +24,7 @@ pub enum Method { Constructor = METHOD_CONSTRUCTOR, AuthenticateMessageExported = frc42_dispatch::method_hash!("AuthenticateMessage"), UniversalReceiverHook = frc42_dispatch::method_hash!("Receive"), + InvokeEVM = frc42_dispatch::method_hash!("InvokeEVM"), } /// Ethereum Account actor. @@ -126,15 +126,6 @@ impl EthAccountActor { Ok(()) } - - // Always succeeds, accepting any transfers. - pub fn universal_receiver_hook( - rt: &mut impl Runtime, - _params: UniversalReceiverParams, - ) -> Result<(), ActorError> { - rt.validate_immediate_caller_accept_any()?; - Ok(()) - } } impl ActorCode for EthAccountActor { @@ -142,6 +133,7 @@ impl ActorCode for EthAccountActor { actor_dispatch! { Constructor => constructor, AuthenticateMessageExported => authenticate_message, - UniversalReceiverHook => universal_receiver_hook, + UniversalReceiverHook => (), + InvokeEVM => (), } } diff --git a/runtime/src/dispatch.rs b/runtime/src/dispatch.rs index 63e579585..efe55cf57 100644 --- a/runtime/src/dispatch.rs +++ b/runtime/src/dispatch.rs @@ -24,7 +24,7 @@ use crate::ActorError; /// ``` #[macro_export] macro_rules! actor_dispatch { - ($($(#[$m:meta])* $method:ident => $func:ident,)*) => { + ($($(#[$m:meta])* $method:ident => $func:tt,)*) => { fn invoke_method( rt: &mut RT, method: MethodNum, @@ -36,16 +36,25 @@ macro_rules! actor_dispatch { { restrict_internal_api(rt, method)?; match FromPrimitive::from_u64(method) { - $($(#[$m])* Some(Self::Methods::$method) => $crate::dispatch(rt, Self::$func, &args),)* + $($(#[$m])* Some(Self::Methods::$method) => { + $crate::actor_dispatch!(@dispatch (rt args) $func) + }),* None => Err(actor_error!(unhandled_message; "invalid method: {}", method)), } } }; + (@dispatch ($rt:ident $args:ident) ()) => {{ + $rt.validate_immediate_caller_accept_any()?; + Ok(None) + }}; + (@dispatch ($rt:ident $args:ident) $func:ident) => { + $crate::dispatch($rt, Self::$func, &$args) + }; } #[macro_export] macro_rules! actor_dispatch_unrestricted { - ($($(#[$m:meta])* $method:ident => $func:ident,)*) => { + ($($(#[$m:meta])* $method:ident => $func:tt,)*) => { fn invoke_method( rt: &mut RT, method: MethodNum, @@ -56,11 +65,20 @@ macro_rules! actor_dispatch_unrestricted { RT::Blockstore: Clone, { match FromPrimitive::from_u64(method) { - $($(#[$m])* Some(Self::Methods::$method) => $crate::dispatch(rt, Self::$func, &args),)* + $($(#[$m])* Some(Self::Methods::$method) => { + $crate::actor_dispatch!(@dispatch (rt args) $func) + }),* None => Err(actor_error!(unhandled_message; "invalid method: {}", method)), } } }; + (@dispatch ($rt:ident $args:ident) ()) => {{ + $rt.validate_immediate_caller_accept_any()?; + Ok(None) + }}; + (@dispatch ($rt:ident $args:ident) $func:ident) => { + $crate::dispatch($rt, Self::$func, &$args) + }; } pub trait Dispatch<'de, RT> {