Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Start fee distribution changes
  • Loading branch information
clabby committed Sep 1, 2023
commit 66d200d0ccf125f03a2215975f6c995b04473a1f
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ revm-interpreter = { path = "../interpreter", version = "1.1.2", default-feature

#misc
auto_impl = { version = "1.1", default-features = false }
once_cell = "1.18.0"
bytes = "1.4.0"

# Optional
serde = { version = "1.0", features = ["derive", "rc"], optional = true }
Expand Down
60 changes: 51 additions & 9 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ use revm_interpreter::gas::initial_tx_gas;
use revm_interpreter::MAX_CODE_SIZE;
use revm_precompile::{Precompile, Precompiles};

#[cfg(feature = "optimism")]
use crate::optimism;
#[cfg(feature = "optimism")]
use core::ops::Mul;

pub struct EVMData<'a, DB: Database> {
pub env: &'a mut Env,
pub journaled_state: JournaledState,
Expand Down Expand Up @@ -319,7 +324,16 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
let effective_gas_price = self.data.env.effective_gas_price();
let basefee = self.data.env.block.basefee;

let gas_refunded = if self.env().cfg.is_gas_refund_disabled() {
let is_gas_refund_disabled = self.data.env.cfg.is_gas_refund_disabled();

#[cfg(feature = "optimism")]
let is_deposit = self.data.env.tx.source_hash.is_some();

#[cfg(feature = "optimism")]
let is_gas_refund_disabled =
is_gas_refund_disabled && is_deposit && !SPEC::enabled(SpecId::REGOLITH);

let gas_refunded = if is_gas_refund_disabled {
0
} else {
// EIP-3529: Reduction in refunds
Expand All @@ -338,12 +352,10 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
effective_gas_price * U256::from(gas.remaining() + gas_refunded),
);

#[cfg(not(feature = "optimism"))]
let disable_coinbase_tip = self.data.env.cfg.disable_coinbase_tip;

#[cfg(feature = "optimism")]
let disable_coinbase_tip = self.data.env.cfg.disable_coinbase_tip
|| self.data.env.tx.source_hash.is_some();
let disable_coinbase_tip = disable_coinbase_tip || is_deposit;

// transfer fee to coinbase/beneficiary.
if !disable_coinbase_tip {
Expand All @@ -368,12 +380,42 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
}

#[cfg(feature = "optimism")]
if self.data.env.cfg.optimism && self.data.env.tx.source_hash.is_none() {
if self.data.env.cfg.optimism && !is_deposit {
// If the transaction is not a deposit transaction, fees are paid out
// to both the Base Fee Vault as well as the Sequencer Fee Vault.
// TODO(clabby): Need to load the L1 fee information from the L1 block contract
// and pay out fees to the vaults.
todo!()
// to both the Base Fee Vault as well as the L1 Fee Vault.

// Fetch the L1 block information from account storage.
let Ok(l1_block_info) = optimism::fetch_l1_block_info(&mut self.data.db) else {
panic!("Failed to fetch L1 block info from account storage.");
};

// Calculate the L1 cost of the transaction based on the L1 block info.
// TODO(clabby): This is incorrect. The L1 cost is computed with the full
// enveloped encoding of the transaction, not its input. How do we get the full
// encoded tx here? We may pass it through the `TxEnv`, but that feels hacky.
let l1_cost =
l1_block_info.calculate_tx_l1_cost::<SPEC>(&self.data.env.tx.data, true);

// Send the L1 cost of the transaction to the L1 Fee Vault.
let Ok((l1_fee_vault_account, _)) = self
.data
.journaled_state
.load_account(*optimism::L1_FEE_RECIPIENT, self.data.db)
else {
panic!("L1 Fee Vault account not found");
};
l1_fee_vault_account.info.balance += l1_cost;

// Send the base fee of the transaction to the Base Fee Vault.
let Ok((base_fee_vault_account, _)) = self
.data
.journaled_state
.load_account(*optimism::BASE_FEE_RECIPIENT, self.data.db)
else {
panic!("Base Fee Vault account not found");
};
base_fee_vault_account.info.balance +=
l1_block_info.l1_base_fee.mul(U256::from(gas.spend()));
}

(gas.spend() - gas_refunded, gas_refunded)
Expand Down
7 changes: 7 additions & 0 deletions crates/revm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ mod evm_impl;
mod inspector;
mod journaled_state;

#[cfg(feature = "optimism")]
pub mod optimism;

#[cfg(all(feature = "with-serde", not(feature = "serde")))]
compile_error!("`with-serde` feature has been renamed to `serde`.");

Expand Down Expand Up @@ -39,3 +42,7 @@ pub use revm_interpreter::primitives;
// reexport inspector implementations
pub use inspector::inspectors;
pub use inspector::Inspector;

// export Optimism types, helpers, and constants
#[cfg(feature = "optimism")]
pub use optimism::*;
100 changes: 100 additions & 0 deletions crates/revm/src/optimism.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//! Optimism-specific constants, types, and helpers.

use core::ops::Mul;

use bytes::Bytes;
use once_cell::sync::Lazy;
use revm_interpreter::primitives::{db::Database, hex_literal::hex, Address, Spec, SpecId, U256};

const ZERO_BYTE_COST: u64 = 4;
const NON_ZERO_BYTE_COST: u64 = 16;

static L1_BASE_FEE_SLOT: Lazy<U256> = Lazy::new(|| U256::from(1));
static L1_OVERHEAD_SLOT: Lazy<U256> = Lazy::new(|| U256::from(5));
static L1_SCALAR_SLOT: Lazy<U256> = Lazy::new(|| U256::from(6));

/// The address of L1 fee recipient.
pub static L1_FEE_RECIPIENT: Lazy<Address> =
Lazy::new(|| Address::from_slice(&hex!("420000000000000000000000000000000000001A")));

/// The address of the base fee recipient.
pub static BASE_FEE_RECIPIENT: Lazy<Address> =
Lazy::new(|| Address::from_slice(&hex!("4200000000000000000000000000000000000019")));

/// The address of the L1Block contract.
pub static L1_BLOCK_CONTRACT: Lazy<Address> =
Lazy::new(|| Address::from_slice(&hex!("4200000000000000000000000000000000000015")));

/// L1 block info
///
/// We can extract L1 epoch data from each L2 block, by looking at the `setL1BlockValues`
/// transaction data. This data is then used to calculate the L1 cost of a transaction.
///
/// Here is the format of the `setL1BlockValues` transaction data:
///
/// setL1BlockValues(uint64 _number, uint64 _timestamp, uint256 _basefee, bytes32 _hash,
/// uint64 _sequenceNumber, bytes32 _batcherHash, uint256 _l1FeeOverhead, uint256 _l1FeeScalar)
///
/// For now, we only care about the fields necessary for L1 cost calculation.
#[derive(Clone, Debug)]
pub struct L1BlockInfo {
/// The base fee of the L1 origin block.
pub l1_base_fee: U256,
/// The current L1 fee overhead.
pub l1_fee_overhead: U256,
/// The current L1 fee scalar.
pub l1_fee_scalar: U256,
}

impl L1BlockInfo {
/// Calculate the data gas for posting the transaction on L1. Calldata costs 16 gas per non-zero
/// byte and 4 gas per zero byte.
///
/// Prior to regolith, an extra 68 non-zero bytes were included in the rollup data costs to
/// account for the empty signature.
pub fn data_gas<SPEC: Spec>(&self, input: &Bytes) -> U256 {
let mut rollup_data_gas_cost = U256::from(input.iter().fold(0, |acc, byte| {
acc + if *byte == 0x00 {
ZERO_BYTE_COST
} else {
NON_ZERO_BYTE_COST
}
}));

// Prior to regolith, an extra 68 non zero bytes were included in the rollup data costs.
if !SPEC::enabled(SpecId::REGOLITH) {
rollup_data_gas_cost += U256::from(NON_ZERO_BYTE_COST).mul(U256::from(68));
}

rollup_data_gas_cost
}

/// Calculate the gas cost of a transaction based on L1 block data posted on L2
pub fn calculate_tx_l1_cost<SPEC: Spec>(&self, input: &Bytes, is_deposit: bool) -> U256 {
let rollup_data_gas_cost = self.data_gas::<SPEC>(input);

if is_deposit || rollup_data_gas_cost == U256::ZERO {
return U256::ZERO;
}

rollup_data_gas_cost
.saturating_add(self.l1_fee_overhead)
.saturating_mul(self.l1_base_fee)
.saturating_mul(self.l1_fee_scalar)
.checked_div(U256::from(1_000_000))
.unwrap_or_default()
}
}

/// Fetches the L1 block info from the `L1Block` contract in the database.
pub fn fetch_l1_block_info<DB: Database>(db: &mut DB) -> Result<L1BlockInfo, DB::Error> {
let l1_base_fee = db.storage(*L1_BLOCK_CONTRACT, *L1_BASE_FEE_SLOT)?;
let l1_fee_overhead = db.storage(*L1_BLOCK_CONTRACT, *L1_OVERHEAD_SLOT)?;
let l1_fee_scalar = db.storage(*L1_BLOCK_CONTRACT, *L1_SCALAR_SLOT)?;

Ok(L1BlockInfo {
l1_base_fee,
l1_fee_overhead,
l1_fee_scalar,
})
}