From 506c80682b04e7744ccf32be69db6b945e55821a Mon Sep 17 00:00:00 2001 From: takatakei Date: Mon, 27 Jul 2020 17:30:03 +0200 Subject: [PATCH] pallet-evm: add support for tuple-based precompile declarations (#6681) * pallet-evm: add support for tuple-based precompile declarations * Add missing license header * Switch to use impl_for_tuples * Remove unnecessary impl for () --- Cargo.toml | 1 + src/lib.rs | 26 ++--------------- src/precompiles.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 24 deletions(-) create mode 100644 src/precompiles.rs diff --git a/Cargo.toml b/Cargo.toml index 768d85b..05f44f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ primitive-types = { version = "0.7.0", default-features = false, features = ["rl rlp = { version = "0.4", default-features = false } evm = { version = "0.17", default-features = false } sha3 = { version = "0.8", default-features = false } +impl-trait-for-tuples = "0.1" [features] default = ["std"] diff --git a/src/lib.rs b/src/lib.rs index 68e86a9..0cbeac6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,8 +21,10 @@ #![cfg_attr(not(feature = "std"), no_std)] mod backend; +mod precompiles; mod tests; +pub use crate::precompiles::{Precompile, Precompiles}; pub use crate::backend::{Account, Log, Vicinity, Backend}; use sp_std::vec::Vec; @@ -175,30 +177,6 @@ impl> AddressMapping for HashedAddressMapping - ) -> Option, usize), ExitError>>; -} - -impl Precompiles for () { - fn execute( - _address: H160, - _input: &[u8], - _target_gas: Option - ) -> Option, usize), ExitError>> { - None - } -} - /// Substrate system chain ID. pub struct SystemChainId; diff --git a/src/precompiles.rs b/src/precompiles.rs new file mode 100644 index 0000000..a6a10d4 --- /dev/null +++ b/src/precompiles.rs @@ -0,0 +1,69 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use sp_std::vec::Vec; +use sp_core::H160; +use evm::{ExitError, ExitSucceed}; +use impl_trait_for_tuples::impl_for_tuples; + +/// Custom precompiles to be used by EVM engine. +pub trait Precompiles { + /// Try to execute the code address as precompile. If the code address is not + /// a precompile or the precompile is not yet available, return `None`. + /// Otherwise, calculate the amount of gas needed with given `input` and + /// `target_gas`. Return `Some(Ok(status, output, gas_used))` if the execution + /// is successful. Otherwise return `Some(Err(_))`. + fn execute( + address: H160, + input: &[u8], + target_gas: Option, + ) -> Option, usize), ExitError>>; +} + +/// 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, + ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError>; +} + +#[impl_for_tuples(16)] +#[tuple_types_no_default_trait_bound] +impl Precompiles for Tuple { + for_tuples!( where #( Tuple: Precompile )* ); + + fn execute( + address: H160, + input: &[u8], + target_gas: Option, + ) -> Option, usize), ExitError>> { + let mut index = 0; + + for_tuples!( #( + index += 1; + if address == H160::from_low_u64_be(index) { + return Some(Tuple::execute(input, target_gas)) + } + )* ); + + None + } +}