diff --git a/Cargo.lock b/Cargo.lock index cb585701..8b611d31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3739,6 +3739,9 @@ dependencies = [ "pallet-ethereum", "pallet-evm", "pallet-evm-chain-id", + "pallet-evm-precompile-modexp", + "pallet-evm-precompile-sha3fips", + "pallet-evm-precompile-simple", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", @@ -4010,6 +4013,20 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-bigint 0.4.3", + "num-complex", + "num-integer", + "num-iter", + "num-rational 0.4.1", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.2.6" @@ -4021,6 +4038,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-complex" version = "0.4.2" @@ -4050,6 +4078,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.2.4" @@ -4057,7 +4096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ "autocfg", - "num-bigint", + "num-bigint 0.2.6", "num-integer", "num-traits", ] @@ -4069,6 +4108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", + "num-bigint 0.4.3", "num-integer", "num-traits", ] @@ -4265,6 +4305,34 @@ dependencies = [ "serde", ] +[[package]] +name = "pallet-evm-precompile-modexp" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/frontier.git?branch=polkadot-v0.9.27#32f9c7eaf5aa550191c90e14476b145e5d7833d7" +dependencies = [ + "fp-evm", + "num", +] + +[[package]] +name = "pallet-evm-precompile-sha3fips" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/frontier.git?branch=polkadot-v0.9.27#32f9c7eaf5aa550191c90e14476b145e5d7833d7" +dependencies = [ + "fp-evm", + "tiny-keccak", +] + +[[package]] +name = "pallet-evm-precompile-simple" +version = "2.0.0-dev" +source = "git+https://github.com/paritytech/frontier.git?branch=polkadot-v0.9.27#32f9c7eaf5aa550191c90e14476b145e5d7833d7" +dependencies = [ + "fp-evm", + "ripemd", + "sp-io", +] + [[package]] name = "pallet-sudo" version = "4.0.0-dev" @@ -5091,6 +5159,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74e2ee464e763f6527991a6d532142e3c2016eb9907cc081401c11862c26a840" +dependencies = [ + "digest 0.10.3", +] + [[package]] name = "rlp" version = "0.5.1" @@ -5509,7 +5586,7 @@ dependencies = [ "futures", "log", "merlin", - "num-bigint", + "num-bigint 0.2.6", "num-rational 0.2.4", "num-traits", "parity-scale-codec", diff --git a/meta/meta-runtime/Cargo.toml b/meta/meta-runtime/Cargo.toml index 4a59f6ff..6c0db208 100644 --- a/meta/meta-runtime/Cargo.toml +++ b/meta/meta-runtime/Cargo.toml @@ -41,6 +41,9 @@ pallet-dynamic-fee = { default-features = false, git = "https://github.co pallet-ethereum = { default-features = false, git = "https://github.com/paritytech/frontier.git", branch = "polkadot-v0.9.27" } pallet-evm = { default-features = false, git = "https://github.com/paritytech/frontier.git", branch = "polkadot-v0.9.27" } pallet-evm-chain-id = { default-features = false, git = "https://github.com/paritytech/frontier.git", branch = "polkadot-v0.9.27" } +pallet-evm-precompile-modexp = { default-features = false, git = "https://github.com/paritytech/frontier.git", branch = "polkadot-v0.9.27" } +pallet-evm-precompile-sha3fips = { default-features = false, git = "https://github.com/paritytech/frontier.git", branch = "polkadot-v0.9.27" } +pallet-evm-precompile-simple = { default-features = false, git = "https://github.com/paritytech/frontier.git", branch = "polkadot-v0.9.27" } [build-dependencies] substrate-wasm-builder = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } @@ -81,6 +84,9 @@ std = [ "pallet-ethereum/std", "pallet-evm/std", "pallet-evm-chain-id/std", + "pallet-evm-precompile-modexp/std", + "pallet-evm-precompile-sha3fips/std", + "pallet-evm-precompile-simple/std", "pallet-sudo/std", "pallet-timestamp/std", "pallet-transaction-payment/std", diff --git a/meta/meta-runtime/src/lib.rs b/meta/meta-runtime/src/lib.rs index 1db74971..58c946af 100644 --- a/meta/meta-runtime/src/lib.rs +++ b/meta/meta-runtime/src/lib.rs @@ -48,6 +48,9 @@ use pallet_transaction_payment::CurrencyAdapter; pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; +mod precompiles; +use precompiles::FrontierPrecompiles; + #[cfg(test)] mod mock; #[cfg(test)] @@ -239,6 +242,7 @@ impl GasWeightMapping for FixedGasWeightMapping { parameter_types! { pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WEIGHT_PER_GAS); + pub PrecompilesValue: FrontierPrecompiles = FrontierPrecompiles::<_>::new(); } impl pallet_evm::Config for Runtime { @@ -251,8 +255,8 @@ impl pallet_evm::Config for Runtime { type Currency = Balances; type Event = Event; type Runner = pallet_evm::runner::stack::Runner; - type PrecompilesType = (); - type PrecompilesValue = (); + type PrecompilesType = FrontierPrecompiles; + type PrecompilesValue = PrecompilesValue; type ChainId = EVMChainId; type BlockGasLimit = BlockGasLimit; type OnChargeTransaction = (); diff --git a/meta/meta-runtime/src/precompiles.rs b/meta/meta-runtime/src/precompiles.rs new file mode 100644 index 00000000..3395dcf1 --- /dev/null +++ b/meta/meta-runtime/src/precompiles.rs @@ -0,0 +1,56 @@ +use pallet_evm::{Precompile, PrecompileHandle, PrecompileResult, PrecompileSet}; +use sp_core::H160; +use sp_std::marker::PhantomData; + +use pallet_evm_precompile_modexp::Modexp; +use pallet_evm_precompile_sha3fips::Sha3FIPS256; +use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; + +pub struct FrontierPrecompiles(PhantomData); + +impl FrontierPrecompiles +where + R: pallet_evm::Config, +{ + pub fn new() -> Self { + Self(Default::default()) + } + pub fn used_addresses() -> [H160; 7] { + [ + hash(1), + hash(2), + hash(3), + hash(4), + hash(5), + hash(1024), + hash(1025), + ] + } +} +impl PrecompileSet for FrontierPrecompiles +where + R: pallet_evm::Config, +{ + fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { + match handle.code_address() { + // Ethereum precompiles : + a if a == hash(1) => Some(ECRecover::execute(handle)), + a if a == hash(2) => Some(Sha256::execute(handle)), + a if a == hash(3) => Some(Ripemd160::execute(handle)), + a if a == hash(4) => Some(Identity::execute(handle)), + a if a == hash(5) => Some(Modexp::execute(handle)), + // Non-Frontier specific nor Ethereum precompiles : + a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), + a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), + _ => None, + } + } + + fn is_precompile(&self, address: H160) -> bool { + Self::used_addresses().contains(&address) + } +} + +fn hash(a: u64) -> H160 { + H160::from_low_u64_be(a) +}