diff --git a/Cargo.lock b/Cargo.lock index cf05b8981..953ae1563 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -969,6 +969,7 @@ dependencies = [ "pallet-treasury 37.0.0", "pallet-xc-asset-config", "parity-scale-codec", + "precompile-utils", "scale-info", "sp-arithmetic", "sp-core", @@ -1035,7 +1036,6 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-dapp-staking", "pallet-evm-precompile-dispatch", - "pallet-evm-precompile-dispatch-lockdrop", "pallet-evm-precompile-ed25519", "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", @@ -7867,7 +7867,6 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-dapp-staking", "pallet-evm-precompile-dispatch", - "pallet-evm-precompile-dispatch-lockdrop", "pallet-evm-precompile-ed25519", "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", @@ -9982,32 +9981,6 @@ dependencies = [ "sp-runtime", ] -[[package]] -name = "pallet-evm-precompile-dispatch-lockdrop" -version = "0.1.0" -dependencies = [ - "astar-primitives", - "ethers", - "fp-evm", - "frame-support", - "frame-system", - "hex-literal", - "libsecp256k1", - "log", - "pallet-balances", - "pallet-evm", - "pallet-evm-precompile-dispatch", - "pallet-timestamp", - "pallet-utility", - "parity-scale-codec", - "precompile-utils", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-evm-precompile-ed25519" version = "2.0.0-dev" @@ -16121,7 +16094,6 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-dapp-staking", "pallet-evm-precompile-dispatch", - "pallet-evm-precompile-dispatch-lockdrop", "pallet-evm-precompile-ed25519", "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", @@ -16240,7 +16212,6 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-dapp-staking", "pallet-evm-precompile-dispatch", - "pallet-evm-precompile-dispatch-lockdrop", "pallet-evm-precompile-ed25519", "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", diff --git a/Cargo.toml b/Cargo.toml index 8eb6d54a1..89fd7c29a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -341,7 +341,6 @@ pallet-evm-precompile-substrate-ecdsa = { path = "./precompiles/substrate-ecdsa" pallet-evm-precompile-xcm = { path = "./precompiles/xcm", default-features = false } pallet-evm-precompile-dapp-staking = { path = "./precompiles/dapp-staking", default-features = false } pallet-evm-precompile-unified-accounts = { path = "./precompiles/unified-accounts", default-features = false } -pallet-evm-precompile-dispatch-lockdrop = { path = "./precompiles/dispatch-lockdrop", default-features = false } pallet-chain-extension-assets = { path = "./chain-extensions/pallet-assets", default-features = false } pallet-chain-extension-unified-accounts = { path = "./chain-extensions/unified-accounts", default-features = false } diff --git a/precompiles/dispatch-lockdrop/Cargo.toml b/precompiles/dispatch-lockdrop/Cargo.toml deleted file mode 100644 index be38f2317..000000000 --- a/precompiles/dispatch-lockdrop/Cargo.toml +++ /dev/null @@ -1,63 +0,0 @@ -[package] -name = "pallet-evm-precompile-dispatch-lockdrop" -description = "Evm Precompile to dispatch calls for lockdrop accounts" -version = "0.1.0" -authors.workspace = true -edition.workspace = true -homepage.workspace = true -repository.workspace = true - -[lints] -workspace = true - -[dependencies] -fp-evm = { workspace = true } -frame-support = { workspace = true } -frame-system = { workspace = true } -hex-literal = { workspace = true } -libsecp256k1 = { workspace = true, features = ["hmac", "static-context"] } -log = { workspace = true } -pallet-evm = { workspace = true } -pallet-evm-precompile-dispatch = { workspace = true } -parity-scale-codec = { workspace = true } -precompile-utils = { workspace = true } -sp-core = { workspace = true } -sp-io = { workspace = true } -sp-runtime = { workspace = true } -sp-std = { workspace = true } - -[dev-dependencies] -astar-primitives = { workspace = true } -ethers = { workspace = true } -frame-system = { workspace = true } -pallet-balances = { workspace = true } -pallet-timestamp = { workspace = true } -pallet-utility = { workspace = true } -precompile-utils = { workspace = true, features = ["testing"] } -scale-info = { workspace = true } -sp-core = { workspace = true } -sp-io = { workspace = true } -sp-runtime = { workspace = true } -sp-std = { workspace = true } - -[features] -default = ["std"] -std = [ - "log/std", - "libsecp256k1/std", - "parity-scale-codec/std", - "scale-info/std", - "sp-std/std", - "sp-core/std", - "sp-io/std", - "sp-runtime/std", - "frame-support/std", - "frame-system/std", - "astar-primitives/std", - "precompile-utils/std", - "pallet-evm/std", - "pallet-balances/std", - "pallet-timestamp/std", - "fp-evm/std", - "pallet-evm-precompile-dispatch/std", -] diff --git a/precompiles/dispatch-lockdrop/DispatchLockdrop.sol b/precompiles/dispatch-lockdrop/DispatchLockdrop.sol deleted file mode 100644 index f464b5c3d..000000000 --- a/precompiles/dispatch-lockdrop/DispatchLockdrop.sol +++ /dev/null @@ -1,20 +0,0 @@ -pragma solidity ^0.8.0; - -/** - * @title Dispatch Lockdrop calls interface. - */ - -/// Interface to dispatch lockdrop calls precompiled contract -/// Pre-deployed at the address 0x0000000000000000000000000000000000005007 -interface RescueLockdrop { - /** - * @dev Dispatch lockdrop call - * @param call - SCALE-encoded call arguments - * @param pubkey - full ECDSA pubkey 64 bytes - * @return boolean confirming whether the call got successfully dispatched - */ - function dispatch_lockdrop_call( - bytes calldata call, - bytes calldata pubkey - ) external returns (bool); -} \ No newline at end of file diff --git a/precompiles/dispatch-lockdrop/src/lib.rs b/precompiles/dispatch-lockdrop/src/lib.rs deleted file mode 100644 index 5708a509d..000000000 --- a/precompiles/dispatch-lockdrop/src/lib.rs +++ /dev/null @@ -1,133 +0,0 @@ -// This file is part of Astar. - -// Copyright (C) Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later - -// Astar is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Astar is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Astar. If not, see . - -#![cfg_attr(not(feature = "std"), no_std)] - -extern crate alloc; - -use core::marker::PhantomData; -use fp_evm::PrecompileHandle; -use frame_support::pallet_prelude::IsType; -use frame_support::traits::Get; -use frame_support::weights::Weight; -use frame_support::{ - dispatch::{GetDispatchInfo, PostDispatchInfo}, - traits::ConstU32, -}; -use frame_system::Config; -use pallet_evm::GasWeightMapping; -use pallet_evm_precompile_dispatch::DispatchValidateT; -use parity_scale_codec::DecodeLimit; -use precompile_utils::prelude::{revert, BoundedBytes, RuntimeHelper}; -use precompile_utils::EvmResult; -use sp_core::{crypto::AccountId32, H160, H256}; -use sp_io::hashing::keccak_256; -use sp_runtime::traits::Dispatchable; -use sp_std::vec::Vec; - -#[cfg(test)] -mod mock; -#[cfg(test)] -mod tests; - -pub const LOG_TARGET: &str = "precompile::dispatch-lockdrop"; - -// ECDSA PublicKey -type ECDSAPublic = ConstU32<64>; - -// `DecodeLimit` specifies the max depth a call can use when decoding, as unbounded depth -// can be used to overflow the stack. -// Default value is 8, which is the same as in XCM call decoding. -pub struct DispatchLockdrop>( - PhantomData<(Runtime, DispatchValidator, DecodeLimit)>, -); - -type CallLengthLimit = ConstU32<2048>; - -#[precompile_utils::precompile] -impl - DispatchLockdrop -where - Runtime: pallet_evm::Config, - ::RuntimeOrigin: From>, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, - ::AccountId: IsType, - ::AccountId: From<[u8; 32]>, - DispatchValidator: - DispatchValidateT<::AccountId, ::RuntimeCall>, - DecodeLimit: Get, -{ - #[precompile::public("dispatch_lockdrop_call(bytes,bytes)")] - fn dispatch_lockdrop_call( - handle: &mut impl PrecompileHandle, - call: BoundedBytes, - pubkey: BoundedBytes, - ) -> EvmResult { - log::trace!( - target: LOG_TARGET, - "raw arguments: call: {call:?}, pubkey: {pubkey:?}", - ); - - let caller: H160 = handle.context().caller; - let input: Vec = call.into(); - - // Record a fixed amount of weight to ensure there is no free execution - handle.record_cost(Runtime::GasWeightMapping::weight_to_gas( - Weight::from_parts(1_000_000_000u64, 0), - ))?; - - // Ensure that the caller matches the public key - if caller != Self::get_evm_address_from_pubkey(pubkey.as_bytes()) { - let message: &str = "caller does not match the public key"; - log::trace!(target: LOG_TARGET, "{message}"); - return Err(revert(message)); - } - - // Derive the account id from the public key - let origin = Self::get_account_id_from_pubkey(pubkey.as_bytes()) - .ok_or(revert("could not derive AccountId from pubkey"))?; - - // Decode the call - let call = Runtime::RuntimeCall::decode_with_depth_limit(DecodeLimit::get(), &mut &*input) - .map_err(|_| revert("could not decode call"))?; - - // Validate the call - ensure that the call is allowed in filter - DispatchValidator::validate_before_dispatch(&origin, &call) - .map_or_else(|| Ok(()), |_| Err(revert("invalid Call")))?; - - // Dispatch the call and handle the cost - RuntimeHelper::::try_dispatch::( - handle, - Some(origin).into(), - call, - 0, - )?; - - Ok(true) - } - - fn get_account_id_from_pubkey(pubkey: &[u8]) -> Option<::AccountId> { - libsecp256k1::PublicKey::parse_slice(pubkey, None) - .map(|k| sp_io::hashing::blake2_256(k.serialize_compressed().as_ref()).into()) - .ok() - } - - fn get_evm_address_from_pubkey(pubkey: &[u8]) -> H160 { - H160::from(H256::from_slice(&keccak_256(pubkey))) - } -} diff --git a/precompiles/dispatch-lockdrop/src/mock.rs b/precompiles/dispatch-lockdrop/src/mock.rs deleted file mode 100644 index df51c0423..000000000 --- a/precompiles/dispatch-lockdrop/src/mock.rs +++ /dev/null @@ -1,213 +0,0 @@ -// This file is part of Astar. - -// Copyright (C) Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later - -// Astar is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Astar is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Astar. If not, see . - -use super::*; -use std::marker::PhantomData; - -use fp_evm::{IsPrecompileResult, Precompile}; -use frame_support::{ - construct_runtime, derive_impl, parameter_types, traits::ConstU64, weights::Weight, -}; -pub use pallet_evm::{ - AddressMapping, EnsureAddressNever, EnsureAddressRoot, PrecompileResult, PrecompileSet, -}; -use sp_core::{keccak_256, H160}; -use sp_runtime::{ - traits::{ConstU32, IdentityLookup}, - AccountId32, -}; - -use frame_support::traits::Contains; - -use astar_primitives::precompiles::DispatchFilterValidate; -pub type AccountId = AccountId32; -pub type Balance = u128; -pub type Block = frame_system::mocking::MockBlock; -pub const PRECOMPILE_ADDRESS: H160 = H160::repeat_byte(0x7B); - -pub const ONE: u128 = 1_000_000_000_000_000_000; -pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]); -pub const DUMMY: AccountId32 = AccountId32::new([2u8; 32]); - -pub fn alice_secret() -> libsecp256k1::SecretKey { - libsecp256k1::SecretKey::parse(&keccak_256(b"Alice")).unwrap() -} - -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, 0)); -} - -#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] -impl frame_system::Config for TestRuntime { - type Block = Block; - type AccountId = AccountId32; - type Lookup = IdentityLookup; - type AccountData = pallet_balances::AccountData; -} - -pub struct WhitelistedCalls; - -impl Contains for WhitelistedCalls { - fn contains(call: &RuntimeCall) -> bool { - match call { - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::System(frame_system::Call::remark { .. }) => true, - RuntimeCall::Utility(_) => true, - _ => false, - } - } -} - -#[derive(Debug, Clone, Copy)] -pub struct TestPrecompileSet(PhantomData); - -impl PrecompileSet for TestPrecompileSet -where - R: pallet_evm::Config, - DispatchLockdrop>: Precompile, -{ - fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { - match handle.code_address() { - a if a == PRECOMPILE_ADDRESS => Some(DispatchLockdrop::< - R, - DispatchFilterValidate, - >::execute(handle)), - _ => None, - } - } - - fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: address == PRECOMPILE_ADDRESS, - extra_cost: 0, - } - } -} - -parameter_types! { - pub const ExistentialDeposit: u128 = 1; -} - -#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] -impl pallet_balances::Config for TestRuntime { - type Balance = Balance; - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; -} - -parameter_types! { - pub const MinimumPeriod: u64 = 5; -} - -#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)] -impl pallet_timestamp::Config for TestRuntime { - type MinimumPeriod = MinimumPeriod; -} - -parameter_types! { - pub const PrecompilesValue: TestPrecompileSet = - TestPrecompileSet(PhantomData); - pub WeightPerGas: Weight = Weight::from_parts(1, 0); -} - -pub type PrecompileCall = DispatchLockdropCall< - TestRuntime, - DispatchFilterValidate<::RuntimeCall, WhitelistedCalls>, - ConstU32<8>, ->; - -pub struct AddressMapper; -impl AddressMapping for AddressMapper { - fn into_account_id(account: H160) -> astar_primitives::AccountId { - let mut account_id = [0u8; 32]; - account_id[0..20].clone_from_slice(&account.as_bytes()); - - account_id - .try_into() - .expect("H160 is 20 bytes long so it must fit into 32 bytes; QED") - } -} - -impl pallet_evm::Config for TestRuntime { - type FeeCalculator = (); - type GasWeightMapping = pallet_evm::FixedGasWeightMapping; - type WeightPerGas = WeightPerGas; - type CallOrigin = EnsureAddressRoot; - type WithdrawOrigin = EnsureAddressNever; - type AddressMapping = AddressMapper; - type Currency = Balances; - type Runner = pallet_evm::runner::stack::Runner; - type PrecompilesType = TestPrecompileSet; - type PrecompilesValue = PrecompilesValue; - type Timestamp = Timestamp; - type ChainId = ChainId; - type OnChargeTransaction = (); - type BlockGasLimit = (); - type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping; - type FindAuthor = (); - type OnCreate = (); - type WeightInfo = (); - type GasLimitPovSizeRatio = ConstU64<4>; - type AccountProvider = pallet_evm::FrameSystemAccountProvider; - type GasLimitStorageGrowthRatio = ConstU64<0>; - type CreateOriginFilter = (); - type CreateInnerOriginFilter = (); -} - -impl pallet_utility::Config for TestRuntime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - type PalletsOrigin = OriginCaller; - type WeightInfo = (); -} - -parameter_types! { - // 2 storage items with value size 20 and 32 - pub const AccountMappingStorageFee: u128 = 0; - pub ChainId: u64 = 1024; -} - -// Configure a mock runtime to test the pallet. -construct_runtime!( - pub enum TestRuntime - { - System: frame_system, - Evm: pallet_evm, - Balances : pallet_balances, - Timestamp: pallet_timestamp, - Utility: pallet_utility, - } -); - -#[derive(Default)] -pub(crate) struct ExtBuilder; - -impl ExtBuilder { - pub(crate) fn build(self) -> sp_io::TestExternalities { - use sp_runtime::BuildStorage; - let t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } -} diff --git a/precompiles/dispatch-lockdrop/src/tests.rs b/precompiles/dispatch-lockdrop/src/tests.rs deleted file mode 100644 index 78fb95fb6..000000000 --- a/precompiles/dispatch-lockdrop/src/tests.rs +++ /dev/null @@ -1,372 +0,0 @@ -// This file is part of Astar. - -// Copyright (C) Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later - -// Astar is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Astar is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Astar. If not, see . - -use core::str::from_utf8; -use frame_support::dispatch::GetDispatchInfo; -use frame_support::traits::Currency; -use libsecp256k1::PublicKeyFormat; -use sp_core::crypto::{AccountId32, Ss58Codec}; - -use crate::mock::*; - -use astar_primitives::evm::EvmAddress; -use hex_literal::hex; -use parity_scale_codec::Encode; -use precompile_utils::testing::*; -use sp_core::{ecdsa, Pair}; - -fn precompiles() -> TestPrecompileSet { - PrecompilesValue::get() -} - -#[test] -fn dispatch_calls_on_behalf_of_lockdrop_works() { - ExtBuilder.build().execute_with(|| { - // Transfer balance to Alice - let call = RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { - dest: ALICE, - value: 15 * ONE, - }); - // Sanity check - Alice holds no Balance - assert_eq!(Balances::free_balance(ALICE), 0); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_returns(true); - - // Get Balance of ALICE in pallet balances - assert_eq!(Balances::free_balance(ALICE), 15 * ONE); - }); -} - -#[test] -fn proper_gas_is_charged() { - ExtBuilder.build().execute_with(|| { - let call = RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { - dest: ALICE, - value: 15 * ONE, - }); - - // Dispatch a call and ensure gas is charged properly - // Expected gas is the constant weight of 1_000_000_000 and the weight of the call - // In mock one unit of ref_time us charged 1 - let expected_gas = 1_000_000_000u64 + call.get_dispatch_info().total_weight().ref_time(); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_cost(expected_gas) - .execute_returns(true); - }); -} - -#[test] -fn pubkey_does_not_match_caller_address() { - ExtBuilder.build().execute_with(|| { - // Transfer balance to Alice - let call = RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { - dest: ALICE, - value: 15 * ONE, - }); - // Sanity check - Alice holds no Balance - assert_eq!(Balances::free_balance(ALICE), 0); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Dummy AccountId to sign the EIP712 payload with - let account_id = DUMMY; - // Fund this dummy account - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Create a dummy pubkey - let pubkey = [10u8; 64]; - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_reverts(|output| output == b"caller does not match the public key"); - - // Get Balance of ALICE in pallet balances and ensure it has not received any funds - assert_eq!(Balances::free_balance(ALICE), 0); - }); -} - -#[test] -fn pubkey_derive_to_proper_ss58() { - ExtBuilder.build().execute_with(|| { - // Transfer balance to Alice - let call = RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { - dest: ALICE, - value: 15 * ONE, - }); - // Sanity check - Alice holds no Balance - assert_eq!(Balances::free_balance(ALICE), 0); - - // The seed "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - // should resolve to the SS58 address "5EGynCAEvv8NLeHx8vDMvb8hTcEcMYUMWCDQEEncNEfNWB2W" - // If we fund this account, it will be able to dispatch the Transfer call - let pair = ecdsa::Pair::from_seed(&hex!( - "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - )); - let pubkey = crate::tests::public_key_full_from_compressed(pair.public().as_ref()); - let alice_eth = EvmAddress::from_slice(&sp_io::hashing::keccak_256(&pubkey)[12..]); - let account_id = - AccountId::from_ss58check("5EGynCAEvv8NLeHx8vDMvb8hTcEcMYUMWCDQEEncNEfNWB2W").unwrap(); - // Fund this account - let _ = Balances::deposit_creating(&account_id, ONE * 20); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_returns(true); - - // Assert that the call (Transfer) was successful - assert_eq!(Balances::free_balance(ALICE), 15 * ONE); - }); -} - -#[test] -fn decode_limit_too_high() { - ExtBuilder.build().execute_with(|| { - let mut nested_call = - RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() }); - - // More than 8 depth - for _ in 0..9 { - nested_call = RuntimeCall::Utility(pallet_utility::Call::as_derivative { - index: 0, - call: Box::new(nested_call), - }); - } - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: nested_call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_reverts(|output| from_utf8(output).unwrap().contains("could not decode call")); - }); -} - -#[test] -fn decode_limit_bounded() { - ExtBuilder.build().execute_with(|| { - let calls: Vec<_> = (0..681) - .map(|_| RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() })) - .collect(); - let call = RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }); - let out_of_bounds_calls: Vec<_> = (0..682) - .map(|_| RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() })) - .collect(); - let out_of_bounds_call = RuntimeCall::Utility(pallet_utility::Call::batch_all { - calls: out_of_bounds_calls, - }); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_returns(true); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: out_of_bounds_call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_reverts(|output| output == b"call: Value is too large for length"); - }); -} - -#[test] -fn decode_limit_ok() { - ExtBuilder.build().execute_with(|| { - let mut nested_call = - RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() }); - - for _ in 0..8 { - nested_call = RuntimeCall::Utility(pallet_utility::Call::as_derivative { - index: 0, - call: Box::new(nested_call), - }); - } - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: nested_call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_returns(true); - }); -} - -#[test] -fn only_whitelisted_calls_can_be_dispatched() { - ExtBuilder.build().execute_with(|| { - // Transfer balance to Alice - let call = RuntimeCall::System(frame_system::Call::remark_with_event { - remark: b"Hello World".to_vec(), - }); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = crate::tests::account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_reverts(|output| output == b"invalid Call"); - }); -} - -fn account_id(secret: &libsecp256k1::SecretKey) -> AccountId32 { - sp_io::hashing::blake2_256( - ecdsa::Public::from_full( - &libsecp256k1::PublicKey::from_secret_key(secret).serialize()[1..65], - ) - .unwrap() - .as_ref(), - ) - .into() -} - -fn eth_address(secret: &libsecp256k1::SecretKey) -> EvmAddress { - EvmAddress::from_slice( - &sp_io::hashing::keccak_256( - &libsecp256k1::PublicKey::from_secret_key(secret).serialize()[1..65], - )[12..], - ) -} - -fn public_key_full_from_compressed(pubkey: &[u8]) -> [u8; 64] { - libsecp256k1::PublicKey::parse_slice(pubkey, Some(PublicKeyFormat::Compressed)) - .unwrap() - .serialize()[1..65] - .try_into() - .unwrap() -} - -fn public_key_full(secret: &libsecp256k1::SecretKey) -> [u8; 64] { - libsecp256k1::PublicKey::from_secret_key(secret).serialize()[1..65] - .try_into() - .unwrap() -} diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 2735d3843..7f0808cca 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -20,6 +20,7 @@ scale-info = { workspace = true } ethereum = { workspace = true, features = ["with-scale"] } ethereum-types = { workspace = true } fp-evm = { workspace = true } +precompile-utils = { workspace = true, default-features = false } # Substrate dependencies frame-support = { workspace = true } @@ -70,6 +71,7 @@ std = [ "frame-system/std", "pallet-membership/std", "pallet-collective/std", + "precompile-utils/std", "sp-std/std", "sp-runtime/std", "sp-core/std", diff --git a/primitives/src/precompiles.rs b/primitives/src/precompiles.rs index 84184399a..04a45242e 100644 --- a/primitives/src/precompiles.rs +++ b/primitives/src/precompiles.rs @@ -18,12 +18,13 @@ use core::marker::PhantomData; -use fp_evm::{ExitError, PrecompileFailure}; +use fp_evm::{ExitError, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult}; use frame_support::{ dispatch::{DispatchClass, GetDispatchInfo, Pays}, traits::Contains, }; use pallet_evm_precompile_dispatch::DispatchValidateT; +use precompile_utils::prelude::*; /// Struct that allows only calls based on `Filter` to pass through. pub struct DispatchFilterValidate>( @@ -53,3 +54,12 @@ impl> } } } + +/// A minimal precompile that always reverts +pub struct DisabledPrecompile(PhantomData); + +impl Precompile for DisabledPrecompile { + fn execute(_handle: &mut impl PrecompileHandle) -> PrecompileResult { + Err(revert("This precompile has been disabled")) + } +} diff --git a/runtime/astar/Cargo.toml b/runtime/astar/Cargo.toml index 5ab92fd2b..6e32de790 100644 --- a/runtime/astar/Cargo.toml +++ b/runtime/astar/Cargo.toml @@ -126,7 +126,6 @@ pallet-collective-proxy = { workspace = true } pallet-dapp-staking = { workspace = true } pallet-evm-precompile-assets-erc20 = { workspace = true } pallet-evm-precompile-dapp-staking = { workspace = true } -pallet-evm-precompile-dispatch-lockdrop = { workspace = true } pallet-evm-precompile-sr25519 = { workspace = true } pallet-evm-precompile-substrate-ecdsa = { workspace = true } pallet-evm-precompile-xcm = { workspace = true } @@ -200,7 +199,6 @@ std = [ "pallet-evm-precompile-blake2/std", "pallet-evm-precompile-bn128/std", "pallet-evm-precompile-dapp-staking/std", - "pallet-evm-precompile-dispatch-lockdrop/std", "pallet-evm-precompile-dispatch/std", "pallet-evm-precompile-ed25519/std", "pallet-evm-precompile-modexp/std", diff --git a/runtime/astar/src/precompiles.rs b/runtime/astar/src/precompiles.rs index 25f1ad0c3..c9e988ff0 100644 --- a/runtime/astar/src/precompiles.rs +++ b/runtime/astar/src/precompiles.rs @@ -19,14 +19,13 @@ //! The Astar Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm. use crate::{Runtime, RuntimeCall}; -use astar_primitives::precompiles::DispatchFilterValidate; +use astar_primitives::precompiles::{DisabledPrecompile, DispatchFilterValidate}; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dapp_staking::DappStakingV3Precompile; use pallet_evm_precompile_dispatch::Dispatch; -use pallet_evm_precompile_dispatch_lockdrop::DispatchLockdrop; use pallet_evm_precompile_ed25519::Ed25519Verify; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; @@ -35,7 +34,6 @@ use pallet_evm_precompile_sr25519::Sr25519Precompile; use pallet_evm_precompile_substrate_ecdsa::SubstrateEcdsaPrecompile; use pallet_evm_precompile_xcm::XcmPrecompile; use precompile_utils::precompile_set::*; -use sp_core::ConstU32; use sp_std::fmt::Debug; /// The asset precompile address prefix. Addresses that match against this prefix will be routed @@ -73,26 +71,10 @@ impl Contains for WhitelistedCalls { } } -/// Filter that only allows whitelisted runtime call to pass through dispatch-lockdrop precompile -pub struct WhitelistedLockdropCalls; - -impl Contains for WhitelistedLockdropCalls { - fn contains(t: &RuntimeCall) -> bool { - match t { - RuntimeCall::Utility(pallet_utility::Call::batch { calls }) - | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls - .iter() - .all(|call| WhitelistedLockdropCalls::contains(call)), - RuntimeCall::DappStaking(pallet_dapp_staking::Call::unbond_and_unstake { .. }) => true, - RuntimeCall::DappStaking(pallet_dapp_staking::Call::withdraw_unbonded { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) => true, - RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) => true, - _ => false, - } - } -} +// Type aliases to avoid name collision in the precompile_name_from_address macro +// when the same deprecated precompile is used at multiple addresses +type DisabledXvmPrecompile = DisabledPrecompile; +type DisabledLockdropPrecompile = DisabledPrecompile; /// The PrecompileSet installed in the Astar runtime. #[precompile_utils::precompile_name_from_address] @@ -148,18 +130,9 @@ pub type AstarPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 and 20486 to make sure all network have consistent - // precompiles address - PrecompileAt< - AddressU64<20487>, - DispatchLockdrop< - R, - DispatchFilterValidate, - ConstU32<8>, - >, - // Not callable from smart contract nor precompiled, only EOA accounts - (), - >, + PrecompileAt, DisabledXvmPrecompile, ()>, + // Skipping 20486 to make sure all network have consistent precompiles address + PrecompileAt, DisabledLockdropPrecompile, ()>, ); pub type AstarPrecompiles = PrecompileSetBuilder< @@ -167,8 +140,8 @@ pub type AstarPrecompiles = PrecompileSetBuilder< ( // Skip precompiles if out of range. PrecompilesInRangeInclusive< - // We take range as last precompile index, UPDATE this once new prcompile is added - (AddressU64<1>, AddressU64<20487>), + // We take range as last precompile index, UPDATE this once new precompile is added/removed + (AddressU64<1>, AddressU64<20484>), AstarPrecompilesSetAt, >, // Prefixed precompile sets (XC20) diff --git a/runtime/local/Cargo.toml b/runtime/local/Cargo.toml index 6a57012af..83ba1dfbd 100644 --- a/runtime/local/Cargo.toml +++ b/runtime/local/Cargo.toml @@ -83,7 +83,6 @@ pallet-dapp-staking = { workspace = true } pallet-dynamic-evm-base-fee = { workspace = true } pallet-evm-precompile-assets-erc20 = { workspace = true } pallet-evm-precompile-dapp-staking = { workspace = true } -pallet-evm-precompile-dispatch-lockdrop = { workspace = true } pallet-evm-precompile-sr25519 = { workspace = true } pallet-evm-precompile-substrate-ecdsa = { workspace = true } pallet-evm-precompile-unified-accounts = { workspace = true } @@ -152,7 +151,6 @@ std = [ "pallet-evm-precompile-sr25519/std", "pallet-evm-precompile-substrate-ecdsa/std", "pallet-evm-precompile-unified-accounts/std", - "pallet-evm-precompile-dispatch-lockdrop/std", "pallet-grandpa/std", "pallet-insecure-randomness-collective-flip/std", "pallet-preimage/std", diff --git a/runtime/local/src/precompiles.rs b/runtime/local/src/precompiles.rs index d9b522d27..68cbd1493 100644 --- a/runtime/local/src/precompiles.rs +++ b/runtime/local/src/precompiles.rs @@ -19,15 +19,13 @@ //! The Local Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm. use crate::{Runtime, RuntimeCall, UnifiedAccounts}; -use astar_primitives::precompiles::DispatchFilterValidate; -use frame_support::traits::ConstU32; +use astar_primitives::precompiles::{DisabledPrecompile, DispatchFilterValidate}; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dapp_staking::DappStakingV3Precompile; use pallet_evm_precompile_dispatch::Dispatch; -use pallet_evm_precompile_dispatch_lockdrop::DispatchLockdrop; use pallet_evm_precompile_ed25519::Ed25519Verify; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; @@ -70,26 +68,10 @@ impl Contains for WhitelistedCalls { } } -/// Filter that only allows whitelisted runtime call to pass through dispatch-lockdrop precompile -pub struct WhitelistedLockdropCalls; - -impl Contains for WhitelistedLockdropCalls { - fn contains(t: &RuntimeCall) -> bool { - match t { - RuntimeCall::Utility(pallet_utility::Call::batch { calls }) - | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls - .iter() - .all(|call| WhitelistedLockdropCalls::contains(call)), - RuntimeCall::DappStaking(pallet_dapp_staking::Call::unbond_and_unstake { .. }) => true, - RuntimeCall::DappStaking(pallet_dapp_staking::Call::withdraw_unbonded { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) => true, - RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) => true, - _ => false, - } - } -} +// Type aliases to avoid name collision in the precompile_name_from_address macro +// when the same deprecated precompile is used at multiple addresses +type DisabledXvmPrecompile = DisabledPrecompile; +type DisabledLockdropPrecompile = DisabledPrecompile; /// The PrecompileSet installed in the Local runtime. #[precompile_utils::precompile_name_from_address] @@ -136,22 +118,13 @@ pub type LocalPrecompilesSetAt = ( (CallableByContract, CallableByPrecompile), >, // skip 20484 for xcm precompile - // Skipping 20485 to make sure all network have consistent precompiles address + PrecompileAt, DisabledXvmPrecompile, ()>, PrecompileAt< AddressU64<20486>, UnifiedAccountsPrecompile, (CallableByContract, CallableByPrecompile), >, - PrecompileAt< - AddressU64<20487>, - DispatchLockdrop< - R, - DispatchFilterValidate, - ConstU32<8>, - >, - // Not callable from smart contract nor precompiled, only EOA accounts - (), - >, + PrecompileAt, DisabledLockdropPrecompile, ()>, ); pub type LocalPrecompiles = PrecompileSetBuilder< @@ -159,8 +132,8 @@ pub type LocalPrecompiles = PrecompileSetBuilder< ( // Skip precompiles if out of range. PrecompilesInRangeInclusive< - // We take range as last precompile index, UPDATE this once new precompile is added - (AddressU64<1>, AddressU64<20487>), + // We take range as last precompile index, UPDATE this once new precompile is added/removed + (AddressU64<1>, AddressU64<20486>), LocalPrecompilesSetAt, >, // Prefixed precompile sets (XC20) diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index 515b91547..c777ddd7d 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -121,7 +121,6 @@ pallet-dynamic-evm-base-fee = { workspace = true } pallet-ethereum-checked = { workspace = true } pallet-evm-precompile-assets-erc20 = { workspace = true } pallet-evm-precompile-dapp-staking = { workspace = true } -pallet-evm-precompile-dispatch-lockdrop = { workspace = true } pallet-evm-precompile-sr25519 = { workspace = true } pallet-evm-precompile-substrate-ecdsa = { workspace = true } pallet-evm-precompile-unified-accounts = { workspace = true } @@ -208,7 +207,6 @@ std = [ "pallet-evm-precompile-blake2/std", "pallet-evm-precompile-bn128/std", "pallet-evm-precompile-dapp-staking/std", - "pallet-evm-precompile-dispatch-lockdrop/std", "pallet-evm-precompile-dispatch/std", "pallet-evm-precompile-ed25519/std", "pallet-evm-precompile-modexp/std", diff --git a/runtime/shibuya/src/precompiles.rs b/runtime/shibuya/src/precompiles.rs index 5490b7ba5..eafc04b7d 100644 --- a/runtime/shibuya/src/precompiles.rs +++ b/runtime/shibuya/src/precompiles.rs @@ -19,15 +19,13 @@ //! The Astar Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm. use crate::{Runtime, RuntimeCall, UnifiedAccounts}; -use astar_primitives::precompiles::DispatchFilterValidate; -use frame_support::traits::ConstU32; +use astar_primitives::precompiles::{DisabledPrecompile, DispatchFilterValidate}; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dapp_staking::DappStakingV3Precompile; use pallet_evm_precompile_dispatch::Dispatch; -use pallet_evm_precompile_dispatch_lockdrop::DispatchLockdrop; use pallet_evm_precompile_ed25519::Ed25519Verify; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; @@ -74,26 +72,10 @@ impl Contains for WhitelistedCalls { } } -/// Filter that only allows whitelisted runtime call to pass through dispatch-lockdrop precompile -pub struct WhitelistedLockdropCalls; - -impl Contains for WhitelistedLockdropCalls { - fn contains(t: &RuntimeCall) -> bool { - match t { - RuntimeCall::Utility(pallet_utility::Call::batch { calls }) - | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls - .iter() - .all(|call| WhitelistedLockdropCalls::contains(call)), - RuntimeCall::DappStaking(pallet_dapp_staking::Call::unbond_and_unstake { .. }) => true, - RuntimeCall::DappStaking(pallet_dapp_staking::Call::withdraw_unbonded { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) => true, - RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) => true, - _ => false, - } - } -} +// Type aliases to avoid name collision in the precompile_name_from_address macro +// when the same deprecated precompile is used at multiple addresses +type DisabledXvmPrecompile = DisabledPrecompile; +type DisabledLockdropPrecompile = DisabledPrecompile; /// The PrecompileSet installed in the Shibuya runtime. #[precompile_utils::precompile_name_from_address] @@ -148,22 +130,13 @@ pub type ShibuyaPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 to make sure all network have consistent precompiles address + PrecompileAt, DisabledXvmPrecompile, ()>, PrecompileAt< AddressU64<20486>, UnifiedAccountsPrecompile, (CallableByContract, CallableByPrecompile), >, - PrecompileAt< - AddressU64<20487>, - DispatchLockdrop< - R, - DispatchFilterValidate, - ConstU32<8>, - >, - // Not callable from smart contract nor precompiled, only EOA accounts - (), - >, + PrecompileAt, DisabledLockdropPrecompile, ()>, ); pub type ShibuyaPrecompiles = PrecompileSetBuilder< @@ -171,8 +144,8 @@ pub type ShibuyaPrecompiles = PrecompileSetBuilder< ( // Skip precompiles if out of range. PrecompilesInRangeInclusive< - // TODO: what is the range for precompiles sets 1 - ? - (AddressU64<1>, AddressU64<40951>), + // We take range as last precompile index, UPDATE this once new precompile is added/removed + (AddressU64<1>, AddressU64<20486>), ShibuyaPrecompilesSetAt, >, // Prefixed precompile sets (XC20) diff --git a/runtime/shiden/Cargo.toml b/runtime/shiden/Cargo.toml index 05f58a9a9..0ae7a73f4 100644 --- a/runtime/shiden/Cargo.toml +++ b/runtime/shiden/Cargo.toml @@ -120,7 +120,6 @@ pallet-collator-selection = { workspace = true } pallet-dapp-staking = { workspace = true } pallet-evm-precompile-assets-erc20 = { workspace = true } pallet-evm-precompile-dapp-staking = { workspace = true } -pallet-evm-precompile-dispatch-lockdrop = { workspace = true } pallet-evm-precompile-sr25519 = { workspace = true } pallet-evm-precompile-substrate-ecdsa = { workspace = true } pallet-evm-precompile-xcm = { workspace = true } @@ -183,7 +182,6 @@ std = [ "pallet-evm-precompile-bn128/std", "sp-genesis-builder/std", "pallet-evm-precompile-dispatch/std", - "pallet-evm-precompile-dispatch-lockdrop/std", "pallet-evm-precompile-ed25519/std", "pallet-evm-precompile-modexp/std", "xcm-runtime-apis/std", diff --git a/runtime/shiden/src/precompiles.rs b/runtime/shiden/src/precompiles.rs index 85f768854..dcbbc3322 100644 --- a/runtime/shiden/src/precompiles.rs +++ b/runtime/shiden/src/precompiles.rs @@ -19,15 +19,13 @@ //! The Shiden Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm. use crate::{Runtime, RuntimeCall}; -use astar_primitives::precompiles::DispatchFilterValidate; -use frame_support::pallet_prelude::ConstU32; +use astar_primitives::precompiles::{DisabledPrecompile, DispatchFilterValidate}; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dapp_staking::DappStakingV3Precompile; use pallet_evm_precompile_dispatch::Dispatch; -use pallet_evm_precompile_dispatch_lockdrop::DispatchLockdrop; use pallet_evm_precompile_ed25519::Ed25519Verify; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; @@ -67,26 +65,11 @@ impl Contains for WhitelistedCalls { } } } -/// Filter that only allows whitelisted runtime call to pass through dispatch-lockdrop precompile -pub struct WhitelistedLockdropCalls; -impl Contains for WhitelistedLockdropCalls { - fn contains(t: &RuntimeCall) -> bool { - match t { - RuntimeCall::Utility(pallet_utility::Call::batch { calls }) - | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls - .iter() - .all(|call| WhitelistedLockdropCalls::contains(call)), - RuntimeCall::DappStaking(pallet_dapp_staking::Call::unbond_and_unstake { .. }) => true, - RuntimeCall::DappStaking(pallet_dapp_staking::Call::withdraw_unbonded { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) => true, - RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) => true, - _ => false, - } - } -} +// Type aliases to avoid name collision in the precompile_name_from_address macro +// when the same deprecated precompile is used at multiple addresses +type DisabledXvmPrecompile = DisabledPrecompile; +type DisabledLockdropPrecompile = DisabledPrecompile; /// The PrecompileSet installed in the Shiden runtime. #[precompile_utils::precompile_name_from_address] @@ -141,18 +124,9 @@ pub type ShidenPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 and 20486 to make sure all network have consistent - // precompiles address - PrecompileAt< - AddressU64<20487>, - DispatchLockdrop< - R, - DispatchFilterValidate, - ConstU32<8>, - >, - // Not callable from smart contract nor precompiled, only EOA accounts - (), - >, + PrecompileAt, DisabledXvmPrecompile, ()>, + // Skipping 20486 to make sure all network have consistent precompiles address + PrecompileAt, DisabledLockdropPrecompile, ()>, ); pub type ShidenPrecompiles = PrecompileSetBuilder< @@ -160,8 +134,8 @@ pub type ShidenPrecompiles = PrecompileSetBuilder< ( // Skip precompiles if out of range. PrecompilesInRangeInclusive< - // We take range as last precompile index, UPDATE this once new prcompile is added - (AddressU64<1>, AddressU64<20487>), + // We take range as last precompile index, UPDATE this once new precompile is added/removed + (AddressU64<1>, AddressU64<20484>), ShidenPrecompilesSetAt, >, // Prefixed precompile sets (XC20)