Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Refactor precompile list from Hash to vec #823

Merged
merged 12 commits into from
Oct 25, 2023
4 changes: 2 additions & 2 deletions crates/precompile/src/blake2.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::{Error, PrecompileAddress, StandardPrecompileFn};
use crate::{Error, PrecompileWithAddress, StandardPrecompileFn};
use crate::{Precompile, PrecompileResult};
use core::convert::TryInto;

const F_ROUND: u64 = 1;
const INPUT_LENGTH: usize = 213;

pub const FUN: PrecompileAddress = PrecompileAddress(
pub const FUN: PrecompileWithAddress = PrecompileWithAddress(
crate::u64_to_address(9),
Precompile::Standard(run as StandardPrecompileFn),
);
Expand Down
16 changes: 9 additions & 7 deletions crates/precompile/src/bn128.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::{primitives::U256, Address, Error, Precompile, PrecompileAddress, PrecompileResult};
use crate::{
primitives::U256, Address, Error, Precompile, PrecompileResult, PrecompileWithAddress,
};
use alloc::vec::Vec;

pub mod add {
use super::*;
const ADDRESS: Address = crate::u64_to_address(6);

pub const ISTANBUL: PrecompileAddress = PrecompileAddress(
pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress(
ADDRESS,
Precompile::Standard(|input: &[u8], target_gas: u64| -> PrecompileResult {
if 150 > target_gas {
Expand All @@ -15,7 +17,7 @@ pub mod add {
}),
);

pub const BYZANTIUM: PrecompileAddress = PrecompileAddress(
pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress(
ADDRESS,
Precompile::Standard(|input: &[u8], target_gas: u64| -> PrecompileResult {
if 500 > target_gas {
Expand All @@ -29,7 +31,7 @@ pub mod add {
pub mod mul {
use super::*;
const ADDRESS: Address = crate::u64_to_address(7);
pub const ISTANBUL: PrecompileAddress = PrecompileAddress(
pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress(
ADDRESS,
Precompile::Standard(|input: &[u8], gas_limit: u64| -> PrecompileResult {
if 6_000 > gas_limit {
Expand All @@ -39,7 +41,7 @@ pub mod mul {
}),
);

pub const BYZANTIUM: PrecompileAddress = PrecompileAddress(
pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress(
ADDRESS,
Precompile::Standard(|input: &[u8], gas_limit: u64| -> PrecompileResult {
if 40_000 > gas_limit {
Expand All @@ -56,7 +58,7 @@ pub mod pair {

const ISTANBUL_PAIR_PER_POINT: u64 = 34_000;
const ISTANBUL_PAIR_BASE: u64 = 45_000;
pub const ISTANBUL: PrecompileAddress = PrecompileAddress(
pub const ISTANBUL: PrecompileWithAddress = PrecompileWithAddress(
ADDRESS,
Precompile::Standard(|input: &[u8], target_gas: u64| -> PrecompileResult {
super::run_pair(
Expand All @@ -70,7 +72,7 @@ pub mod pair {

const BYZANTIUM_PAIR_PER_POINT: u64 = 80_000;
const BYZANTIUM_PAIR_BASE: u64 = 100_000;
pub const BYZANTIUM: PrecompileAddress = PrecompileAddress(
pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress(
ADDRESS,
Precompile::Standard(|input: &[u8], target_gas: u64| -> PrecompileResult {
super::run_pair(
Expand Down
6 changes: 3 additions & 3 deletions crates/precompile/src/hash.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use super::calc_linear_cost_u32;
use crate::{Error, Precompile, PrecompileAddress, PrecompileResult, StandardPrecompileFn};
use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress, StandardPrecompileFn};
use sha2::*;

pub const SHA256: PrecompileAddress = PrecompileAddress(
pub const SHA256: PrecompileWithAddress = PrecompileWithAddress(
crate::u64_to_address(2),
Precompile::Standard(sha256_run as StandardPrecompileFn),
);
pub const RIPEMD160: PrecompileAddress = PrecompileAddress(
pub const RIPEMD160: PrecompileWithAddress = PrecompileWithAddress(
crate::u64_to_address(3),
Precompile::Standard(ripemd160_run as StandardPrecompileFn),
);
Expand Down
4 changes: 2 additions & 2 deletions crates/precompile/src/identity.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::calc_linear_cost_u32;
use crate::{Error, Precompile, PrecompileAddress, PrecompileResult, StandardPrecompileFn};
use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress, StandardPrecompileFn};

pub const FUN: PrecompileAddress = PrecompileAddress(
pub const FUN: PrecompileWithAddress = PrecompileWithAddress(
crate::u64_to_address(4),
Precompile::Standard(identity_run as StandardPrecompileFn),
);
Expand Down
5 changes: 3 additions & 2 deletions crates/precompile/src/kzg_point_evaluation.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::{Address, Error, Precompile, PrecompileAddress, PrecompileResult};
use crate::{Address, Error, Precompile, PrecompileResult, PrecompileWithAddress};
use c_kzg::{Bytes32, Bytes48, KzgProof, KzgSettings};
use revm_primitives::{hex_literal::hex, Env};
use sha2::{Digest, Sha256};

pub const POINT_EVALUATION: PrecompileAddress = PrecompileAddress(ADDRESS, Precompile::Env(run));
pub const POINT_EVALUATION: PrecompileWithAddress =
PrecompileWithAddress(ADDRESS, Precompile::Env(run));

const ADDRESS: Address = crate::u64_to_address(0x0A);
const GAS_COST: u64 = 50_000;
Expand Down
121 changes: 61 additions & 60 deletions crates/precompile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@ use once_cell::race::OnceBox;
pub use revm_primitives as primitives;
pub use revm_primitives::{
precompile::{PrecompileError as Error, *},
Bytes, HashMap,
Address, Bytes, HashMap, B256,
};

pub type Address = [u8; 20];
pub type B256 = [u8; 32];

pub fn calc_linear_cost_u32(len: usize, base: u64, word: u64) -> u64 {
(len as u64 + 32 - 1) / 32 * word + base
}
Expand Down Expand Up @@ -61,7 +58,7 @@ impl PrecompileOutput {
}
#[derive(Clone, Debug)]
pub struct Precompiles {
pub fun: HashMap<Address, Precompile>,
pub inner: Vec<PrecompileWithAddress>,
}

impl Default for Precompiles {
Expand All @@ -86,10 +83,10 @@ impl fmt::Debug for Precompile {
}

#[derive(Clone, Debug)]
pub struct PrecompileAddress(Address, Precompile);
pub struct PrecompileWithAddress(Address, Precompile);

impl From<PrecompileAddress> for (Address, Precompile) {
fn from(value: PrecompileAddress) -> Self {
impl From<PrecompileWithAddress> for (Address, Precompile) {
fn from(value: PrecompileWithAddress) -> Self {
(value.0, value.1)
}
}
Expand Down Expand Up @@ -121,86 +118,77 @@ impl SpecId {
BEDROCK | REGOLITH => Self::BERLIN,
}
}

pub const fn enabled(self, spec_id: u8) -> bool {
spec_id >= self as u8
}
}

impl Precompiles {
/// Returns precompiles for Homestead spec.
pub fn homestead() -> &'static Self {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
INSTANCE.get_or_init(|| {
let fun = [
let mut inner = vec![
secp256k1::ECRECOVER,
hash::SHA256,
hash::RIPEMD160,
identity::FUN,
]
.into_iter()
.map(From::from)
.collect();
Box::new(Self { fun })
];
inner.sort_unstable_by_key(|i| i.0);
Box::new(Self { inner })
})
}

/// Returns precompiles for Byzantium spec.
pub fn byzantium() -> &'static Self {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
INSTANCE.get_or_init(|| {
let mut precompiles = Box::new(Self::homestead().clone());
precompiles.fun.extend(
[
// 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()
.map(From::from),
);
precompiles.inner.extend([
// 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,
]);
precompiles.inner.sort_unstable_by_key(|i| i.0);
precompiles
})
}

/// Returns precompiles for Istanbul spec.
pub fn istanbul() -> &'static Self {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
INSTANCE.get_or_init(|| {
let mut precompiles = Box::new(Self::byzantium().clone());
precompiles.fun.extend(
[
// 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()
.map(From::from),
);
precompiles.inner.extend([
// 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,
]);
precompiles.inner.sort_unstable_by_key(|i| i.0);
precompiles
})
}

/// Returns precompiles for Berlin spec.
pub fn berlin() -> &'static Self {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
INSTANCE.get_or_init(|| {
let mut precompiles = Box::new(Self::istanbul().clone());
precompiles.fun.extend(
[
// EIP-2565: ModExp Gas Cost.
modexp::BERLIN,
]
.into_iter()
.map(From::from),
);
precompiles.inner.extend([
// EIP-2565: ModExp Gas Cost.
modexp::BERLIN,
]);
precompiles.inner.sort_unstable_by_key(|i| i.0);
precompiles
})
}

/// Returns precompiles for Cancun spec.
///
/// If `std` feature is not enabled KZG Point Evaluation precompile will not be included.
rakita marked this conversation as resolved.
Show resolved Hide resolved
pub fn cancun() -> &'static Self {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
Expand All @@ -209,7 +197,7 @@ impl Precompiles {
#[cfg(feature = "c-kzg")]
{
let mut precompiles = Box::new(Self::berlin().clone());
precompiles.fun.extend(
precompiles.inner.extend(
[
// EIP-4844: Shard Blob Transactions
kzg_point_evaluation::POINT_EVALUATION,
Expand All @@ -226,10 +214,12 @@ impl Precompiles {
})
}

/// Returns the precompiles for the latest spec.
pub fn latest() -> &'static Self {
Self::berlin()
Self::cancun()
}

/// Returns the precompiles for the given spec.
pub fn new(spec: SpecId) -> &'static Self {
match spec {
SpecId::HOMESTEAD => Self::homestead(),
Expand All @@ -241,25 +231,36 @@ impl Precompiles {
}
}

/// Returns an iterator over the precompiles addresses.
#[inline]
pub fn addresses(&self) -> impl IntoIterator<Item = &Address> {
self.fun.keys()
self.inner.iter().map(|i| &i.0)
}

/// Is the given address a precompile.
#[inline]
pub fn contains(&self, address: &Address) -> bool {
self.fun.contains_key(address)
self.get(address).is_some()
}

/// Returns the precompile for the given address.
#[inline]
pub fn get(&self, address: &Address) -> Option<Precompile> {
//return None;
self.fun.get(address).cloned()
self.inner
.binary_search_by_key(address, |i| i.0)
.ok()
.map(|i| self.inner[i].1.clone())
}

/// Is the precompiles list empty.
pub fn is_empty(&self) -> bool {
self.fun.len() == 0
self.inner.len() == 0
}

/// Returns the number of precompiles.
pub fn len(&self) -> usize {
self.fun.len()
self.inner.len()
}
}

Expand All @@ -270,7 +271,7 @@ impl Precompiles {
#[inline]
const fn u64_to_address(x: u64) -> Address {
let x = x.to_be_bytes();
[
Address::new([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7],
]
])
}
6 changes: 3 additions & 3 deletions crates/precompile/src/modexp.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use crate::{
primitives::U256,
utilities::{get_right_padded, get_right_padded_vec, left_padding, left_padding_vec},
Error, Precompile, PrecompileAddress, PrecompileResult, StandardPrecompileFn,
Error, Precompile, PrecompileResult, PrecompileWithAddress, StandardPrecompileFn,
};
use alloc::vec::Vec;
use aurora_engine_modexp::modexp;
use core::cmp::{max, min};

pub const BYZANTIUM: PrecompileAddress = PrecompileAddress(
pub const BYZANTIUM: PrecompileWithAddress = PrecompileWithAddress(
crate::u64_to_address(5),
Precompile::Standard(byzantium_run as StandardPrecompileFn),
);

pub const BERLIN: PrecompileAddress = PrecompileAddress(
pub const BERLIN: PrecompileWithAddress = PrecompileWithAddress(
crate::u64_to_address(5),
Precompile::Standard(berlin_run as StandardPrecompileFn),
);
Expand Down
Loading
Loading