Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: dispatch precompile filter #1022

Merged
merged 16 commits into from
Sep 27, 2023
Prev Previous commit
Next Next commit
integration
  • Loading branch information
gitofdeepanshu committed Sep 14, 2023
commit f8ee6d04f417030b5ce489c6c3104a2e39fbfe29
45 changes: 45 additions & 0 deletions primitives/src/precompiles.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,13 @@

#![cfg_attr(not(feature = "std"), no_std)]

use core::marker::PhantomData;

use fp_evm::{ExitError, PrecompileFailure};
use frame_support::{
dispatch::{DispatchClass, GetDispatchInfo, Pays},
traits::InstanceFilter,
};
use pallet_evm_precompile_dispatch::DispatchValidateT;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add Rustdoc to public structs.

pub struct BlockAllDispatchValidate;
@@ -36,3 +42,42 @@ impl<AccountId, RuntimeCall> DispatchValidateT<AccountId, RuntimeCall>
})
}
}

pub struct DispatchFilterValidate<RuntimeCall, Filter: InstanceFilter<RuntimeCall> + Default>(
PhantomData<(RuntimeCall, Filter)>,
);

impl<AccountId, RuntimeCall: GetDispatchInfo, Filter: InstanceFilter<RuntimeCall> + Default>
DispatchValidateT<AccountId, RuntimeCall> for DispatchFilterValidate<RuntimeCall, Filter>
{
fn validate_before_dispatch(
_origin: &AccountId,
call: &RuntimeCall,
) -> Option<PrecompileFailure> {
let info = call.get_dispatch_info();
if !(info.pays_fee == Pays::Yes && info.class == DispatchClass::Normal) {
return Some(PrecompileFailure::Error {
exit_status: ExitError::Other("invalid call".into()),
});
} else if Filter::default().filter(call) {
return None;
} else {
return Some(PrecompileFailure::Error {
exit_status: ExitError::Other("invalid call".into()),
});
}
}
shaunxw marked this conversation as resolved.
Show resolved Hide resolved
}

mod test {
use super::*;
#[test]
fn all_non_whitelisted_call_should_fail() {
assert_eq!(
BlockAllDispatchValidate::validate_before_dispatch(&(), &()).unwrap(),
PrecompileFailure::Error {
exit_status: ExitError::Other("invalid call".into()),
}
)
}
}
15 changes: 15 additions & 0 deletions runtime/shibuya/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1052,6 +1052,21 @@ impl pallet_sudo::Config for Runtime {
type RuntimeCall = RuntimeCall;
type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
}
#[derive(Default)]
pub struct DispatchPrecompileFilter;

impl InstanceFilter<RuntimeCall> for DispatchPrecompileFilter {
fn filter(&self, c: &RuntimeCall) -> bool {
match c {
RuntimeCall::Utility(pallet_utility::Call::batch { .. }) => true,
RuntimeCall::DappsStaking(_) => true,
_ => false,
}
}
fn is_superset(&self, _o: &Self) -> bool {
false
}
}

parameter_types! {
// One storage item; key size 32, value size 8.
7 changes: 4 additions & 3 deletions runtime/shibuya/src/precompiles.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,8 @@

//! The Shibuya Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm.

use astar_primitives::precompiles::BlockAllDispatchValidate;
use crate::{DispatchPrecompileFilter, RuntimeCall};
use astar_primitives::precompiles::DispatchFilterValidate;
use pallet_evm::{
ExitRevert, IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle,
PrecompileResult, PrecompileSet,
@@ -78,7 +79,7 @@ where
XcmPrecompile<R, C>: Precompile,
BatchPrecompile<R>: Precompile,
XvmPrecompile<R, pallet_xvm::Pallet<R>>: Precompile,
Dispatch<R, BlockAllDispatchValidate>: Precompile,
Dispatch<R, DispatchFilterValidate<RuntimeCall, DispatchPrecompileFilter>>: Precompile,
R: pallet_evm::Config
+ pallet_assets::Config
+ pallet_xcm::Config
@@ -111,7 +112,7 @@ where
a if a == hash(9) => Some(Blake2F::execute(handle)),
// nor Ethereum precompiles :
a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)),
a if a == hash(1025) => Some(Dispatch::<R, BlockAllDispatchValidate>::execute(handle)),
a if a == hash(1025) => Some(Dispatch::<R, DispatchFilterValidate<RuntimeCall,DispatchPrecompileFilter>>::execute(handle)),
a if a == hash(1026) => Some(ECRecoverPublicKey::execute(handle)),
a if a == hash(1027) => Some(Ed25519Verify::execute(handle)),
// Astar precompiles (starts from 0x5000):