Skip to content

Commit

Permalink
feat: restructuring Part6 transaction crate (bluealloy#1814)
Browse files Browse the repository at this point in the history
* chore: refactor *copy common code

* doc link fix

* feat: Transaction abstraction

* wip tx abstraction

* temp

* impl Transactions trait on TxEnv

* switching to new tx abstraction

* wip

* first frame creation handle

* tx validation first part

* compiling tx transition

* tx/block verification

* cleanup

* make it compile

* fix tests

* tx type in statetests

* fix docs

* fix some panics

* try to fix statetest tx type deduction

* work on optimism tx type

* optimism impl

* fmt clippy

* impl auth list and access list traits

* expection handling for invalid statetest tx

* fix op tests

* docs

* docs and test fix

* basefee check for legacy

* clippy

* default tx gas limit to 30M

* set max gas limit

* readd eip7702 validity check

* docs and cleanup

* rm std check
  • Loading branch information
rakita authored Oct 8, 2024
1 parent 925c042 commit ee4809e
Show file tree
Hide file tree
Showing 81 changed files with 2,539 additions and 1,662 deletions.
572 changes: 289 additions & 283 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@ members = [
"crates/interpreter",
"crates/inspector",
"crates/precompile",
"crates/optimism",
"crates/database",
"crates/database/interface",
"crates/bytecode",
"crates/state",
"crates/wiring",
"crates/wiring/transaction",
"crates/specification",
"crates/statetest-types",

# variants
"crates/optimism",

# examples
"examples/block_traces",
"examples/contract_deployment",
Expand All @@ -32,14 +35,15 @@ members = [

[workspace.dependencies]
# revm
revm = { path = "crates/revm", version = "14.0.1", default-features = false }
primitives = { path = "crates/primitives", package = "revm-primitives", version = "9.0.1", default-features = false }
bytecode = { path = "crates/bytecode", package = "revm-bytecode", version = "1.0.0", default-features = false }
database = { path = "crates/database", package = "revm-database", version = "1.0.0", default-features = false }
database-interface = { path = "crates/database/interface", package = "revm-database-interface", version = "1.0.0", default-features = false }
specification = { path = "crates/specification", package = "revm-specification", version = "1.0.0", default-features = false }
state = { path = "crates/state", package = "revm-state", version = "1.0.0", default-features = false }
wiring = { path = "crates/wiring", package = "revm-wiring", version = "1.0.0", default-features = false }
revm = { path = "crates/revm", version = "14.0.1", default-features = false }
transaction = { path = "crates/wiring/transaction", package = "revm-transaction", version = "1.0.0", default-features = false }
interpreter = { path = "crates/interpreter", package = "revm-interpreter", version = "10.0.1", default-features = false }
inspector = { path = "crates/inspector", package = "revm-inspector", version = "1.0.0", default-features = false }
precompile = { path = "crates/precompile", package = "revm-precompile", version = "11.0.1", default-features = false }
Expand Down
3 changes: 2 additions & 1 deletion bins/revme/src/cmd/bytecode.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use clap::Parser;
use revm::{
bytecode::eof::{self, validate_eof_inner, CodeType, Eof, EofError},
primitives::{hex, Bytes, MAX_INITCODE_SIZE},
primitives::{hex, Bytes},
specification::constants::MAX_INITCODE_SIZE,
};
use std::io;

Expand Down
35 changes: 24 additions & 11 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ pub fn execute_test_suite(
.unwrap_or_default();
env.tx.gas_priority_fee = unit.transaction.max_priority_fee_per_gas;
// EIP-4844
env.tx.blob_hashes = unit.transaction.blob_versioned_hashes;
env.tx.blob_hashes = unit.transaction.blob_versioned_hashes.clone();
env.tx.max_fee_per_blob_gas = unit.transaction.max_fee_per_blob_gas;

// post and execution
Expand All @@ -360,6 +360,17 @@ pub fn execute_test_suite(
}

for (index, test) in tests.into_iter().enumerate() {
// TODO TX TYPE needs to be set
let Some(tx_type) = unit.transaction.tx_type(test.indexes.data) else {
if test.expect_exception.is_some() {
continue;
} else {
panic!("Invalid transaction type without expected exception");
}
};

env.tx.tx_type = tx_type;

env.tx.gas_limit = unit.transaction.gas_limit[test.indexes.gas].saturating_to();

env.tx.data = unit
Expand All @@ -378,17 +389,19 @@ pub fn execute_test_suite(
.get(test.indexes.data)
.and_then(Option::as_deref)
.cloned()
.unwrap_or_default();
.unwrap_or_default()
.into();

env.tx.authorization_list =
unit.transaction
.authorization_list
.as_ref()
.map(|auth_list| {
AuthorizationList::Recovered(
auth_list.iter().map(|auth| auth.into_recovered()).collect(),
)
});
env.tx.authorization_list = unit
.transaction
.authorization_list
.as_ref()
.map(|auth_list| {
AuthorizationList::Recovered(
auth_list.iter().map(|auth| auth.into_recovered()).collect(),
)
})
.unwrap_or_default();

let to = match unit.transaction.to {
Some(add) => TxKind::Call(add),
Expand Down
4 changes: 2 additions & 2 deletions crates/bytecode/src/eof/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::{
opcode::{self, OPCODE_INFO},
utils::{read_i16, read_u16},
};
use primitives::{Bytes, MAX_INITCODE_SIZE};
use specification::constants::STACK_LIMIT;
use primitives::Bytes;
use specification::constants::{MAX_INITCODE_SIZE, STACK_LIMIT};

use core::{convert::identity, mem};
use std::{borrow::Cow, fmt, vec, vec::Vec};
Expand Down
Empty file added crates/context/CHANGELOG.md
Empty file.
35 changes: 35 additions & 0 deletions crates/context/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[package]
name = "revm-context"
description = "Revm context crates"
version = "1.0.0"
authors.workspace = true
edition.workspace = true
keywords.workspace = true
license.workspace = true
repository.workspace = true
readme.workspace = true

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[lints.rust]
unreachable_pub = "warn"
unused_must_use = "deny"
rust_2018_idioms = "deny"

[lints.rustdoc]
all = "warn"

[dependencies]
# Optional
serde = { version = "1.0", default-features = false, features = [
"derive",
"rc",
], optional = true }

[features]
default = ["std"]
std = ["serde?/std"]
serde = ["dep:serde"]
serde-json = ["serde"]
8 changes: 8 additions & 0 deletions crates/context/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! Optimism-specific constants, types, and helpers.
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(not(feature = "std"))]
extern crate alloc as std;


1 change: 1 addition & 0 deletions crates/inspector/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ serde_json = { version = "1.0", default-features = false, features = [
], optional = true }

[dev-dependencies]
revm = { workspace = true, features = ["serde"] }
database = { workspace = true, features = ["serde"] }

[features]
Expand Down
1 change: 1 addition & 0 deletions crates/inspector/src/customprinter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ mod test {
tx.transact_to = TxKind::Call(callee);
tx.data = Bytes::new();
tx.value = U256::ZERO;
tx.gas_limit = 100_000;
})
.with_spec_id(SpecId::BERLIN)
.append_handler_register(inspector_handle_register)
Expand Down
3 changes: 2 additions & 1 deletion crates/inspector/src/eip3155.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ impl TracerEip3155 {
state_root: B256::ZERO.to_string(),
output: result.output.to_string(),
gas_used: hex_number(
context.inner.env().tx.gas_limit() - self.gas_inspector.gas_remaining(),
context.inner.env().tx.common_fields().gas_limit()
- self.gas_inspector.gas_remaining(),
),
pass: result.is_ok(),
time: None,
Expand Down
1 change: 1 addition & 0 deletions crates/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ bytecode.workspace = true
primitives.workspace = true
specification.workspace = true
wiring.workspace = true
transaction.workspace = true

# mics
derive-where = { version = "1.2.7", default-features = false }
Expand Down
17 changes: 9 additions & 8 deletions crates/interpreter/src/gas/calc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::constants::*;
use crate::{num_words, AccountLoad, Eip7702CodeLoad, SStoreResult, SelfDestructResult, StateLoad};
use primitives::U256;
use specification::{eip2930::AccessListItem, eip7702, hardfork::SpecId};
use specification::{eip7702, hardfork::SpecId};
use transaction::AccessListTrait;

/// `const` Option `?`.
macro_rules! tri {
Expand Down Expand Up @@ -357,11 +358,11 @@ pub const fn memory_gas(num_words: u64) -> u64 {

/// Initial gas that is deducted for transaction to be included.
/// Initial gas contains initial stipend gas, gas for access list and input data.
pub fn validate_initial_tx_gas(
pub fn validate_initial_tx_gas<AccessListT: AccessListTrait>(
spec_id: SpecId,
input: &[u8],
is_create: bool,
access_list: &[AccessListItem],
access_list: Option<&AccessListT>,
authorization_list_num: u64,
) -> u64 {
let mut initial_gas = 0;
Expand All @@ -379,10 +380,10 @@ pub fn validate_initial_tx_gas(
};

// get number of access list account and storages.
if spec_id.is_enabled_in(SpecId::BERLIN) {
let accessed_slots: usize = access_list.iter().map(|item| item.storage_keys.len()).sum();
initial_gas += access_list.len() as u64 * ACCESS_LIST_ADDRESS;
initial_gas += accessed_slots as u64 * ACCESS_LIST_STORAGE_KEY;
if let Some(access_list) = access_list {
let (account_num, storage_num) = access_list.num_account_storages();
initial_gas += account_num as u64 * ACCESS_LIST_ADDRESS;
initial_gas += storage_num as u64 * ACCESS_LIST_STORAGE_KEY;
}

// base stipend
Expand All @@ -403,7 +404,7 @@ pub fn validate_initial_tx_gas(
initial_gas += initcode_cost(input.len() as u64)
}

// EIP-7702
// EIP-7702
if spec_id.is_enabled_in(SpecId::PRAGUE) {
initial_gas += authorization_list_num * eip7702::PER_EMPTY_ACCOUNT_COST;
}
Expand Down
25 changes: 13 additions & 12 deletions crates/interpreter/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
pub mod macros;
pub mod arithmetic;
pub mod bitwise;
pub mod block_info;
pub mod contract;
pub mod control;
pub mod data;
pub mod host;
pub mod host_env;
pub mod i256;
pub mod memory;
pub mod stack;
pub mod system;
pub mod tx_info;
pub mod utility;

use crate::Host;
Expand Down Expand Up @@ -64,7 +65,7 @@ pub const fn instruction_table<H: Host + ?Sized, SPEC: Spec>() -> [crate::table:

table[ADDRESS as usize] = system::address;
table[BALANCE as usize] = host::balance::<H, SPEC>;
table[ORIGIN as usize] = host_env::origin;
table[ORIGIN as usize] = tx_info::origin;
table[CALLER as usize] = system::caller;
table[CALLVALUE as usize] = system::callvalue;
table[CALLDATALOAD as usize] = system::calldataload;
Expand All @@ -73,23 +74,23 @@ pub const fn instruction_table<H: Host + ?Sized, SPEC: Spec>() -> [crate::table:
table[CODESIZE as usize] = system::codesize;
table[CODECOPY as usize] = system::codecopy;

table[GASPRICE as usize] = host_env::gasprice;
table[GASPRICE as usize] = tx_info::gasprice;
table[EXTCODESIZE as usize] = host::extcodesize::<H, SPEC>;
table[EXTCODECOPY as usize] = host::extcodecopy::<H, SPEC>;
table[RETURNDATASIZE as usize] = system::returndatasize::<H, SPEC>;
table[RETURNDATACOPY as usize] = system::returndatacopy::<H, SPEC>;
table[EXTCODEHASH as usize] = host::extcodehash::<H, SPEC>;
table[BLOCKHASH as usize] = host::blockhash::<H, SPEC>;
table[COINBASE as usize] = host_env::coinbase;
table[TIMESTAMP as usize] = host_env::timestamp;
table[NUMBER as usize] = host_env::block_number;
table[DIFFICULTY as usize] = host_env::difficulty::<H, SPEC>;
table[GASLIMIT as usize] = host_env::gaslimit;
table[CHAINID as usize] = host_env::chainid::<H, SPEC>;
table[COINBASE as usize] = block_info::coinbase;
table[TIMESTAMP as usize] = block_info::timestamp;
table[NUMBER as usize] = block_info::block_number;
table[DIFFICULTY as usize] = block_info::difficulty::<H, SPEC>;
table[GASLIMIT as usize] = block_info::gaslimit;
table[CHAINID as usize] = block_info::chainid::<H, SPEC>;
table[SELFBALANCE as usize] = host::selfbalance::<H, SPEC>;
table[BASEFEE as usize] = host_env::basefee::<H, SPEC>;
table[BLOBHASH as usize] = host_env::blob_hash::<H, SPEC>;
table[BLOBBASEFEE as usize] = host_env::blob_basefee::<H, SPEC>;
table[BASEFEE as usize] = block_info::basefee::<H, SPEC>;
table[BLOBHASH as usize] = tx_info::blob_hash::<H, SPEC>;
table[BLOBBASEFEE as usize] = block_info::blob_basefee::<H, SPEC>;

table[POP as usize] = stack::pop;
table[MLOAD as usize] = memory::mload;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{gas, Host, Interpreter};
use primitives::U256;
use specification::hardfork::{Spec, SpecId::*};
use wiring::{Block, Transaction};
use wiring::Block;

/// EIP-1344: ChainID opcode
pub fn chainid<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
Expand Down Expand Up @@ -39,47 +39,19 @@ pub fn gaslimit<H: Host + ?Sized>(interpreter: &mut Interpreter, host: &mut H) {
push!(interpreter, *host.env().block.gas_limit());
}

pub fn gasprice<H: Host + ?Sized>(interpreter: &mut Interpreter, host: &mut H) {
gas!(interpreter, gas::BASE);
push!(interpreter, host.env().effective_gas_price());
}

/// EIP-3198: BASEFEE opcode
pub fn basefee<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
check!(interpreter, LONDON);
gas!(interpreter, gas::BASE);
push!(interpreter, *host.env().block.basefee());
}

pub fn origin<H: Host + ?Sized>(interpreter: &mut Interpreter, host: &mut H) {
gas!(interpreter, gas::BASE);
push_b256!(interpreter, host.env().tx.caller().into_word());
}

// EIP-4844: Shard Blob Transactions
pub fn blob_hash<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
check!(interpreter, CANCUN);
gas!(interpreter, gas::VERYLOW);
pop_top!(interpreter, index);
let i = as_usize_saturated!(index);
*index = match host.env().tx.blob_hashes().get(i) {
Some(hash) => U256::from_be_bytes(hash.0),
None => U256::ZERO,
};
}

/// EIP-7516: BLOBBASEFEE opcode
pub fn blob_basefee<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut H) {
check!(interpreter, CANCUN);
gas!(interpreter, gas::BASE);
push!(
interpreter,
U256::from(
host.env()
.block
.get_blob_gasprice()
.copied()
.unwrap_or_default()
)
U256::from(host.env().block.blob_gasprice().unwrap_or_default())
);
}
Loading

0 comments on commit ee4809e

Please sign in to comment.