diff --git a/Cargo.lock b/Cargo.lock index 9ffec35c8b..e616b86dc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1436,8 +1436,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", @@ -1457,8 +1456,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", @@ -1469,8 +1467,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", @@ -1481,8 +1478,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", @@ -4510,6 +4506,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 65d61f1beb..4e85c93e08 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -9,7 +9,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0" [dependencies] 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 eece07a264..425b77ac03 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 ed1ec6b1c0..11dc705135 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 720bd7eef4..f2eec864b6 100644 --- a/frame/evm/precompile/blake2/src/lib.rs +++ b/frame/evm/precompile/blake2/src/lib.rs @@ -23,7 +23,7 @@ mod eip_152; use core::mem::size_of; use fp_evm::{ - Context, ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileOutput, + ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; @@ -36,14 +36,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( @@ -65,6 +63,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]; @@ -116,9 +117,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 6c90f71ab4..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,13 +41,12 @@ where T::Call: Dispatchable + GetDispatchInfo + Decode, ::Origin: From>, { - fn execute( - input: &[u8], - target_gas: Option, - context: &Context, - _is_static: bool, - ) -> PrecompileResult { - let call = T::Call::decode(&mut &input[..]).map_err(|_| PrecompileFailure::Error { + 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()), })?; let info = call.get_dispatch_info(); @@ -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 2d454ca44d..ee42c4b808 100644 --- a/frame/evm/precompile/modexp/src/lib.rs +++ b/frame/evm/precompile/modexp/src/lib.rs @@ -25,7 +25,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, }; @@ -110,12 +110,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()), @@ -195,6 +193,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(); @@ -203,9 +203,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); @@ -213,9 +211,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 { @@ -229,7 +225,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> { @@ -239,7 +236,7 @@ mod tests { #[test] fn test_empty_input() -> Result<(), PrecompileFailure> { - let input: [u8; 0] = []; + let input = Vec::new(); let cost: u64 = 1; @@ -249,7 +246,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"); } @@ -284,7 +283,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"); } @@ -317,7 +318,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"); } @@ -355,7 +358,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[..]); @@ -390,7 +395,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[..]); @@ -423,7 +430,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[..]); @@ -462,8 +471,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 8e245e41c3..63a19e3008 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -87,7 +87,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::{pallet::*, runner::Runner}; diff --git a/frame/evm/test-vector-support/Cargo.toml b/frame/evm/test-vector-support/Cargo.toml index 59e0c89984..9c359f9e21 100644 --- a/frame/evm/test-vector-support/Cargo.toml +++ b/frame/evm/test-vector-support/Cargo.toml @@ -9,20 +9,10 @@ repository = "https://github.com/paritytech/frontier/" description = "Test vector support for EVM pallet." [dependencies] -evm = { version = "0.35.0", default-features = false, features = ["with-codec"] } -hex = { version = "0.4.0", optional = true } -serde = { version = "1.0.101", features = ["derive"], optional = true } -serde_json = { version = "1.0", optional = true } +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" +sp-core = { version = "6.0.0", git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.19", default-features = false } fp-evm = { version = "3.0.0-dev", path = "../../../primitives/evm", default-features = false } - -[features] -default = ["std"] -std = [ - "evm/std", - "hex", - "serde", - "serde_json", - - "fp-evm/std", -] diff --git a/frame/evm/test-vector-support/src/lib.rs b/frame/evm/test-vector-support/src/lib.rs index 71d9792a8c..1a4a161e6e 100644 --- a/frame/evm/test-vector-support/src/lib.rs +++ b/frame/evm/test-vector-support/src/lib.rs @@ -15,15 +15,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use evm::{Context, ExitSucceed}; -use fp_evm::Precompile; - -#[cfg(feature = "std")] -use serde::Deserialize; +use evm::{Context, ExitError, ExitReason, ExitSucceed, Transfer}; +use fp_evm::{Precompile, PrecompileHandle}; +use sp_core::{H160, H256}; #[allow(non_snake_case)] -#[derive(Deserialize, Debug)] -#[cfg(feature = "std")] +#[derive(serde::Deserialize, Debug)] struct EthConsensusTest { Input: String, Expected: String, @@ -31,10 +28,78 @@ 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". -#[cfg(feature = "std")] pub fn test_precompile_test_vectors(filepath: &str) -> Result<(), String> { use std::fs; @@ -53,7 +118,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!( @@ -70,7 +137,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 c39b170bff..fd30f27e3e 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 3bf053ebb2..42eab50482 100644 --- a/primitives/evm/src/lib.rs +++ b/primitives/evm/src/lib.rs @@ -30,7 +30,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 17a4ec2b9e..5e89af31bd 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, } }