Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 21c02bc

Browse files
authored
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 ()
1 parent 1bb7bb4 commit 21c02bc

File tree

4 files changed

+73
-24
lines changed

4 files changed

+73
-24
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frame/evm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ primitive-types = { version = "0.7.0", default-features = false, features = ["rl
2626
rlp = { version = "0.4", default-features = false }
2727
evm = { version = "0.17", default-features = false }
2828
sha3 = { version = "0.8", default-features = false }
29+
impl-trait-for-tuples = "0.1"
2930

3031
[features]
3132
default = ["std"]

frame/evm/src/lib.rs

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
#![cfg_attr(not(feature = "std"), no_std)]
2222

2323
mod backend;
24+
mod precompiles;
2425
mod tests;
2526

27+
pub use crate::precompiles::{Precompile, Precompiles};
2628
pub use crate::backend::{Account, Log, Vicinity, Backend};
2729

2830
use sp_std::vec::Vec;
@@ -175,30 +177,6 @@ impl<H: Hasher<Out=H256>> AddressMapping<AccountId32> for HashedAddressMapping<H
175177
}
176178
}
177179

178-
/// Custom precompiles to be used by EVM engine.
179-
pub trait Precompiles {
180-
/// Try to execute the code address as precompile. If the code address is not
181-
/// a precompile or the precompile is not yet available, return `None`.
182-
/// Otherwise, calculate the amount of gas needed with given `input` and
183-
/// `target_gas`. Return `Some(Ok(status, output, gas_used))` if the execution
184-
/// is successful. Otherwise return `Some(Err(_))`.
185-
fn execute(
186-
address: H160,
187-
input: &[u8],
188-
target_gas: Option<usize>
189-
) -> Option<core::result::Result<(ExitSucceed, Vec<u8>, usize), ExitError>>;
190-
}
191-
192-
impl Precompiles for () {
193-
fn execute(
194-
_address: H160,
195-
_input: &[u8],
196-
_target_gas: Option<usize>
197-
) -> Option<core::result::Result<(ExitSucceed, Vec<u8>, usize), ExitError>> {
198-
None
199-
}
200-
}
201-
202180
/// Substrate system chain ID.
203181
pub struct SystemChainId;
204182

frame/evm/src/precompiles.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
use sp_std::vec::Vec;
19+
use sp_core::H160;
20+
use evm::{ExitError, ExitSucceed};
21+
use impl_trait_for_tuples::impl_for_tuples;
22+
23+
/// Custom precompiles to be used by EVM engine.
24+
pub trait Precompiles {
25+
/// Try to execute the code address as precompile. If the code address is not
26+
/// a precompile or the precompile is not yet available, return `None`.
27+
/// Otherwise, calculate the amount of gas needed with given `input` and
28+
/// `target_gas`. Return `Some(Ok(status, output, gas_used))` if the execution
29+
/// is successful. Otherwise return `Some(Err(_))`.
30+
fn execute(
31+
address: H160,
32+
input: &[u8],
33+
target_gas: Option<usize>,
34+
) -> Option<core::result::Result<(ExitSucceed, Vec<u8>, usize), ExitError>>;
35+
}
36+
37+
/// One single precompile used by EVM engine.
38+
pub trait Precompile {
39+
/// Try to execute the precompile. Calculate the amount of gas needed with given `input` and
40+
/// `target_gas`. Return `Ok(status, output, gas_used)` if the execution is
41+
/// successful. Otherwise return `Err(_)`.
42+
fn execute(
43+
input: &[u8],
44+
target_gas: Option<usize>,
45+
) -> core::result::Result<(ExitSucceed, Vec<u8>, usize), ExitError>;
46+
}
47+
48+
#[impl_for_tuples(16)]
49+
#[tuple_types_no_default_trait_bound]
50+
impl Precompiles for Tuple {
51+
for_tuples!( where #( Tuple: Precompile )* );
52+
53+
fn execute(
54+
address: H160,
55+
input: &[u8],
56+
target_gas: Option<usize>,
57+
) -> Option<core::result::Result<(ExitSucceed, Vec<u8>, usize), ExitError>> {
58+
let mut index = 0;
59+
60+
for_tuples!( #(
61+
index += 1;
62+
if address == H160::from_low_u64_be(index) {
63+
return Some(Tuple::execute(input, target_gas))
64+
}
65+
)* );
66+
67+
None
68+
}
69+
}

0 commit comments

Comments
 (0)