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

feat: Optimism execution changes #682

Merged
merged 90 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
ec46f3e
Start `op-revm` changes
clabby Sep 1, 2023
66d200d
Start fee distribution changes
clabby Sep 1, 2023
c61c762
Add L1 fee deduction
clabby Sep 1, 2023
2257bb9
Start deposit tx gas accounting
clabby Sep 1, 2023
3fd2f61
Move L1 cost into `TxEnv`
clabby Sep 2, 2023
2cc96da
Add helpers for computing the L1 cost of a transaction back
clabby Sep 2, 2023
75f8287
:broom:
clabby Sep 2, 2023
4154183
Enforce runtime config flag for cross-compatibility
clabby Sep 2, 2023
9bb0c49
style: Use env rather than passing a flag
clabby Sep 2, 2023
a31c31c
review: Address first few comments
clabby Sep 5, 2023
9490270
Flatten optimism hoisted tx fields
refcell Sep 5, 2023
8f0caa1
feat flag ontop
refcell Sep 5, 2023
2d137e2
Merge pull request #2 from anton-rs/refcell/tx-field-flattening
refcell Sep 5, 2023
128e440
Refactor l1 cost and mint computations
refcell Sep 5, 2023
6b868b3
l1 cost erroring
refcell Sep 5, 2023
ae76b7e
Merge pull request #4 from anton-rs/refcell/refactors
refcell Sep 5, 2023
d642582
Refactor gas usage functions
refcell Sep 5, 2023
868f593
Rip gas construction back to the transact
refcell Sep 5, 2023
8eab1ad
Rip out crate use gas
refcell Sep 5, 2023
f2d59b9
Merge pull request #5 from anton-rs/refcell/gas-refactor
refcell Sep 5, 2023
063b4e6
push gas usage unit logic into the gas impl
refcell Sep 6, 2023
21bba33
Resolve env conflicts
refcell Sep 6, 2023
f97400f
Merge pull request #7 from anton-rs/refcell/upstream-sync
refcell Sep 6, 2023
b0d703c
Further document the cfg env optimism bool field.
refcell Sep 6, 2023
0404385
Reword
refcell Sep 6, 2023
d9cd733
Add deposit sys tx docs
refcell Sep 6, 2023
cee3dae
Fix the spec enabled function and add unit tests.
refcell Sep 6, 2023
af654a3
data gas tests
refcell Sep 6, 2023
e60a4d5
calculate tx l1 cost test
refcell Sep 6, 2023
fa8b4e0
Add a zero rollup data gas cost check
refcell Sep 6, 2023
f0d7ad6
Fix suggestions
refcell Sep 6, 2023
43254d1
Merge pull request #10 from anton-rs/refcell/spec-enabling-fixes
refcell Sep 6, 2023
5ef737f
Merge pull request #8 from anton-rs/refcell/optimism-hot-toggle
refcell Sep 6, 2023
fc227f6
Merge pull request #9 from anton-rs/refcell/deposit-sys-tx
refcell Sep 6, 2023
d193011
Bump the account nonce post-regolith for contract creation
refcell Sep 6, 2023
710c6ed
Add tx validation tests
refcell Sep 7, 2023
988d640
Add a deposit tx test
refcell Sep 7, 2023
f7a3373
Add gas tests
refcell Sep 7, 2023
b31029e
Add gas tests
refcell Sep 7, 2023
a0cc070
Fix regolith check
refcell Sep 7, 2023
dc28e02
Merge pull request #12 from anton-rs/refcell/validate-tx-tests
refcell Sep 7, 2023
99a364e
Merge pull request #11 from anton-rs/refcell/bump-nonce-post-regolith
refcell Sep 7, 2023
b163419
Fix func ordering
refcell Sep 7, 2023
742c79a
Merge pull request #6 from anton-rs/refcell/refactor-gas-usage
refcell Sep 7, 2023
b0f4d1f
Merge branch 'main' into refcell/upstreamsync
refcell Sep 7, 2023
d3057fd
Merge pull request #14 from anton-rs/refcell/upstreamsync
refcell Sep 7, 2023
23373ae
Fix test
refcell Sep 7, 2023
4acb344
Merge pull request #15 from anton-rs/refcell/fix-test
refcell Sep 7, 2023
531aca0
Swap the l1_cost to use the raw enveloped tx
refcell Sep 7, 2023
bdc334e
Update crates/revm/src/evm_impl.rs
refcell Sep 7, 2023
a92bb4f
Update crates/revm/src/evm_impl.rs
refcell Sep 7, 2023
21d907d
Update crates/primitives/src/env.rs
refcell Sep 7, 2023
8b0a222
Merge pull request #16 from anton-rs/refcell/l1_cost_refactor
refcell Sep 7, 2023
27760ca
Make clippy happy
clabby Sep 7, 2023
4fd2422
Merge pull request #17 from anton-rs/clippy
refcell Sep 7, 2023
0d4ccb5
perf: Only load `L1BlockInfo` once
clabby Sep 7, 2023
bb9acfe
Remove extra `try_fetch` fn
clabby Sep 7, 2023
3f9ca9d
perf: lazy `try_fetch` eval
clabby Sep 7, 2023
8fd3a3c
andreas was right
clabby Sep 8, 2023
2c72f86
Improve error abstraction
clabby Sep 8, 2023
03fd637
Merge pull request #18 from anton-rs/clabby/reduce-db-reads
refcell Sep 8, 2023
61b21a0
EVM Impl Tests
refcell Sep 7, 2023
476f7f2
More tests
refcell Sep 7, 2023
2096fd0
Merge pull request #13 from anton-rs/refcell/mint-value-commits
clabby Sep 8, 2023
e7a2440
Fix breaking changes
refcell Sep 8, 2023
21880f7
Merge pull request #21 from anton-rs/refcell/hot-fix
clabby Sep 8, 2023
2962e7a
Update the enveloped tx to be optional.
refcell Sep 8, 2023
0970280
Merge branch 'main' into refcell/quick-upstream-sync
refcell Sep 8, 2023
ad2c951
Merge pull request #23 from anton-rs/refcell/quick-upstream-sync
refcell Sep 8, 2023
bd03c2f
Merge pull request #22 from anton-rs/refcell/optional-envelope
refcell Sep 8, 2023
c1d667f
Merge REVM upgrades
clabby Sep 16, 2023
3c7878a
Merge pull request #24 from anton-rs/cl/merge-revm-upgrades
refcell Sep 17, 2023
fff1d42
Upstream sync?
refcell Sep 17, 2023
572f52c
Merge pull request #25 from anton-rs/refcell/upstream-fixes
clabby Sep 17, 2023
feec29a
Introduce call return handler
rakita Sep 22, 2023
2b9d0cc
Merge pull request #26 from rakita/call_return_handler
refcell Sep 25, 2023
5918f28
feat: Handler logic
rakita Sep 26, 2023
07c4cbc
Merge remote-tracking branch 'origin/main' into final_handler
rakita Sep 26, 2023
8fa4ea3
Merge pull request #27 from rakita/handler
refcell Sep 26, 2023
c656896
Merge pull request #28 from rakita/oprevm-merge
refcell Sep 26, 2023
8d97ea3
remove USE_GAS from handlers
rakita Sep 27, 2023
feaafe8
Merge pull request #30 from rakita/rm_handler_use_gas
refcell Sep 27, 2023
5eacff1
Fix lints
refcell Sep 27, 2023
ba0266a
Merge branch 'main' into refcell/quick-us
refcell Sep 27, 2023
d87381b
Merge pull request #31 from anton-rs/refcell/quick-us
refcell Sep 27, 2023
e63c990
Update runner.rs
clabby Sep 27, 2023
7aaf390
Merge branch 'main' into refcell/another-quick-us
refcell Sep 27, 2023
4a615ea
Merge pull request #32 from anton-rs/refcell/another-quick-us
refcell Sep 27, 2023
ec1f488
Fix param mutability
refcell Sep 27, 2023
8048613
Merge pull request #33 from anton-rs/refcell/fix-param-mutability
refcell Sep 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ jobs:
cache-on-failure: true

- name: cargo test
run: cargo test --workspace

- name: cargo test all features
run: cargo test --workspace --all-features

- name: cargo check no_std
Expand Down
2 changes: 2 additions & 0 deletions crates/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ arbitrary = [
"revm-primitives/arbitrary",
]

optimism = ["revm-primitives/optimism"]

dev = [
"memory_limit",
"optional_balance_check",
Expand Down
16 changes: 14 additions & 2 deletions crates/interpreter/src/instructions/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,12 +834,24 @@ const fn make_gas_table(spec: SpecId) -> [OpInfo; 256] {
pub const fn spec_opcode_gas(spec_id: SpecId) -> &'static [OpInfo; 256] {
macro_rules! gas_maps {
($($id:ident),* $(,)?) => {
match spec_id {$(
match spec_id {
$(
SpecId::$id => {
const TABLE: &[OpInfo; 256] = &make_gas_table(SpecId::$id);
TABLE
}
)*}
)*
#[cfg(feature = "optimism")]
SpecId::BEDROCK => {
const TABLE: &[OpInfo;256] = &make_gas_table(SpecId::BEDROCK);
TABLE
}
#[cfg(feature = "optimism")]
SpecId::REGOLITH => {
const TABLE: &[OpInfo;256] = &make_gas_table(SpecId::REGOLITH);
TABLE
}
}
};
}

Expand Down
1 change: 1 addition & 0 deletions crates/precompile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ c-kzg = ["dep:c-kzg", "revm-primitives/c-kzg"]
# The problem that `secp256k1` has is it fails to build for `wasm` target on Windows and Mac as it is c lib.
# In Linux it passes. If you don't require to build wasm on win/mac, it is safe to use it and it is enabled by default.
secp256k1 = ["dep:secp256k1"]
optimism = ["revm-primitives/optimism"]
2 changes: 2 additions & 0 deletions crates/precompile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ impl SpecId {
BERLIN | LONDON | ARROW_GLACIER | GRAY_GLACIER | MERGE | SHANGHAI => Self::BERLIN,
CANCUN => Self::CANCUN,
LATEST => Self::LATEST,
#[cfg(feature = "optimism")]
BEDROCK | REGOLITH => Self::BERLIN,
}
}

Expand Down
2 changes: 2 additions & 0 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ arbitrary = [
"bitflags/arbitrary",
]

optimism = []

dev = [
"memory_limit",
"optional_balance_check",
Expand Down
136 changes: 132 additions & 4 deletions crates/primitives/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ impl BlobExcessGasAndPrice {
}
}

#[cfg(feature = "optimism")]
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct OptimismFields {
pub source_hash: Option<B256>,
pub mint: Option<u128>,
pub is_system_transaction: Option<bool>,
/// An enveloped EIP-2718 typed transaction. This is used
/// to compute the L1 tx cost using the L1 block info, as
/// opposed to requiring downstream apps to compute the cost
/// externally.
/// This field is optional to allow the [TxEnv] to be constructed
/// for non-optimism chains when the `optimism` feature is enabled,
/// but the [CfgEnv] `optimism` field is set to false.
pub enveloped_tx: Option<Bytes>,
}

impl BlockEnv {
/// Takes `blob_excess_gas` saves it inside env
/// and calculates `blob_fee` with [`BlobGasAndFee`].
Expand Down Expand Up @@ -162,6 +179,10 @@ pub struct TxEnv {
///
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
pub max_fee_per_blob_gas: Option<U256>,

#[cfg_attr(feature = "serde", serde(flatten))]
#[cfg(feature = "optimism")]
pub optimism: OptimismFields,
}

impl TxEnv {
Expand Down Expand Up @@ -248,9 +269,6 @@ pub struct CfgEnv {
/// If some it will effects EIP-170: Contract code size limit. Useful to increase this because of tests.
/// By default it is 0x6000 (~25kb).
pub limit_contract_code_size: Option<usize>,
/// Disables the coinbase tip during the finalization of the transaction. This is useful for
/// rollups that redirect the tip to the sequencer.
pub disable_coinbase_tip: bool,
/// A hard memory limit in bytes beyond which [Memory] cannot be resized.
///
/// In cases where the gas limit may be extraordinarily high, it is recommended to set this to
Expand Down Expand Up @@ -280,6 +298,14 @@ pub struct CfgEnv {
/// This is useful for testing method calls with zero gas price.
#[cfg(feature = "optional_no_base_fee")]
pub disable_base_fee: bool,
/// Enables Optimism's execution changes for deposit transactions and fee
/// collection. Hot toggling the optimism field gives applications built
/// on revm the ability to switch optimism execution on and off at runtime,
/// allowing for features like multichain fork testing. Setting this field
/// to false will disable all optimism execution changes regardless of
/// compilation with the optimism feature flag.
#[cfg(feature = "optimism")]
pub optimism: bool,
}

impl CfgEnv {
Expand Down Expand Up @@ -332,6 +358,16 @@ impl CfgEnv {
pub fn is_block_gas_limit_disabled(&self) -> bool {
false
}

#[cfg(feature = "optimism")]
pub fn is_optimism(&self) -> bool {
self.optimism
}

#[cfg(not(feature = "optimism"))]
pub fn is_optimism(&self) -> bool {
false
}
}

/// What bytecode analysis to perform.
Expand All @@ -354,7 +390,6 @@ impl Default for CfgEnv {
spec_id: SpecId::LATEST,
perf_analyse_created_bytecodes: AnalysisKind::default(),
limit_contract_code_size: None,
disable_coinbase_tip: false,
#[cfg(feature = "c-kzg")]
kzg_settings: crate::kzg::EnvKzgSettings::Default,
#[cfg(feature = "memory_limit")]
Expand All @@ -369,6 +404,8 @@ impl Default for CfgEnv {
disable_gas_refund: false,
#[cfg(feature = "optional_no_base_fee")]
disable_base_fee: false,
#[cfg(feature = "optimism")]
optimism: false,
}
}
}
Expand Down Expand Up @@ -403,6 +440,8 @@ impl Default for TxEnv {
access_list: Vec::new(),
blob_hashes: Vec::new(),
max_fee_per_blob_gas: None,
#[cfg(feature = "optimism")]
optimism: OptimismFields::default(),
}
}
}
Expand Down Expand Up @@ -449,6 +488,21 @@ impl Env {
/// Return initial spend gas (Gas needed to execute transaction).
#[inline]
pub fn validate_tx<SPEC: Spec>(&self) -> Result<(), InvalidTransaction> {
#[cfg(feature = "optimism")]
if self.cfg.optimism {
// Do not allow for a system transaction to be processed if Regolith is enabled.
if self.tx.optimism.is_system_transaction.unwrap_or(false)
&& SPEC::enabled(SpecId::REGOLITH)
{
return Err(InvalidTransaction::DepositSystemTxPostRegolith);
}

// Do not perform any extra validation for deposit transactions, they are pre-verified on L1.
if self.tx.optimism.source_hash.is_some() {
return Ok(());
}
}

let gas_limit = self.tx.gas_limit;
let effective_gas_price = self.effective_gas_price();
let is_create = self.tx.transact_to.is_create();
Expand Down Expand Up @@ -561,6 +615,13 @@ impl Env {
return Err(InvalidTransaction::RejectCallerWithCode);
}

// On Optimism, deposit transactions do not have verification on the nonce
// nor the balance of the account.
#[cfg(feature = "optimism")]
if self.cfg.optimism && self.tx.optimism.source_hash.is_some() {
return Ok(());
}

// Check that the transaction's nonce is correct
if let Some(tx) = self.tx.nonce {
let state = account.info.nonce;
Expand Down Expand Up @@ -604,3 +665,70 @@ impl Env {
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;

#[cfg(feature = "optimism")]
#[test]
fn test_validate_sys_tx() {
// Set the optimism flag to true and mark
// the tx as a system transaction.
let mut env = Env::default();
env.cfg.optimism = true;
env.tx.optimism.is_system_transaction = Some(true);
assert_eq!(
env.validate_tx::<crate::RegolithSpec>(),
Err(InvalidTransaction::DepositSystemTxPostRegolith)
);

// Pre-regolith system transactions should be allowed.
assert!(env.validate_tx::<crate::BedrockSpec>().is_ok());
}

#[cfg(feature = "optimism")]
#[test]
fn test_validate_deposit_tx() {
// Set the optimism flag and source hash.
let mut env = Env::default();
env.cfg.optimism = true;
env.tx.optimism.source_hash = Some(B256::zero());
assert!(env.validate_tx::<crate::RegolithSpec>().is_ok());
}

#[cfg(feature = "optimism")]
#[test]
fn test_validate_tx_against_state_deposit_tx() {
// Set the optimism flag and source hash.
let mut env = Env::default();
env.cfg.optimism = true;
env.tx.optimism.source_hash = Some(B256::zero());

// Nonce and balance checks should be skipped for deposit transactions.
assert!(env
.validate_tx_against_state(&mut Account::default())
.is_ok());
}

#[test]
fn test_validate_tx_chain_id() {
let mut env = Env::default();
env.tx.chain_id = Some(1);
env.cfg.chain_id = 2;
assert_eq!(
env.validate_tx::<crate::LatestSpec>(),
Err(InvalidTransaction::InvalidChainId)
);
}

#[test]
fn test_validate_tx_access_list() {
let mut env = Env::default();
env.tx.access_list = vec![(B160::zero(), vec![])];
assert_eq!(
env.validate_tx::<crate::FrontierSpec>(),
Err(InvalidTransaction::AccessListNotSupported)
);
}
}
10 changes: 9 additions & 1 deletion crates/primitives/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ use bytes::Bytes;
use core::fmt;
use ruint::aliases::U256;

pub type EVMResult<DBError> = core::result::Result<ResultAndState, EVMError<DBError>>;
/// Result of EVM execution.
pub type EVMResult<DBError> = EVMResultGeneric<ResultAndState, DBError>;

/// Generic result of EVM execution. Used to represent error and generic output.
pub type EVMResultGeneric<T, DBError> = core::result::Result<T, EVMError<DBError>>;

#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
Expand Down Expand Up @@ -206,6 +210,10 @@ pub enum InvalidTransaction {
TooManyBlobs,
/// Blob transaction contains a versioned hash with an incorrect version
BlobVersionNotSupported,
/// System transactions are not supported
/// post-regolith hardfork.
#[cfg(feature = "optimism")]
DepositSystemTxPostRegolith,
}

impl<DBError> From<InvalidHeader> for EVMError<DBError> {
Expand Down
Loading