Skip to content

Commit

Permalink
Cache precompile hashmaps
Browse files Browse the repository at this point in the history
  • Loading branch information
rakita committed Aug 29, 2022
1 parent 5572e30 commit 8191892
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 42 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/revm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ macro_rules! create_evm {
$db,
$env,
$inspector,
Precompiles::new::<{ SpecId::to_precompile_id($spec::SPEC_ID) }>(),
Precompiles::new(SpecId::to_precompile_id($spec::SPEC_ID)).clone(),
)) as Box<dyn Transact + 'a>
};
}
Expand Down
10 changes: 5 additions & 5 deletions crates/revm/src/specification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ pub enum SpecId {
}

impl SpecId {
pub const fn to_precompile_id(self) -> u8 {
pub const fn to_precompile_id(self) -> PrecompileId {
match self {
FRONTIER | FRONTIER_THAWING | HOMESTEAD | DAO_FORK | TANGERINE | SPURIOUS_DRAGON => {
PrecompileId::HOMESTEAD as u8
PrecompileId::HOMESTEAD
}
BYZANTIUM | CONSTANTINOPLE | PETERSBURG => PrecompileId::BYZANTIUM as u8,
ISTANBUL | MUIR_GLACIER => PrecompileId::ISTANBUL as u8,
BYZANTIUM | CONSTANTINOPLE | PETERSBURG => PrecompileId::BYZANTIUM,
ISTANBUL | MUIR_GLACIER => PrecompileId::ISTANBUL,
BERLIN | LONDON | ARROW_GLACIER | GRAY_GLACIER | MERGE | LATEST => {
PrecompileId::BERLIN as u8
PrecompileId::BERLIN
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/revm_precompiles/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ secp256k1 = { version = "0.24.0", default-features = false, features = ["alloc",
sha2 = { version = "0.10.2", default-features = false }
sha3 = { version = "0.10.1", default-features = false }
hashbrown = { version = "0.12" }
once_cell = "1.13"

[dev-dependencies]
hex = "0.4"
Expand Down
117 changes: 81 additions & 36 deletions crates/revm_precompiles/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![no_std]

use bytes::Bytes;
use once_cell::sync::OnceCell;
use primitive_types::{H160 as Address, H256, U256};

mod blake2;
Expand Down Expand Up @@ -61,13 +62,14 @@ pub type PrecompileResult = Result<PrecompileOutput, Return>;
pub type StandardPrecompileFn = fn(&[u8], u64) -> PrecompileResult;
pub type CustomPrecompileFn = fn(&[u8], u64) -> PrecompileResult;

#[derive(Clone)]
pub struct Precompiles {
fun: HashMap<Address, Precompile>,
}

impl Default for Precompiles {
fn default() -> Self {
Self::new::<3>() //berlin
Self::new(SpecId::LATEST).clone() //berlin
}
}

Expand All @@ -82,6 +84,7 @@ pub enum SpecId {
BYZANTIUM = 1,
ISTANBUL = 2,
BERLIN = 3,
LATEST = 4,
}

impl SpecId {
Expand All @@ -91,45 +94,87 @@ impl SpecId {
}

impl Precompiles {
pub fn new<const SPEC_ID: u8>() -> Self {
let mut fun: HashMap<Address, Precompile> = HashMap::new();
let mut insert_fun =
|precompile: (Address, Precompile)| fun.insert(precompile.0, precompile.1);

if SpecId::HOMESTEAD.enabled(SPEC_ID) {
insert_fun(secp256k1::ECRECOVER);
insert_fun(hash::SHA256);
insert_fun(hash::RIPEMD160);
insert_fun(identity::FUN);
}
pub fn homestead() -> &'static Self {
static INSTANCE: OnceCell<Precompiles> = OnceCell::new();
INSTANCE.get_or_init(|| {
let fun = vec![
secp256k1::ECRECOVER,
hash::SHA256,
hash::RIPEMD160,
identity::FUN,
]
.into_iter()
.collect();
Self { fun }
})
}

if SpecId::ISTANBUL.enabled(SPEC_ID) {
// EIP-152: Add BLAKE2 compression function `F` precompile.
insert_fun(blake2::FUN);
}
pub fn byzantium() -> &'static Self {
static INSTANCE: OnceCell<Precompiles> = OnceCell::new();
INSTANCE.get_or_init(|| {
let mut precompiles = Self::homestead().clone();
precompiles.fun.extend(
vec![
// EIP-196: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128.
// EIP-197: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128.
bn128::add::BYZANTIUM,
bn128::mul::BYZANTIUM,
bn128::pair::BYZANTIUM,
// EIP-198: Big integer modular exponentiation.
modexp::BYZANTIUM,
]
.into_iter(),
);
precompiles
})
}

if SpecId::ISTANBUL.enabled(SPEC_ID) {
// EIP-1108: Reduce alt_bn128 precompile gas costs.
insert_fun(bn128::add::ISTANBUL);
insert_fun(bn128::mul::ISTANBUL);
insert_fun(bn128::pair::ISTANBUL);
} else if SpecId::BYZANTIUM.enabled(SPEC_ID) {
// EIP-196: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128.
// EIP-197: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128.
insert_fun(bn128::add::BYZANTIUM);
insert_fun(bn128::mul::BYZANTIUM);
insert_fun(bn128::pair::BYZANTIUM);
}
pub fn istanbul() -> &'static Self {
static INSTANCE: OnceCell<Precompiles> = OnceCell::new();
INSTANCE.get_or_init(|| {
let mut precompiles = Self::byzantium().clone();
precompiles.fun.extend(
vec![
// EIP-152: Add BLAKE2 compression function `F` precompile.
blake2::FUN,
// EIP-1108: Reduce alt_bn128 precompile gas costs.
bn128::add::ISTANBUL,
bn128::mul::ISTANBUL,
bn128::pair::ISTANBUL,
]
.into_iter(),
);
precompiles
})
}

if SpecId::BERLIN.enabled(SPEC_ID) {
// EIP-2565: ModExp Gas Cost.
insert_fun(modexp::BERLIN);
} else if SpecId::BYZANTIUM.enabled(SPEC_ID) {
// EIP-198: Big integer modular exponentiation.
insert_fun(modexp::BYZANTIUM);
}
pub fn berlin() -> &'static Self {
static INSTANCE: OnceCell<Precompiles> = OnceCell::new();
INSTANCE.get_or_init(|| {
let mut precompiles = Self::istanbul().clone();
precompiles.fun.extend(
vec![
// EIP-2565: ModExp Gas Cost.
modexp::BERLIN,
]
.into_iter(),
);
precompiles
})
}

Self { fun }
pub fn latest() -> &'static Self {
Self::berlin()
}

pub fn new(spec: SpecId) -> &'static Self {
match spec {
SpecId::HOMESTEAD => Self::homestead(),
SpecId::BYZANTIUM => Self::byzantium(),
SpecId::ISTANBUL => Self::istanbul(),
SpecId::BERLIN => Self::berlin(),
SpecId::LATEST => Self::latest(),
}
}

pub fn addresses(&self) -> impl IntoIterator<Item = &Address> {
Expand Down

0 comments on commit 8191892

Please sign in to comment.