Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
499 changes: 310 additions & 189 deletions Cargo.lock

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ revmc-context = { version = "0.1.0", path = "crates/revmc-context", default-feat
revmc-llvm = { version = "0.1.0", path = "crates/revmc-llvm", default-features = false }
revmc-runtime = { version = "0.1.0", path = "crates/revmc-runtime", default-features = false }

alloy-primitives = { version = "1.5.6", default-features = false }
ruint = { version = "1.17", default-features = false }
alloy-evm = { version = "0.34.0", default-features = false }
alloy-primitives = { version = "1.6.0", default-features = false }
ruint = { version = "1.18", default-features = false }
alloy-evm = { version = "0.35.0", default-features = false }

revm-bytecode = { version = "10.0.0", default-features = false, features = ["parse"] }
revm-context = { version = "16.0.0", default-features = false }
revm-context-interface = { version = "17.0.0", default-features = false }
revm-database = { version = "13.0.0", default-features = false }
revm-database-interface = { version = "11.0.0", default-features = false }
revm-handler = { version = "18.0.0", default-features = false }
revm-inspector = { version = "19.0.0", default-features = false }
revm-interpreter = { version = "35.0.0", default-features = false }
revm-primitives = { version = "23.0.0", default-features = false }
revm-state = { version = "11.0.0", default-features = false }
revm-statetest-types = { version = "17.0.0", default-features = false }
revm-bytecode = { version = "11.0.0", default-features = false, features = ["parse"] }
revm-context = { version = "18.0.2", default-features = false }
revm-context-interface = { version = "19.0.2", default-features = false }
revm-database = { version = "15.0.1", default-features = false }
revm-database-interface = { version = "12.1.0", default-features = false }
revm-handler = { version = "20.0.2", default-features = false }
revm-inspector = { version = "21.0.2", default-features = false }
revm-interpreter = { version = "37.0.2", default-features = false }
revm-primitives = { version = "24.0.0", default-features = false }
revm-state = { version = "12.0.0", default-features = false }
revm-statetest-types = { version = "19.0.2", default-features = false }

crossbeam-channel = "0.5"
crossbeam-queue = "0.3"
Expand Down
14 changes: 11 additions & 3 deletions crates/revmc-builtins/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,13 @@ pub unsafe extern "C" fn __revmc_builtin_sstore(

// State gas for new slot creation (EIP-8037).
if ecx.host.is_amsterdam_eip8037_enabled() {
state_gas!(ecx, gp.sstore_state_gas(&state_load.data));
let cpsb = ecx.host.cpsb();
state_gas!(ecx, gp.sstore_state_gas(&state_load.data, cpsb));

let refill = gp.sstore_state_gas_refill(&state_load.data, cpsb);
if refill > 0 {
ecx.gas.refill_reservoir(refill);
}
}

ecx.gas.record_refund(gp.sstore_refund(is_istanbul, &state_load.data));
Expand Down Expand Up @@ -670,7 +676,7 @@ pub unsafe extern "C" fn __revmc_builtin_create(

// State gas for account creation + contract metadata (EIP-8037).
if ecx.host.is_amsterdam_eip8037_enabled() {
state_gas!(ecx, ecx.gas_params.create_state_gas());
state_gas!(ecx, ecx.gas_params.create_state_gas(ecx.host.cpsb()));
}

let mut gas_limit = ecx.gas.remaining();
Expand Down Expand Up @@ -763,6 +769,7 @@ pub unsafe extern "C" fn __revmc_builtin_call(
transfers_value,
call_kind == CallKind::Call,
)?;
let charged_new_account_state_gas = state_gas_cost > 0;

gas!(ecx, dynamic_gas);

Expand Down Expand Up @@ -809,6 +816,7 @@ pub unsafe extern "C" fn __revmc_builtin_call(
scheme: call_kind.into(),
is_static: ecx.is_static || call_kind == CallKind::StaticCall,
reservoir: ecx.gas.reservoir(),
charged_new_account_state_gas,
}),
)));

Expand Down Expand Up @@ -878,7 +886,7 @@ pub unsafe extern "C" fn __revmc_builtin_selfdestruct(

// State gas for new account creation (EIP-8037).
if ecx.host.is_amsterdam_eip8037_enabled() && should_charge_topup {
state_gas!(ecx, ecx.gas_params.new_account_state_gas());
state_gas!(ecx, ecx.gas_params.new_account_state_gas(ecx.host.cpsb()));
}

if !res.previously_destroyed {
Expand Down
12 changes: 6 additions & 6 deletions crates/revmc-cli/src/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,20 +399,20 @@ impl From<SpecIdValueEnum> for SpecId {
fn from(v: SpecIdValueEnum) -> Self {
match v {
SpecIdValueEnum::FRONTIER => Self::FRONTIER,
SpecIdValueEnum::FRONTIER_THAWING => Self::FRONTIER_THAWING,
SpecIdValueEnum::FRONTIER_THAWING => Self::FRONTIER,
SpecIdValueEnum::HOMESTEAD => Self::HOMESTEAD,
SpecIdValueEnum::DAO_FORK => Self::DAO_FORK,
SpecIdValueEnum::DAO_FORK => Self::HOMESTEAD,
SpecIdValueEnum::TANGERINE => Self::TANGERINE,
SpecIdValueEnum::SPURIOUS_DRAGON => Self::SPURIOUS_DRAGON,
SpecIdValueEnum::BYZANTIUM => Self::BYZANTIUM,
SpecIdValueEnum::CONSTANTINOPLE => Self::CONSTANTINOPLE,
SpecIdValueEnum::CONSTANTINOPLE => Self::PETERSBURG,
SpecIdValueEnum::PETERSBURG => Self::PETERSBURG,
SpecIdValueEnum::ISTANBUL => Self::ISTANBUL,
SpecIdValueEnum::MUIR_GLACIER => Self::MUIR_GLACIER,
SpecIdValueEnum::MUIR_GLACIER => Self::ISTANBUL,
SpecIdValueEnum::BERLIN => Self::BERLIN,
SpecIdValueEnum::LONDON => Self::LONDON,
SpecIdValueEnum::ARROW_GLACIER => Self::ARROW_GLACIER,
SpecIdValueEnum::GRAY_GLACIER => Self::GRAY_GLACIER,
SpecIdValueEnum::ARROW_GLACIER => Self::LONDON,
SpecIdValueEnum::GRAY_GLACIER => Self::LONDON,
SpecIdValueEnum::MERGE => Self::MERGE,
SpecIdValueEnum::SHANGHAI => Self::SHANGHAI,
SpecIdValueEnum::CANCUN => Self::CANCUN,
Expand Down
32 changes: 15 additions & 17 deletions crates/revmc-codegen/src/bytecode/info.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use revm_bytecode::opcode as op;
use revm_interpreter::{
host::DummyHost, instructions::instruction_table_gas_changes_spec, interpreter::EthInterpreter,
};
use revm_interpreter::instructions::gas_table_spec;
use revm_primitives::hardfork::SpecId;

/// Opcode information.
Expand Down Expand Up @@ -126,13 +124,13 @@ const FULLY_DYNAMIC: &[u8] = &[op::SSTORE, op::CREATE, op::CREATE2];

/// Opcodes that are gated behind a specific `SpecId`, paired with the spec they were introduced in.
const SPEC_GATED_OPCODES: &[(u8, SpecId)] = &[
(op::SHL, SpecId::CONSTANTINOPLE),
(op::SHR, SpecId::CONSTANTINOPLE),
(op::SAR, SpecId::CONSTANTINOPLE),
(op::SHL, SpecId::PETERSBURG),
(op::SHR, SpecId::PETERSBURG),
(op::SAR, SpecId::PETERSBURG),
(op::CLZ, SpecId::OSAKA),
(op::RETURNDATASIZE, SpecId::BYZANTIUM),
(op::RETURNDATACOPY, SpecId::BYZANTIUM),
(op::EXTCODEHASH, SpecId::CONSTANTINOPLE),
(op::EXTCODEHASH, SpecId::PETERSBURG),
(op::CHAINID, SpecId::ISTANBUL),
(op::SELFBALANCE, SpecId::ISTANBUL),
(op::BASEFEE, SpecId::LONDON),
Expand All @@ -156,7 +154,7 @@ const SPEC_GATED_OPCODES: &[(u8, SpecId)] = &[
const UNSUPPORTED_OPCODES: &[u8] = &[];

fn make_map(spec_id: SpecId) -> [OpcodeInfo; 256] {
let table = instruction_table_gas_changes_spec::<EthInterpreter, DummyHost>(spec_id);
let table = gas_table_spec(spec_id);

let mut map = [OpcodeInfo(OpcodeInfo::UNKNOWN); 256];

Expand All @@ -182,7 +180,7 @@ fn make_map(spec_id: SpecId) -> [OpcodeInfo; 256] {
let gas = if is_fully_dynamic {
0u16
} else {
let static_gas = table[op as usize].static_gas();
let static_gas = table[op as usize] as u64;
assert!(
static_gas <= OpcodeInfo::MASK as u64,
"static gas for opcode 0x{op:02X} exceeds OpcodeInfo capacity: {static_gas}"
Expand Down Expand Up @@ -215,19 +213,19 @@ mod tests {

#[test]
fn test_clz_flags() {
let arrow_glacier = op_info_map(SpecId::ARROW_GLACIER);
let london = op_info_map(SpecId::LONDON);
let cancun = op_info_map(SpecId::CANCUN);
let osaka = op_info_map(SpecId::OSAKA);

let clz_ag = arrow_glacier[op::CLZ as usize];
let clz_london = london[op::CLZ as usize];
let clz_cancun = cancun[op::CLZ as usize];
let clz_osaka = osaka[op::CLZ as usize];

eprintln!(
"CLZ on ARROW_GLACIER: is_unknown={}, is_disabled={}, raw={:#06x}",
clz_ag.is_unknown(),
clz_ag.is_disabled(),
clz_ag.0
"CLZ on LONDON: is_unknown={}, is_disabled={}, raw={:#06x}",
clz_london.is_unknown(),
clz_london.is_disabled(),
clz_london.0
);
eprintln!(
"CLZ on CANCUN: is_unknown={}, is_disabled={}, raw={:#06x}",
Expand All @@ -242,8 +240,8 @@ mod tests {
clz_osaka.0
);

assert!(!clz_ag.is_unknown(), "CLZ should not be unknown on pre-OSAKA");
assert!(clz_ag.is_disabled(), "CLZ should be disabled on ARROW_GLACIER");
assert!(!clz_london.is_unknown(), "CLZ should not be unknown on pre-OSAKA");
assert!(clz_london.is_disabled(), "CLZ should be disabled on LONDON");
assert!(!clz_cancun.is_unknown(), "CLZ should not be unknown on pre-OSAKA");
assert!(clz_cancun.is_disabled(), "CLZ should be disabled on CANCUN");
assert!(!clz_osaka.is_unknown(), "CLZ should not be unknown on OSAKA");
Expand Down
2 changes: 1 addition & 1 deletion crates/revmc-codegen/src/bytecode/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ mod tests {
use super::*;
use revm_bytecode::opcode as op;

const DEF_SPEC: SpecId = SpecId::ARROW_GLACIER;
const DEF_SPEC: SpecId = SpecId::LONDON;

#[test]
fn iter_basic() {
Expand Down
2 changes: 1 addition & 1 deletion crates/revmc-codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type FxHashMap<K, V> = alloy_primitives::map::HashMap<K, V, alloy_primitives::ma
#[cfg(any())]
pub fn generate_all_assembly() -> EvmCompiler<revmc_llvm::EvmLlvmBackend> {
let mut compiler = EvmCompiler::new_llvm(false).unwrap();
let _ = compiler.jit(None, &[], revm_primitives::hardfork::SpecId::ARROW_GLACIER).unwrap();
let _ = compiler.jit(None, &[], revm_primitives::hardfork::SpecId::LONDON).unwrap();
unsafe { compiler.clear().unwrap() };
compiler
}
8 changes: 4 additions & 4 deletions crates/revmc-codegen/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ tests! {
}),
clz_arrow_glacier(@raw {
bytecode: &[op::MSIZE, op::CLZ],
spec_id: SpecId::ARROW_GLACIER,
spec_id: SpecId::LONDON,
expected_return: InstructionResult::NotActivated,
expected_stack: STACK_WHAT_INTERPRETER_SAYS,
expected_gas: GAS_WHAT_INTERPRETER_SAYS,
Expand Down Expand Up @@ -973,7 +973,7 @@ tests! {
}),
difficulty(@raw {
bytecode: &[op::DIFFICULTY, op::DIFFICULTY],
spec_id: SpecId::GRAY_GLACIER,
spec_id: SpecId::LONDON,
expected_stack: &[def_env().block.difficulty, def_env().block.difficulty],
expected_gas: 4,
}),
Expand Down Expand Up @@ -1205,7 +1205,7 @@ tests! {
}),
sstore_constantinople(@raw {
bytecode: &[op::PC, op::PC, op::SSTORE, op::PC, op::COINBASE],
spec_id: SpecId::CONSTANTINOPLE,
spec_id: SpecId::PETERSBURG,
expected_stack: STACK_WHAT_INTERPRETER_SAYS,
expected_gas: GAS_WHAT_INTERPRETER_SAYS,
}),
Expand Down Expand Up @@ -1651,7 +1651,7 @@ tests! {
op::PUSH1, 7, // gas
op::CALL,
],
spec_id: SpecId::MUIR_GLACIER,
spec_id: SpecId::ISTANBUL,
expected_return: RETURN_WHAT_INTERPRETER_SAYS,
expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
expected_gas: GAS_WHAT_INTERPRETER_SAYS,
Expand Down
23 changes: 13 additions & 10 deletions crates/revmc-codegen/src/tests/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use context_interface::{
use revm_bytecode::opcode as op;
use revm_interpreter::{
CallInput, Host, InputsImpl, Interpreter, SharedMemory,
instructions::instruction_table_gas_changes_spec, interpreter::ExtBytecode,
instructions::{gas_table_spec, instruction_table},
interpreter::ExtBytecode,
};
use revm_primitives::{B256, HashMap, Log, hardfork::SpecId};
use similar_asserts::assert_eq;
Expand Down Expand Up @@ -289,6 +290,10 @@ impl Host for TestHost {
false
}

fn cpsb(&self) -> u64 {
0
}

fn difficulty(&self) -> U256 {
U256::from(0xcdef)
}
Expand Down Expand Up @@ -523,12 +528,10 @@ fn run_compiled_test_case(test_case: &TestCase<'_>, f: EvmCompilerFn) {
gas_limit,
);

let table = instruction_table_gas_changes_spec::<
revm_interpreter::interpreter::EthInterpreter,
TestHost,
>(spec_id);
let table = instruction_table::<revm_interpreter::interpreter::EthInterpreter, TestHost>();
let gas_table = gas_table_spec(spec_id);
let mut int_host = TestHost::with_spec(spec_id);
let interpreter_action = interpreter.run_plain(&table, &mut int_host);
let interpreter_action = interpreter.run_plain(&table, &gas_table, &mut int_host);

let int_result = match &interpreter_action {
InterpreterAction::Return(result) => result.result,
Expand All @@ -547,7 +550,7 @@ fn run_compiled_test_case(test_case: &TestCase<'_>, f: EvmCompilerFn) {

// When modify_ecx is set, the interpreter runs with different inputs than the JIT,
// so we cannot use interpreter results as expected values or compare against them.
let skip_interpreter_checks = modify_ecx.is_some() || expected_return.is_error();
let skip_interpreter_checks = modify_ecx.is_some() || expected_return.is_halt();

let mut expected_stack = expected_stack;
if expected_stack == STACK_WHAT_INTERPRETER_SAYS {
Expand Down Expand Up @@ -625,8 +628,8 @@ fn run_compiled_test_case(test_case: &TestCase<'_>, f: EvmCompilerFn) {
| InstructionResult::OutOfGas | InstructionResult::MemoryOOG | InstructionResult::InvalidOperandOOG
) {
assert_eq!(
actual_return.is_error(),
expected_return.is_error(),
actual_return.is_halt(),
expected_return.is_halt(),
"return value mismatch: {actual_return:?} != {expected_return:?}"
);
} else {
Expand All @@ -638,7 +641,7 @@ fn run_compiled_test_case(test_case: &TestCase<'_>, f: EvmCompilerFn) {

// On EVM halt all available gas is consumed, so resulting stack, memory, and gas do not
// matter. We do less work than the interpreter by bailing out earlier due to sections.
if !actual_return.is_error() {
if !actual_return.is_halt() {
if !skip_jit_stack {
assert_eq!(actual_stack, *expected_stack, "stack mismatch");
}
Expand Down
2 changes: 1 addition & 1 deletion crates/revmc-llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ workspace = true
[dependencies]
revmc-backend.workspace = true

inkwell = { git = "https://github.com/TheDan64/inkwell", rev = "4f4d09a57b26e581a532aec9457b332bfe6469dc", features = ["llvm22-1"] }
inkwell = { version = "0.9.0", features = ["llvm22-1"] }
alloy-primitives = { workspace = true, features = ["std", "map-fxhash"] }
object = { version = "0.39", default-features = false, features = ["read_core", "elf"] }
tracing.workspace = true
Expand Down
7 changes: 5 additions & 2 deletions crates/revmc-runtime/src/alloy_evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use alloy_evm::{
};
use alloy_primitives::{Address, Bytes};
use revm_context::{BlockEnv, Evm as RevmEvm, TxEnv};
use revm_context_interface::result::{EVMError, HaltReason, ResultAndState};
use revm_context_interface::{
DBErrorMarker,
result::{EVMError, HaltReason, ResultAndState},
};
use revm_handler::{
EthFrame, ExecuteEvm, PrecompileProvider, SystemCallEvm, instructions::EthInstructions,
};
Expand Down Expand Up @@ -159,7 +162,7 @@ impl EvmFactory for JitEvmFactory {
type Evm<DB: Database, I: Inspector<EthEvmContext<DB>>> = JitEvm<DB, I, PrecompilesMap>;
type Context<DB: Database> = EthEvmContext<DB>;
type Tx = TxEnv;
type Error<DBError: core::error::Error + Send + Sync + 'static> = EVMError<DBError>;
type Error<DBError: DBErrorMarker> = EVMError<DBError>;
type HaltReason = HaltReason;
type Spec = SpecId;
type BlockEnv = BlockEnv;
Expand Down
2 changes: 1 addition & 1 deletion crates/revmc-statetest/src/btest/post_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub const fn block_reward(spec: SpecId, ommers: usize) -> u128 {
return 0;
}

let reward = if spec.is_enabled_in(SpecId::CONSTANTINOPLE) {
let reward = if spec.is_enabled_in(SpecId::PETERSBURG) {
ONE_ETHER * 2
} else if spec.is_enabled_in(SpecId::BYZANTIUM) {
ONE_ETHER * 3
Expand Down
Loading