diff --git a/Cargo.lock b/Cargo.lock index 8be7cd2efb..44b4e9a1ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1478,8 +1478,7 @@ checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" [[package]] name = "evm" version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8ff320c1e25e7f6d676858f16ffd9b0493d2cc67c3d900c6f2ed027b747f43" +source = "git+https://github.com/rust-blockchain/evm?branch=master#01bcbd2205a212c34451d3b4fabc962793b057d3" dependencies = [ "auto_impl", "environmental", @@ -1499,8 +1498,7 @@ dependencies = [ [[package]] name = "evm-core" version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d4537041d3a3438d59b2d01bd950ce89fb1ccb3cf21d9331193c10be12e849f" +source = "git+https://github.com/rust-blockchain/evm?branch=master#01bcbd2205a212c34451d3b4fabc962793b057d3" dependencies = [ "parity-scale-codec", "primitive-types", @@ -1511,8 +1509,7 @@ dependencies = [ [[package]] name = "evm-gasometer" version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6181da8734c86873ac9b3f9886d4e00105361039dcfb9f621be9a0ddb8f43961" +source = "git+https://github.com/rust-blockchain/evm?branch=master#01bcbd2205a212c34451d3b4fabc962793b057d3" dependencies = [ "environmental", "evm-core", @@ -1523,8 +1520,7 @@ dependencies = [ [[package]] name = "evm-runtime" version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6157af91ca70fcf3581afaea1fa25974a71b9ef63d454c08dfba93ab0c7715d" +source = "git+https://github.com/rust-blockchain/evm?branch=master#01bcbd2205a212c34451d3b4fabc962793b057d3" dependencies = [ "auto_impl", "environmental", @@ -4557,6 +4553,7 @@ dependencies = [ "hex", "serde", "serde_json", + "sp-core", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 475851df39..3827572e1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,4 +25,4 @@ members = [ "template/node", "template/runtime", ] -resolver = "2" +resolver = "2" \ No newline at end of file diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 0b96e298ed..0348deddf7 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" codec = { package = "parity-scale-codec", version = "3.0.0" } ethereum = { version = "0.12.0", features = ["with-codec"] } ethereum-types = "0.13.1" -evm = "0.35.0" +evm = { git = "https://github.com/rust-blockchain/evm", branch = "master" } futures = { version = "0.3.1", features = ["compat"] } hex = "0.4" jsonrpc-core = "18.0" diff --git a/frame/ethereum/Cargo.toml b/frame/ethereum/Cargo.toml index 6a78712a1b..b35157a20d 100644 --- a/frame/ethereum/Cargo.toml +++ b/frame/ethereum/Cargo.toml @@ -9,7 +9,7 @@ license = "Apache-2.0" [dependencies] ethereum = { version = "0.12.0", default-features = false, features = ["with-codec"] } ethereum-types = { version = "0.13.1", default-features = false } -evm = { version = "0.35.0", features = ["with-codec"], default-features = false } +evm = { git = "https://github.com/rust-blockchain/evm", branch = "master", features = ["with-codec"], default-features = false } rlp = { version = "0.5", default-features = false } serde = { version = "1.0.101", optional = true } sha3 = { version = "0.10", default-features = false } diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index e1d5a6ac7f..0195c83d2e 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -evm = { version = "0.35.0", default-features = false, features = ["with-codec"] } +evm = { git = "https://github.com/rust-blockchain/evm", branch = "master", default-features = false, features = ["with-codec"] } hex = { version = "0.4", default-features = false, features = ["alloc"] } log = { version = "0.4", default-features = false } primitive-types = { version = "0.11.1", default-features = false, features = ["rlp", "byteorder"] } diff --git a/frame/evm/precompile/blake2/src/lib.rs b/frame/evm/precompile/blake2/src/lib.rs index 23e967d518..139ef13e3d 100644 --- a/frame/evm/precompile/blake2/src/lib.rs +++ b/frame/evm/precompile/blake2/src/lib.rs @@ -22,7 +22,7 @@ extern crate alloc; mod eip_152; use fp_evm::{ - Context, ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileOutput, + ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; @@ -35,14 +35,12 @@ impl Blake2F { impl Precompile for Blake2F { /// Format of `input`: /// [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f] - fn execute( - input: &[u8], - target_gas: Option, - _context: &Context, - _is_static: bool, - ) -> PrecompileResult { + fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { const BLAKE2_F_ARG_LEN: usize = 213; + let input = handle.input(); + let target_gas = handle.gas_limit(); + if input.len() != BLAKE2_F_ARG_LEN { return Err(PrecompileFailure::Error { exit_status: ExitError::Other( @@ -64,6 +62,9 @@ impl Precompile for Blake2F { } } + handle.record_cost(gas_cost)?; + let input = handle.input(); + // we use from_le_bytes below to effectively swap byte order to LE if architecture is BE let mut h_buf: [u8; 64] = [0; 64]; @@ -115,9 +116,7 @@ impl Precompile for Blake2F { Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - cost: gas_cost, output: output_buf.to_vec(), - logs: Default::default(), }) } } diff --git a/frame/evm/precompile/bn128/src/lib.rs b/frame/evm/precompile/bn128/src/lib.rs index d7a18182d3..1fcae3cd82 100644 --- a/frame/evm/precompile/bn128/src/lib.rs +++ b/frame/evm/precompile/bn128/src/lib.rs @@ -21,7 +21,7 @@ extern crate alloc; use alloc::vec::Vec; use fp_evm::{ - Context, ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileOutput, + ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; use sp_core::U256; @@ -76,14 +76,13 @@ impl Bn128Add { } impl Precompile for Bn128Add { - fn execute( - input: &[u8], - _target_gas: Option, - _context: &Context, - _is_static: bool, - ) -> PrecompileResult { + fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { use bn::AffineG1; + handle.record_cost(Bn128Add::GAS_COST)?; + + let input = handle.input(); + let p1 = read_point(input, 0)?; let p2 = read_point(input, 64)?; @@ -108,9 +107,7 @@ impl Precompile for Bn128Add { Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - cost: Bn128Add::GAS_COST, output: buf.to_vec(), - logs: Default::default(), }) } } @@ -123,14 +120,13 @@ impl Bn128Mul { } impl Precompile for Bn128Mul { - fn execute( - input: &[u8], - _target_gas: Option, - _context: &Context, - _is_static: bool, - ) -> PrecompileResult { + fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { use bn::AffineG1; + handle.record_cost(Bn128Mul::GAS_COST)?; + + let input = handle.input(); + let p = read_point(input, 0)?; let fr = read_fr(input, 64)?; @@ -155,9 +151,7 @@ impl Precompile for Bn128Mul { Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - cost: Bn128Mul::GAS_COST, output: buf.to_vec(), - logs: Default::default(), }) } } @@ -172,14 +166,12 @@ impl Bn128Pairing { } impl Precompile for Bn128Pairing { - fn execute( - input: &[u8], - target_gas: Option, - _context: &Context, - _is_static: bool, - ) -> PrecompileResult { + fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { use bn::{pairing_batch, AffineG1, AffineG2, Fq, Fq2, Group, Gt, G1, G2}; + let input = handle.input(); + let target_gas = handle.gas_limit(); + let (ret_val, gas_cost) = if input.is_empty() { (U256::one(), Bn128Pairing::BASE_GAS_COST) } else { @@ -282,14 +274,14 @@ impl Precompile for Bn128Pairing { } }; + handle.record_cost(gas_cost)?; + let mut buf = [0u8; 32]; ret_val.to_big_endian(&mut buf); Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - cost: gas_cost, output: buf.to_vec(), - logs: Default::default(), }) } } diff --git a/frame/evm/precompile/dispatch/src/lib.rs b/frame/evm/precompile/dispatch/src/lib.rs index 2eb4b3dfdc..7eedab5f75 100644 --- a/frame/evm/precompile/dispatch/src/lib.rs +++ b/frame/evm/precompile/dispatch/src/lib.rs @@ -21,7 +21,7 @@ extern crate alloc; use core::marker::PhantomData; use fp_evm::{ - Context, ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileOutput, + ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; use frame_support::{ @@ -41,12 +41,11 @@ where T::Call: Dispatchable + GetDispatchInfo + Decode, ::Origin: From>, { - fn execute( - input: &[u8], - target_gas: Option, - context: &Context, - _is_static: bool, - ) -> PrecompileResult { + fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { + let input = handle.input(); + let target_gas = handle.gas_limit(); + let context = handle.context(); + let call = T::Call::decode(&mut &*input).map_err(|_| PrecompileFailure::Error { exit_status: ExitError::Other("decode failed".into()), })?; @@ -75,11 +74,12 @@ where let cost = T::GasWeightMapping::weight_to_gas( post_info.actual_weight.unwrap_or(info.weight), ); + + handle.record_cost(cost)?; + Ok(PrecompileOutput { exit_status: ExitSucceed::Stopped, - cost, output: Default::default(), - logs: Default::default(), }) } Err(_) => Err(PrecompileFailure::Error { diff --git a/frame/evm/precompile/modexp/src/lib.rs b/frame/evm/precompile/modexp/src/lib.rs index 2cdb6359ba..7f2f8573b1 100644 --- a/frame/evm/precompile/modexp/src/lib.rs +++ b/frame/evm/precompile/modexp/src/lib.rs @@ -26,7 +26,7 @@ use core::{cmp::max, ops::BitAnd}; use num::{BigUint, FromPrimitive, One, ToPrimitive, Zero}; use fp_evm::{ - Context, ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileOutput, + ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; @@ -109,12 +109,10 @@ fn calculate_gas_cost( // see: https://eips.ethereum.org/EIPS/eip-198 impl Precompile for Modexp { - fn execute( - input: &[u8], - target_gas: Option, - _context: &Context, - _is_static: bool, - ) -> PrecompileResult { + fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { + let input = handle.input(); + let target_gas = handle.gas_limit(); + if input.len() < 96 { return Err(PrecompileFailure::Error { exit_status: ExitError::Other("input must contain at least 96 bytes".into()), @@ -194,6 +192,8 @@ impl Precompile for Modexp { } }; + handle.record_cost(gas_cost)?; + // write output to given memory, left padded and same length as the modulus. let bytes = r.to_bytes_be(); @@ -202,9 +202,7 @@ impl Precompile for Modexp { if bytes.len() == mod_len { Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - cost: gas_cost, output: bytes.to_vec(), - logs: Default::default(), }) } else if bytes.len() < mod_len { let mut ret = Vec::with_capacity(mod_len); @@ -212,9 +210,7 @@ impl Precompile for Modexp { ret.extend_from_slice(&bytes[..]); Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - cost: gas_cost, output: ret.to_vec(), - logs: Default::default(), }) } else { Err(PrecompileFailure::Error { @@ -228,7 +224,8 @@ impl Precompile for Modexp { mod tests { use super::*; extern crate hex; - use pallet_evm_test_vector_support::test_precompile_test_vectors; + use fp_evm::Context; + use pallet_evm_test_vector_support::{test_precompile_test_vectors, MockHandle}; #[test] fn process_consensus_tests() -> Result<(), String> { @@ -238,7 +235,7 @@ mod tests { #[test] fn test_empty_input() -> Result<(), PrecompileFailure> { - let input: [u8; 0] = []; + let input = Vec::new(); let cost: u64 = 1; @@ -248,7 +245,9 @@ mod tests { apparent_value: From::from(0), }; - match Modexp::execute(&input, Some(cost), &context, false) { + let mut handle = MockHandle::new(input, Some(cost), context); + + match Modexp::execute(&mut handle) { Ok(_) => { panic!("Test not expected to pass"); } @@ -283,7 +282,9 @@ mod tests { apparent_value: From::from(0), }; - match Modexp::execute(&input, Some(cost), &context, false) { + let mut handle = MockHandle::new(input, Some(cost), context); + + match Modexp::execute(&mut handle) { Ok(_) => { panic!("Test not expected to pass"); } @@ -316,7 +317,9 @@ mod tests { apparent_value: From::from(0), }; - match Modexp::execute(&input, Some(cost), &context, false) { + let mut handle = MockHandle::new(input, Some(cost), context); + + match Modexp::execute(&mut handle) { Ok(_) => { panic!("Test not expected to pass"); } @@ -354,7 +357,9 @@ mod tests { apparent_value: From::from(0), }; - match Modexp::execute(&input, Some(cost), &context, false) { + let mut handle = MockHandle::new(input, Some(cost), context); + + match Modexp::execute(&mut handle) { Ok(precompile_result) => { assert_eq!(precompile_result.output.len(), 1); // should be same length as mod let result = BigUint::from_bytes_be(&precompile_result.output[..]); @@ -389,7 +394,9 @@ mod tests { apparent_value: From::from(0), }; - match Modexp::execute(&input, Some(cost), &context, false) { + let mut handle = MockHandle::new(input, Some(cost), context); + + match Modexp::execute(&mut handle) { Ok(precompile_result) => { assert_eq!(precompile_result.output.len(), 32); // should be same length as mod let result = BigUint::from_bytes_be(&precompile_result.output[..]); @@ -422,7 +429,9 @@ mod tests { apparent_value: From::from(0), }; - match Modexp::execute(&input, Some(cost), &context, false) { + let mut handle = MockHandle::new(input, Some(cost), context); + + match Modexp::execute(&mut handle) { Ok(precompile_result) => { assert_eq!(precompile_result.output.len(), 32); // should be same length as mod let result = BigUint::from_bytes_be(&precompile_result.output[..]); @@ -461,8 +470,10 @@ mod tests { apparent_value: From::from(0), }; - let precompile_result = Modexp::execute(&input, Some(cost), &context, false) - .expect("Modexp::execute() returned error"); + let mut handle = MockHandle::new(input, Some(cost), context); + + let precompile_result = + Modexp::execute(&mut handle).expect("Modexp::execute() returned error"); assert_eq!(precompile_result.output.len(), 1); // should be same length as mod let result = BigUint::from_bytes_be(&precompile_result.output[..]); diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 325f95967f..9a3f87c747 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -88,7 +88,8 @@ pub use evm::{ use fp_evm::GenesisAccount; pub use fp_evm::{ Account, CallInfo, CreateInfo, ExecutionInfo, FeeCalculator, LinearCostPrecompile, Log, - Precompile, PrecompileFailure, PrecompileOutput, PrecompileResult, PrecompileSet, Vicinity, + Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, + PrecompileSet, Vicinity, }; pub use self::{ diff --git a/frame/evm/test-vector-support/Cargo.toml b/frame/evm/test-vector-support/Cargo.toml index 5adf26a56f..3bcd398b65 100644 --- a/frame/evm/test-vector-support/Cargo.toml +++ b/frame/evm/test-vector-support/Cargo.toml @@ -9,9 +9,10 @@ repository = "https://github.com/paritytech/frontier/" description = "Test vector support for EVM pallet." [dependencies] -evm = { version = "0.35.0", features = ["with-codec"] } +evm = { git = "https://github.com/rust-blockchain/evm", branch = "master", features = ["with-codec"] } hex = "0.4.0" serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0" -fp-evm = { version = "3.0.0-dev", path = "../../../primitives/evm" } +sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20", default-features = false } +fp-evm = { version = "3.0.0-dev", path = "../../../primitives/evm", default-features = false } diff --git a/frame/evm/test-vector-support/src/lib.rs b/frame/evm/test-vector-support/src/lib.rs index 95bfd40ee8..3a627fa146 100644 --- a/frame/evm/test-vector-support/src/lib.rs +++ b/frame/evm/test-vector-support/src/lib.rs @@ -15,13 +15,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use evm::{Context, ExitError, ExitReason, ExitSucceed, Transfer}; +use fp_evm::{Precompile, PrecompileHandle}; +use sp_core::{H160, H256}; use std::fs; -use evm::{Context, ExitSucceed}; -use fp_evm::Precompile; - -#[derive(Debug, serde::Deserialize)] -#[serde(rename_all = "PascalCase")] +#[derive(serde::Deserialize, Debug)] struct EthConsensusTest { input: String, expected: String, @@ -29,6 +28,75 @@ struct EthConsensusTest { gas: Option, } +pub struct MockHandle { + pub input: Vec, + pub gas_limit: Option, + pub context: Context, + pub is_static: bool, + pub gas_used: u64, +} + +impl MockHandle { + pub fn new(input: Vec, gas_limit: Option, context: Context) -> Self { + Self { + input, + gas_limit, + context, + is_static: false, + gas_used: 0, + } + } +} + +impl PrecompileHandle for MockHandle { + /// Perform subcall in provided context. + /// Precompile specifies in which context the subcall is executed. + fn call( + &mut self, + _: H160, + _: Option, + _: Vec, + _: Option, + _: bool, + _: &Context, + ) -> (ExitReason, Vec) { + unimplemented!() + } + + fn record_cost(&mut self, cost: u64) -> Result<(), ExitError> { + self.gas_used += cost; + Ok(()) + } + + fn log(&mut self, _: H160, _: Vec, _: Vec) -> Result<(), ExitError> { + unimplemented!() + } + + fn remaining_gas(&self) -> u64 { + unimplemented!() + } + + fn code_address(&self) -> H160 { + unimplemented!() + } + + fn input(&self) -> &[u8] { + &self.input + } + + fn context(&self) -> &Context { + &self.context + } + + fn is_static(&self) -> bool { + self.is_static + } + + fn gas_limit(&self) -> Option { + self.gas_limit + } +} + /// Tests a precompile against the ethereum consensus tests defined in the given file at filepath. /// The file is expected to be in JSON format and contain an array of test vectors, where each /// vector can be deserialized into an "EthConsensusTest". @@ -48,7 +116,9 @@ pub fn test_precompile_test_vectors(filepath: &str) -> Result<(), apparent_value: From::from(0), }; - match P::execute(&input, Some(cost), &context, false) { + let mut handle = MockHandle::new(input, Some(cost), context); + + match P::execute(&mut handle) { Ok(result) => { let as_hex: String = hex::encode(result.output); assert_eq!( @@ -65,7 +135,7 @@ pub fn test_precompile_test_vectors(filepath: &str) -> Result<(), ); if let Some(expected_gas) = test.gas { assert_eq!( - result.cost, expected_gas, + handle.gas_used, expected_gas, "test '{}' failed (different gas cost)", test.name ); diff --git a/primitives/evm/Cargo.toml b/primitives/evm/Cargo.toml index 41aaf59fdd..9d660969a2 100644 --- a/primitives/evm/Cargo.toml +++ b/primitives/evm/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sp-evm" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -evm = { version = "0.35.0", default-features = false, features = ["with-codec"] } +evm = { git = "https://github.com/rust-blockchain/evm", branch = "master", default-features = false, features = ["with-codec"] } serde = { version = "1.0.101", features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } diff --git a/primitives/evm/src/lib.rs b/primitives/evm/src/lib.rs index 4f7c3c6f23..557a76f101 100644 --- a/primitives/evm/src/lib.rs +++ b/primitives/evm/src/lib.rs @@ -31,7 +31,8 @@ pub use evm::backend::{Basic as Account, Log}; pub use self::precompile::{ Context, ExitError, ExitRevert, ExitSucceed, LinearCostPrecompile, Precompile, - PrecompileFailure, PrecompileOutput, PrecompileResult, PrecompileSet, + PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet, + Transfer, }; #[derive(Clone, Eq, PartialEq, Encode, Decode, Default)] diff --git a/primitives/evm/src/precompile.rs b/primitives/evm/src/precompile.rs index 3a058cb9e2..4996445cb6 100644 --- a/primitives/evm/src/precompile.rs +++ b/primitives/evm/src/precompile.rs @@ -16,8 +16,8 @@ // limitations under the License. pub use evm::{ - executor::stack::{PrecompileFailure, PrecompileOutput, PrecompileSet}, - Context, ExitError, ExitRevert, ExitSucceed, + executor::stack::{PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileSet}, + Context, ExitError, ExitRevert, ExitSucceed, Transfer, }; use sp_std::vec::Vec; @@ -25,15 +25,9 @@ pub type PrecompileResult = Result; /// One single precompile used by EVM engine. pub trait Precompile { - /// Try to execute the precompile. Calculate the amount of gas needed with given `input` and - /// `target_gas`. Return `Ok(status, output, gas_used)` if the execution is - /// successful. Otherwise return `Err(_)`. - fn execute( - input: &[u8], - target_gas: Option, - context: &Context, - is_static: bool, - ) -> PrecompileResult; + /// Try to execute the precompile with given `handle` which provides all call data + /// and allow to register costs and logs. + fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult; } pub trait LinearCostPrecompile { @@ -47,15 +41,15 @@ pub trait LinearCostPrecompile { } impl Precompile for T { - fn execute(input: &[u8], target_gas: Option, _: &Context, _: bool) -> PrecompileResult { - let cost = ensure_linear_cost(target_gas, input.len() as u64, T::BASE, T::WORD)?; + fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { + let target_gas = handle.gas_limit(); + let cost = ensure_linear_cost(target_gas, handle.input().len() as u64, T::BASE, T::WORD)?; - let (exit_status, output) = T::execute(input, cost)?; + handle.record_cost(cost)?; + let (exit_status, output) = T::execute(handle.input(), cost)?; Ok(PrecompileOutput { exit_status, - cost, output, - logs: Default::default(), }) } } diff --git a/template/runtime/src/precompiles.rs b/template/runtime/src/precompiles.rs index 1e1c0845db..93b54c030f 100644 --- a/template/runtime/src/precompiles.rs +++ b/template/runtime/src/precompiles.rs @@ -1,4 +1,4 @@ -use pallet_evm::{Context, Precompile, PrecompileResult, PrecompileSet}; +use pallet_evm::{Precompile, PrecompileHandle, PrecompileResult, PrecompileSet}; use sp_core::H160; use sp_std::marker::PhantomData; @@ -26,28 +26,17 @@ impl PrecompileSet for FrontierPrecompiles where R: pallet_evm::Config, { - fn execute( - &self, - address: H160, - input: &[u8], - target_gas: Option, - context: &Context, - is_static: bool, - ) -> Option { - match address { + fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { + match handle.code_address() { // Ethereum precompiles : - a if a == hash(1) => Some(ECRecover::execute(input, target_gas, context, is_static)), - a if a == hash(2) => Some(Sha256::execute(input, target_gas, context, is_static)), - a if a == hash(3) => Some(Ripemd160::execute(input, target_gas, context, is_static)), - a if a == hash(4) => Some(Identity::execute(input, target_gas, context, is_static)), - a if a == hash(5) => Some(Modexp::execute(input, target_gas, context, is_static)), + 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(input, target_gas, context, is_static)) - } - a if a == hash(1025) => Some(ECRecoverPublicKey::execute( - input, target_gas, context, is_static, - )), + a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), + a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), _ => None, } }