Skip to content

Commit

Permalink
Update generic params and add tests (polkadot-evm#1047)
Browse files Browse the repository at this point in the history
  • Loading branch information
boundless-forest authored and ashutoshvarma committed Jun 8, 2023
1 parent cac126b commit 9bce3c8
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 60 deletions.
17 changes: 8 additions & 9 deletions frame/evm/precompile/dispatch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ where
T: pallet_evm::Config,
T::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo + Decode,
<T::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<T::AccountId>>,
DispatchValidator: DispatchValidateT<T>,
DispatchValidator: DispatchValidateT<T::AccountId, T::RuntimeCall>,
DecodeLimit: Get<u32>,
{
fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult {
Expand Down Expand Up @@ -106,22 +106,21 @@ where
}

/// Dispatch validation trait.
pub trait DispatchValidateT<T: pallet_evm::Config> {
pub trait DispatchValidateT<AccountId, RuntimeCall> {
fn validate_before_dispatch(
origin: &T::AccountId,
call: &T::RuntimeCall,
origin: &AccountId,
call: &RuntimeCall,
) -> Option<PrecompileFailure>;
}

/// The default implementation of `DispatchValidateT`.
impl<T> DispatchValidateT<T> for ()
impl<AccountId, RuntimeCall> DispatchValidateT<AccountId, RuntimeCall> for ()
where
T: pallet_evm::Config,
T::RuntimeCall: GetDispatchInfo,
RuntimeCall: GetDispatchInfo,
{
fn validate_before_dispatch(
_origin: &T::AccountId,
call: &T::RuntimeCall,
_origin: &AccountId,
call: &RuntimeCall,
) -> Option<PrecompileFailure> {
let info = call.get_dispatch_info();
if !(info.pays_fee == Pays::Yes && info.class == DispatchClass::Normal) {
Expand Down
95 changes: 44 additions & 51 deletions frame/evm/precompile/dispatch/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,62 +20,16 @@
use super::*;
use crate::mock::*;

use fp_evm::{Context, GenesisAccount};
use frame_support::{assert_ok, traits::GenesisBuild};
use fp_evm::Context;
use frame_support::{assert_err, assert_ok};
use scale_codec::Encode;
use sp_core::{H160, U256};
use std::{collections::BTreeMap, str::FromStr};

pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default()
frame_system::GenesisConfig::default()
.build_storage::<Test>()
.unwrap();

let mut accounts = BTreeMap::new();
accounts.insert(
H160::from_str("1000000000000000000000000000000000000001").unwrap(),
GenesisAccount {
nonce: U256::from(1),
balance: U256::from(1000000),
storage: Default::default(),
code: vec![
0x00, // STOP
],
},
);
accounts.insert(
H160::from_str("1000000000000000000000000000000000000002").unwrap(),
GenesisAccount {
nonce: U256::from(1),
balance: U256::from(1000000),
storage: Default::default(),
code: vec![
0xff, // INVALID
],
},
);
accounts.insert(
H160::default(), // root
GenesisAccount {
nonce: U256::from(1),
balance: U256::max_value(),
storage: Default::default(),
code: vec![],
},
);

pallet_balances::GenesisConfig::<Test> {
// Create the block author account with some balance.
balances: vec![(
H160::from_str("0x1234500000000000000000000000000000000000").unwrap(),
12345,
)],
}
.assimilate_storage(&mut t)
.expect("Pallet balances storage can be assimilated");
GenesisBuild::<Test>::assimilate_storage(&pallet_evm::GenesisConfig { accounts }, &mut t)
.unwrap();
t.into()
.unwrap()
.into()
}

#[test]
Expand Down Expand Up @@ -135,3 +89,42 @@ fn decode_limit_ok() {
assert_ok!(Dispatch::<Test>::execute(&mut handle));
});
}

#[test]
fn dispatch_validator_works_well() {
new_test_ext().execute_with(|| {
let call = RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() });
let mut handle = MockHandle {
input: call.encode(),
context: Context {
address: H160::default(),
caller: H160::default(),
apparent_value: U256::default(),
},
};
assert_ok!(Dispatch::<Test>::execute(&mut handle));

pub struct MockValidator;
impl DispatchValidateT<H160, RuntimeCall> for MockValidator {
fn validate_before_dispatch(
_origin: &H160,
call: &RuntimeCall,
) -> Option<PrecompileFailure> {
match call {
RuntimeCall::System(frame_system::Call::remark { remark: _ }) => {
return Some(PrecompileFailure::Error {
exit_status: ExitError::Other("This call is not allowed".into()),
})
}
_ => None,
}
}
}
assert_err!(
Dispatch::<Test, MockValidator>::execute(&mut handle),
PrecompileFailure::Error {
exit_status: ExitError::Other("This call is not allowed".into()),
}
);
});
}

0 comments on commit 9bce3c8

Please sign in to comment.