Skip to content

Commit

Permalink
chore: use keccak256 for blockhash (bluealloy#854)
Browse files Browse the repository at this point in the history
  • Loading branch information
minaminao authored and mattsse committed Nov 10, 2023
1 parent 50726f3 commit 25cc4cc
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 101 deletions.
178 changes: 91 additions & 87 deletions crates/precompile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,83 +62,18 @@ pub struct Precompiles {
}

impl Precompiles {
/// Extends the precompiles with the given precompiles.
///
/// Other precompiles with overwrite existing precompiles.
pub fn extend(&mut self, other: impl IntoIterator<Item = PrecompileWithAddress>) {
self.inner = self
.inner
.iter()
.cloned()
.chain(other)
.map(|i| (i.0, i.1.clone()))
.collect::<BTreeMap<Address, Precompile>>()
.into_iter()
.map(|(k, v)| PrecompileWithAddress(k, v))
.collect::<Vec<_>>();
}
}

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

#[derive(Clone)]
pub enum Precompile {
Standard(StandardPrecompileFn),
Env(EnvPrecompileFn),
}

impl fmt::Debug for Precompile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Precompile::Standard(_) => f.write_str("Standard"),
Precompile::Env(_) => f.write_str("Env"),
}
}
}

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

impl From<PrecompileWithAddress> for (Address, Precompile) {
fn from(value: PrecompileWithAddress) -> Self {
(value.0, value.1)
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum SpecId {
HOMESTEAD,
BYZANTIUM,
ISTANBUL,
BERLIN,
CANCUN,
LATEST,
}

impl SpecId {
/// Returns the appropriate precompile Spec for the primitive [SpecId](revm_primitives::SpecId)
pub const fn from_spec_id(spec_id: revm_primitives::SpecId) -> Self {
use revm_primitives::SpecId::*;
match spec_id {
FRONTIER | FRONTIER_THAWING | HOMESTEAD | DAO_FORK | TANGERINE | SPURIOUS_DRAGON => {
Self::HOMESTEAD
}
BYZANTIUM | CONSTANTINOPLE | PETERSBURG => Self::BYZANTIUM,
ISTANBUL | MUIR_GLACIER => Self::ISTANBUL,
BERLIN | LONDON | ARROW_GLACIER | GRAY_GLACIER | MERGE | SHANGHAI => Self::BERLIN,
CANCUN => Self::CANCUN,
LATEST => Self::LATEST,
#[cfg(feature = "optimism")]
BEDROCK | REGOLITH => Self::BERLIN,
/// Returns the precompiles for the given spec.
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::CANCUN => Self::cancun(),
SpecId::LATEST => Self::latest(),
}
}
}

impl Precompiles {
/// Returns precompiles for Homestead spec.
pub fn homestead() -> &'static Self {
static INSTANCE: OnceBox<Precompiles> = OnceBox::new();
Expand Down Expand Up @@ -230,24 +165,18 @@ impl Precompiles {
Self::cancun()
}

/// Returns the precompiles for the given spec.
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::CANCUN => Self::cancun(),
SpecId::LATEST => Self::latest(),
}
}

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

/// Consumes the type and returns all precompile addresses.
#[inline]
pub fn into_addresses(self) -> impl Iterator<Item = Address> {
self.inner.into_iter().map(|precompile| precompile.0)
}

/// Is the given address a precompile.
#[inline]
pub fn contains(&self, address: &Address) -> bool {
Expand All @@ -273,6 +202,81 @@ impl Precompiles {
pub fn len(&self) -> usize {
self.inner.len()
}

/// Extends the precompiles with the given precompiles.
///
/// Other precompiles with overwrite existing precompiles.
pub fn extend(&mut self, other: impl IntoIterator<Item = PrecompileWithAddress>) {
self.inner = self
.inner
.iter()
.cloned()
.chain(other)
.map(|i| (i.0, i.1.clone()))
.collect::<BTreeMap<Address, Precompile>>()
.into_iter()
.map(|(k, v)| PrecompileWithAddress(k, v))
.collect::<Vec<_>>();
}
}

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

#[derive(Clone)]
pub enum Precompile {
Standard(StandardPrecompileFn),
Env(EnvPrecompileFn),
}

impl fmt::Debug for Precompile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Precompile::Standard(_) => f.write_str("Standard"),
Precompile::Env(_) => f.write_str("Env"),
}
}
}

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

impl From<PrecompileWithAddress> for (Address, Precompile) {
fn from(value: PrecompileWithAddress) -> Self {
(value.0, value.1)
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum SpecId {
HOMESTEAD,
BYZANTIUM,
ISTANBUL,
BERLIN,
CANCUN,
LATEST,
}

impl SpecId {
/// Returns the appropriate precompile Spec for the primitive [SpecId](revm_primitives::SpecId)
pub const fn from_spec_id(spec_id: revm_primitives::SpecId) -> Self {
use revm_primitives::SpecId::*;
match spec_id {
FRONTIER | FRONTIER_THAWING | HOMESTEAD | DAO_FORK | TANGERINE | SPURIOUS_DRAGON => {
Self::HOMESTEAD
}
BYZANTIUM | CONSTANTINOPLE | PETERSBURG => Self::BYZANTIUM,
ISTANBUL | MUIR_GLACIER => Self::ISTANBUL,
BERLIN | LONDON | ARROW_GLACIER | GRAY_GLACIER | MERGE | SHANGHAI => Self::BERLIN,
CANCUN => Self::CANCUN,
LATEST => Self::LATEST,
#[cfg(feature = "optimism")]
BEDROCK | REGOLITH => Self::BERLIN,
}
}
}

/// Const function for making an address by concatenating the bytes from two given numbers.
Expand Down
4 changes: 2 additions & 2 deletions crates/revm/src/db/emptydb.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::{convert::Infallible, fmt, marker::PhantomData};
use revm_interpreter::primitives::{
db::{Database, DatabaseRef},
AccountInfo, Address, Bytecode, B256, U256,
keccak256, AccountInfo, Address, Bytecode, B256, U256,
};

/// An empty database that always returns default values when queried.
Expand Down Expand Up @@ -101,6 +101,6 @@ impl<E> DatabaseRef for EmptyDBTyped<E> {

#[inline]
fn block_hash_ref(&self, number: U256) -> Result<B256, Self::Error> {
Ok(number.to_be_bytes().into())
Ok(keccak256(number.to_be_bytes::<{ U256::BYTES }>()))
}
}
8 changes: 4 additions & 4 deletions crates/revm/src/db/states/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ mod tests {
states::reverts::AccountInfoRevert, AccountRevert, AccountStatus, BundleAccount,
RevertToSlot,
};
use revm_interpreter::primitives::StorageSlot;
use revm_interpreter::primitives::{keccak256, StorageSlot};

#[test]
fn block_hash_cache() {
Expand All @@ -315,9 +315,9 @@ mod tests {

let test_number = BLOCK_HASH_HISTORY as u64 + 2;

let block1_hash = B256::from(U256::from(1).to_be_bytes());
let block2_hash = B256::from(U256::from(2).to_be_bytes());
let block_test_hash = B256::from(U256::from(test_number).to_be_bytes());
let block1_hash = keccak256(&U256::from(1).to_be_bytes::<{ U256::BYTES }>());
let block2_hash = keccak256(&U256::from(2).to_be_bytes::<{ U256::BYTES }>());
let block_test_hash = keccak256(&U256::from(test_number).to_be_bytes::<{ U256::BYTES }>());

assert_eq!(
state.block_hashes,
Expand Down
10 changes: 2 additions & 8 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,8 @@ impl<'a, SPEC: Spec + 'static, DB: Database> EVMImpl<'a, SPEC, DB> {
inspector: Option<&'a mut dyn Inspector<DB>>,
precompiles: Precompiles,
) -> Self {
let journaled_state = JournaledState::new(
SPEC::SPEC_ID,
precompiles
.addresses()
.into_iter()
.cloned()
.collect::<Vec<_>>(),
);
let journaled_state =
JournaledState::new(SPEC::SPEC_ID, precompiles.addresses().copied().collect());
// If T is present it should be a generic T that modifies handler.
let instruction_table = if inspector.is_some() {
let instruction_table = make_boxed_instruction_table::<Self, SPEC, _>(
Expand Down

0 comments on commit 25cc4cc

Please sign in to comment.