Skip to content
This repository has been archived by the owner on Nov 5, 2023. It is now read-only.

Commit

Permalink
revm env [wip]
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Oct 15, 2023
1 parent 43309e1 commit c2ea10f
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 101 deletions.
5 changes: 5 additions & 0 deletions crates/payload/builder/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ impl PayloadBuilderAttributes {
let mut cfg = CfgEnv::default();
cfg.chain_id = chain_spec.chain().id();

#[cfg(feature = "optimism")]
{
cfg.optimism = chain_spec.optimism;
}

// ensure we're not missing any timestamp based hardforks
cfg.spec_id = revm_spec_by_timestamp_after_merge(chain_spec, self.timestamp);

Expand Down
6 changes: 3 additions & 3 deletions crates/primitives/src/chain/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ impl ChainSpecBuilder {
/// Enable Bedrock at genesis
#[cfg(feature = "optimism")]
pub fn bedrock_activated(mut self) -> Self {
self = self.london_activated();
self = self.paris_activated();
self.hardforks.insert(Hardfork::Bedrock, ForkCondition::Block(0));
self
}
Expand All @@ -1046,9 +1046,9 @@ impl ChainSpecBuilder {
/// For post-bedrock op-stack chains, this will be at genesis.
/// For pre-bedrock op-stack chains, this will be at the timestamp of regolith activation.
#[cfg(feature = "optimism")]
pub fn regolith_activated(mut self, timestamp: u64) -> Self {
pub fn regolith_activated(mut self) -> Self {
self = self.bedrock_activated();
self.hardforks.insert(Hardfork::Regolith, ForkCondition::Timestamp(timestamp));
self.hardforks.insert(Hardfork::Regolith, ForkCondition::Timestamp(0));
self
}

Expand Down
35 changes: 35 additions & 0 deletions crates/revm/revm-primitives/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ pub fn revm_spec_by_timestamp_after_merge(
chain_spec: &ChainSpec,
timestamp: u64,
) -> revm_primitives::SpecId {
#[cfg(feature = "optimism")]
if chain_spec.optimism {
if chain_spec.fork(Hardfork::Regolith).active_at_timestamp(timestamp) {
return revm_primitives::REGOLITH
} else {
return revm_primitives::BEDROCK
}
}

if chain_spec.is_cancun_active_at_timestamp(timestamp) {
revm_primitives::CANCUN
} else if chain_spec.is_shanghai_active_at_timestamp(timestamp) {
Expand All @@ -21,6 +30,15 @@ pub fn revm_spec_by_timestamp_after_merge(

/// return revm_spec from spec configuration.
pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm_primitives::SpecId {
#[cfg(feature = "optimism")]
if chain_spec.optimism {
if chain_spec.fork(Hardfork::Regolith).active_at_head(&block) {
return revm_primitives::REGOLITH
} else if chain_spec.fork(Hardfork::Bedrock).active_at_head(&block) {
return revm_primitives::BEDROCK
}
}

if chain_spec.fork(Hardfork::Cancun).active_at_head(&block) {
revm_primitives::CANCUN
} else if chain_spec.fork(Hardfork::Shanghai).active_at_head(&block) {
Expand Down Expand Up @@ -114,6 +132,23 @@ mod tests {
revm_spec(&ChainSpecBuilder::mainnet().frontier_activated().build(), Head::default()),
revm_primitives::FRONTIER
);
#[cfg(feature = "optimism")]
{
assert_eq!(
revm_spec(
&ChainSpecBuilder::mainnet().bedrock_activated().build(),
Head::default()
),
revm_primitives::BEDROCK
);
assert_eq!(
revm_spec(
&ChainSpecBuilder::mainnet().regolith_activated().build(),
Head::default()
),
revm_primitives::REGOLITH
);
}
}

#[test]
Expand Down
212 changes: 118 additions & 94 deletions crates/revm/revm-primitives/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ use reth_primitives::{
recover_signer,
revm_primitives::{AnalysisKind, BlockEnv, CfgEnv, Env, SpecId, TransactTo, TxEnv},
Address, Bytes, Chain, ChainSpec, Head, Header, Transaction, TransactionKind,
TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxEip4844, TxLegacy, B256, U256,
TransactionSignedEcRecovered, B256, U256,
};

#[cfg(feature = "optimism")]
use reth_primitives::{revm_primitives::OptimismFields, TxDeposit};
use reth_primitives::revm_primitives::OptimismFields;

/// Convenience function to call both [fill_cfg_env] and [fill_block_env]
pub fn fill_cfg_and_block_env(
Expand Down Expand Up @@ -44,6 +44,11 @@ pub fn fill_cfg_env(
cfg_env.chain_id = chain_spec.chain().id();
cfg_env.spec_id = spec_id;
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;

#[cfg(feature = "optimism")]
{
cfg_env.optimism = chain_spec.optimism;
}
}

/// Fill block environment from Block.
Expand Down Expand Up @@ -112,7 +117,17 @@ pub fn recover_header_signer(header: &Header) -> Option<Address> {
/// 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();

#[cfg(not(feature = "optimism"))]
fill_tx_env(&mut tx_env, transaction.as_ref(), transaction.signer());

#[cfg(feature = "optimism")]
{
let mut envelope_buf = Vec::default();
transaction.encode_enveloped(&mut envelope_buf);
fill_tx_env(&mut tx_env, transaction.as_ref(), transaction.signer(), envelope_buf.into());
}

tx_env
}

Expand Down Expand Up @@ -169,63 +184,58 @@ pub fn fill_tx_env_with_beacon_root_contract_call(env: &mut Env, parent_beacon_b
}

/// 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())
pub fn fill_tx_env_with_recovered(
tx_env: &mut TxEnv,
transaction: &TransactionSignedEcRecovered,
#[cfg(feature = "optimism")] envelope: Bytes,
) {
fill_tx_env(tx_env, transaction.as_ref(), transaction.signer(), envelope)
}

/// 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
pub fn fill_tx_env<T>(
tx_env: &mut TxEnv,
transaction: T,
sender: Address,
#[cfg(feature = "optimism")] envelope: Bytes,
) 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);
Transaction::Legacy(tx) => {
tx_env.gas_limit = tx.gas_limit;
tx_env.gas_price = U256::from(tx.gas_price);
tx_env.gas_priority_fee = None;
tx_env.transact_to = match to {
TransactionKind::Call(to) => TransactTo::Call(*to),
tx_env.transact_to = match tx.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.value = tx.value.into();
tx_env.data = tx.input.clone();
tx_env.chain_id = tx.chain_id;
tx_env.nonce = Some(tx.nonce);
tx_env.access_list.clear();
tx_env.blob_hashes.clear();
tx_env.max_fee_per_blob_gas.take();

#[cfg(feature = "optimism")]
fill_op_tx_env(tx_env, transaction, envelope);
}
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);
Transaction::Eip2930(tx) => {
tx_env.gas_limit = tx.gas_limit;
tx_env.gas_price = U256::from(tx.gas_price);
tx_env.gas_priority_fee = None;
tx_env.transact_to = match to {
TransactionKind::Call(to) => TransactTo::Call(*to),
tx_env.transact_to = match tx.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
tx_env.value = tx.value.into();
tx_env.data = tx.input.clone();
tx_env.chain_id = Some(tx.chain_id);
tx_env.nonce = Some(tx.nonce);
tx_env.access_list = tx
.access_list
.0
.iter()
.map(|l| {
Expand All @@ -234,30 +244,24 @@ where
.collect();
tx_env.blob_hashes.clear();
tx_env.max_fee_per_blob_gas.take();

#[cfg(feature = "optimism")]
fill_op_tx_env(tx_env, transaction, envelope);
}
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),
Transaction::Eip1559(tx) => {
tx_env.gas_limit = tx.gas_limit;
tx_env.gas_price = U256::from(tx.max_fee_per_gas);
tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas));
tx_env.transact_to = match tx.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
tx_env.value = tx.value.into();
tx_env.data = tx.input.clone();
tx_env.chain_id = Some(tx.chain_id);
tx_env.nonce = Some(tx.nonce);
tx_env.access_list = tx
.access_list
.0
.iter()
.map(|l| {
Expand All @@ -266,54 +270,74 @@ where
.collect();
tx_env.blob_hashes.clear();
tx_env.max_fee_per_blob_gas.take();

#[cfg(feature = "optimism")]
fill_op_tx_env(tx_env, transaction, envelope);
}
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),
Transaction::Eip4844(tx) => {
tx_env.gas_limit = tx.gas_limit;
tx_env.gas_price = U256::from(tx.max_fee_per_gas);
tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas));
tx_env.transact_to = match tx.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
tx_env.value = tx.value.into();
tx_env.data = tx.input.clone();
tx_env.chain_id = Some(tx.chain_id);
tx_env.nonce = Some(tx.nonce);
tx_env.access_list = tx
.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));
tx_env.blob_hashes = tx.blob_versioned_hashes.clone();
tx_env.max_fee_per_blob_gas = Some(U256::from(tx.max_fee_per_blob_gas));

#[cfg(feature = "optimism")]
fill_op_tx_env(tx_env, transaction, envelope);
}
#[cfg(feature = "optimism")]
Transaction::Deposit(TxDeposit { to, value, gas_limit, input, .. }) => {
tx_env.gas_limit = *gas_limit;
Transaction::Deposit(tx) => {
tx_env.gas_limit = tx.gas_limit;
tx_env.gas_price = U256::ZERO;
tx_env.gas_priority_fee = None;
match to {
TransactionKind::Call(to) => tx_env.transact_to = TransactTo::Call(*to),
match tx.to {
TransactionKind::Call(to) => tx_env.transact_to = TransactTo::Call(to),
TransactionKind::Create => tx_env.transact_to = TransactTo::create(),
}
tx_env.value = value.0;
tx_env.data = input.clone();
tx_env.value = tx.value.0;
tx_env.data = tx.input.clone();
tx_env.chain_id = None;
tx_env.nonce = None;

fill_op_tx_env(tx_env, transaction, envelope);
}
}
}

#[cfg(feature = "optimism")]
#[inline(always)]
fn fill_op_tx_env<T: AsRef<Transaction>>(tx_env: &mut TxEnv, transaction: T, envelope: Bytes) {
match transaction.as_ref() {
Transaction::Deposit(tx) => {
tx_env.optimism = OptimismFields {
source_hash: Some(tx.source_hash),
mint: tx.mint,
is_system_transaction: Some(tx.is_system_transaction),
enveloped_tx: Some(envelope),
};
}
_ => {
tx_env.optimism = OptimismFields {
source_hash: None,
mint: None,
is_system_transaction: Some(false),
enveloped_tx: Some(envelope),
}
}
}
}
Loading

0 comments on commit c2ea10f

Please sign in to comment.