From 6d5e5251f32a44224849524923048ecc7111565a Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Mon, 28 Feb 2022 18:58:16 +0100 Subject: [PATCH] update precompile set --- primitives/Cargo.toml | 2 +- primitives/src/evm.rs | 8 +- runtime/acala/src/lib.rs | 2 +- runtime/common/Cargo.toml | 2 +- runtime/common/src/precompile/mock.rs | 2 +- runtime/common/src/precompile/mod.rs | 181 +++++++++++++++++++------- runtime/karura/src/lib.rs | 2 +- runtime/mandala/src/lib.rs | 2 +- 8 files changed, 143 insertions(+), 58 deletions(-) diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index f27589b5f..f1f4e7324 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Acala Developers"] edition = "2021" [dependencies] +hex-literal = "0.3.1" bstringify = "0.1.2" serde = { version = "1.0.124", optional = true } codec = { package = "parity-scale-codec", version = "2.3.1", default-features = false, features = ["max-encoded-len"] } @@ -27,7 +28,6 @@ nutsfinance-stable-asset = { version = "0.1.0", default-features = false, path = [dev-dependencies] serde_json = { version = "1.0.68" } -hex-literal = "0.3.1" [features] default = ["std"] diff --git a/primitives/src/evm.rs b/primitives/src/evm.rs index b073edd53..0a3a34138 100644 --- a/primitives/src/evm.rs +++ b/primitives/src/evm.rs @@ -22,6 +22,7 @@ use crate::{ }; use codec::{Decode, Encode}; use core::ops::Range; +use hex_literal::hex; pub use module_evm_utiltity::{ ethereum::{AccessListItem, Log, TransactionAction}, evm::ExitReason, @@ -106,12 +107,11 @@ pub struct EthereumTransactionMessage { /// 0 - 0x0000000000000000000000000000000000000400 /// Acala precompiles /// 0x0000000000000000000000000000000000000400 - 0x0000000000000000000000000000000000000800 -pub const PRECOMPILE_ADDRESS_START: EvmAddress = H160([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]); +pub const PRECOMPILE_ADDRESS_START: EvmAddress = H160(hex!("0000000000000000000000000000000000000400")); /// Predeployed system contracts (except Mirrored ERC20) /// 0x0000000000000000000000000000000000000800 - 0x0000000000000000000000000000000000001000 -pub const PREDEPLOY_ADDRESS_START: EvmAddress = H160([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0]); -pub const MIRRORED_TOKENS_ADDRESS_START: EvmAddress = - H160([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); +pub const PREDEPLOY_ADDRESS_START: EvmAddress = H160(hex!("0000000000000000000000000000000000000800")); +pub const MIRRORED_TOKENS_ADDRESS_START: EvmAddress = H160(hex!("0000000000000000000100000000000000000000")); pub const MIRRORED_NFT_ADDRESS_START: u64 = 0x2000000; /// System contract address prefix pub const SYSTEM_CONTRACT_ADDRESS_PREFIX: [u8; 9] = [0u8; 9]; diff --git a/runtime/acala/src/lib.rs b/runtime/acala/src/lib.rs index 3f0d7e733..e9e0b8175 100644 --- a/runtime/acala/src/lib.rs +++ b/runtime/acala/src/lib.rs @@ -1355,7 +1355,7 @@ parameter_types! { pub NetworkContractSource: H160 = H160::from_low_u64_be(0); pub DeveloperDeposit: Balance = 100 * dollar(ACA); pub PublicationFee: Balance = 10000 * dollar(ACA); - pub PrecompilesValue: AllPrecompiles = AllPrecompiles::<_>::new(); + pub PrecompilesValue: AllPrecompiles = AllPrecompiles::<_>::acala(); } #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 2dc5a69ad..a4df7cc1c 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Acala Developers"] edition = "2021" [dependencies] +hex-literal = "0.3.1" static_assertions = "1.1.0" num_enum = { version = "0.5.1", default-features = false } serde = { version = "1.0.124", optional = true, default-features = false } @@ -43,7 +44,6 @@ xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "releas [dev-dependencies] serde_json = "1.0.68" -hex-literal = "0.3.1" sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } diff --git a/runtime/common/src/precompile/mock.rs b/runtime/common/src/precompile/mock.rs index 845427d35..fe36c2243 100644 --- a/runtime/common/src/precompile/mock.rs +++ b/runtime/common/src/precompile/mock.rs @@ -395,7 +395,7 @@ pub type EvmErc20InfoMapping = module_asset_registry::EvmErc20InfoMapping; parameter_types! { pub NetworkContractSource: H160 = alice_evm_addr(); - pub PrecompilesValue: AllPrecompiles = AllPrecompiles::<_>::new(); + pub PrecompilesValue: AllPrecompiles = AllPrecompiles::<_>::mandala(); } ord_parameter_types! { diff --git a/runtime/common/src/precompile/mod.rs b/runtime/common/src/precompile/mod.rs index fc09d45f8..fbdc0ef4a 100644 --- a/runtime/common/src/precompile/mod.rs +++ b/runtime/common/src/precompile/mod.rs @@ -25,6 +25,7 @@ mod mock; mod tests; use frame_support::log; +use hex_literal::hex; use module_evm::{ precompiles::{ Blake2F, Bn128Add, Bn128Mul, Bn128Pairing, ECRecover, ECRecoverPublicKey, Identity, IstanbulModexp, Modexp, @@ -34,9 +35,8 @@ use module_evm::{ Context, ExitRevert, }; use module_support::PrecompileCallerFilter as PrecompileCallerFilterT; -use primitives::evm::PRECOMPILE_ADDRESS_START; use sp_core::H160; -use sp_std::marker::PhantomData; +use sp_std::{collections::btree_set::BTreeSet, marker::PhantomData}; pub mod dex; pub mod evm; @@ -54,39 +54,118 @@ pub use nft::NFTPrecompile; pub use oracle::OraclePrecompile; pub use schedule::SchedulePrecompile; -#[derive(Default)] -pub struct AllPrecompiles(PhantomData); +pub const ECRECOVER: H160 = H160(hex!("0000000000000000000000000000000000000001")); +pub const SHA256: H160 = H160(hex!("0000000000000000000000000000000000000002")); +pub const RIPEMD: H160 = H160(hex!("0000000000000000000000000000000000000003")); +pub const IDENTITY: H160 = H160(hex!("0000000000000000000000000000000000000004")); +pub const MODEXP: H160 = H160(hex!("0000000000000000000000000000000000000005")); +pub const BN_ADD: H160 = H160(hex!("0000000000000000000000000000000000000006")); +pub const BN_MUL: H160 = H160(hex!("0000000000000000000000000000000000000007")); +pub const BN_PAIRING: H160 = H160(hex!("0000000000000000000000000000000000000008")); +pub const BLAKE2F: H160 = H160(hex!("0000000000000000000000000000000000000009")); + +pub const ECRECOVER_PUBLICKEY: H160 = H160(hex!("0000000000000000000000000000000000000080")); +pub const SHA3_256: H160 = H160(hex!("0000000000000000000000000000000000000081")); +pub const SHA3_512: H160 = H160(hex!("0000000000000000000000000000000000000082")); + +pub const MULTI_CURRENCY: H160 = H160(hex!("0000000000000000000000000000000000000400")); +pub const NFT: H160 = H160(hex!("0000000000000000000000000000000000000401")); +pub const EVM: H160 = H160(hex!("0000000000000000000000000000000000000402")); +pub const ORACLE: H160 = H160(hex!("0000000000000000000000000000000000000403")); +pub const SCHEDULER: H160 = H160(hex!("0000000000000000000000000000000000000404")); +pub const DEX: H160 = H160(hex!("0000000000000000000000000000000000000405")); + +pub struct AllPrecompiles { + active: BTreeSet, + _marker: PhantomData, +} impl AllPrecompiles where R: module_evm::Config, { - pub fn new() -> Self { - Self(Default::default()) + pub fn acala() -> Self { + Self { + active: BTreeSet::from([ + ECRECOVER, + SHA256, + RIPEMD, + IDENTITY, + MODEXP, + BN_ADD, + BN_MUL, + BN_PAIRING, + BLAKE2F, + // Non-standard precompile starts with 128 + ECRECOVER_PUBLICKEY, + SHA3_256, + SHA3_512, + // Acala precompile + MULTI_CURRENCY, + NFT, + EVM, + ORACLE, + // SCHEDULER, + DEX, + ]), + _marker: Default::default(), + } + } + + pub fn karura() -> Self { + Self { + active: BTreeSet::from([ + ECRECOVER, + SHA256, + RIPEMD, + IDENTITY, + MODEXP, + BN_ADD, + BN_MUL, + BN_PAIRING, + BLAKE2F, + // Non-standard precompile starts with 128 + ECRECOVER_PUBLICKEY, + SHA3_256, + SHA3_512, + // Acala precompile + MULTI_CURRENCY, + NFT, + EVM, + ORACLE, + // SCHEDULER, + DEX, + ]), + _marker: Default::default(), + } } - pub fn used_addresses() -> sp_std::vec::Vec { - sp_std::vec![ - H160::from_low_u64_be(1), - H160::from_low_u64_be(2), - H160::from_low_u64_be(3), - H160::from_low_u64_be(4), - H160::from_low_u64_be(5), - H160::from_low_u64_be(6), - H160::from_low_u64_be(7), - H160::from_low_u64_be(8), - H160::from_low_u64_be(9), - // Non-standard precompile starts with 128 - H160::from_low_u64_be(128), - H160::from_low_u64_be(129), - H160::from_low_u64_be(130), - // Acala precompile - PRECOMPILE_ADDRESS_START, - PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(1), - PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(2), - PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(3), - PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(4), - PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(5), - ] + + pub fn mandala() -> Self { + Self { + active: BTreeSet::from([ + ECRECOVER, + SHA256, + RIPEMD, + IDENTITY, + MODEXP, + BN_ADD, + BN_MUL, + BN_PAIRING, + BLAKE2F, + // Non-standard precompile starts with 128 + ECRECOVER_PUBLICKEY, + SHA3_256, + SHA3_512, + // Acala precompile + MULTI_CURRENCY, + NFT, + EVM, + ORACLE, + SCHEDULER, + DEX, + ]), + _marker: Default::default(), + } } } @@ -114,35 +193,35 @@ where log::trace!(target: "evm", "Precompile begin, address: {:?}, input: {:?}, target_gas: {:?}, context: {:?}", address, input, target_gas, context); // https://github.com/ethereum/go-ethereum/blob/9357280fce5c5d57111d690a336cca5f89e34da6/core/vm/contracts.go#L83 - let result = if address == H160::from_low_u64_be(1) { + let result = if address == ECRECOVER { Some(ECRecover::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(2) { + } else if address == SHA256 { Some(Sha256::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(3) { + } else if address == RIPEMD { Some(Ripemd160::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(4) { + } else if address == IDENTITY { Some(Identity::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(5) { + } else if address == MODEXP { if R::config().increase_state_access_gas { Some(Modexp::execute(input, target_gas, context, is_static)) } else { Some(IstanbulModexp::execute(input, target_gas, context, is_static)) } - } else if address == H160::from_low_u64_be(6) { + } else if address == BN_ADD { Some(Bn128Add::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(7) { + } else if address == BN_MUL { Some(Bn128Mul::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(8) { + } else if address == BN_PAIRING { Some(Bn128Pairing::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(9) { + } else if address == BLAKE2F { Some(Blake2F::execute(input, target_gas, context, is_static)) } // Non-standard precompile starts with 128 - else if address == H160::from_low_u64_be(128) { + else if address == ECRECOVER_PUBLICKEY { Some(ECRecoverPublicKey::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(129) { + } else if address == SHA3_256 { Some(Sha3FIPS256::execute(input, target_gas, context, is_static)) - } else if address == H160::from_low_u64_be(130) { + } else if address == SHA3_512 { Some(Sha3FIPS512::execute(input, target_gas, context, is_static)) } // Acala precompile @@ -156,19 +235,19 @@ where })); } - if address == PRECOMPILE_ADDRESS_START { + if address == MULTI_CURRENCY { Some(MultiCurrencyPrecompile::::execute( input, target_gas, context, is_static, )) - } else if address == PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(1) { + } else if address == NFT { Some(NFTPrecompile::::execute(input, target_gas, context, is_static)) - } else if address == PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(2) { + } else if address == EVM { Some(EVMPrecompile::::execute(input, target_gas, context, is_static)) - } else if address == PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(3) { + } else if address == ORACLE { Some(OraclePrecompile::::execute(input, target_gas, context, is_static)) - } else if address == PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(4) { + } else if address == SCHEDULER { Some(SchedulePrecompile::::execute(input, target_gas, context, is_static)) - } else if address == PRECOMPILE_ADDRESS_START | H160::from_low_u64_be(5) { + } else if address == DEX { Some(DEXPrecompile::::execute(input, target_gas, context, is_static)) } else { None @@ -183,6 +262,12 @@ where } fn is_precompile(&self, address: H160) -> bool { - Self::used_addresses().contains(&address) + self.active.contains(&address) } } + +#[test] +fn ensure_precompile_address_start() { + use primitives::evm::PRECOMPILE_ADDRESS_START; + assert_eq!(PRECOMPILE_ADDRESS_START, MULTI_CURRENCY); +} diff --git a/runtime/karura/src/lib.rs b/runtime/karura/src/lib.rs index 3ad98ff22..368ee8df5 100644 --- a/runtime/karura/src/lib.rs +++ b/runtime/karura/src/lib.rs @@ -1365,7 +1365,7 @@ parameter_types! { pub NetworkContractSource: H160 = H160::from_low_u64_be(0); pub DeveloperDeposit: Balance = 100 * dollar(KAR); pub PublicationFee: Balance = 10000 * dollar(KAR); - pub PrecompilesValue: AllPrecompiles = AllPrecompiles::<_>::new(); + pub PrecompilesValue: AllPrecompiles = AllPrecompiles::<_>::karura(); } #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, TypeInfo)] diff --git a/runtime/mandala/src/lib.rs b/runtime/mandala/src/lib.rs index d48fc7985..3e300494a 100644 --- a/runtime/mandala/src/lib.rs +++ b/runtime/mandala/src/lib.rs @@ -1488,7 +1488,7 @@ impl ecosystem_compound_cash::Config for Runtime { parameter_types! { pub const ChainId: u64 = 595; pub NetworkContractSource: H160 = H160::from_low_u64_be(0); - pub PrecompilesValue: AllPrecompiles = AllPrecompiles::<_>::new(); + pub PrecompilesValue: AllPrecompiles = AllPrecompiles::<_>::mandala(); } #[cfg(feature = "with-ethereum-compatibility")]