From 4d75a5de8062d2edd02f720416a6aa0fef591a7d Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Tue, 22 Oct 2024 16:43:17 +0800 Subject: [PATCH] Refactor precompile set --- node/src/chain_spec/crab.rs | 8 +- node/src/chain_spec/darwinia.rs | 10 +- node/src/chain_spec/koi.rs | 8 +- precompile/assets/src/mock.rs | 5 +- precompile/deposit/src/mock.rs | 4 +- precompile/staking/src/mock.rs | 4 +- precompile/state-storage/src/mock.rs | 4 +- runtime/common/src/lib.rs | 3 +- runtime/common/src/pallet_config.rs | 77 +++++++++++- runtime/crab/src/pallets/evm.rs | 123 ++++++++------------ runtime/darwinia/src/pallets/evm.rs | 129 +++++++++------------ runtime/koi/src/pallets/evm.rs | 167 ++++++++++++--------------- 12 files changed, 277 insertions(+), 265 deletions(-) diff --git a/node/src/chain_spec/crab.rs b/node/src/chain_spec/crab.rs index 552ce1b65..00098e8b6 100644 --- a/node/src/chain_spec/crab.rs +++ b/node/src/chain_spec/crab.rs @@ -78,11 +78,11 @@ pub fn development_config() -> ChainSpec { // EVM stuff. "evm": { "accounts": BTreeMap::from_iter( - >::used_addresses() - .iter() + Precompiles::set() + .into_iter() .map(|p| { ( - p.to_owned(), + H160(p), GenesisAccount { nonce: Default::default(), balance: Default::default(), @@ -236,7 +236,7 @@ pub fn genesis_config() -> ChainSpec { // EVM stuff. "evm": { "accounts": BTreeMap::from_iter( - >::used_addresses().iter().map(|p| { + Precompiles::set().iter().map(|p| { ( p, GenesisAccount { diff --git a/node/src/chain_spec/darwinia.rs b/node/src/chain_spec/darwinia.rs index 159174f51..edbda436a 100644 --- a/node/src/chain_spec/darwinia.rs +++ b/node/src/chain_spec/darwinia.rs @@ -78,11 +78,11 @@ pub fn development_config() -> ChainSpec { // EVM stuff. "evm": { "accounts": BTreeMap::from_iter( - >::used_addresses() - .iter() + Precompiles::set() + .into_iter() .map(|p| { ( - p.to_owned(), + H160(p), GenesisAccount { nonce: Default::default(), balance: Default::default(), @@ -225,9 +225,9 @@ pub fn genesis_config() -> ChainSpec { // EVM stuff. "evm": { "accounts": BTreeMap::from_iter( - >::used_addresses().iter().map(|p| { + Precompiles::set().into_iter().map(|p| { ( - p, + H160(p), GenesisAccount { nonce: Default::default(), balance: Default::default(), diff --git a/node/src/chain_spec/koi.rs b/node/src/chain_spec/koi.rs index 1241a253e..46d331d8d 100644 --- a/node/src/chain_spec/koi.rs +++ b/node/src/chain_spec/koi.rs @@ -86,11 +86,11 @@ pub fn development_config() -> ChainSpec { // EVM stuff. "evm": { "accounts": BTreeMap::from_iter( - >::used_addresses() - .iter() + Precompiles::set() + .into_iter() .map(|p| { ( - p.to_owned(), + H160(p), GenesisAccount { nonce: Default::default(), balance: Default::default(), @@ -183,7 +183,7 @@ pub fn genesis_config() -> ChainSpec { // EVM stuff. "evm": { "accounts": BTreeMap::from_iter( - >::used_addresses().iter().map(|p| { + Precompiles::set().iter().map(|p| { ( p, GenesisAccount { diff --git a/precompile/assets/src/mock.rs b/precompile/assets/src/mock.rs index e0b3fe077..94bc7b61b 100644 --- a/precompile/assets/src/mock.rs +++ b/precompile/assets/src/mock.rs @@ -91,7 +91,7 @@ where Self(Default::default()) } - pub fn used_addresses() -> [H160; 1] { + pub fn set() -> [H160; 1] { [addr_of(TEST_ID)] } } @@ -110,7 +110,7 @@ where fn is_precompile(&self, address: H160, _gas: u64) -> fp_evm::IsPrecompileResult { fp_evm::IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), + is_precompile: Self::set().contains(&address), extra_cost: 0, } } @@ -214,6 +214,7 @@ impl ExtBuilder { } } +// TODO: unify with the one in `darwinia-common-runtime`. fn addr_of(v: V) -> H160 where V: Into, diff --git a/precompile/deposit/src/mock.rs b/precompile/deposit/src/mock.rs index c1134fb1f..8c74dcf46 100644 --- a/precompile/deposit/src/mock.rs +++ b/precompile/deposit/src/mock.rs @@ -103,7 +103,7 @@ where Self(Default::default()) } - pub fn used_addresses() -> [H160; 1] { + pub fn set() -> [H160; 1] { [addr(1)] } } @@ -121,7 +121,7 @@ where fn is_precompile(&self, address: H160, _gas: u64) -> fp_evm::IsPrecompileResult { fp_evm::IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), + is_precompile: Self::set().contains(&address), extra_cost: 0, } } diff --git a/precompile/staking/src/mock.rs b/precompile/staking/src/mock.rs index 721957a12..15bd55949 100644 --- a/precompile/staking/src/mock.rs +++ b/precompile/staking/src/mock.rs @@ -102,7 +102,7 @@ where Self(Default::default()) } - pub fn used_addresses() -> [H160; 1] { + pub fn set() -> [H160; 1] { [addr(1)] } } @@ -120,7 +120,7 @@ where fn is_precompile(&self, address: H160, _gas: u64) -> fp_evm::IsPrecompileResult { fp_evm::IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), + is_precompile: Self::set().contains(&address), extra_cost: 0, } } diff --git a/precompile/state-storage/src/mock.rs b/precompile/state-storage/src/mock.rs index 63950a62b..98cf310fd 100644 --- a/precompile/state-storage/src/mock.rs +++ b/precompile/state-storage/src/mock.rs @@ -83,7 +83,7 @@ where Self(Default::default()) } - pub fn used_addresses() -> [H160; 1] { + pub fn set() -> [H160; 1] { [addr(1)] } } @@ -101,7 +101,7 @@ where fn is_precompile(&self, address: H160, _gas: u64) -> fp_evm::IsPrecompileResult { fp_evm::IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), + is_precompile: Self::set().contains(&address), extra_cost: 0, } } diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 9c8a55e01..3e3bd542c 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -263,7 +263,6 @@ impl pallet_evm::FeeCalculator for FixedGasPrice { pub struct AssetIdConverter; impl darwinia_precompile_assets::AccountToAssetId for AssetIdConverter { fn account_to_asset_id(account_id: AccountId) -> AssetId { - let addr: H160 = account_id.into(); - addr.to_low_u64_be() + H160::from(account_id).to_low_u64_be() } } diff --git a/runtime/common/src/pallet_config.rs b/runtime/common/src/pallet_config.rs index ae9f6051a..6081dc361 100644 --- a/runtime/common/src/pallet_config.rs +++ b/runtime/common/src/pallet_config.rs @@ -1,3 +1,76 @@ +pub mod precompiles { + pub const ADDR_EC_RECOVER: [u8; 20] = address_of(0x01); + pub const ADDR_SHA256: [u8; 20] = address_of(0x02); + pub const ADDR_RIPEMD160: [u8; 20] = address_of(0x03); + pub const ADDR_IDENTITY: [u8; 20] = address_of(0x04); + pub const ADDR_MODEXP: [u8; 20] = address_of(0x05); + pub const ADDR_BN128_ADD: [u8; 20] = address_of(0x06); + pub const ADDR_BN128_MUL: [u8; 20] = address_of(0x07); + pub const ADDR_BN128_PAIRING: [u8; 20] = address_of(0x08); + pub const ADDR_BLAKE2F: [u8; 20] = address_of(0x09); + pub const ADDR_BLS12381_G1_ADD: [u8; 20] = address_of(0x0c); + pub const ADDR_BLS12381_G1_MUL: [u8; 20] = address_of(0x0d); + pub const ADDR_BLS12381_G1_MULTI_EXP: [u8; 20] = address_of(0x0e); + pub const ADDR_BLS12381_G2_ADD: [u8; 20] = address_of(0x0f); + pub const ADDR_BLS12381_G2_MUL: [u8; 20] = address_of(0x10); + pub const ADDR_BLS12381_G2_MULTI_EXP: [u8; 20] = address_of(0x11); + pub const ADDR_BLS12381_PAIRING: [u8; 20] = address_of(0x12); + pub const ADDR_BLS12381_MAP_G1: [u8; 20] = address_of(0x13); + pub const ADDR_BLS12381_MAP_G2: [u8; 20] = address_of(0x14); + // [0x400, 0x800) for stable precompiles. + pub const ADDR_STATE_STORAGE: [u8; 20] = address_of(0x400); + pub const ADDR_DISPATCH: [u8; 20] = address_of(0x401); + // [0x402, 0x600) for assets precompiles. + pub const ADDR_KTON: [u8; 20] = address_of(0x402); + pub const ADDR_USDT: [u8; 20] = address_of(0x403); + pub const ADDR_PINK: [u8; 20] = address_of(0x404); + pub const ADDR_DOT: [u8; 20] = address_of(0x405); + pub const ADDR_DEPOSIT_DEPRECATED: [u8; 20] = address_of(0x600); + pub const ADDR_STAKING_DEPRECATED: [u8; 20] = address_of(0x601); + pub const ADDR_CONVICTION_VOTING: [u8; 20] = address_of(0x602); + // [0x800..) for the experimental precompiles. + pub const ADDR_EXPERIMENTAL: [u8; 20] = address_of(0x800); + + pub const fn address_of(v: u64) -> [u8; 20] { + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ((v >> 56) & 0xff) as u8, + ((v >> 48) & 0xff) as u8, + ((v >> 40) & 0xff) as u8, + ((v >> 32) & 0xff) as u8, + ((v >> 24) & 0xff) as u8, + ((v >> 16) & 0xff) as u8, + ((v >> 8) & 0xff) as u8, + (v & 0xff) as u8, + ] + } + + #[test] + fn address_of_should_work() { + // polkadot-sdk + use sp_core::H160; + + fn non_const_address_of(v: u64) -> H160 { + H160::from_low_u64_be(v) + } + + for code in 0x01..=0x800 { + assert_eq!(address_of(code), non_const_address_of(code).0); + } + } +} + // darwinia use dc_primitives::*; // polkadot-sdk @@ -18,13 +91,13 @@ pub const MAXIMUM_BLOCK_WEIGHT: frame_support::weights::Weight = cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, ); +const BLOCK_GAS_LIMIT: u64 = 20_000_000; + #[cfg(not(feature = "runtime-benchmarks"))] const EXISTENTIAL_DEPOSIT: Balance = 0; #[cfg(feature = "runtime-benchmarks")] const EXISTENTIAL_DEPOSIT: Balance = 1; -const BLOCK_GAS_LIMIT: u64 = 20_000_000; - frame_support::parameter_types! { pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; pub const MaxBalance: Balance = Balance::max_value(); diff --git a/runtime/crab/src/pallets/evm.rs b/runtime/crab/src/pallets/evm.rs index 71bb74bf1..6e5d85f99 100644 --- a/runtime/crab/src/pallets/evm.rs +++ b/runtime/crab/src/pallets/evm.rs @@ -18,6 +18,7 @@ // darwinia use crate::*; +use pallet_config::precompiles::{self, *}; // frontier use pallet_evm::{ExitError, IsPrecompileResult, Precompile}; use pallet_evm_precompile_dispatch::DispatchValidateT; @@ -25,44 +26,31 @@ use pallet_evm_precompile_dispatch::DispatchValidateT; use frame_support::dispatch::{DispatchClass, GetDispatchInfo, Pays}; frame_support::parameter_types! { - pub PrecompilesValue: CrabPrecompiles = CrabPrecompiles::<_>::new(); + pub PrecompilesValue: Precompiles = Precompiles; } -pub struct CrabPrecompiles(core::marker::PhantomData); -impl CrabPrecompiles -where - R: pallet_evm::Config, -{ - #[allow(clippy::new_without_default)] - pub fn new() -> Self { - Self(Default::default()) - } - - pub fn used_addresses() -> [H160; 16] { +pub struct Precompiles; +impl Precompiles { + pub fn set() -> [[u8; 20]; 14] { [ - addr(0x01), - addr(0x02), - addr(0x03), - addr(0x04), - addr(0x05), - addr(0x06), - addr(0x07), - addr(0x08), - addr(0x09), - addr(0x400), - addr(0x401), - addr(0x402), // For KTON asset. - addr(0x600), - addr(0x601), - addr(0x602), - addr(0x800), + ADDR_EC_RECOVER, + ADDR_SHA256, + ADDR_RIPEMD160, + ADDR_IDENTITY, + ADDR_MODEXP, + ADDR_BN128_ADD, + ADDR_BN128_MUL, + ADDR_BN128_PAIRING, + ADDR_BLAKE2F, + ADDR_STATE_STORAGE, + ADDR_DISPATCH, + ADDR_KTON, + ADDR_CONVICTION_VOTING, + ADDR_EXPERIMENTAL, ] } } -impl pallet_evm::PrecompileSet for CrabPrecompiles -where - R: pallet_evm::Config, -{ +impl pallet_evm::PrecompileSet for Precompiles { fn execute( &self, handle: &mut impl pallet_evm::PrecompileHandle, @@ -70,58 +58,53 @@ where // darwinia use darwinia_precompile_assets::AccountToAssetId; - let (code_addr, context_addr) = (handle.code_address(), handle.context().address); + let (code_addr, context_addr) = (handle.code_address().0, handle.context().address.0); + // Filter known precompile addresses except Ethereum officials - if Self::used_addresses().contains(&code_addr) - && code_addr > addr(9) + if Self::set().contains(&code_addr) + && code_addr > precompiles::address_of(9) && code_addr != context_addr { return Some(Err(precompile_utils::prelude::revert( - "cannot be called with DELEGATECALL or CALLCODE", + "Cannot be called using `DELEGATECALL` or `CALLCODE`.", ))); }; - match code_addr { - // Ethereum precompiles: - a if a == addr(0x01) => Some(pallet_evm_precompile_simple::ECRecover::execute(handle)), - a if a == addr(0x02) => Some(pallet_evm_precompile_simple::Sha256::execute(handle)), - a if a == addr(0x03) => Some(pallet_evm_precompile_simple::Ripemd160::execute(handle)), - a if a == addr(0x04) => Some(pallet_evm_precompile_simple::Identity::execute(handle)), - a if a == addr(0x05) => Some(pallet_evm_precompile_modexp::Modexp::execute(handle)), - a if a == addr(0x06) => Some(pallet_evm_precompile_bn128::Bn128Add::execute(handle)), - a if a == addr(0x07) => Some(pallet_evm_precompile_bn128::Bn128Mul::execute(handle)), - a if a == addr(0x08) => Some(pallet_evm_precompile_bn128::Bn128Pairing::execute(handle)), - a if a == addr(0x09) => Some(pallet_evm_precompile_blake2::Blake2F::execute(handle)), - // Darwinia precompiles: [0x400, 0x800) for stable precompiles. - a if a == addr(0x400) => Some( pallet_evm_precompile_simple::ECRecover::execute(handle), + ADDR_SHA256 => pallet_evm_precompile_simple::Sha256::execute(handle), + ADDR_RIPEMD160 => pallet_evm_precompile_simple::Ripemd160::execute(handle), + ADDR_IDENTITY => pallet_evm_precompile_simple::Identity::execute(handle), + ADDR_MODEXP => pallet_evm_precompile_modexp::Modexp::execute(handle), + ADDR_BN128_ADD => pallet_evm_precompile_bn128::Bn128Add::execute(handle), + ADDR_BN128_MUL => pallet_evm_precompile_bn128::Bn128Mul::execute(handle), + ADDR_BN128_PAIRING => pallet_evm_precompile_bn128::Bn128Pairing::execute(handle), + ADDR_BLAKE2F => pallet_evm_precompile_blake2::Blake2F::execute(handle), + ADDR_STATE_STORAGE => >::execute(handle)), - a if a == addr(0x401) => Some(>::execute(handle), + ADDR_DISPATCH => >::execute(handle)), - // [0x402, 0x600) reserved for assets precompiles. + >>::execute(handle), a if (0x402..0x600).contains(&AssetIdConverter::account_to_asset_id(a.into())) => - Some(>::execute( + >::execute( handle, - )), - // [0x600, 0x800) reserved for other stable precompiles. - a if a == addr(0x600) => - Some(>::execute(handle)), - a if a == addr(0x601) => - Some(>::execute(handle)), - a if a == addr(0x602) => - Some(>::execute(handle)), - // [0x800..) reserved for the experimental precompiles. - a if a == addr(0x800) => Some(Err(precompile_utils::prelude::revert("This precompile is no longer supported."))), - _ => None, - } + ), + ADDR_CONVICTION_VOTING => + >::execute(handle), + ADDR_EXPERIMENTAL | ADDR_DEPOSIT_DEPRECATED | ADDR_STAKING_DEPRECATED => + Err(precompile_utils::prelude::revert("This precompile is not supported.")), + _ => return None, + }; + + Some(output) } fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), + is_precompile: Self::set().contains(&address.0), extra_cost: 0, } } @@ -177,10 +160,6 @@ impl DispatchValidateT for DarwiniaDispatchValidator { } } -fn addr(a: u64) -> H160 { - H160::from_low_u64_be(a) -} - impl pallet_evm::Config for Runtime { type AddressMapping = pallet_evm::IdentityAddressMapping; type BlockGasLimit = pallet_config::BlockGasLimit; @@ -194,7 +173,7 @@ impl pallet_evm::Config for Runtime { type GasWeightMapping = pallet_evm::FixedGasWeightMapping; type OnChargeTransaction = pallet_evm::EVMFungibleAdapter; type OnCreate = (); - type PrecompilesType = CrabPrecompiles; + type PrecompilesType = Precompiles; type PrecompilesValue = PrecompilesValue; type Runner = pallet_evm::runner::stack::Runner; type RuntimeEvent = RuntimeEvent; diff --git a/runtime/darwinia/src/pallets/evm.rs b/runtime/darwinia/src/pallets/evm.rs index 6b3fbe642..35a00a110 100644 --- a/runtime/darwinia/src/pallets/evm.rs +++ b/runtime/darwinia/src/pallets/evm.rs @@ -18,6 +18,7 @@ // darwinia use crate::*; +use pallet_config::precompiles::{self, *}; // frontier use pallet_evm::{ExitError, IsPrecompileResult, Precompile}; use pallet_evm_precompile_dispatch::DispatchValidateT; @@ -25,46 +26,33 @@ use pallet_evm_precompile_dispatch::DispatchValidateT; use frame_support::dispatch::{DispatchClass, GetDispatchInfo, Pays}; frame_support::parameter_types! { - pub PrecompilesValue: DarwiniaPrecompiles = DarwiniaPrecompiles::<_>::new(); + pub PrecompilesValue: Precompiles = Precompiles; } -pub struct DarwiniaPrecompiles(core::marker::PhantomData); -impl DarwiniaPrecompiles -where - R: pallet_evm::Config, -{ - #[allow(clippy::new_without_default)] - pub fn new() -> Self { - Self(Default::default()) - } - - pub fn used_addresses() -> [sp_core::H160; 19] { +pub struct Precompiles; +impl Precompiles { + pub fn set() -> [[u8; 20]; 17] { [ - addr(0x01), - addr(0x02), - addr(0x03), - addr(0x04), - addr(0x05), - addr(0x06), - addr(0x07), - addr(0x08), - addr(0x09), - addr(0x400), - addr(0x401), - addr(0x402), // For KTON asset. - addr(0x403), // For Tether USDT. - addr(0x404), // For PINK. - addr(0x405), // For DOT. - addr(0x600), - addr(0x601), - addr(0x602), - addr(0x800), + ADDR_EC_RECOVER, + ADDR_SHA256, + ADDR_RIPEMD160, + ADDR_IDENTITY, + ADDR_MODEXP, + ADDR_BN128_ADD, + ADDR_BN128_MUL, + ADDR_BN128_PAIRING, + ADDR_BLAKE2F, + ADDR_STATE_STORAGE, + ADDR_DISPATCH, + ADDR_KTON, + ADDR_USDT, + ADDR_PINK, + ADDR_DOT, + ADDR_CONVICTION_VOTING, + ADDR_EXPERIMENTAL, ] } } -impl pallet_evm::PrecompileSet for DarwiniaPrecompiles -where - R: pallet_evm::Config, -{ +impl pallet_evm::PrecompileSet for Precompiles { fn execute( &self, handle: &mut impl pallet_evm::PrecompileHandle, @@ -72,58 +60,53 @@ where // darwinia use darwinia_precompile_assets::AccountToAssetId; - let (code_addr, context_addr) = (handle.code_address(), handle.context().address); + let (code_addr, context_addr) = (handle.code_address().0, handle.context().address.0); + // Filter known precompile addresses except Ethereum officials - if Self::used_addresses().contains(&code_addr) - && code_addr > addr(9) + if Self::set().contains(&code_addr) + && code_addr > precompiles::address_of(9) && code_addr != context_addr { return Some(Err(precompile_utils::prelude::revert( - "cannot be called with DELEGATECALL or CALLCODE", + "Cannot be called using `DELEGATECALL` or `CALLCODE`.", ))); }; - match code_addr { - // Ethereum precompiles: - a if a == addr(0x01) => Some(pallet_evm_precompile_simple::ECRecover::execute(handle)), - a if a == addr(0x02) => Some(pallet_evm_precompile_simple::Sha256::execute(handle)), - a if a == addr(0x03) => Some(pallet_evm_precompile_simple::Ripemd160::execute(handle)), - a if a == addr(0x04) => Some(pallet_evm_precompile_simple::Identity::execute(handle)), - a if a == addr(0x05) => Some(pallet_evm_precompile_modexp::Modexp::execute(handle)), - a if a == addr(0x06) => Some(pallet_evm_precompile_bn128::Bn128Add::execute(handle)), - a if a == addr(0x07) => Some(pallet_evm_precompile_bn128::Bn128Mul::execute(handle)), - a if a == addr(0x08) => Some(pallet_evm_precompile_bn128::Bn128Pairing::execute(handle)), - a if a == addr(0x09) => Some(pallet_evm_precompile_blake2::Blake2F::execute(handle)), - // Darwinia precompiles: [0x400, 0x800) for stable precompiles. - a if a == addr(0x400) => Some( pallet_evm_precompile_simple::ECRecover::execute(handle), + ADDR_SHA256 => pallet_evm_precompile_simple::Sha256::execute(handle), + ADDR_RIPEMD160 => pallet_evm_precompile_simple::Ripemd160::execute(handle), + ADDR_IDENTITY => pallet_evm_precompile_simple::Identity::execute(handle), + ADDR_MODEXP => pallet_evm_precompile_modexp::Modexp::execute(handle), + ADDR_BN128_ADD => pallet_evm_precompile_bn128::Bn128Add::execute(handle), + ADDR_BN128_MUL => pallet_evm_precompile_bn128::Bn128Mul::execute(handle), + ADDR_BN128_PAIRING => pallet_evm_precompile_bn128::Bn128Pairing::execute(handle), + ADDR_BLAKE2F => pallet_evm_precompile_blake2::Blake2F::execute(handle), + ADDR_STATE_STORAGE => >::execute(handle)), - a if a == addr(0x401) => Some(>::execute(handle), + ADDR_DISPATCH => >::execute(handle)), - // [0x402, 0x600) reserved for assets precompiles. + >>::execute(handle), a if (0x402..0x600).contains(&AssetIdConverter::account_to_asset_id(a.into())) => - Some(>::execute( + >::execute( handle, - )), - // [0x600, 0x800) reserved for other stable precompiles. - a if a == addr(0x600) => - Some(>::execute(handle)), - a if a == addr(0x601) => - Some(>::execute(handle)), - a if a == addr(0x602) => - Some(>::execute(handle)), - // [0x800..) reserved for the experimental precompiles. - a if a == addr(0x800) => Some(Err(precompile_utils::prelude::revert("This precompile is no longer supported."))), - _ => None, - } + ), + ADDR_CONVICTION_VOTING => + >::execute(handle), + ADDR_EXPERIMENTAL | ADDR_DEPOSIT_DEPRECATED | ADDR_STAKING_DEPRECATED => + Err(precompile_utils::prelude::revert("This precompile is not supported.")), + _ => return None, + }; + + Some(output) } fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), + is_precompile: Self::set().contains(&address.0), extra_cost: 0, } } @@ -179,10 +162,6 @@ impl DispatchValidateT for DarwiniaDispatchValidator { } } -fn addr(a: u64) -> H160 { - H160::from_low_u64_be(a) -} - impl pallet_evm::Config for Runtime { type AddressMapping = pallet_evm::IdentityAddressMapping; type BlockGasLimit = pallet_config::BlockGasLimit; @@ -196,7 +175,7 @@ impl pallet_evm::Config for Runtime { type GasWeightMapping = pallet_evm::FixedGasWeightMapping; type OnChargeTransaction = pallet_evm::EVMFungibleAdapter; type OnCreate = (); - type PrecompilesType = DarwiniaPrecompiles; + type PrecompilesType = Precompiles; type PrecompilesValue = PrecompilesValue; type Runner = pallet_evm::runner::stack::Runner; type RuntimeEvent = RuntimeEvent; diff --git a/runtime/koi/src/pallets/evm.rs b/runtime/koi/src/pallets/evm.rs index c2e4f158f..e29afb231 100644 --- a/runtime/koi/src/pallets/evm.rs +++ b/runtime/koi/src/pallets/evm.rs @@ -18,6 +18,7 @@ // darwinia use crate::*; +use pallet_config::precompiles::{self, *}; // frontier use pallet_evm::{ExitError, IsPrecompileResult, Precompile}; use pallet_evm_precompile_dispatch::DispatchValidateT; @@ -25,55 +26,42 @@ use pallet_evm_precompile_dispatch::DispatchValidateT; use frame_support::dispatch::{DispatchClass, GetDispatchInfo, Pays}; frame_support::parameter_types! { - pub PrecompilesValue: KoiPrecompiles = KoiPrecompiles::<_>::new(); + pub PrecompilesValue: Precompiles = Precompiles; } -pub struct KoiPrecompiles(core::marker::PhantomData); -impl KoiPrecompiles -where - R: pallet_evm::Config, -{ - #[allow(clippy::new_without_default)] - pub fn new() -> Self { - Self(Default::default()) - } - - pub fn used_addresses() -> [sp_core::H160; 27] { +pub struct Precompiles; +impl Precompiles { + pub const fn set() -> [[u8; 20]; 25] { [ - addr(0x01), - addr(0x02), - addr(0x03), - addr(0x04), - addr(0x05), - addr(0x06), - addr(0x07), - addr(0x08), - addr(0x09), - addr(0x0c), - addr(0x0d), - addr(0x0e), - addr(0x0f), - addr(0x10), - addr(0x11), - addr(0x12), - addr(0x13), - addr(0x14), - addr(0x400), - addr(0x401), - addr(0x402), // For KTON asset. - addr(0x403), // For Tether USDT. - addr(0x405), // For DOT. - addr(0x600), - addr(0x601), - addr(0x602), - addr(0x800), + ADDR_EC_RECOVER, + ADDR_SHA256, + ADDR_RIPEMD160, + ADDR_IDENTITY, + ADDR_MODEXP, + ADDR_BN128_ADD, + ADDR_BN128_MUL, + ADDR_BN128_PAIRING, + ADDR_BLAKE2F, + ADDR_BLS12381_G1_ADD, + ADDR_BLS12381_G1_MUL, + ADDR_BLS12381_G1_MULTI_EXP, + ADDR_BLS12381_G2_ADD, + ADDR_BLS12381_G2_MUL, + ADDR_BLS12381_G2_MULTI_EXP, + ADDR_BLS12381_PAIRING, + ADDR_BLS12381_MAP_G1, + ADDR_BLS12381_MAP_G2, + ADDR_STATE_STORAGE, + ADDR_DISPATCH, + ADDR_KTON, + ADDR_USDT, + ADDR_DOT, + ADDR_CONVICTION_VOTING, + ADDR_EXPERIMENTAL, ] } } -impl pallet_evm::PrecompileSet for KoiPrecompiles -where - R: pallet_evm::Config, -{ +impl pallet_evm::PrecompileSet for Precompiles { fn execute( &self, handle: &mut impl pallet_evm::PrecompileHandle, @@ -81,67 +69,64 @@ where // darwinia use darwinia_precompile_assets::AccountToAssetId; - let (code_addr, context_addr) = (handle.code_address(), handle.context().address); - // Filter known precompile addresses except Ethereum officials - if Self::used_addresses().contains(&code_addr) - && code_addr > addr(9) + let (code_addr, context_addr) = (handle.code_address().0, handle.context().address.0); + + // Filter known precompile addresses except Ethereum officials. + if Self::set().contains(&code_addr) + && code_addr > precompiles::address_of(9) && code_addr != context_addr { return Some(Err(precompile_utils::prelude::revert( - "cannot be called with DELEGATECALL or CALLCODE", + "Cannot be called using `DELEGATECALL` or `CALLCODE`.", ))); }; - match code_addr { - // Ethereum precompiles: - a if a == addr(0x01) => Some(pallet_evm_precompile_simple::ECRecover::execute(handle)), - a if a == addr(0x02) => Some(pallet_evm_precompile_simple::Sha256::execute(handle)), - a if a == addr(0x03) => Some(pallet_evm_precompile_simple::Ripemd160::execute(handle)), - a if a == addr(0x04) => Some(pallet_evm_precompile_simple::Identity::execute(handle)), - a if a == addr(0x05) => Some(pallet_evm_precompile_modexp::Modexp::execute(handle)), - a if a == addr(0x06) => Some(pallet_evm_precompile_bn128::Bn128Add::execute(handle)), - a if a == addr(0x07) => Some(pallet_evm_precompile_bn128::Bn128Mul::execute(handle)), - a if a == addr(0x08) => Some(pallet_evm_precompile_bn128::Bn128Pairing::execute(handle)), - a if a == addr(0x09) => Some(pallet_evm_precompile_blake2::Blake2F::execute(handle)), - a if a == addr(0x0c) => Some(pallet_evm_precompile_bls12381::Bls12381G1Add::execute(handle)), - a if a == addr(0x0d) => Some(pallet_evm_precompile_bls12381::Bls12381G1Mul::execute(handle)), - a if a == addr(0x0e) => Some(pallet_evm_precompile_bls12381::Bls12381G1MultiExp::execute(handle)), - a if a == addr(0x0f) => Some(pallet_evm_precompile_bls12381::Bls12381G2Add::execute(handle)), - a if a == addr(0x10) => Some(pallet_evm_precompile_bls12381::Bls12381G2Mul::execute(handle)), - a if a == addr(0x11) => Some(pallet_evm_precompile_bls12381::Bls12381G2MultiExp::execute(handle)), - a if a == addr(0x12) => Some(pallet_evm_precompile_bls12381::Bls12381Pairing::execute(handle)), - a if a == addr(0x13) => Some(pallet_evm_precompile_bls12381::Bls12381MapG1::execute(handle)), - a if a == addr(0x14) => Some(pallet_evm_precompile_bls12381::Bls12381MapG2::execute(handle)), - // Darwinia precompiles: [0x400, 0x800) for stable precompiles. - a if a == addr(0x400) => Some( pallet_evm_precompile_simple::ECRecover::execute(handle), + ADDR_SHA256 => pallet_evm_precompile_simple::Sha256::execute(handle), + ADDR_RIPEMD160 => pallet_evm_precompile_simple::Ripemd160::execute(handle), + ADDR_IDENTITY => pallet_evm_precompile_simple::Identity::execute(handle), + ADDR_MODEXP => pallet_evm_precompile_modexp::Modexp::execute(handle), + ADDR_BN128_ADD => pallet_evm_precompile_bn128::Bn128Add::execute(handle), + ADDR_BN128_MUL => pallet_evm_precompile_bn128::Bn128Mul::execute(handle), + ADDR_BN128_PAIRING => pallet_evm_precompile_bn128::Bn128Pairing::execute(handle), + ADDR_BLAKE2F => pallet_evm_precompile_blake2::Blake2F::execute(handle), + ADDR_BLS12381_G1_ADD => pallet_evm_precompile_bls12381::Bls12381G1Add::execute(handle), + ADDR_BLS12381_G1_MUL => pallet_evm_precompile_bls12381::Bls12381G1Mul::execute(handle), + ADDR_BLS12381_G1_MULTI_EXP => + pallet_evm_precompile_bls12381::Bls12381G1MultiExp::execute(handle), + ADDR_BLS12381_G2_ADD => pallet_evm_precompile_bls12381::Bls12381G2Add::execute(handle), + ADDR_BLS12381_G2_MUL => pallet_evm_precompile_bls12381::Bls12381G2Mul::execute(handle), + ADDR_BLS12381_G2_MULTI_EXP => + pallet_evm_precompile_bls12381::Bls12381G2MultiExp::execute(handle), + ADDR_BLS12381_PAIRING => pallet_evm_precompile_bls12381::Bls12381Pairing::execute(handle), + ADDR_BLS12381_MAP_G1 => pallet_evm_precompile_bls12381::Bls12381MapG1::execute(handle), + ADDR_BLS12381_MAP_G2 => pallet_evm_precompile_bls12381::Bls12381MapG2::execute(handle), + ADDR_STATE_STORAGE => >::execute(handle)), - a if a == addr(0x401) => Some(>::execute(handle), + ADDR_DISPATCH => >::execute(handle)), - // [0x402, 0x600) reserved for assets precompiles. + >>::execute(handle), a if (0x402..0x600).contains(&AssetIdConverter::account_to_asset_id(a.into())) => - Some(>::execute( + >::execute( handle, - )), - // [0x600, 0x800) reserved for other stable precompiles. - a if a == addr(0x600) => - Some(>::execute(handle)), - a if a == addr(0x601) => - Some(>::execute(handle)), - a if a == addr(0x602) => - Some(>::execute(handle)), - // [0x800..) reserved for the experimental precompiles. - a if a == addr(0x800) => Some(Err(precompile_utils::prelude::revert("This precompile is no longer supported."))), - _ => None, - } + ), + ADDR_CONVICTION_VOTING => + >::execute(handle), + ADDR_EXPERIMENTAL | ADDR_DEPOSIT_DEPRECATED | ADDR_STAKING_DEPRECATED => + Err(precompile_utils::prelude::revert("This precompile is not supported.")), + _ => return None, + }; + + Some(output) } fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), + is_precompile: Self::set().contains(&address.0), extra_cost: 0, } } @@ -197,10 +182,6 @@ impl DispatchValidateT for DarwiniaDispatchValidator { } } -fn addr(a: u64) -> H160 { - H160::from_low_u64_be(a) -} - impl pallet_evm::Config for Runtime { type AddressMapping = pallet_evm::IdentityAddressMapping; type BlockGasLimit = pallet_config::BlockGasLimit; @@ -214,7 +195,7 @@ impl pallet_evm::Config for Runtime { type GasWeightMapping = pallet_evm::FixedGasWeightMapping; type OnChargeTransaction = pallet_evm::EVMFungibleAdapter; type OnCreate = (); - type PrecompilesType = KoiPrecompiles; + type PrecompilesType = Precompiles; type PrecompilesValue = PrecompilesValue; type Runner = pallet_evm::runner::stack::Runner; type RuntimeEvent = RuntimeEvent;