mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-30 03:01:58 -04:00
feat: add revm-inspectors crate and accesslist inspector (#1529)
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
use reth_primitives::{Account, Log as RethLog, H160, H256, KECCAK_EMPTY};
|
||||
use revm::primitives::{AccountInfo, Log};
|
||||
|
||||
/// Check equality between [`reth_primitives::Log`] and [`revm::primitives::Log`]
|
||||
pub fn is_log_equal(revm_log: &Log, reth_log: &reth_primitives::Log) -> bool {
|
||||
revm_log.topics.len() == reth_log.topics.len() &&
|
||||
revm_log.address.0 == reth_log.address.0 &&
|
||||
revm_log.data == reth_log.data.0 &&
|
||||
!revm_log
|
||||
.topics
|
||||
.iter()
|
||||
.zip(reth_log.topics.iter())
|
||||
.any(|(revm_topic, reth_topic)| revm_topic.0 != reth_topic.0)
|
||||
}
|
||||
|
||||
/// Into reth primitive [Log] from [revm::primitives::Log].
|
||||
pub fn into_reth_log(log: Log) -> RethLog {
|
||||
RethLog {
|
||||
address: H160(log.address.0),
|
||||
topics: log.topics.into_iter().map(|h| H256(h.0)).collect(),
|
||||
data: log.data.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create reth primitive [Account] from [revm::primitives::AccountInfo].
|
||||
/// Check if revm bytecode hash is [KECCAK_EMPTY] and put None to reth [Account]
|
||||
pub fn to_reth_acc(revm_acc: &AccountInfo) -> Account {
|
||||
let code_hash = revm_acc.code_hash;
|
||||
Account {
|
||||
balance: revm_acc.balance,
|
||||
nonce: revm_acc.nonce,
|
||||
bytecode_hash: if code_hash == KECCAK_EMPTY { None } else { Some(code_hash) },
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
//! Reth block execution/validation configuration and constants
|
||||
|
||||
use reth_primitives::{ChainSpec, Hardfork, Head};
|
||||
|
||||
/// Two ethereum worth of wei
|
||||
pub const WEI_2ETH: u128 = 2000000000000000000u128;
|
||||
/// Three ethereum worth of wei
|
||||
pub const WEI_3ETH: u128 = 3000000000000000000u128;
|
||||
/// Five ethereum worth of wei
|
||||
pub const WEI_5ETH: u128 = 5000000000000000000u128;
|
||||
|
||||
/// return revm_spec from spec configuration.
|
||||
pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm::primitives::SpecId {
|
||||
if chain_spec.fork(Hardfork::Shanghai).active_at_head(&block) {
|
||||
revm::primitives::SHANGHAI
|
||||
} else if chain_spec.fork(Hardfork::Paris).active_at_head(&block) {
|
||||
revm::primitives::MERGE
|
||||
} else if chain_spec.fork(Hardfork::London).active_at_head(&block) {
|
||||
revm::primitives::LONDON
|
||||
} else if chain_spec.fork(Hardfork::Berlin).active_at_head(&block) {
|
||||
revm::primitives::BERLIN
|
||||
} else if chain_spec.fork(Hardfork::Istanbul).active_at_head(&block) {
|
||||
revm::primitives::ISTANBUL
|
||||
} else if chain_spec.fork(Hardfork::Petersburg).active_at_head(&block) {
|
||||
revm::primitives::PETERSBURG
|
||||
} else if chain_spec.fork(Hardfork::Byzantium).active_at_head(&block) {
|
||||
revm::primitives::BYZANTIUM
|
||||
} else if chain_spec.fork(Hardfork::SpuriousDragon).active_at_head(&block) {
|
||||
revm::primitives::SPURIOUS_DRAGON
|
||||
} else if chain_spec.fork(Hardfork::Tangerine).active_at_head(&block) {
|
||||
revm::primitives::TANGERINE
|
||||
} else if chain_spec.fork(Hardfork::Homestead).active_at_head(&block) {
|
||||
revm::primitives::HOMESTEAD
|
||||
} else if chain_spec.fork(Hardfork::Frontier).active_at_head(&block) {
|
||||
revm::primitives::FRONTIER
|
||||
} else {
|
||||
panic!("wrong configuration")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::config::revm_spec;
|
||||
use reth_primitives::{ChainSpecBuilder, Head, MAINNET, U256};
|
||||
#[test]
|
||||
fn test_to_revm_spec() {
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().paris_activated().build(), Head::default()),
|
||||
revm::primitives::MERGE
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().london_activated().build(), Head::default()),
|
||||
revm::primitives::LONDON
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().berlin_activated().build(), Head::default()),
|
||||
revm::primitives::BERLIN
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().istanbul_activated().build(), Head::default()),
|
||||
revm::primitives::ISTANBUL
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().petersburg_activated().build(), Head::default()),
|
||||
revm::primitives::PETERSBURG
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().byzantium_activated().build(), Head::default()),
|
||||
revm::primitives::BYZANTIUM
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(
|
||||
&ChainSpecBuilder::mainnet().spurious_dragon_activated().build(),
|
||||
Head::default()
|
||||
),
|
||||
revm::primitives::SPURIOUS_DRAGON
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(
|
||||
&ChainSpecBuilder::mainnet().tangerine_whistle_activated().build(),
|
||||
Head::default()
|
||||
),
|
||||
revm::primitives::TANGERINE
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().homestead_activated().build(), Head::default()),
|
||||
revm::primitives::HOMESTEAD
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), Head::default()),
|
||||
revm::primitives::FRONTIER
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eth_spec() {
|
||||
assert_eq!(
|
||||
revm_spec(
|
||||
&MAINNET,
|
||||
Head {
|
||||
total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128),
|
||||
difficulty: U256::from(10_u128),
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
revm::primitives::MERGE
|
||||
);
|
||||
// TTD trumps the block number
|
||||
assert_eq!(
|
||||
revm_spec(
|
||||
&MAINNET,
|
||||
Head {
|
||||
number: 15537394 - 10,
|
||||
total_difficulty: U256::from(58_750_000_000_000_000_000_010_u128),
|
||||
difficulty: U256::from(10_u128),
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
revm::primitives::MERGE
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 15537394 - 10, ..Default::default() }),
|
||||
revm::primitives::LONDON
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 12244000 + 10, ..Default::default() }),
|
||||
revm::primitives::BERLIN
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 12244000 - 10, ..Default::default() }),
|
||||
revm::primitives::ISTANBUL
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 7280000 + 10, ..Default::default() }),
|
||||
revm::primitives::PETERSBURG
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 7280000 - 10, ..Default::default() }),
|
||||
revm::primitives::BYZANTIUM
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 2675000 + 10, ..Default::default() }),
|
||||
revm::primitives::SPURIOUS_DRAGON
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 2675000 - 10, ..Default::default() }),
|
||||
revm::primitives::TANGERINE
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 1150000 + 10, ..Default::default() }),
|
||||
revm::primitives::HOMESTEAD
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&MAINNET, Head { number: 1150000 - 10, ..Default::default() }),
|
||||
revm::primitives::FRONTIER
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
use crate::config::revm_spec;
|
||||
use reth_primitives::{
|
||||
Address, ChainSpec, Head, Header, Transaction, TransactionKind, TransactionSigned, TxEip1559,
|
||||
TxEip2930, TxLegacy, U256,
|
||||
};
|
||||
use revm::primitives::{AnalysisKind, BlockEnv, CfgEnv, TransactTo, TxEnv};
|
||||
|
||||
/// Fill [CfgEnv] fields according to the chain spec and given header
|
||||
pub fn fill_cfg_env(
|
||||
cfg_env: &mut CfgEnv,
|
||||
chain_spec: &ChainSpec,
|
||||
header: &Header,
|
||||
total_difficulty: U256,
|
||||
) {
|
||||
let spec_id = revm_spec(
|
||||
chain_spec,
|
||||
Head {
|
||||
number: header.number,
|
||||
timestamp: header.timestamp,
|
||||
difficulty: header.difficulty,
|
||||
total_difficulty,
|
||||
hash: Default::default(),
|
||||
},
|
||||
);
|
||||
|
||||
cfg_env.chain_id = U256::from(chain_spec.chain().id());
|
||||
cfg_env.spec_id = spec_id;
|
||||
cfg_env.perf_all_precompiles_have_balance = false;
|
||||
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Raw;
|
||||
}
|
||||
/// Fill block environment from Block.
|
||||
pub fn fill_block_env(block_env: &mut BlockEnv, header: &Header, after_merge: bool) {
|
||||
block_env.number = U256::from(header.number);
|
||||
block_env.coinbase = header.beneficiary;
|
||||
block_env.timestamp = U256::from(header.timestamp);
|
||||
if after_merge {
|
||||
block_env.prevrandao = Some(header.mix_hash);
|
||||
block_env.difficulty = U256::ZERO;
|
||||
} else {
|
||||
block_env.difficulty = header.difficulty;
|
||||
block_env.prevrandao = None;
|
||||
}
|
||||
block_env.basefee = U256::from(header.base_fee_per_gas.unwrap_or_default());
|
||||
block_env.gas_limit = U256::from(header.gas_limit);
|
||||
}
|
||||
|
||||
/// Fill transaction environment from Transaction.
|
||||
pub fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) {
|
||||
tx_env.caller = sender;
|
||||
match transaction.as_ref() {
|
||||
Transaction::Legacy(TxLegacy {
|
||||
nonce,
|
||||
chain_id,
|
||||
gas_price,
|
||||
gas_limit,
|
||||
to,
|
||||
value,
|
||||
input,
|
||||
}) => {
|
||||
tx_env.gas_limit = *gas_limit;
|
||||
tx_env.gas_price = U256::from(*gas_price);
|
||||
tx_env.gas_priority_fee = None;
|
||||
tx_env.transact_to = match to {
|
||||
TransactionKind::Call(to) => TransactTo::Call(*to),
|
||||
TransactionKind::Create => TransactTo::create(),
|
||||
};
|
||||
tx_env.value = U256::from(*value);
|
||||
tx_env.data = input.0.clone();
|
||||
tx_env.chain_id = *chain_id;
|
||||
tx_env.nonce = Some(*nonce);
|
||||
}
|
||||
Transaction::Eip2930(TxEip2930 {
|
||||
nonce,
|
||||
chain_id,
|
||||
gas_price,
|
||||
gas_limit,
|
||||
to,
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
}) => {
|
||||
tx_env.gas_limit = *gas_limit;
|
||||
tx_env.gas_price = U256::from(*gas_price);
|
||||
tx_env.gas_priority_fee = None;
|
||||
tx_env.transact_to = match to {
|
||||
TransactionKind::Call(to) => TransactTo::Call(*to),
|
||||
TransactionKind::Create => TransactTo::create(),
|
||||
};
|
||||
tx_env.value = U256::from(*value);
|
||||
tx_env.data = input.0.clone();
|
||||
tx_env.chain_id = Some(*chain_id);
|
||||
tx_env.nonce = Some(*nonce);
|
||||
tx_env.access_list = access_list
|
||||
.0
|
||||
.iter()
|
||||
.map(|l| {
|
||||
(
|
||||
l.address,
|
||||
l.storage_keys
|
||||
.iter()
|
||||
.map(|k| U256::from_be_bytes(k.to_fixed_bytes()))
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
Transaction::Eip1559(TxEip1559 {
|
||||
nonce,
|
||||
chain_id,
|
||||
gas_limit,
|
||||
max_fee_per_gas,
|
||||
max_priority_fee_per_gas,
|
||||
to,
|
||||
value,
|
||||
input,
|
||||
access_list,
|
||||
}) => {
|
||||
tx_env.gas_limit = *gas_limit;
|
||||
tx_env.gas_price = U256::from(*max_fee_per_gas);
|
||||
tx_env.gas_priority_fee = Some(U256::from(*max_priority_fee_per_gas));
|
||||
tx_env.transact_to = match to {
|
||||
TransactionKind::Call(to) => TransactTo::Call(*to),
|
||||
TransactionKind::Create => TransactTo::create(),
|
||||
};
|
||||
tx_env.value = U256::from(*value);
|
||||
tx_env.data = input.0.clone();
|
||||
tx_env.chain_id = Some(*chain_id);
|
||||
tx_env.nonce = Some(*nonce);
|
||||
tx_env.access_list = access_list
|
||||
.0
|
||||
.iter()
|
||||
.map(|l| {
|
||||
(
|
||||
l.address,
|
||||
l.storage_keys
|
||||
.iter()
|
||||
.map(|k| U256::from_be_bytes(k.to_fixed_bytes()))
|
||||
.collect(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,8 @@
|
||||
|
||||
//! revm utils and implementations specific to reth.
|
||||
|
||||
pub mod config;
|
||||
|
||||
/// Contains glue code for integrating reth database into revm's [Database](revm::Database).
|
||||
pub mod database;
|
||||
|
||||
/// Helpers for configuring revm [Env](revm::primitives::Env)
|
||||
pub mod env;
|
||||
|
||||
/// Helpers for type compatibility between reth and revm types
|
||||
mod compat;
|
||||
pub use compat::*;
|
||||
/// reexport for convenience
|
||||
pub use reth_revm_primitives::*;
|
||||
|
||||
Reference in New Issue
Block a user