mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(primitives): move revm-primitives to reth-primitives (#5088)
This commit is contained in:
@ -65,6 +65,8 @@ proptest = { workspace = true, optional = true }
|
||||
proptest-derive = { workspace = true, optional = true }
|
||||
strum = { workspace = true, features = ["derive"] }
|
||||
|
||||
revm.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json.workspace = true
|
||||
test-fuzz = "4"
|
||||
@ -83,8 +85,8 @@ hash-db = "~0.15"
|
||||
reth-primitives = { path = ".", features = ["value-256"] }
|
||||
|
||||
|
||||
# necessary so we don't hit a "undeclared 'std'":
|
||||
# https://github.com/paradigmxyz/reth/pull/177#discussion_r1021172198
|
||||
# necessary so we don't hit a "undeclared 'std'":
|
||||
# https://github.com/paradigmxyz/reth/pull/177#discussion_r1021172198
|
||||
secp256k1.workspace = true
|
||||
criterion = "0.5"
|
||||
pprof = { version = "0.12", features = ["flamegraph", "frame-pointer", "criterion"] }
|
||||
|
||||
@ -39,6 +39,8 @@ mod precaution;
|
||||
pub mod proofs;
|
||||
mod prune;
|
||||
mod receipt;
|
||||
/// Helpers for working with revm
|
||||
pub mod revm;
|
||||
pub mod serde_helper;
|
||||
pub mod snapshot;
|
||||
pub mod stage;
|
||||
|
||||
61
crates/primitives/src/revm/compat.rs
Normal file
61
crates/primitives/src/revm/compat.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use crate::{
|
||||
revm_primitives::{AccountInfo, Log},
|
||||
Account, Address, Log as RethLog, TransactionKind, KECCAK_EMPTY, U256,
|
||||
};
|
||||
use revm::{
|
||||
interpreter::gas::initial_tx_gas,
|
||||
primitives::{MergeSpec, ShanghaiSpec},
|
||||
};
|
||||
|
||||
/// Check equality between Revm and Reth `Log`s.
|
||||
pub fn is_log_equal(revm_log: &Log, reth_log: &crate::Log) -> bool {
|
||||
revm_log.address == reth_log.address &&
|
||||
revm_log.data == reth_log.data &&
|
||||
revm_log.topics == reth_log.topics
|
||||
}
|
||||
|
||||
/// Converts a Revm `Log` into a Reth `Log`.
|
||||
pub fn into_reth_log(log: Log) -> RethLog {
|
||||
RethLog { address: log.address, topics: log.topics, data: log.data }
|
||||
}
|
||||
|
||||
/// Converts a Revm [`AccountInfo`] into a Reth [`Account`].
|
||||
///
|
||||
/// Sets `bytecode_hash` to `None` if `code_hash` is [`KECCAK_EMPTY`].
|
||||
pub fn into_reth_acc(revm_acc: AccountInfo) -> Account {
|
||||
let code_hash = revm_acc.code_hash;
|
||||
Account {
|
||||
balance: revm_acc.balance,
|
||||
nonce: revm_acc.nonce,
|
||||
bytecode_hash: (code_hash != KECCAK_EMPTY).then_some(code_hash),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a Revm [`AccountInfo`] into a Reth [`Account`].
|
||||
///
|
||||
/// Sets `code_hash` to [`KECCAK_EMPTY`] if `bytecode_hash` is `None`.
|
||||
pub fn into_revm_acc(reth_acc: Account) -> AccountInfo {
|
||||
AccountInfo {
|
||||
balance: reth_acc.balance,
|
||||
nonce: reth_acc.nonce,
|
||||
code_hash: reth_acc.bytecode_hash.unwrap_or(KECCAK_EMPTY),
|
||||
code: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the Intrinsic Gas usage for a Transaction
|
||||
///
|
||||
/// Caution: This only checks past the Merge hardfork.
|
||||
#[inline]
|
||||
pub fn calculate_intrinsic_gas_after_merge(
|
||||
input: &[u8],
|
||||
kind: &TransactionKind,
|
||||
access_list: &[(Address, Vec<U256>)],
|
||||
is_shanghai: bool,
|
||||
) -> u64 {
|
||||
if is_shanghai {
|
||||
initial_tx_gas::<ShanghaiSpec>(input, kind.is_create(), access_list)
|
||||
} else {
|
||||
initial_tx_gas::<MergeSpec>(input, kind.is_create(), access_list)
|
||||
}
|
||||
}
|
||||
180
crates/primitives/src/revm/config.rs
Normal file
180
crates/primitives/src/revm/config.rs
Normal file
@ -0,0 +1,180 @@
|
||||
use crate::{revm_primitives, ChainSpec, Hardfork, Head};
|
||||
|
||||
/// Returns the spec id at the given timestamp.
|
||||
///
|
||||
/// Note: This is only intended to be used after the merge, when hardforks are activated by
|
||||
/// timestamp.
|
||||
pub fn revm_spec_by_timestamp_after_merge(
|
||||
chain_spec: &ChainSpec,
|
||||
timestamp: u64,
|
||||
) -> revm_primitives::SpecId {
|
||||
if chain_spec.is_cancun_active_at_timestamp(timestamp) {
|
||||
revm_primitives::CANCUN
|
||||
} else if chain_spec.is_shanghai_active_at_timestamp(timestamp) {
|
||||
revm_primitives::SHANGHAI
|
||||
} else {
|
||||
revm_primitives::MERGE
|
||||
}
|
||||
}
|
||||
|
||||
/// return revm_spec from spec configuration.
|
||||
pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm_primitives::SpecId {
|
||||
if chain_spec.fork(Hardfork::Cancun).active_at_head(&block) {
|
||||
revm_primitives::CANCUN
|
||||
} else 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!(
|
||||
"invalid hardfork chainspec: expected at least one hardfork, got {:?}",
|
||||
chain_spec.hardforks
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{ChainSpecBuilder, Head, MAINNET, U256};
|
||||
|
||||
#[test]
|
||||
fn test_to_revm_spec() {
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().cancun_activated().build(), Head::default()),
|
||||
revm_primitives::CANCUN
|
||||
);
|
||||
assert_eq!(
|
||||
revm_spec(&ChainSpecBuilder::mainnet().shanghai_activated().build(), Head::default()),
|
||||
revm_primitives::SHANGHAI
|
||||
);
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
295
crates/primitives/src/revm/env.rs
Normal file
295
crates/primitives/src/revm/env.rs
Normal file
@ -0,0 +1,295 @@
|
||||
use crate::{
|
||||
constants::{BEACON_ROOTS_ADDRESS, SYSTEM_ADDRESS},
|
||||
recover_signer,
|
||||
revm::config::revm_spec,
|
||||
revm_primitives::{AnalysisKind, BlockEnv, CfgEnv, Env, SpecId, TransactTo, TxEnv},
|
||||
Address, Bytes, Chain, ChainSpec, Head, Header, Transaction, TransactionKind,
|
||||
TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxEip4844, TxLegacy, B256, U256,
|
||||
};
|
||||
|
||||
/// Convenience function to call both [fill_cfg_env] and [fill_block_env]
|
||||
pub fn fill_cfg_and_block_env(
|
||||
cfg: &mut CfgEnv,
|
||||
block_env: &mut BlockEnv,
|
||||
chain_spec: &ChainSpec,
|
||||
header: &Header,
|
||||
total_difficulty: U256,
|
||||
) {
|
||||
fill_cfg_env(cfg, chain_spec, header, total_difficulty);
|
||||
let after_merge = cfg.spec_id >= SpecId::MERGE;
|
||||
fill_block_env(block_env, chain_spec, header, after_merge);
|
||||
}
|
||||
|
||||
/// 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 = chain_spec.chain().id();
|
||||
cfg_env.spec_id = spec_id;
|
||||
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;
|
||||
}
|
||||
|
||||
/// Fill block environment from Block.
|
||||
pub fn fill_block_env(
|
||||
block_env: &mut BlockEnv,
|
||||
chain_spec: &ChainSpec,
|
||||
header: &Header,
|
||||
after_merge: bool,
|
||||
) {
|
||||
let coinbase = block_coinbase(chain_spec, header, after_merge);
|
||||
fill_block_env_with_coinbase(block_env, header, after_merge, coinbase);
|
||||
}
|
||||
|
||||
/// Fill block environment with coinbase.
|
||||
#[inline]
|
||||
pub fn fill_block_env_with_coinbase(
|
||||
block_env: &mut BlockEnv,
|
||||
header: &Header,
|
||||
after_merge: bool,
|
||||
coinbase: Address,
|
||||
) {
|
||||
block_env.number = U256::from(header.number);
|
||||
block_env.coinbase = coinbase;
|
||||
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);
|
||||
|
||||
// EIP-4844 excess blob gas of this block, introduced in Cancun
|
||||
if let Some(excess_blob_gas) = header.excess_blob_gas {
|
||||
block_env.set_blob_excess_gas_and_price(excess_blob_gas);
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the coinbase address for the given header and chain spec.
|
||||
pub fn block_coinbase(chain_spec: &ChainSpec, header: &Header, after_merge: bool) -> Address {
|
||||
if chain_spec.chain == Chain::goerli() && !after_merge {
|
||||
recover_header_signer(header).expect("failed to recover signer")
|
||||
} else {
|
||||
header.beneficiary
|
||||
}
|
||||
}
|
||||
|
||||
/// Recover the account from signed header per clique consensus rules.
|
||||
pub fn recover_header_signer(header: &Header) -> Option<Address> {
|
||||
let extra_data_len = header.extra_data.len();
|
||||
// Fixed number of extra-data suffix bytes reserved for signer signature.
|
||||
// 65 bytes fixed as signatures are based on the standard secp256k1 curve.
|
||||
// Filled with zeros on genesis block.
|
||||
let signature_start_byte = extra_data_len - 65;
|
||||
let signature: [u8; 65] = header.extra_data[signature_start_byte..].try_into().ok()?;
|
||||
let seal_hash = {
|
||||
let mut header_to_seal = header.clone();
|
||||
header_to_seal.extra_data = Bytes::from(header.extra_data[..signature_start_byte].to_vec());
|
||||
header_to_seal.hash_slow()
|
||||
};
|
||||
recover_signer(&signature, &seal_hash.0).ok()
|
||||
}
|
||||
|
||||
/// Returns a new [TxEnv] filled with the transaction's data.
|
||||
pub fn tx_env_with_recovered(transaction: &TransactionSignedEcRecovered) -> TxEnv {
|
||||
let mut tx_env = TxEnv::default();
|
||||
fill_tx_env(&mut tx_env, transaction.as_ref(), transaction.signer());
|
||||
tx_env
|
||||
}
|
||||
|
||||
/// Fill transaction environment with the EIP-4788 system contract message data.
|
||||
///
|
||||
/// This requirements for the beacon root contract call defined by
|
||||
/// [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) are:
|
||||
///
|
||||
/// At the start of processing any execution block where `block.timestamp >= FORK_TIMESTAMP` (i.e.
|
||||
/// before processing any transactions), call `BEACON_ROOTS_ADDRESS` as `SYSTEM_ADDRESS` with the
|
||||
/// 32-byte input of `header.parent_beacon_block_root`, a gas limit of `30_000_000`, and `0` value.
|
||||
/// This will trigger the `set()` routine of the beacon roots contract. This is a system operation
|
||||
/// and therefore:
|
||||
/// * the call must execute to completion
|
||||
/// * the call does not count against the block’s gas limit
|
||||
/// * the call does not follow the EIP-1559 burn semantics - no value should be transferred as
|
||||
/// part of the call
|
||||
/// * if no code exists at `BEACON_ROOTS_ADDRESS`, the call must fail silently
|
||||
pub fn fill_tx_env_with_beacon_root_contract_call(env: &mut Env, parent_beacon_block_root: B256) {
|
||||
env.tx = TxEnv {
|
||||
caller: SYSTEM_ADDRESS,
|
||||
transact_to: TransactTo::Call(BEACON_ROOTS_ADDRESS),
|
||||
// Explicitly set nonce to None so revm does not do any nonce checks
|
||||
nonce: None,
|
||||
gas_limit: 30_000_000,
|
||||
value: U256::ZERO,
|
||||
data: parent_beacon_block_root.0.to_vec().into(),
|
||||
// Setting the gas price to zero enforces that no value is transferred as part of the call,
|
||||
// and that the call will not count against the block's gas limit
|
||||
gas_price: U256::ZERO,
|
||||
// The chain ID check is not relevant here and is disabled if set to None
|
||||
chain_id: None,
|
||||
// Setting the gas priority fee to None ensures the effective gas price is derived from the
|
||||
// `gas_price` field, which we need to be zero
|
||||
gas_priority_fee: None,
|
||||
access_list: Vec::new(),
|
||||
// blob fields can be None for this tx
|
||||
blob_hashes: Vec::new(),
|
||||
max_fee_per_blob_gas: None,
|
||||
};
|
||||
|
||||
// ensure the block gas limit is >= the tx
|
||||
env.block.gas_limit = U256::from(env.tx.gas_limit);
|
||||
|
||||
// disable the base fee check for this call by setting the base fee to zero
|
||||
env.block.basefee = U256::ZERO;
|
||||
}
|
||||
|
||||
/// Fill transaction environment from [TransactionSignedEcRecovered].
|
||||
pub fn fill_tx_env_with_recovered(tx_env: &mut TxEnv, transaction: &TransactionSignedEcRecovered) {
|
||||
fill_tx_env(tx_env, transaction.as_ref(), transaction.signer())
|
||||
}
|
||||
|
||||
/// Fill transaction environment from a [Transaction] and the given sender address.
|
||||
pub fn fill_tx_env<T>(tx_env: &mut TxEnv, transaction: T, sender: Address)
|
||||
where
|
||||
T: AsRef<Transaction>,
|
||||
{
|
||||
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 = (*value).into();
|
||||
tx_env.data = input.clone();
|
||||
tx_env.chain_id = *chain_id;
|
||||
tx_env.nonce = Some(*nonce);
|
||||
tx_env.access_list.clear();
|
||||
tx_env.blob_hashes.clear();
|
||||
tx_env.max_fee_per_blob_gas.take();
|
||||
}
|
||||
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 = (*value).into();
|
||||
tx_env.data = input.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.0)).collect())
|
||||
})
|
||||
.collect();
|
||||
tx_env.blob_hashes.clear();
|
||||
tx_env.max_fee_per_blob_gas.take();
|
||||
}
|
||||
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 = (*value).into();
|
||||
tx_env.data = input.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.0)).collect())
|
||||
})
|
||||
.collect();
|
||||
tx_env.blob_hashes.clear();
|
||||
tx_env.max_fee_per_blob_gas.take();
|
||||
}
|
||||
Transaction::Eip4844(TxEip4844 {
|
||||
nonce,
|
||||
chain_id,
|
||||
gas_limit,
|
||||
max_fee_per_gas,
|
||||
max_priority_fee_per_gas,
|
||||
to,
|
||||
value,
|
||||
access_list,
|
||||
blob_versioned_hashes,
|
||||
max_fee_per_blob_gas,
|
||||
input,
|
||||
}) => {
|
||||
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 = (*value).into();
|
||||
tx_env.data = input.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.0)).collect())
|
||||
})
|
||||
.collect();
|
||||
tx_env.blob_hashes = blob_versioned_hashes.clone();
|
||||
tx_env.max_fee_per_blob_gas = Some(U256::from(*max_fee_per_blob_gas));
|
||||
}
|
||||
}
|
||||
}
|
||||
20
crates/primitives/src/revm/mod.rs
Normal file
20
crates/primitives/src/revm/mod.rs
Normal file
@ -0,0 +1,20 @@
|
||||
/// The `compat` module contains a set of utility functions that bridge the gap between Revm and
|
||||
/// Reth Ethereum implementations.
|
||||
///
|
||||
/// These functions enable the conversion of data structures between the two implementations, such
|
||||
/// as converting `Log` structures, `AccountInfo`, and `Account` objects.
|
||||
///
|
||||
/// Additionally, it provides a function to calculate intrinsic gas usage for transactions beyond
|
||||
/// the Merge hardfork, offering compatibility for both Shanghai and Merge Ethereum specifications.
|
||||
///
|
||||
/// These utilities facilitate interoperability and data exchange between Revm and Reth
|
||||
/// implementations.
|
||||
pub mod compat;
|
||||
/// Reth block execution/validation configuration and constants
|
||||
pub mod config;
|
||||
/// The `env` module provides essential utilities for managing Ethereum transaction and block
|
||||
/// environments.
|
||||
///
|
||||
/// It includes functions to fill transaction and block environments with relevant data, handle
|
||||
/// system contract calls, and recover the signer of Ethereum headers.
|
||||
pub mod env;
|
||||
Reference in New Issue
Block a user