From 2f0941d6f2a896bac2900d7c3f2d17a46ca6948b Mon Sep 17 00:00:00 2001 From: Bear Wang Date: Fri, 1 Sep 2023 12:44:08 +0800 Subject: [PATCH] Allow operational call in EVM (#1252) --- runtime/common/src/test.rs | 30 ++++++++++++++++++++++++++--- runtime/crab/src/pallets/evm.rs | 18 ++++++++++++----- runtime/darwinia/src/pallets/evm.rs | 18 ++++++++++++----- runtime/pangolin/src/pallets/evm.rs | 18 ++++++++++++----- runtime/pangoro/src/pallets/evm.rs | 18 ++++++++++++----- 5 files changed, 79 insertions(+), 23 deletions(-) diff --git a/runtime/common/src/test.rs b/runtime/common/src/test.rs index 106bc562e..31ea6f09f 100644 --- a/runtime/common/src/test.rs +++ b/runtime/common/src/test.rs @@ -486,17 +486,15 @@ macro_rules! impl_evm_tests { } #[test] - fn dispatch_validator_works() { + fn dispatch_validator_filter_runtime_calls() { ExtBuilder::default().build().execute_with(|| { assert!(DarwiniaDispatchValidator::validate_before_dispatch( - // normal account &H160::default().into(), &RuntimeCall::System(frame_system::Call::remark { remark: vec![] }) ) .is_none()); assert!(DarwiniaDispatchValidator::validate_before_dispatch( - // normal account &H160::default().into(), // forbidden call &RuntimeCall::EVM(pallet_evm::Call::call { @@ -514,6 +512,32 @@ macro_rules! impl_evm_tests { .is_some()); }); } + + #[test] + fn dispatch_validator_filter_dispatch_class() { + ExtBuilder::default().build().execute_with(|| { + // Default class + assert!(DarwiniaDispatchValidator::validate_before_dispatch( + &H160::default().into(), + &RuntimeCall::System(frame_system::Call::remark { remark: vec![] }) + ) + .is_none()); + + // Operational class + assert!(DarwiniaDispatchValidator::validate_before_dispatch( + &H160::default().into(), + &RuntimeCall::System(frame_system::Call::set_heap_pages { pages: 20 }) + ) + .is_none()); + + // Mandatory class + assert!(DarwiniaDispatchValidator::validate_before_dispatch( + &H160::default().into(), + &RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: 100 }) + ) + .is_some()); + }); + } } }; } diff --git a/runtime/crab/src/pallets/evm.rs b/runtime/crab/src/pallets/evm.rs index c64188c8a..15d61a13f 100644 --- a/runtime/crab/src/pallets/evm.rs +++ b/runtime/crab/src/pallets/evm.rs @@ -18,6 +18,8 @@ // darwinia use crate::*; +// substrate +use frame_support::dispatch::{DispatchClass, GetDispatchInfo, Pays}; // frontier use pallet_evm::{ExitError, IsPrecompileResult, Precompile}; use pallet_evm_precompile_dispatch::DispatchValidateT; @@ -182,9 +184,11 @@ fn addr(a: u64) -> sp_core::H160 { pub struct DarwiniaDispatchValidator; impl DispatchValidateT for DarwiniaDispatchValidator { fn validate_before_dispatch( - origin: &AccountId, + _origin: &AccountId, call: &RuntimeCall, ) -> Option { + let info = call.get_dispatch_info(); + if matches!( call, RuntimeCall::Assets(..) @@ -194,12 +198,16 @@ impl DispatchValidateT for DarwiniaDispatchValidator { | RuntimeCall::MessageTransact(..) ) { Some(fp_evm::PrecompileFailure::Error { - exit_status: ExitError::Other("These pallet's calls are forbidden".into()), + exit_status: ExitError::Other( + "These pallet's calls are not allowed to be called from precompile.".into(), + ), + }) + } else if info.pays_fee == Pays::No || info.class == DispatchClass::Mandatory { + Some(fp_evm::PrecompileFailure::Error { + exit_status: ExitError::Other("Permission denied calls".into()), }) } else { - <() as DispatchValidateT>::validate_before_dispatch( - origin, call, - ) + None } } } diff --git a/runtime/darwinia/src/pallets/evm.rs b/runtime/darwinia/src/pallets/evm.rs index 8c53decc7..66ba7634f 100644 --- a/runtime/darwinia/src/pallets/evm.rs +++ b/runtime/darwinia/src/pallets/evm.rs @@ -18,6 +18,8 @@ // darwinia use crate::*; +// substrate +use frame_support::dispatch::{DispatchClass, GetDispatchInfo, Pays}; // frontier use pallet_evm::{ExitError, IsPrecompileResult, Precompile}; use pallet_evm_precompile_dispatch::DispatchValidateT; @@ -181,9 +183,11 @@ fn addr(a: u64) -> sp_core::H160 { pub struct DarwiniaDispatchValidator; impl DispatchValidateT for DarwiniaDispatchValidator { fn validate_before_dispatch( - origin: &AccountId, + _origin: &AccountId, call: &RuntimeCall, ) -> Option { + let info = call.get_dispatch_info(); + if matches!( call, RuntimeCall::Assets(..) @@ -193,12 +197,16 @@ impl DispatchValidateT for DarwiniaDispatchValidator { | RuntimeCall::MessageTransact(..) ) { Some(fp_evm::PrecompileFailure::Error { - exit_status: ExitError::Other("These pallet's calls are forbidden".into()), + exit_status: ExitError::Other( + "These pallet's calls are not allowed to be called from precompile.".into(), + ), + }) + } else if info.pays_fee == Pays::No || info.class == DispatchClass::Mandatory { + Some(fp_evm::PrecompileFailure::Error { + exit_status: ExitError::Other("Permission denied calls".into()), }) } else { - <() as DispatchValidateT>::validate_before_dispatch( - origin, call, - ) + None } } } diff --git a/runtime/pangolin/src/pallets/evm.rs b/runtime/pangolin/src/pallets/evm.rs index 80e56606d..80b776499 100644 --- a/runtime/pangolin/src/pallets/evm.rs +++ b/runtime/pangolin/src/pallets/evm.rs @@ -18,6 +18,8 @@ // darwinia use crate::*; +// substrate +use frame_support::dispatch::{DispatchClass, GetDispatchInfo, Pays}; // frontier use pallet_evm::{ExitError, IsPrecompileResult, Precompile}; use pallet_evm_precompile_dispatch::DispatchValidateT; @@ -184,9 +186,11 @@ fn addr(a: u64) -> sp_core::H160 { pub struct DarwiniaDispatchValidator; impl DispatchValidateT for DarwiniaDispatchValidator { fn validate_before_dispatch( - origin: &AccountId, + _origin: &AccountId, call: &RuntimeCall, ) -> Option { + let info = call.get_dispatch_info(); + if matches!( call, RuntimeCall::Assets(..) @@ -195,12 +199,16 @@ impl DispatchValidateT for DarwiniaDispatchValidator { | RuntimeCall::MessageTransact(..) ) { Some(fp_evm::PrecompileFailure::Error { - exit_status: ExitError::Other("These pallet's calls are forbidden".into()), + exit_status: ExitError::Other( + "These pallet's calls are not allowed to be called from precompile.".into(), + ), + }) + } else if info.pays_fee == Pays::No || info.class == DispatchClass::Mandatory { + Some(fp_evm::PrecompileFailure::Error { + exit_status: ExitError::Other("Permission denied calls".into()), }) } else { - <() as DispatchValidateT>::validate_before_dispatch( - origin, call, - ) + None } } } diff --git a/runtime/pangoro/src/pallets/evm.rs b/runtime/pangoro/src/pallets/evm.rs index 5664306e0..e5f4c5cf8 100644 --- a/runtime/pangoro/src/pallets/evm.rs +++ b/runtime/pangoro/src/pallets/evm.rs @@ -18,6 +18,8 @@ // darwinia use crate::*; +// substrate +use frame_support::dispatch::{DispatchClass, GetDispatchInfo, Pays}; // frontier use pallet_evm::{ExitError, IsPrecompileResult, Precompile}; use pallet_evm_precompile_dispatch::DispatchValidateT; @@ -182,9 +184,11 @@ fn addr(a: u64) -> sp_core::H160 { pub struct DarwiniaDispatchValidator; impl DispatchValidateT for DarwiniaDispatchValidator { fn validate_before_dispatch( - origin: &AccountId, + _origin: &AccountId, call: &RuntimeCall, ) -> Option { + let info = call.get_dispatch_info(); + if matches!( call, RuntimeCall::Assets(..) @@ -193,12 +197,16 @@ impl DispatchValidateT for DarwiniaDispatchValidator { | RuntimeCall::MessageTransact(..) ) { Some(fp_evm::PrecompileFailure::Error { - exit_status: ExitError::Other("These pallet's calls are forbidden".into()), + exit_status: ExitError::Other( + "These pallet's calls are not allowed to be called from precompile.".into(), + ), + }) + } else if info.pays_fee == Pays::No || info.class == DispatchClass::Mandatory { + Some(fp_evm::PrecompileFailure::Error { + exit_status: ExitError::Other("Permission denied calls".into()), }) } else { - <() as DispatchValidateT>::validate_before_dispatch( - origin, call, - ) + None } } }