From e0e043ec5f68ab01874fc786d69f71f6d7b9ac71 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 9 Sep 2024 10:56:25 +0300 Subject: [PATCH 1/7] Enable import formatting --- .github/workflows/ci.yml | 2 +- Cargo.lock | 1 + afl-fuzz/Cargo.toml | 1 + afl-fuzz/src/show_testcase.rs | 11 ++-- eravm-stable-interface/src/lib.rs | 4 +- .../src/tracer_interface.rs | 3 +- src/addressing_modes.rs | 3 +- src/callframe.rs | 7 +-- src/decode.rs | 19 +++---- src/decommit.rs | 3 +- src/heap.rs | 6 ++- src/instruction_handlers/binop.rs | 11 ++-- src/instruction_handlers/common.rs | 3 +- src/instruction_handlers/context.rs | 13 ++--- src/instruction_handlers/decommit.rs | 7 +-- src/instruction_handlers/event.rs | 7 +-- src/instruction_handlers/far_call.rs | 19 +++---- src/instruction_handlers/heap_access.rs | 9 ++-- src/instruction_handlers/jump.rs | 3 +- src/instruction_handlers/mod.rs | 5 +- src/instruction_handlers/monomorphization.rs | 9 ++-- src/instruction_handlers/near_call.rs | 3 +- src/instruction_handlers/nop.rs | 3 +- src/instruction_handlers/pointer.rs | 11 ++-- src/instruction_handlers/precompiles.rs | 15 +++--- src/instruction_handlers/ret.rs | 14 ++--- src/instruction_handlers/storage.rs | 3 +- src/lib.rs | 53 +++++++++---------- src/program.rs | 9 ++-- src/single_instruction_test/callframe.rs | 9 ++-- src/single_instruction_test/heap.rs | 8 +-- src/single_instruction_test/into_zk_evm.rs | 9 ++-- src/single_instruction_test/mock_array.rs | 4 +- src/single_instruction_test/mod.rs | 10 ++-- src/single_instruction_test/program.rs | 5 +- src/single_instruction_test/stack.rs | 3 +- .../state_to_zk_evm.rs | 6 ++- src/single_instruction_test/validation.rs | 3 +- src/single_instruction_test/vm.rs | 10 ++-- src/single_instruction_test/world.rs | 5 +- src/stack.rs | 4 +- src/state.rs | 3 +- src/testworld.rs | 6 ++- src/tracing.rs | 11 ++-- src/vm.rs | 21 ++++---- src/world_diff.rs | 12 +++-- tests/far_call_decommitment.rs | 17 +++--- 47 files changed, 224 insertions(+), 179 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c8f6d2b..e4ac63cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: - name: Check formatting run: | - cargo fmt --check + cargo fmt --check -- --config imports_granularity=Crate --config group_imports=StdExternalCrate - name: Run Tests run: | diff --git a/Cargo.lock b/Cargo.lock index 3ca30e20..78592c19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -246,6 +246,7 @@ dependencies = [ "eravm-stable-interface", "pretty_assertions", "vm2", + "zkevm_opcode_defs", ] [[package]] diff --git a/afl-fuzz/Cargo.toml b/afl-fuzz/Cargo.toml index b658bee1..6adbbee5 100644 --- a/afl-fuzz/Cargo.toml +++ b/afl-fuzz/Cargo.toml @@ -8,6 +8,7 @@ publish = false afl = "0.15" arbitrary = "1" pretty_assertions = "1.4.0" +zkevm_opcode_defs = "0.150.0" [dependencies.vm2] path = ".." diff --git a/afl-fuzz/src/show_testcase.rs b/afl-fuzz/src/show_testcase.rs index 04f2e521..26aab4c9 100644 --- a/afl-fuzz/src/show_testcase.rs +++ b/afl-fuzz/src/show_testcase.rs @@ -1,12 +1,9 @@ +use std::{env, fs}; + use differential_fuzzing::VmAndWorld; use pretty_assertions::assert_eq; -use std::env; -use std::fs; -use vm2::single_instruction_test::add_heap_to_zk_evm; -use vm2::single_instruction_test::vm2_to_zk_evm; -use vm2::single_instruction_test::NoTracer; -use vm2::single_instruction_test::UniversalVmState; -use vm2::zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; +use vm2::single_instruction_test::{add_heap_to_zk_evm, vm2_to_zk_evm, NoTracer, UniversalVmState}; +use zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; fn main() { let filename = env::args() diff --git a/eravm-stable-interface/src/lib.rs b/eravm-stable-interface/src/lib.rs index 17b3d0d7..3d8dfa2f 100644 --- a/eravm-stable-interface/src/lib.rs +++ b/eravm-stable-interface/src/lib.rs @@ -82,7 +82,7 @@ //! } //! ``` +pub use self::{state_interface::*, tracer_interface::*}; + mod state_interface; mod tracer_interface; -pub use state_interface::*; -pub use tracer_interface::*; diff --git a/eravm-stable-interface/src/tracer_interface.rs b/eravm-stable-interface/src/tracer_interface.rs index d497d0f5..c12fe67b 100644 --- a/eravm-stable-interface/src/tracer_interface.rs +++ b/eravm-stable-interface/src/tracer_interface.rs @@ -53,9 +53,10 @@ macro_rules! pub_struct { } pub mod opcodes { - use super::{CallingMode, ReturnType}; use std::marker::PhantomData; + use super::{CallingMode, ReturnType}; + forall_simple_opcodes!(pub_struct); pub struct FarCall(PhantomData); pub struct Ret(PhantomData); diff --git a/src/addressing_modes.rs b/src/addressing_modes.rs index 94d5c2a5..b0b8298a 100644 --- a/src/addressing_modes.rs +++ b/src/addressing_modes.rs @@ -1,10 +1,11 @@ -use crate::{mode_requirements::ModeRequirements, predication::Predicate}; #[cfg(feature = "arbitrary")] use arbitrary::{Arbitrary, Unstructured}; use enum_dispatch::enum_dispatch; use u256::U256; use zkevm_opcode_defs::erase_fat_pointer_metadata; +use crate::{mode_requirements::ModeRequirements, predication::Predicate}; + pub(crate) trait Source { /// Get a word's value for non-pointer operations. (Pointers are erased.) fn get(args: &Arguments, state: &mut impl Addressable) -> U256 { diff --git a/src/callframe.rs b/src/callframe.rs index f06483cc..d47f4598 100644 --- a/src/callframe.rs +++ b/src/callframe.rs @@ -1,3 +1,7 @@ +use eravm_stable_interface::HeapId; +use u256::H160; +use zkevm_opcode_defs::system_params::{NEW_FRAME_MEMORY_STIPEND, NEW_KERNEL_FRAME_MEMORY_STIPEND}; + use crate::{ decommit::is_kernel, instruction_handlers::invalid_instruction, @@ -6,9 +10,6 @@ use crate::{ world_diff::Snapshot, Instruction, }; -use eravm_stable_interface::HeapId; -use u256::H160; -use zkevm_opcode_defs::system_params::{NEW_FRAME_MEMORY_STIPEND, NEW_KERNEL_FRAME_MEMORY_STIPEND}; #[derive(Debug)] pub struct Callframe { diff --git a/src/decode.rs b/src/decode.rs index 6b971fca..9e841541 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -1,3 +1,13 @@ +use eravm_stable_interface::{opcodes, Tracer}; +use zkevm_opcode_defs::{ + decoding::{EncodingModeProduction, VmEncodingMode}, + ImmMemHandlerFlags, Opcode, + Operand::*, + RegOrImmFlags, FAR_CALL_SHARD_FLAG_IDX, FAR_CALL_STATIC_FLAG_IDX, FIRST_MESSAGE_FLAG_IDX, + RET_TO_LABEL_BIT_IDX, SET_FLAGS_FLAG_IDX, SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES, + SWAP_OPERANDS_FLAG_IDX_FOR_PTR_OPCODE, UMA_INCREMENT_FLAG_IDX, +}; + use crate::{ addressing_modes::{ AbsoluteStack, AdvanceStackPointer, AnyDestination, AnySource, Arguments, CodePage, @@ -13,15 +23,6 @@ use crate::{ mode_requirements::ModeRequirements, Instruction, Predicate, VirtualMachine, World, }; -use eravm_stable_interface::{opcodes, Tracer}; -use zkevm_opcode_defs::{ - decoding::{EncodingModeProduction, VmEncodingMode}, - ImmMemHandlerFlags, Opcode, - Operand::*, - RegOrImmFlags, FAR_CALL_SHARD_FLAG_IDX, FAR_CALL_STATIC_FLAG_IDX, FIRST_MESSAGE_FLAG_IDX, - RET_TO_LABEL_BIT_IDX, SET_FLAGS_FLAG_IDX, SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES, - SWAP_OPERANDS_FLAG_IDX_FOR_PTR_OPCODE, UMA_INCREMENT_FLAG_IDX, -}; pub fn decode_program>( raw: &[u64], diff --git a/src/decommit.rs b/src/decommit.rs index 34b6553e..54f94612 100644 --- a/src/decommit.rs +++ b/src/decommit.rs @@ -1,10 +1,11 @@ -use crate::{program::Program, world_diff::WorldDiff, World}; use eravm_stable_interface::{CycleStats, Tracer}; use u256::{H160, U256}; use zkevm_opcode_defs::{ ethereum_types::Address, system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW, }; +use crate::{program::Program, world_diff::WorldDiff, World}; + impl WorldDiff { pub(crate) fn decommit( &mut self, diff --git a/src/heap.rs b/src/heap.rs index 3e8711a4..3f61e959 100644 --- a/src/heap.rs +++ b/src/heap.rs @@ -1,11 +1,13 @@ -use crate::instruction_handlers::HeapInterface; -use eravm_stable_interface::HeapId; use std::{ fmt, mem, ops::{Index, Range}, }; + +use eravm_stable_interface::HeapId; use u256::U256; +use crate::instruction_handlers::HeapInterface; + /// Heap page size in bytes. const HEAP_PAGE_SIZE: usize = 1 << 12; diff --git a/src/instruction_handlers/binop.rs b/src/instruction_handlers/binop.rs index 54253a27..951d9d97 100644 --- a/src/instruction_handlers/binop.rs +++ b/src/instruction_handlers/binop.rs @@ -1,3 +1,9 @@ +use eravm_stable_interface::{ + opcodes::{Add, And, Div, Mul, Or, RotateLeft, RotateRight, ShiftLeft, ShiftRight, Sub, Xor}, + OpcodeType, Tracer, +}; +use u256::U256; + use super::common::boilerplate; use crate::{ addressing_modes::{ @@ -9,11 +15,6 @@ use crate::{ predication::Flags, VirtualMachine, }; -use eravm_stable_interface::{ - opcodes::{Add, And, Div, Mul, Or, RotateLeft, RotateRight, ShiftLeft, ShiftRight, Sub, Xor}, - OpcodeType, Tracer, -}; -use u256::U256; fn binop< T: Tracer, diff --git a/src/instruction_handlers/common.rs b/src/instruction_handlers/common.rs index d274e740..5d8ca85b 100644 --- a/src/instruction_handlers/common.rs +++ b/src/instruction_handlers/common.rs @@ -1,6 +1,7 @@ +use eravm_stable_interface::{opcodes, OpcodeType, Tracer}; + use super::ret::free_panic; use crate::{addressing_modes::Arguments, instruction::ExecutionStatus, VirtualMachine}; -use eravm_stable_interface::{opcodes, OpcodeType, Tracer}; #[inline(always)] pub(crate) fn boilerplate( diff --git a/src/instruction_handlers/context.rs b/src/instruction_handlers/context.rs index 74c02650..fdfbf5dc 100644 --- a/src/instruction_handlers/context.rs +++ b/src/instruction_handlers/context.rs @@ -1,3 +1,10 @@ +use eravm_stable_interface::{ + opcodes::{self, Caller, CodeAddress, ContextU128, ErgsLeft, This, SP}, + OpcodeType, Tracer, +}; +use u256::U256; +use zkevm_opcode_defs::VmMetaParameters; + use super::common::boilerplate; use crate::{ addressing_modes::{Arguments, Destination, Register1, Source}, @@ -6,12 +13,6 @@ use crate::{ state::State, Instruction, VirtualMachine, }; -use eravm_stable_interface::{ - opcodes::{self, Caller, CodeAddress, ContextU128, ErgsLeft, This, SP}, - OpcodeType, Tracer, -}; -use u256::U256; -use zkevm_opcode_defs::VmMetaParameters; fn context( vm: &mut VirtualMachine, diff --git a/src/instruction_handlers/decommit.rs b/src/instruction_handlers/decommit.rs index dc2e0d9c..80763e6c 100644 --- a/src/instruction_handlers/decommit.rs +++ b/src/instruction_handlers/decommit.rs @@ -1,3 +1,7 @@ +use eravm_stable_interface::{opcodes, Tracer}; +use u256::U256; +use zkevm_opcode_defs::{BlobSha256Format, ContractCodeSha256Format, VersionedHashLen32}; + use super::common::boilerplate_ext; use crate::{ addressing_modes::{Arguments, Destination, Register1, Register2, Source}, @@ -5,9 +9,6 @@ use crate::{ instruction::ExecutionStatus, Instruction, VirtualMachine, World, }; -use eravm_stable_interface::{opcodes, Tracer}; -use u256::U256; -use zkevm_opcode_defs::{BlobSha256Format, ContractCodeSha256Format, VersionedHashLen32}; fn decommit>( vm: &mut VirtualMachine, diff --git a/src/instruction_handlers/event.rs b/src/instruction_handlers/event.rs index 62895734..98bc065a 100644 --- a/src/instruction_handlers/event.rs +++ b/src/instruction_handlers/event.rs @@ -1,3 +1,7 @@ +use eravm_stable_interface::{opcodes, Tracer}; +use u256::H160; +use zkevm_opcode_defs::ADDRESS_EVENT_WRITER; + use super::common::boilerplate_ext; use crate::{ addressing_modes::{Arguments, Immediate1, Register1, Register2, Source}, @@ -5,9 +9,6 @@ use crate::{ world_diff::{Event, L2ToL1Log}, Instruction, VirtualMachine, }; -use eravm_stable_interface::{opcodes, Tracer}; -use u256::H160; -use zkevm_opcode_defs::ADDRESS_EVENT_WRITER; fn event( vm: &mut VirtualMachine, diff --git a/src/instruction_handlers/far_call.rs b/src/instruction_handlers/far_call.rs index 9437ee57..086e4fdf 100644 --- a/src/instruction_handlers/far_call.rs +++ b/src/instruction_handlers/far_call.rs @@ -1,3 +1,13 @@ +use eravm_stable_interface::{ + opcodes::{FarCall, TypeLevelCallingMode}, + Tracer, +}; +use u256::U256; +use zkevm_opcode_defs::{ + system_params::{EVM_SIMULATOR_STIPEND, MSG_VALUE_SIMULATOR_ADDITIVE_COST}, + ADDRESS_MSG_VALUE, +}; + use super::{ common::boilerplate_ext, heap_access::grow_heap, @@ -12,15 +22,6 @@ use crate::{ predication::Flags, Instruction, VirtualMachine, World, }; -use eravm_stable_interface::{ - opcodes::{FarCall, TypeLevelCallingMode}, - Tracer, -}; -use u256::U256; -use zkevm_opcode_defs::{ - system_params::{EVM_SIMULATOR_STIPEND, MSG_VALUE_SIMULATOR_ADDITIVE_COST}, - ADDRESS_MSG_VALUE, -}; /// A call to another contract. /// diff --git a/src/instruction_handlers/heap_access.rs b/src/instruction_handlers/heap_access.rs index 74ff1ce5..b393d7ed 100644 --- a/src/instruction_handlers/heap_access.rs +++ b/src/instruction_handlers/heap_access.rs @@ -1,3 +1,8 @@ +use std::ops::Range; + +use eravm_stable_interface::{opcodes, OpcodeType, Tracer}; +use u256::U256; + use super::common::{boilerplate, full_boilerplate}; use crate::{ addressing_modes::{ @@ -9,10 +14,8 @@ use crate::{ state::State, ExecutionEnd, HeapId, Instruction, VirtualMachine, }; -use eravm_stable_interface::{opcodes, OpcodeType, Tracer}; -use std::ops::Range; -use u256::U256; +// FIXME: reduce visibility pub trait HeapInterface { fn read_u256(&self, start_address: u32) -> U256; fn read_u256_partially(&self, range: Range) -> U256; diff --git a/src/instruction_handlers/jump.rs b/src/instruction_handlers/jump.rs index 28ccc4db..f185ae2c 100644 --- a/src/instruction_handlers/jump.rs +++ b/src/instruction_handlers/jump.rs @@ -1,3 +1,5 @@ +use eravm_stable_interface::{opcodes, Tracer}; + use super::common::boilerplate; use crate::{ addressing_modes::{ @@ -7,7 +9,6 @@ use crate::{ instruction::{ExecutionStatus, Instruction}, VirtualMachine, }; -use eravm_stable_interface::{opcodes, Tracer}; fn jump( vm: &mut VirtualMachine, diff --git a/src/instruction_handlers/mod.rs b/src/instruction_handlers/mod.rs index 1f7e32fc..3afa4d34 100644 --- a/src/instruction_handlers/mod.rs +++ b/src/instruction_handlers/mod.rs @@ -2,8 +2,9 @@ pub use eravm_stable_interface::opcodes::{ Add, And, Div, Mul, Or, PointerAdd, PointerPack, PointerShrink, PointerSub, RotateLeft, RotateRight, ShiftLeft, ShiftRight, Sub, Xor, }; -pub use heap_access::{AuxHeap, Heap, HeapInterface}; -pub(crate) use ret::{invalid_instruction, RETURN_COST}; + +pub use self::heap_access::{AuxHeap, Heap, HeapInterface}; +pub(crate) use self::ret::{invalid_instruction, RETURN_COST}; mod binop; mod common; diff --git a/src/instruction_handlers/monomorphization.rs b/src/instruction_handlers/monomorphization.rs index 87108329..660f15ac 100644 --- a/src/instruction_handlers/monomorphization.rs +++ b/src/instruction_handlers/monomorphization.rs @@ -59,6 +59,9 @@ macro_rules! parameterize { }; } -pub(crate) use { - match_boolean, match_destination, match_reg_imm, match_source, monomorphize, parameterize, -}; +pub(crate) use match_boolean; +pub(crate) use match_destination; +pub(crate) use match_reg_imm; +pub(crate) use match_source; +pub(crate) use monomorphize; +pub(crate) use parameterize; diff --git a/src/instruction_handlers/near_call.rs b/src/instruction_handlers/near_call.rs index 3f3b74b1..a93cb7d9 100644 --- a/src/instruction_handlers/near_call.rs +++ b/src/instruction_handlers/near_call.rs @@ -1,3 +1,5 @@ +use eravm_stable_interface::{opcodes, Tracer}; + use super::common::boilerplate; use crate::{ addressing_modes::{Arguments, Immediate1, Immediate2, Register1, Source}, @@ -5,7 +7,6 @@ use crate::{ predication::Flags, Instruction, VirtualMachine, }; -use eravm_stable_interface::{opcodes, Tracer}; fn near_call( vm: &mut VirtualMachine, diff --git a/src/instruction_handlers/nop.rs b/src/instruction_handlers/nop.rs index b9a00168..916a136b 100644 --- a/src/instruction_handlers/nop.rs +++ b/src/instruction_handlers/nop.rs @@ -1,10 +1,11 @@ +use eravm_stable_interface::{opcodes, Tracer}; + use super::common::boilerplate; use crate::{ addressing_modes::{destination_stack_address, AdvanceStackPointer, Arguments, Source}, instruction::ExecutionStatus, Instruction, VirtualMachine, }; -use eravm_stable_interface::{opcodes, Tracer}; fn nop( vm: &mut VirtualMachine, diff --git a/src/instruction_handlers/pointer.rs b/src/instruction_handlers/pointer.rs index f450ad74..6c183140 100644 --- a/src/instruction_handlers/pointer.rs +++ b/src/instruction_handlers/pointer.rs @@ -1,3 +1,9 @@ +use eravm_stable_interface::{ + opcodes::{PointerAdd, PointerPack, PointerShrink, PointerSub}, + OpcodeType, Tracer, +}; +use u256::U256; + use super::common::boilerplate; use crate::{ addressing_modes::{ @@ -8,11 +14,6 @@ use crate::{ instruction::ExecutionStatus, Instruction, VirtualMachine, }; -use eravm_stable_interface::{ - opcodes::{PointerAdd, PointerPack, PointerShrink, PointerSub}, - OpcodeType, Tracer, -}; -use u256::U256; fn ptr( vm: &mut VirtualMachine, diff --git a/src/instruction_handlers/precompiles.rs b/src/instruction_handlers/precompiles.rs index a337a11c..04c0237e 100644 --- a/src/instruction_handlers/precompiles.rs +++ b/src/instruction_handlers/precompiles.rs @@ -1,10 +1,3 @@ -use super::{common::boilerplate_ext, HeapInterface}; -use crate::{ - addressing_modes::{Arguments, Destination, Register1, Register2, Source}, - heap::Heaps, - instruction::ExecutionStatus, - Instruction, VirtualMachine, -}; use eravm_stable_interface::{opcodes, CycleStats, HeapId, Tracer}; use zk_evm_abstractions::{ aux::Timestamp, @@ -23,6 +16,14 @@ use zkevm_opcode_defs::{ PrecompileAuxData, PrecompileCallABI, }; +use super::{common::boilerplate_ext, HeapInterface}; +use crate::{ + addressing_modes::{Arguments, Destination, Register1, Register2, Source}, + heap::Heaps, + instruction::ExecutionStatus, + Instruction, VirtualMachine, +}; + fn precompile_call( vm: &mut VirtualMachine, world: &mut W, diff --git a/src/instruction_handlers/ret.rs b/src/instruction_handlers/ret.rs index 30ad2394..7a282496 100644 --- a/src/instruction_handlers/ret.rs +++ b/src/instruction_handlers/ret.rs @@ -1,3 +1,9 @@ +use eravm_stable_interface::{ + opcodes::{self, TypeLevelReturnType}, + ReturnType, Tracer, +}; +use u256::U256; + use super::{common::full_boilerplate, far_call::get_far_call_calldata, HeapInterface}; use crate::{ addressing_modes::{Arguments, Immediate1, Register1, Source, INVALID_INSTRUCTION_COST}, @@ -7,11 +13,6 @@ use crate::{ predication::Flags, Instruction, Predicate, VirtualMachine, }; -use eravm_stable_interface::{ - opcodes::{self, TypeLevelReturnType}, - ReturnType, Tracer, -}; -use u256::U256; fn naked_ret( vm: &mut VirtualMachine, @@ -181,9 +182,10 @@ pub fn invalid_instruction<'a, T, W>() -> &'a Instruction { pub(crate) const RETURN_COST: u32 = 5; -use super::monomorphization::*; use eravm_stable_interface::opcodes::{Normal, Panic, Revert}; +use super::monomorphization::*; + impl Instruction { pub fn from_ret(src1: Register1, label: Option, arguments: Arguments) -> Self { let to_label = label.is_some(); diff --git a/src/instruction_handlers/storage.rs b/src/instruction_handlers/storage.rs index 7f6b857c..e3b97b4e 100644 --- a/src/instruction_handlers/storage.rs +++ b/src/instruction_handlers/storage.rs @@ -1,3 +1,5 @@ +use eravm_stable_interface::{opcodes, Tracer}; + use super::common::{boilerplate, boilerplate_ext}; use crate::{ addressing_modes::{ @@ -6,7 +8,6 @@ use crate::{ instruction::ExecutionStatus, Instruction, VirtualMachine, World, }; -use eravm_stable_interface::{opcodes, Tracer}; fn sstore>( vm: &mut VirtualMachine, diff --git a/src/lib.rs b/src/lib.rs index d52150b7..662c9e34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,26 @@ +use std::hash::{DefaultHasher, Hash, Hasher}; + +pub use eravm_stable_interface::{ + CallframeInterface, CycleStats, HeapId, Opcode, OpcodeType, ReturnType, StateInterface, Tracer, +}; +use u256::{H160, U256}; + +// Re-export missing modules if single instruction testing is enabled +#[cfg(feature = "single_instruction_test")] +pub(crate) use self::single_instruction_test::{heap, program, stack}; +pub use self::{ + decommit::{address_into_u256, initial_decommit}, + heap::FIRST_HEAP, + instruction::{jump_to_beginning, ExecutionEnd, Instruction}, + mode_requirements::ModeRequirements, + predication::Predicate, + program::Program, + state::State, + vm::{Settings, VirtualMachine, VmSnapshot as Snapshot}, + world_diff::{Event, L2ToL1Log, WorldDiff}, +}; + +// FIXME: revise visibility pub mod addressing_modes; #[cfg(not(feature = "single_instruction_test"))] mod bitset; @@ -14,6 +37,8 @@ mod predication; #[cfg(not(feature = "single_instruction_test"))] mod program; mod rollback; +#[cfg(feature = "single_instruction_test")] +pub mod single_instruction_test; #[cfg(not(feature = "single_instruction_test"))] mod stack; mod state; @@ -22,34 +47,6 @@ mod tracing; mod vm; mod world_diff; -use std::hash::{DefaultHasher, Hash, Hasher}; -use u256::{H160, U256}; - -pub use decommit::address_into_u256; -pub use decommit::initial_decommit; -pub use eravm_stable_interface::{ - CallframeInterface, CycleStats, HeapId, Opcode, OpcodeType, ReturnType, StateInterface, Tracer, -}; -pub use heap::FIRST_HEAP; -pub use instruction::{jump_to_beginning, ExecutionEnd, Instruction}; -pub use mode_requirements::ModeRequirements; -pub use predication::Predicate; -pub use program::Program; -pub use state::State; -pub use vm::{Settings, VirtualMachine, VmSnapshot as Snapshot}; -pub use world_diff::{Event, L2ToL1Log, WorldDiff}; - -#[cfg(feature = "single_instruction_test")] -pub mod single_instruction_test; -#[cfg(feature = "single_instruction_test")] -use single_instruction_test::heap; -#[cfg(feature = "single_instruction_test")] -use single_instruction_test::program; -#[cfg(feature = "single_instruction_test")] -use single_instruction_test::stack; -#[cfg(feature = "single_instruction_test")] -pub use zkevm_opcode_defs; - pub trait World: StorageInterface + Sized { /// This will be called *every* time a contract is called. Caching and decoding is /// the world implementor's job. diff --git a/src/program.rs b/src/program.rs index 401892b1..143fff67 100644 --- a/src/program.rs +++ b/src/program.rs @@ -1,13 +1,14 @@ -use crate::{hash_for_debugging, Instruction}; use std::{fmt, sync::Arc}; + use u256::U256; -// An internal representation that doesn't need two Arcs would be better -// but it would also require a lot of unsafe, so I made this wrapper to -// enable changing the internals later. +use crate::{hash_for_debugging, Instruction}; /// Cloning this is cheap. It is a handle to memory similar to [`Arc`]. pub struct Program { + // An internal representation that doesn't need two Arcs would be better + // but it would also require a lot of unsafe, so I made this wrapper to + // enable changing the internals later. code_page: Arc<[U256]>, instructions: Arc<[Instruction]>, } diff --git a/src/single_instruction_test/callframe.rs b/src/single_instruction_test/callframe.rs index f2ac3839..66a12a18 100644 --- a/src/single_instruction_test/callframe.rs +++ b/src/single_instruction_test/callframe.rs @@ -1,3 +1,8 @@ +use arbitrary::Arbitrary; +use eravm_stable_interface::Tracer; +use u256::H160; +use zkevm_opcode_defs::EVM_SIMULATOR_STIPEND; + use super::{ heap::FIRST_AUX_HEAP, stack::{Stack, StackPool}, @@ -6,10 +11,6 @@ use crate::{ callframe::Callframe, decommit::is_kernel, predication::Flags, HeapId, Program, World, WorldDiff, }; -use arbitrary::Arbitrary; -use eravm_stable_interface::Tracer; -use u256::H160; -use zkevm_opcode_defs::EVM_SIMULATOR_STIPEND; impl<'a> Arbitrary<'a> for Flags { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { diff --git a/src/single_instruction_test/heap.rs b/src/single_instruction_test/heap.rs index 20bfea89..835b339f 100644 --- a/src/single_instruction_test/heap.rs +++ b/src/single_instruction_test/heap.rs @@ -1,10 +1,12 @@ -use super::mock_array::MockRead; -use crate::instruction_handlers::HeapInterface; +use std::ops::Index; + use arbitrary::Arbitrary; use eravm_stable_interface::HeapId; -use std::ops::Index; use u256::U256; +use super::mock_array::MockRead; +use crate::instruction_handlers::HeapInterface; + #[derive(Debug, Clone)] pub struct Heap { pub(crate) read: MockRead, diff --git a/src/single_instruction_test/into_zk_evm.rs b/src/single_instruction_test/into_zk_evm.rs index 13470752..88611206 100644 --- a/src/single_instruction_test/into_zk_evm.rs +++ b/src/single_instruction_test/into_zk_evm.rs @@ -1,9 +1,5 @@ use std::sync::Arc; -use super::{stack::Stack, state_to_zk_evm::vm2_state_to_zk_evm_state, MockWorld}; -use crate::{ - zkevm_opcode_defs::decoding::EncodingModeProduction, StorageInterface, VirtualMachine, -}; use eravm_stable_interface::Tracer; use u256::U256; use zk_evm::{ @@ -16,7 +12,10 @@ use zk_evm::{ witness_trace::VmWitnessTracer, }; use zk_evm_abstractions::vm::EventSink; -use zkevm_opcode_defs::TRANSIENT_STORAGE_AUX_BYTE; +use zkevm_opcode_defs::{decoding::EncodingModeProduction, TRANSIENT_STORAGE_AUX_BYTE}; + +use super::{stack::Stack, state_to_zk_evm::vm2_state_to_zk_evm_state, MockWorld}; +use crate::{StorageInterface, VirtualMachine}; type ZkEvmState = VmState< MockWorldWrapper, diff --git a/src/single_instruction_test/mock_array.rs b/src/single_instruction_test/mock_array.rs index c18c237b..4b9eff18 100644 --- a/src/single_instruction_test/mock_array.rs +++ b/src/single_instruction_test/mock_array.rs @@ -1,6 +1,6 @@ +use std::{cell::Cell, fmt::Debug}; + use arbitrary::Arbitrary; -use std::cell::Cell; -use std::fmt::Debug; #[derive(Clone, Debug)] pub struct MockRead { diff --git a/src/single_instruction_test/mod.rs b/src/single_instruction_test/mod.rs index abd31636..4db72b28 100644 --- a/src/single_instruction_test/mod.rs +++ b/src/single_instruction_test/mod.rs @@ -5,6 +5,12 @@ //! //! The same kind of mocking in applied to stack memory, the program, the world and callstack. +pub use self::{ + into_zk_evm::{add_heap_to_zk_evm, vm2_to_zk_evm, NoTracer}, + universal_state::UniversalVmState, + world::MockWorld, +}; + mod callframe; pub mod heap; mod into_zk_evm; @@ -17,7 +23,3 @@ mod universal_state; mod validation; mod vm; mod world; - -pub use into_zk_evm::{add_heap_to_zk_evm, vm2_to_zk_evm, NoTracer}; -pub use universal_state::UniversalVmState; -pub use world::MockWorld; diff --git a/src/single_instruction_test/program.rs b/src/single_instruction_test/program.rs index 50ba1bb4..bbdfc441 100644 --- a/src/single_instruction_test/program.rs +++ b/src/single_instruction_test/program.rs @@ -1,10 +1,11 @@ -use crate::{decode::decode, Instruction, World}; +use std::{rc::Rc, sync::Arc}; + use arbitrary::Arbitrary; use eravm_stable_interface::Tracer; -use std::{rc::Rc, sync::Arc}; use u256::U256; use super::mock_array::MockRead; +use crate::{decode::decode, Instruction, World}; #[derive(Debug)] pub struct Program { diff --git a/src/single_instruction_test/stack.rs b/src/single_instruction_test/stack.rs index d6cc12e4..ece25541 100644 --- a/src/single_instruction_test/stack.rs +++ b/src/single_instruction_test/stack.rs @@ -1,8 +1,9 @@ +use u256::U256; + use super::{ mock_array::MockRead, validation::is_valid_tagged_value, vm::arbitrary_register_value, }; use crate::HeapId; -use u256::U256; #[derive(PartialEq, Debug, Clone)] pub struct Stack { diff --git a/src/single_instruction_test/state_to_zk_evm.rs b/src/single_instruction_test/state_to_zk_evm.rs index 907b944b..ac6cb86f 100644 --- a/src/single_instruction_test/state_to_zk_evm.rs +++ b/src/single_instruction_test/state_to_zk_evm.rs @@ -1,6 +1,6 @@ -use crate::callframe::{Callframe, NearCallFrame}; -use eravm_stable_interface::Tracer; use std::iter; + +use eravm_stable_interface::Tracer; use u256::U256; use zk_evm::{ aux_structures::{MemoryPage, PubdataCost}, @@ -8,6 +8,8 @@ use zk_evm::{ }; use zkevm_opcode_defs::decoding::EncodingModeProduction; +use crate::callframe::{Callframe, NearCallFrame}; + pub(crate) fn vm2_state_to_zk_evm_state( state: &crate::State, panic: &crate::Instruction, diff --git a/src/single_instruction_test/validation.rs b/src/single_instruction_test/validation.rs index df4eed4d..c32b5646 100644 --- a/src/single_instruction_test/validation.rs +++ b/src/single_instruction_test/validation.rs @@ -1,6 +1,7 @@ -use crate::{callframe::Callframe, fat_pointer::FatPointer, State}; use u256::U256; +use crate::{callframe::Callframe, fat_pointer::FatPointer, State}; + pub(crate) fn is_valid_tagged_value((value, is_pointer): (U256, bool)) -> bool { if is_pointer { let pointer = FatPointer::from(value); diff --git a/src/single_instruction_test/vm.rs b/src/single_instruction_test/vm.rs index 62b8ca14..a8b96a34 100644 --- a/src/single_instruction_test/vm.rs +++ b/src/single_instruction_test/vm.rs @@ -1,13 +1,15 @@ +use std::fmt::Debug; + +use arbitrary::Arbitrary; +use eravm_stable_interface::Tracer; +use u256::U256; + use super::{heap::Heaps, stack::StackPool}; use crate::{ addressing_modes::Arguments, callframe::Callframe, fat_pointer::FatPointer, instruction::ExecutionStatus, HeapId, Instruction, ModeRequirements, Predicate, Settings, State, VirtualMachine, World, }; -use arbitrary::Arbitrary; -use eravm_stable_interface::Tracer; -use std::fmt::Debug; -use u256::U256; impl VirtualMachine { pub fn run_single_instruction(&mut self, world: &mut W, tracer: &mut T) -> ExecutionStatus { diff --git a/src/single_instruction_test/world.rs b/src/single_instruction_test/world.rs index 1dc7d6c9..d5cdcfec 100644 --- a/src/single_instruction_test/world.rs +++ b/src/single_instruction_test/world.rs @@ -1,9 +1,10 @@ -use super::mock_array::MockRead; -use crate::{Program, StorageInterface, World}; use arbitrary::Arbitrary; use eravm_stable_interface::Tracer; use u256::{H160, U256}; +use super::mock_array::MockRead; +use crate::{Program, StorageInterface, World}; + #[derive(Debug, Arbitrary, Clone)] pub struct MockWorld { storage_slot: MockRead<(H160, U256), Option>, diff --git a/src/stack.rs b/src/stack.rs index 9774e954..201f036b 100644 --- a/src/stack.rs +++ b/src/stack.rs @@ -1,10 +1,12 @@ -use crate::{bitset::Bitset, fat_pointer::FatPointer, hash_for_debugging}; use std::{ alloc::{alloc, alloc_zeroed, Layout}, fmt, }; + use u256::U256; +use crate::{bitset::Bitset, fat_pointer::FatPointer, hash_for_debugging}; + #[derive(PartialEq)] pub struct Stack { /// set of slots that may be interpreted as [`FatPointer`]. diff --git a/src/state.rs b/src/state.rs index ec7fcd0d..21c94f5a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,3 +1,5 @@ +use u256::{H160, U256}; + use crate::{ addressing_modes::Addressable, callframe::{Callframe, CallframeSnapshot}, @@ -8,7 +10,6 @@ use crate::{ stack::Stack, world_diff::Snapshot, }; -use u256::{H160, U256}; #[derive(Debug)] pub struct State { diff --git a/src/testworld.rs b/src/testworld.rs index 4e957fd6..7620c98d 100644 --- a/src/testworld.rs +++ b/src/testworld.rs @@ -1,14 +1,16 @@ -use crate::{address_into_u256, Program, StorageInterface, World}; -use eravm_stable_interface::Tracer; use std::{ collections::{hash_map::DefaultHasher, BTreeMap}, hash::{Hash, Hasher}, }; + +use eravm_stable_interface::Tracer; use u256::U256; use zkevm_opcode_defs::{ ethereum_types::Address, system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW, }; +use crate::{address_into_u256, Program, StorageInterface, World}; + #[derive(Debug)] pub struct TestWorld { pub address_to_hash: BTreeMap, diff --git a/src/tracing.rs b/src/tracing.rs index 5e266614..481f73b3 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -1,11 +1,13 @@ +use std::cmp::Ordering; + +use eravm_stable_interface::*; + use crate::{ callframe::{Callframe, NearCallFrame}, decommit::is_kernel, predication::{self, Predicate}, VirtualMachine, }; -use eravm_stable_interface::*; -use std::cmp::Ordering; impl StateInterface for VirtualMachine { fn read_register(&self, register: u8) -> (u256::U256, bool) { @@ -359,12 +361,13 @@ impl CallframeWrapper<'_, T, W> { #[cfg(all(test, not(feature = "single_instruction_test")))] mod test { - use super::*; - use crate::{initial_decommit, testworld::TestWorld, Instruction, Program, VirtualMachine}; use eravm_stable_interface::HeapId; use u256::H160; use zkevm_opcode_defs::ethereum_types::Address; + use super::*; + use crate::{initial_decommit, testworld::TestWorld, Instruction, Program, VirtualMachine}; + #[test] fn callframe_picking() { let program = Program::new(vec![Instruction::from_invalid()], vec![]); diff --git a/src/vm.rs b/src/vm.rs index ebd90203..9e819aa7 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -1,20 +1,17 @@ -use crate::addressing_modes::Arguments; -use crate::instruction::ExecutionStatus; -use crate::instruction_handlers::RETURN_COST; -use crate::state::StateSnapshot; -use crate::world_diff::ExternalSnapshot; +use eravm_stable_interface::{opcodes::TypeLevelCallingMode, CallingMode, HeapId, Tracer}; +use u256::H160; + use crate::{ + addressing_modes::Arguments, callframe::{Callframe, FrameRemnant}, decommit::u256_into_address, + instruction::ExecutionStatus, + instruction_handlers::RETURN_COST, stack::StackPool, - state::State, - world_diff::{Snapshot, WorldDiff}, - ExecutionEnd, Program, + state::{State, StateSnapshot}, + world_diff::{ExternalSnapshot, Snapshot, WorldDiff}, + ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, }; -use crate::{Instruction, ModeRequirements, Predicate}; -use eravm_stable_interface::opcodes::TypeLevelCallingMode; -use eravm_stable_interface::{CallingMode, HeapId, Tracer}; -use u256::H160; #[derive(Debug)] pub struct Settings { diff --git a/src/world_diff.rs b/src/world_diff.rs index 4fca03bb..aaa6fb65 100644 --- a/src/world_diff.rs +++ b/src/world_diff.rs @@ -1,9 +1,5 @@ use std::collections::BTreeMap; -use crate::{ - rollback::{Rollback, RollbackableLog, RollbackableMap, RollbackablePod, RollbackableSet}, - StorageInterface, -}; use eravm_stable_interface::{CycleStats, Tracer}; use u256::{H160, U256}; use zkevm_opcode_defs::system_params::{ @@ -11,6 +7,11 @@ use zkevm_opcode_defs::system_params::{ STORAGE_ACCESS_WARM_WRITE_COST, }; +use crate::{ + rollback::{Rollback, RollbackableLog, RollbackableMap, RollbackablePod, RollbackableSet}, + StorageInterface, +}; + /// Pending modifications to the global state that are executed at the end of a block. /// In other words, side effects. #[derive(Default)] @@ -375,9 +376,10 @@ const COLD_WRITE_AFTER_WARM_READ_REFUND: u32 = STORAGE_ACCESS_COLD_READ_COST; #[cfg(test)] mod tests { - use super::*; use proptest::prelude::*; + use super::*; + proptest! { #[test] fn test_storage_changes( diff --git a/tests/far_call_decommitment.rs b/tests/far_call_decommitment.rs index f9238d72..89a758d4 100644 --- a/tests/far_call_decommitment.rs +++ b/tests/far_call_decommitment.rs @@ -1,16 +1,17 @@ #![cfg(not(feature = "single_instruction_test"))] -use eravm_stable_interface::opcodes; use std::collections::HashSet; + +use eravm_stable_interface::opcodes; use u256::{H160, U256}; -use vm2::addressing_modes::{ - Arguments, CodePage, Immediate1, Register, Register1, Register2, RegisterAndImmediate, -}; -use vm2::instruction_handlers::Heap; -use vm2::testworld::TestWorld; use vm2::{ - initial_decommit, ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, - VirtualMachine, + addressing_modes::{ + Arguments, CodePage, Immediate1, Register, Register1, Register2, RegisterAndImmediate, + }, + initial_decommit, + instruction_handlers::Heap, + testworld::TestWorld, + ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, VirtualMachine, }; use zkevm_opcode_defs::ethereum_types::Address; From 2404b4081cad3e4491514ef335f707134d70be68 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 9 Sep 2024 11:34:32 +0300 Subject: [PATCH 2/7] Structure + rename crates --- .github/workflows/ci.yml | 4 +- Cargo.lock | 70 +++++++++--------- Cargo.toml | 66 ++++++++--------- afl-fuzz/Cargo.toml | 26 ------- crates/vm2-interface/Cargo.toml | 13 ++++ .../vm2-interface}/src/lib.rs | 0 .../vm2-interface}/src/state_interface.rs | 0 .../vm2-interface}/src/tracer_interface.rs | 0 crates/vm2/Cargo.toml | 34 +++++++++ .../vm2/benches}/nested_near_call.rs | 14 ++-- .../vm2/proptest-regressions}/world_diff.txt | 0 {src => crates/vm2/src}/addressing_modes.rs | 2 +- {src => crates/vm2/src}/bitset.rs | 0 {src => crates/vm2/src}/callframe.rs | 4 +- {src => crates/vm2/src}/decode.rs | 2 +- {src => crates/vm2/src}/decommit.rs | 4 +- {src => crates/vm2/src}/fat_pointer.rs | 4 +- {src => crates/vm2/src}/heap.rs | 4 +- {src => crates/vm2/src}/instruction.rs | 0 .../vm2/src}/instruction_handlers/binop.rs | 4 +- .../vm2/src}/instruction_handlers/common.rs | 2 +- .../vm2/src}/instruction_handlers/context.rs | 6 +- .../vm2/src}/instruction_handlers/decommit.rs | 4 +- .../vm2/src}/instruction_handlers/event.rs | 4 +- .../vm2/src}/instruction_handlers/far_call.rs | 10 +-- .../src}/instruction_handlers/heap_access.rs | 4 +- .../vm2/src}/instruction_handlers/jump.rs | 2 +- .../vm2/src}/instruction_handlers/mod.rs | 2 +- .../instruction_handlers/monomorphization.rs | 0 .../src}/instruction_handlers/near_call.rs | 2 +- .../vm2/src}/instruction_handlers/nop.rs | 2 +- .../vm2/src}/instruction_handlers/pointer.rs | 4 +- .../src}/instruction_handlers/precompiles.rs | 2 +- .../vm2/src}/instruction_handlers/ret.rs | 14 ++-- .../vm2/src}/instruction_handlers/storage.rs | 2 +- {src => crates/vm2/src}/lib.rs | 4 +- {src => crates/vm2/src}/mode_requirements.rs | 0 {src => crates/vm2/src}/predication.rs | 0 {src => crates/vm2/src}/program.rs | 2 +- {src => crates/vm2/src}/rollback.rs | 0 .../src}/single_instruction_test/callframe.rs | 4 +- .../vm2/src}/single_instruction_test/heap.rs | 4 +- .../single_instruction_test/into_zk_evm.rs | 4 +- .../single_instruction_test/mock_array.rs | 0 .../vm2/src}/single_instruction_test/mod.rs | 0 .../print_mock_info.rs | 0 .../src}/single_instruction_test/program.rs | 4 +- .../vm2/src}/single_instruction_test/stack.rs | 2 +- .../state_to_zk_evm.rs | 4 +- .../universal_state.rs | 2 +- .../single_instruction_test/validation.rs | 2 +- .../vm2/src}/single_instruction_test/vm.rs | 4 +- .../vm2/src}/single_instruction_test/world.rs | 4 +- {src => crates/vm2/src}/stack.rs | 2 +- {src => crates/vm2/src}/state.rs | 2 +- {src => crates/vm2/src}/testworld.rs | 10 +-- {src => crates/vm2/src}/tracing.rs | 44 +++++------ {src => crates/vm2/src}/vm.rs | 4 +- {src => crates/vm2/src}/world_diff.rs | 4 +- .../vm2/tests}/bytecode_behaviour.rs | 12 +-- .../vm2/tests}/bytecodes/call_far | Bin .../vm2/tests}/far_call_decommitment.rs | 14 ++-- .../vm2/tests}/panic.proptest-regressions | 0 {tests => crates/vm2/tests}/panic.rs | 8 +- {tests => crates/vm2/tests}/stipend.rs | 12 +-- eravm-stable-interface/Cargo.toml | 9 --- {afl-fuzz => tests/afl-fuzz}/.gitignore | 0 tests/afl-fuzz/Cargo.toml | 27 +++++++ {afl-fuzz => tests/afl-fuzz}/README.md | 0 {afl-fuzz => tests/afl-fuzz}/fuzz.sh | 0 ..._to_msg_value_far_call_forward_fat_pointer | Bin .../afl-fuzz}/in/return_calldata | Bin {afl-fuzz => tests/afl-fuzz}/show_crash.sh | 0 .../afl-fuzz}/src/check_input_size.rs | 2 +- {afl-fuzz => tests/afl-fuzz}/src/lib.rs | 4 +- {afl-fuzz => tests/afl-fuzz}/src/main.rs | 6 +- .../afl-fuzz}/src/show_testcase.rs | 6 +- 77 files changed, 276 insertions(+), 241 deletions(-) delete mode 100644 afl-fuzz/Cargo.toml create mode 100644 crates/vm2-interface/Cargo.toml rename {eravm-stable-interface => crates/vm2-interface}/src/lib.rs (100%) rename {eravm-stable-interface => crates/vm2-interface}/src/state_interface.rs (100%) rename {eravm-stable-interface => crates/vm2-interface}/src/tracer_interface.rs (100%) create mode 100644 crates/vm2/Cargo.toml rename {benches => crates/vm2/benches}/nested_near_call.rs (93%) rename {proptest-regressions => crates/vm2/proptest-regressions}/world_diff.txt (100%) rename {src => crates/vm2/src}/addressing_modes.rs (99%) rename {src => crates/vm2/src}/bitset.rs (100%) rename {src => crates/vm2/src}/callframe.rs (99%) rename {src => crates/vm2/src}/decode.rs (99%) rename {src => crates/vm2/src}/decommit.rs (98%) rename {src => crates/vm2/src}/fat_pointer.rs (92%) rename {src => crates/vm2/src}/heap.rs (99%) rename {src => crates/vm2/src}/instruction.rs (100%) rename {src => crates/vm2/src}/instruction_handlers/binop.rs (99%) rename {src => crates/vm2/src}/instruction_handlers/common.rs (97%) rename {src => crates/vm2/src}/instruction_handlers/context.rs (98%) rename {src => crates/vm2/src}/instruction_handlers/decommit.rs (96%) rename {src => crates/vm2/src}/instruction_handlers/event.rs (97%) rename {src => crates/vm2/src}/instruction_handlers/far_call.rs (99%) rename {src => crates/vm2/src}/instruction_handlers/heap_access.rs (99%) rename {src => crates/vm2/src}/instruction_handlers/jump.rs (96%) rename {src => crates/vm2/src}/instruction_handlers/mod.rs (91%) rename {src => crates/vm2/src}/instruction_handlers/monomorphization.rs (100%) rename {src => crates/vm2/src}/instruction_handlers/near_call.rs (97%) rename {src => crates/vm2/src}/instruction_handlers/nop.rs (95%) rename {src => crates/vm2/src}/instruction_handlers/pointer.rs (98%) rename {src => crates/vm2/src}/instruction_handlers/precompiles.rs (98%) rename {src => crates/vm2/src}/instruction_handlers/ret.rs (96%) rename {src => crates/vm2/src}/instruction_handlers/storage.rs (98%) rename {src => crates/vm2/src}/lib.rs (97%) rename {src => crates/vm2/src}/mode_requirements.rs (100%) rename {src => crates/vm2/src}/predication.rs (100%) rename {src => crates/vm2/src}/program.rs (98%) rename {src => crates/vm2/src}/rollback.rs (100%) rename {src => crates/vm2/src}/single_instruction_test/callframe.rs (98%) rename {src => crates/vm2/src}/single_instruction_test/heap.rs (98%) rename {src => crates/vm2/src}/single_instruction_test/into_zk_evm.rs (99%) rename {src => crates/vm2/src}/single_instruction_test/mock_array.rs (100%) rename {src => crates/vm2/src}/single_instruction_test/mod.rs (100%) rename {src => crates/vm2/src}/single_instruction_test/print_mock_info.rs (100%) rename {src => crates/vm2/src}/single_instruction_test/program.rs (97%) rename {src => crates/vm2/src}/single_instruction_test/stack.rs (99%) rename {src => crates/vm2/src}/single_instruction_test/state_to_zk_evm.rs (98%) rename {src => crates/vm2/src}/single_instruction_test/universal_state.rs (99%) rename {src => crates/vm2/src}/single_instruction_test/validation.rs (96%) rename {src => crates/vm2/src}/single_instruction_test/vm.rs (98%) rename {src => crates/vm2/src}/single_instruction_test/world.rs (92%) rename {src => crates/vm2/src}/stack.rs (99%) rename {src => crates/vm2/src}/state.rs (99%) rename {src => crates/vm2/src}/testworld.rs (90%) rename {src => crates/vm2/src}/tracing.rs (90%) rename {src => crates/vm2/src}/vm.rs (98%) rename {src => crates/vm2/src}/world_diff.rs (99%) rename {tests => crates/vm2/tests}/bytecode_behaviour.rs (91%) rename {tests => crates/vm2/tests}/bytecodes/call_far (100%) rename {tests => crates/vm2/tests}/far_call_decommitment.rs (97%) rename {tests => crates/vm2/tests}/panic.proptest-regressions (100%) rename {tests => crates/vm2/tests}/panic.rs (96%) rename {tests => crates/vm2/tests}/stipend.rs (97%) delete mode 100644 eravm-stable-interface/Cargo.toml rename {afl-fuzz => tests/afl-fuzz}/.gitignore (100%) create mode 100644 tests/afl-fuzz/Cargo.toml rename {afl-fuzz => tests/afl-fuzz}/README.md (100%) rename {afl-fuzz => tests/afl-fuzz}/fuzz.sh (100%) rename {afl-fuzz => tests/afl-fuzz}/in/kernel_to_msg_value_far_call_forward_fat_pointer (100%) rename {afl-fuzz => tests/afl-fuzz}/in/return_calldata (100%) rename {afl-fuzz => tests/afl-fuzz}/show_crash.sh (100%) rename {afl-fuzz => tests/afl-fuzz}/src/check_input_size.rs (89%) rename {afl-fuzz => tests/afl-fuzz}/src/lib.rs (60%) rename {afl-fuzz => tests/afl-fuzz}/src/main.rs (89%) rename {afl-fuzz => tests/afl-fuzz}/src/show_testcase.rs (90%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4ac63cc..0f4df401 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: - name: Run clippy run: | # Check the main library with non-test features (needs to be tested in isolation since the fuzzing crate enables test features) - cargo clippy -p vm2 --all-targets -- -D warnings + cargo clippy -p zksync_vm2 --all-targets -- -D warnings # The benches in `vm2` don't compile with fuzzing enabled cargo clippy --workspace --all-features --lib --bins --tests -- -D warnings @@ -49,4 +49,4 @@ jobs: - name: Run Tests run: | - cargo test -p vm2 --all-targets + cargo test -p zksync_vm2_interface -p zksync_vm2 --all-targets diff --git a/Cargo.lock b/Cargo.lock index 78592c19..56b75e81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,18 +237,6 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" -[[package]] -name = "differential_fuzzing" -version = "0.1.0" -dependencies = [ - "afl", - "arbitrary", - "eravm-stable-interface", - "pretty_assertions", - "vm2", - "zkevm_opcode_defs", -] - [[package]] name = "digest" version = "0.10.7" @@ -338,13 +326,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "eravm-stable-interface" -version = "0.1.0" -dependencies = [ - "primitive-types", -] - [[package]] name = "errno" version = "0.3.9" @@ -1208,22 +1189,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vm2" -version = "0.1.0" -dependencies = [ - "anyhow", - "arbitrary", - "divan", - "enum_dispatch", - "eravm-stable-interface", - "primitive-types", - "proptest", - "zk_evm", - "zk_evm_abstractions", - "zkevm_opcode_defs", -] - [[package]] name = "wait-timeout" version = "0.2.0" @@ -1478,3 +1443,38 @@ dependencies = [ "sha2", "sha3", ] + +[[package]] +name = "zksync_vm2" +version = "0.1.0" +dependencies = [ + "anyhow", + "arbitrary", + "divan", + "enum_dispatch", + "primitive-types", + "proptest", + "zk_evm", + "zk_evm_abstractions", + "zkevm_opcode_defs", + "zksync_vm2_interface", +] + +[[package]] +name = "zksync_vm2_afl_fuzz" +version = "0.1.0" +dependencies = [ + "afl", + "arbitrary", + "pretty_assertions", + "zkevm_opcode_defs", + "zksync_vm2", + "zksync_vm2_interface", +] + +[[package]] +name = "zksync_vm2_interface" +version = "0.1.0" +dependencies = [ + "primitive-types", +] diff --git a/Cargo.toml b/Cargo.toml index 1590bdf3..70428c3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,40 +1,40 @@ -[package] -name = "vm2" +[workspace] +members = [ + # Main published library crates + "crates/vm2-interface", + "crates/vm2", + # Testing crates + "tests/afl-fuzz" +] +resolver = "2" + +[workspace.package] version = "0.1.0" -edition.workspace = true +edition = "2021" +authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" -license.workspace = true -authors.workspace = true - -[dependencies] -eravm-stable-interface = { path = "./eravm-stable-interface" } -zkevm_opcode_defs = "0.150.0" -zk_evm_abstractions = "0.150.0" -u256 = { package = "primitive-types", version = "0.12.1" } -enum_dispatch = "0.3" - -# Optional dependencies (used for fuzzing) -arbitrary = { version = "1", features = ["derive"], optional = true } -# The commit incorporates a fix necessary for fuzzing to work correctly. -zk_evm = { git = "https://github.com/matter-labs/era-zk_evm.git", rev = "b7caa02acc2119b2994730d92c8cb6b861f56484", optional = true } -anyhow = { version = "1", optional = true } +repository = "https://github.com/matter-labs/vm2" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] -[dev-dependencies] +[workspace.dependencies] +# "External" dependencies +afl = "0.15" +anyhow = "1" +arbitrary = "1" divan = "0.1" +enum_dispatch = "0.3" +pretty_assertions = "1.4.0" +primitive-types = "0.12.1" proptest = "1.4" -[[bench]] -name = "nested_near_call" -harness = false - -[features] -default = [] -single_instruction_test = ["arbitrary", "u256/arbitrary", "zk_evm", "anyhow"] - -[workspace] -members = [".", "afl-fuzz", "eravm-stable-interface"] +# "Internal" dependencies +zkevm_opcode_defs = "0.150.0" +zk_evm_abstractions = "0.150.0" +# The commit incorporates a fix necessary for fuzzing to work correctly. +zk_evm = { git = "https://github.com/matter-labs/era-zk_evm.git", rev = "b7caa02acc2119b2994730d92c8cb6b861f56484" } -[workspace.package] -edition = "2021" -license = "MIT OR Apache-2.0" -authors = ["The Matter Labs Team "] \ No newline at end of file +# Dependencies within the workspace +zksync_vm2_interface = { version = "0.1.0", path = "crates/vm2-interface" } +zksync_vm2 = { version = "0.1.0", path = "crates/vm2" } diff --git a/afl-fuzz/Cargo.toml b/afl-fuzz/Cargo.toml deleted file mode 100644 index 6adbbee5..00000000 --- a/afl-fuzz/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "differential_fuzzing" -version = "0.1.0" -edition.workspace = true -publish = false - -[dependencies] -afl = "0.15" -arbitrary = "1" -pretty_assertions = "1.4.0" -zkevm_opcode_defs = "0.150.0" - -[dependencies.vm2] -path = ".." -features = ["single_instruction_test"] - -[dependencies.eravm-stable-interface] -path = "../eravm-stable-interface" - -[[bin]] -name = "show_testcase" -path = "src/show_testcase.rs" - -[[bin]] -name = "check_input_size" -path = "src/check_input_size.rs" diff --git a/crates/vm2-interface/Cargo.toml b/crates/vm2-interface/Cargo.toml new file mode 100644 index 00000000..298e19be --- /dev/null +++ b/crates/vm2-interface/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "zksync_vm2_interface" +version.workspace = true +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +keywords.workspace = true +categories.workspace = true + +[dependencies] +primitive-types.workspace = true diff --git a/eravm-stable-interface/src/lib.rs b/crates/vm2-interface/src/lib.rs similarity index 100% rename from eravm-stable-interface/src/lib.rs rename to crates/vm2-interface/src/lib.rs diff --git a/eravm-stable-interface/src/state_interface.rs b/crates/vm2-interface/src/state_interface.rs similarity index 100% rename from eravm-stable-interface/src/state_interface.rs rename to crates/vm2-interface/src/state_interface.rs diff --git a/eravm-stable-interface/src/tracer_interface.rs b/crates/vm2-interface/src/tracer_interface.rs similarity index 100% rename from eravm-stable-interface/src/tracer_interface.rs rename to crates/vm2-interface/src/tracer_interface.rs diff --git a/crates/vm2/Cargo.toml b/crates/vm2/Cargo.toml new file mode 100644 index 00000000..f3b2a3af --- /dev/null +++ b/crates/vm2/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "zksync_vm2" +version.workspace = true +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +keywords.workspace = true +categories.workspace = true + +[dependencies] +zksync_vm2_interface.workspace = true +zkevm_opcode_defs.workspace = true +zk_evm_abstractions.workspace = true +primitive-types.workspace = true +enum_dispatch.workspace = true + +# Optional dependencies (used for fuzzing) +arbitrary = { workspace = true, features = ["derive"], optional = true } +zk_evm = { workspace = true, optional = true } +anyhow = { workspace = true, optional = true } + +[dev-dependencies] +divan.workspace = true +proptest.workspace = true + +[[bench]] +name = "nested_near_call" +harness = false + +[features] +default = [] +single_instruction_test = ["arbitrary", "primitive-types/arbitrary", "zk_evm", "anyhow"] diff --git a/benches/nested_near_call.rs b/crates/vm2/benches/nested_near_call.rs similarity index 93% rename from benches/nested_near_call.rs rename to crates/vm2/benches/nested_near_call.rs index 5f5fbb24..8119108a 100644 --- a/benches/nested_near_call.rs +++ b/crates/vm2/benches/nested_near_call.rs @@ -1,13 +1,13 @@ use divan::{black_box, Bencher}; -use vm2::{ +use zkevm_opcode_defs::ethereum_types::Address; +use zksync_vm2::{ addressing_modes::{Arguments, Immediate1, Immediate2, Register, Register1, Register2}, initial_decommit, testworld::TestWorld, Instruction, ModeRequirements, Predicate::Always, - Program, + Program, Settings, VirtualMachine, }; -use zkevm_opcode_defs::ethereum_types::Address; #[divan::bench] fn nested_near_call(bencher: Bencher) { @@ -27,13 +27,13 @@ fn nested_near_call(bencher: Bencher) { bencher.bench(|| { let mut world = TestWorld::new(&[(address, program.clone())]); let program = initial_decommit(&mut world, address); - let mut vm = vm2::VirtualMachine::new( + let mut vm = VirtualMachine::new( address, program, Address::zero(), vec![], 10_000_000, - vm2::Settings { + Settings { default_aa_code_hash: [0; 32], evm_interpreter_code_hash: [0; 32], hook_address: 0, @@ -74,13 +74,13 @@ fn nested_near_call_with_storage_write(bencher: Bencher) { bencher.bench(|| { let mut world = TestWorld::new(&[(address, program.clone())]); let program = initial_decommit(&mut world, address); - let mut vm = vm2::VirtualMachine::new( + let mut vm = VirtualMachine::new( address, program, Address::zero(), vec![], 80_000_000, - vm2::Settings { + Settings { default_aa_code_hash: [0; 32], evm_interpreter_code_hash: [0; 32], hook_address: 0, diff --git a/proptest-regressions/world_diff.txt b/crates/vm2/proptest-regressions/world_diff.txt similarity index 100% rename from proptest-regressions/world_diff.txt rename to crates/vm2/proptest-regressions/world_diff.txt diff --git a/src/addressing_modes.rs b/crates/vm2/src/addressing_modes.rs similarity index 99% rename from src/addressing_modes.rs rename to crates/vm2/src/addressing_modes.rs index b0b8298a..70b88551 100644 --- a/src/addressing_modes.rs +++ b/crates/vm2/src/addressing_modes.rs @@ -1,7 +1,7 @@ #[cfg(feature = "arbitrary")] use arbitrary::{Arbitrary, Unstructured}; use enum_dispatch::enum_dispatch; -use u256::U256; +use primitive_types::U256; use zkevm_opcode_defs::erase_fat_pointer_metadata; use crate::{mode_requirements::ModeRequirements, predication::Predicate}; diff --git a/src/bitset.rs b/crates/vm2/src/bitset.rs similarity index 100% rename from src/bitset.rs rename to crates/vm2/src/bitset.rs diff --git a/src/callframe.rs b/crates/vm2/src/callframe.rs similarity index 99% rename from src/callframe.rs rename to crates/vm2/src/callframe.rs index d47f4598..727f99ed 100644 --- a/src/callframe.rs +++ b/crates/vm2/src/callframe.rs @@ -1,6 +1,6 @@ -use eravm_stable_interface::HeapId; -use u256::H160; +use primitive_types::H160; use zkevm_opcode_defs::system_params::{NEW_FRAME_MEMORY_STIPEND, NEW_KERNEL_FRAME_MEMORY_STIPEND}; +use zksync_vm2_interface::HeapId; use crate::{ decommit::is_kernel, diff --git a/src/decode.rs b/crates/vm2/src/decode.rs similarity index 99% rename from src/decode.rs rename to crates/vm2/src/decode.rs index 9e841541..e3b6dc10 100644 --- a/src/decode.rs +++ b/crates/vm2/src/decode.rs @@ -1,4 +1,3 @@ -use eravm_stable_interface::{opcodes, Tracer}; use zkevm_opcode_defs::{ decoding::{EncodingModeProduction, VmEncodingMode}, ImmMemHandlerFlags, Opcode, @@ -7,6 +6,7 @@ use zkevm_opcode_defs::{ RET_TO_LABEL_BIT_IDX, SET_FLAGS_FLAG_IDX, SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES, SWAP_OPERANDS_FLAG_IDX_FOR_PTR_OPCODE, UMA_INCREMENT_FLAG_IDX, }; +use zksync_vm2_interface::{opcodes, Tracer}; use crate::{ addressing_modes::{ diff --git a/src/decommit.rs b/crates/vm2/src/decommit.rs similarity index 98% rename from src/decommit.rs rename to crates/vm2/src/decommit.rs index 54f94612..252508bf 100644 --- a/src/decommit.rs +++ b/crates/vm2/src/decommit.rs @@ -1,8 +1,8 @@ -use eravm_stable_interface::{CycleStats, Tracer}; -use u256::{H160, U256}; +use primitive_types::{H160, U256}; use zkevm_opcode_defs::{ ethereum_types::Address, system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW, }; +use zksync_vm2_interface::{CycleStats, Tracer}; use crate::{program::Program, world_diff::WorldDiff, World}; diff --git a/src/fat_pointer.rs b/crates/vm2/src/fat_pointer.rs similarity index 92% rename from src/fat_pointer.rs rename to crates/vm2/src/fat_pointer.rs index c0012aaa..65d02179 100644 --- a/src/fat_pointer.rs +++ b/crates/vm2/src/fat_pointer.rs @@ -1,5 +1,5 @@ -use eravm_stable_interface::HeapId; -use u256::U256; +use primitive_types::U256; +use zksync_vm2_interface::HeapId; #[derive(Debug)] #[repr(C)] diff --git a/src/heap.rs b/crates/vm2/src/heap.rs similarity index 99% rename from src/heap.rs rename to crates/vm2/src/heap.rs index 3f61e959..1a19efac 100644 --- a/src/heap.rs +++ b/crates/vm2/src/heap.rs @@ -3,8 +3,8 @@ use std::{ ops::{Index, Range}, }; -use eravm_stable_interface::HeapId; -use u256::U256; +use primitive_types::U256; +use zksync_vm2_interface::HeapId; use crate::instruction_handlers::HeapInterface; diff --git a/src/instruction.rs b/crates/vm2/src/instruction.rs similarity index 100% rename from src/instruction.rs rename to crates/vm2/src/instruction.rs diff --git a/src/instruction_handlers/binop.rs b/crates/vm2/src/instruction_handlers/binop.rs similarity index 99% rename from src/instruction_handlers/binop.rs rename to crates/vm2/src/instruction_handlers/binop.rs index 951d9d97..336ca4ac 100644 --- a/src/instruction_handlers/binop.rs +++ b/crates/vm2/src/instruction_handlers/binop.rs @@ -1,8 +1,8 @@ -use eravm_stable_interface::{ +use primitive_types::U256; +use zksync_vm2_interface::{ opcodes::{Add, And, Div, Mul, Or, RotateLeft, RotateRight, ShiftLeft, ShiftRight, Sub, Xor}, OpcodeType, Tracer, }; -use u256::U256; use super::common::boilerplate; use crate::{ diff --git a/src/instruction_handlers/common.rs b/crates/vm2/src/instruction_handlers/common.rs similarity index 97% rename from src/instruction_handlers/common.rs rename to crates/vm2/src/instruction_handlers/common.rs index 5d8ca85b..4f865113 100644 --- a/src/instruction_handlers/common.rs +++ b/crates/vm2/src/instruction_handlers/common.rs @@ -1,4 +1,4 @@ -use eravm_stable_interface::{opcodes, OpcodeType, Tracer}; +use zksync_vm2_interface::{opcodes, OpcodeType, Tracer}; use super::ret::free_panic; use crate::{addressing_modes::Arguments, instruction::ExecutionStatus, VirtualMachine}; diff --git a/src/instruction_handlers/context.rs b/crates/vm2/src/instruction_handlers/context.rs similarity index 98% rename from src/instruction_handlers/context.rs rename to crates/vm2/src/instruction_handlers/context.rs index fdfbf5dc..679ef97e 100644 --- a/src/instruction_handlers/context.rs +++ b/crates/vm2/src/instruction_handlers/context.rs @@ -1,9 +1,9 @@ -use eravm_stable_interface::{ +use primitive_types::U256; +use zkevm_opcode_defs::VmMetaParameters; +use zksync_vm2_interface::{ opcodes::{self, Caller, CodeAddress, ContextU128, ErgsLeft, This, SP}, OpcodeType, Tracer, }; -use u256::U256; -use zkevm_opcode_defs::VmMetaParameters; use super::common::boilerplate; use crate::{ diff --git a/src/instruction_handlers/decommit.rs b/crates/vm2/src/instruction_handlers/decommit.rs similarity index 96% rename from src/instruction_handlers/decommit.rs rename to crates/vm2/src/instruction_handlers/decommit.rs index 80763e6c..13b0ed1b 100644 --- a/src/instruction_handlers/decommit.rs +++ b/crates/vm2/src/instruction_handlers/decommit.rs @@ -1,6 +1,6 @@ -use eravm_stable_interface::{opcodes, Tracer}; -use u256::U256; +use primitive_types::U256; use zkevm_opcode_defs::{BlobSha256Format, ContractCodeSha256Format, VersionedHashLen32}; +use zksync_vm2_interface::{opcodes, Tracer}; use super::common::boilerplate_ext; use crate::{ diff --git a/src/instruction_handlers/event.rs b/crates/vm2/src/instruction_handlers/event.rs similarity index 97% rename from src/instruction_handlers/event.rs rename to crates/vm2/src/instruction_handlers/event.rs index 98bc065a..71bc44a3 100644 --- a/src/instruction_handlers/event.rs +++ b/crates/vm2/src/instruction_handlers/event.rs @@ -1,6 +1,6 @@ -use eravm_stable_interface::{opcodes, Tracer}; -use u256::H160; +use primitive_types::H160; use zkevm_opcode_defs::ADDRESS_EVENT_WRITER; +use zksync_vm2_interface::{opcodes, Tracer}; use super::common::boilerplate_ext; use crate::{ diff --git a/src/instruction_handlers/far_call.rs b/crates/vm2/src/instruction_handlers/far_call.rs similarity index 99% rename from src/instruction_handlers/far_call.rs rename to crates/vm2/src/instruction_handlers/far_call.rs index 086e4fdf..556c728d 100644 --- a/src/instruction_handlers/far_call.rs +++ b/crates/vm2/src/instruction_handlers/far_call.rs @@ -1,12 +1,12 @@ -use eravm_stable_interface::{ - opcodes::{FarCall, TypeLevelCallingMode}, - Tracer, -}; -use u256::U256; +use primitive_types::U256; use zkevm_opcode_defs::{ system_params::{EVM_SIMULATOR_STIPEND, MSG_VALUE_SIMULATOR_ADDITIVE_COST}, ADDRESS_MSG_VALUE, }; +use zksync_vm2_interface::{ + opcodes::{FarCall, TypeLevelCallingMode}, + Tracer, +}; use super::{ common::boilerplate_ext, diff --git a/src/instruction_handlers/heap_access.rs b/crates/vm2/src/instruction_handlers/heap_access.rs similarity index 99% rename from src/instruction_handlers/heap_access.rs rename to crates/vm2/src/instruction_handlers/heap_access.rs index b393d7ed..19843ae2 100644 --- a/src/instruction_handlers/heap_access.rs +++ b/crates/vm2/src/instruction_handlers/heap_access.rs @@ -1,7 +1,7 @@ use std::ops::Range; -use eravm_stable_interface::{opcodes, OpcodeType, Tracer}; -use u256::U256; +use primitive_types::U256; +use zksync_vm2_interface::{opcodes, OpcodeType, Tracer}; use super::common::{boilerplate, full_boilerplate}; use crate::{ diff --git a/src/instruction_handlers/jump.rs b/crates/vm2/src/instruction_handlers/jump.rs similarity index 96% rename from src/instruction_handlers/jump.rs rename to crates/vm2/src/instruction_handlers/jump.rs index f185ae2c..3ca7a557 100644 --- a/src/instruction_handlers/jump.rs +++ b/crates/vm2/src/instruction_handlers/jump.rs @@ -1,4 +1,4 @@ -use eravm_stable_interface::{opcodes, Tracer}; +use zksync_vm2_interface::{opcodes, Tracer}; use super::common::boilerplate; use crate::{ diff --git a/src/instruction_handlers/mod.rs b/crates/vm2/src/instruction_handlers/mod.rs similarity index 91% rename from src/instruction_handlers/mod.rs rename to crates/vm2/src/instruction_handlers/mod.rs index 3afa4d34..54d84ab4 100644 --- a/src/instruction_handlers/mod.rs +++ b/crates/vm2/src/instruction_handlers/mod.rs @@ -1,4 +1,4 @@ -pub use eravm_stable_interface::opcodes::{ +pub use zksync_vm2_interface::opcodes::{ Add, And, Div, Mul, Or, PointerAdd, PointerPack, PointerShrink, PointerSub, RotateLeft, RotateRight, ShiftLeft, ShiftRight, Sub, Xor, }; diff --git a/src/instruction_handlers/monomorphization.rs b/crates/vm2/src/instruction_handlers/monomorphization.rs similarity index 100% rename from src/instruction_handlers/monomorphization.rs rename to crates/vm2/src/instruction_handlers/monomorphization.rs diff --git a/src/instruction_handlers/near_call.rs b/crates/vm2/src/instruction_handlers/near_call.rs similarity index 97% rename from src/instruction_handlers/near_call.rs rename to crates/vm2/src/instruction_handlers/near_call.rs index a93cb7d9..16c3a19d 100644 --- a/src/instruction_handlers/near_call.rs +++ b/crates/vm2/src/instruction_handlers/near_call.rs @@ -1,4 +1,4 @@ -use eravm_stable_interface::{opcodes, Tracer}; +use zksync_vm2_interface::{opcodes, Tracer}; use super::common::boilerplate; use crate::{ diff --git a/src/instruction_handlers/nop.rs b/crates/vm2/src/instruction_handlers/nop.rs similarity index 95% rename from src/instruction_handlers/nop.rs rename to crates/vm2/src/instruction_handlers/nop.rs index 916a136b..7349ae20 100644 --- a/src/instruction_handlers/nop.rs +++ b/crates/vm2/src/instruction_handlers/nop.rs @@ -1,4 +1,4 @@ -use eravm_stable_interface::{opcodes, Tracer}; +use zksync_vm2_interface::{opcodes, Tracer}; use super::common::boilerplate; use crate::{ diff --git a/src/instruction_handlers/pointer.rs b/crates/vm2/src/instruction_handlers/pointer.rs similarity index 98% rename from src/instruction_handlers/pointer.rs rename to crates/vm2/src/instruction_handlers/pointer.rs index 6c183140..c78a92d7 100644 --- a/src/instruction_handlers/pointer.rs +++ b/crates/vm2/src/instruction_handlers/pointer.rs @@ -1,8 +1,8 @@ -use eravm_stable_interface::{ +use primitive_types::U256; +use zksync_vm2_interface::{ opcodes::{PointerAdd, PointerPack, PointerShrink, PointerSub}, OpcodeType, Tracer, }; -use u256::U256; use super::common::boilerplate; use crate::{ diff --git a/src/instruction_handlers/precompiles.rs b/crates/vm2/src/instruction_handlers/precompiles.rs similarity index 98% rename from src/instruction_handlers/precompiles.rs rename to crates/vm2/src/instruction_handlers/precompiles.rs index 04c0237e..664fb7da 100644 --- a/src/instruction_handlers/precompiles.rs +++ b/crates/vm2/src/instruction_handlers/precompiles.rs @@ -1,4 +1,3 @@ -use eravm_stable_interface::{opcodes, CycleStats, HeapId, Tracer}; use zk_evm_abstractions::{ aux::Timestamp, precompiles::{ @@ -15,6 +14,7 @@ use zkevm_opcode_defs::{ }, PrecompileAuxData, PrecompileCallABI, }; +use zksync_vm2_interface::{opcodes, CycleStats, HeapId, Tracer}; use super::{common::boilerplate_ext, HeapInterface}; use crate::{ diff --git a/src/instruction_handlers/ret.rs b/crates/vm2/src/instruction_handlers/ret.rs similarity index 96% rename from src/instruction_handlers/ret.rs rename to crates/vm2/src/instruction_handlers/ret.rs index 7a282496..84823abc 100644 --- a/src/instruction_handlers/ret.rs +++ b/crates/vm2/src/instruction_handlers/ret.rs @@ -1,10 +1,12 @@ -use eravm_stable_interface::{ - opcodes::{self, TypeLevelReturnType}, +use primitive_types::U256; +use zksync_vm2_interface::{ + opcodes::{self, Normal, Panic, Revert, TypeLevelReturnType}, ReturnType, Tracer, }; -use u256::U256; -use super::{common::full_boilerplate, far_call::get_far_call_calldata, HeapInterface}; +use super::{ + common::full_boilerplate, far_call::get_far_call_calldata, monomorphization::*, HeapInterface, +}; use crate::{ addressing_modes::{Arguments, Immediate1, Register1, Source, INVALID_INSTRUCTION_COST}, callframe::FrameRemnant, @@ -182,10 +184,6 @@ pub fn invalid_instruction<'a, T, W>() -> &'a Instruction { pub(crate) const RETURN_COST: u32 = 5; -use eravm_stable_interface::opcodes::{Normal, Panic, Revert}; - -use super::monomorphization::*; - impl Instruction { pub fn from_ret(src1: Register1, label: Option, arguments: Arguments) -> Self { let to_label = label.is_some(); diff --git a/src/instruction_handlers/storage.rs b/crates/vm2/src/instruction_handlers/storage.rs similarity index 98% rename from src/instruction_handlers/storage.rs rename to crates/vm2/src/instruction_handlers/storage.rs index e3b97b4e..ff8fd208 100644 --- a/src/instruction_handlers/storage.rs +++ b/crates/vm2/src/instruction_handlers/storage.rs @@ -1,4 +1,4 @@ -use eravm_stable_interface::{opcodes, Tracer}; +use zksync_vm2_interface::{opcodes, Tracer}; use super::common::{boilerplate, boilerplate_ext}; use crate::{ diff --git a/src/lib.rs b/crates/vm2/src/lib.rs similarity index 97% rename from src/lib.rs rename to crates/vm2/src/lib.rs index 662c9e34..8e65838f 100644 --- a/src/lib.rs +++ b/crates/vm2/src/lib.rs @@ -1,9 +1,9 @@ use std::hash::{DefaultHasher, Hash, Hasher}; -pub use eravm_stable_interface::{ +use primitive_types::{H160, U256}; +pub use zksync_vm2_interface::{ CallframeInterface, CycleStats, HeapId, Opcode, OpcodeType, ReturnType, StateInterface, Tracer, }; -use u256::{H160, U256}; // Re-export missing modules if single instruction testing is enabled #[cfg(feature = "single_instruction_test")] diff --git a/src/mode_requirements.rs b/crates/vm2/src/mode_requirements.rs similarity index 100% rename from src/mode_requirements.rs rename to crates/vm2/src/mode_requirements.rs diff --git a/src/predication.rs b/crates/vm2/src/predication.rs similarity index 100% rename from src/predication.rs rename to crates/vm2/src/predication.rs diff --git a/src/program.rs b/crates/vm2/src/program.rs similarity index 98% rename from src/program.rs rename to crates/vm2/src/program.rs index 143fff67..84c6ef2d 100644 --- a/src/program.rs +++ b/crates/vm2/src/program.rs @@ -1,6 +1,6 @@ use std::{fmt, sync::Arc}; -use u256::U256; +use primitive_types::U256; use crate::{hash_for_debugging, Instruction}; diff --git a/src/rollback.rs b/crates/vm2/src/rollback.rs similarity index 100% rename from src/rollback.rs rename to crates/vm2/src/rollback.rs diff --git a/src/single_instruction_test/callframe.rs b/crates/vm2/src/single_instruction_test/callframe.rs similarity index 98% rename from src/single_instruction_test/callframe.rs rename to crates/vm2/src/single_instruction_test/callframe.rs index 66a12a18..d389ca49 100644 --- a/src/single_instruction_test/callframe.rs +++ b/crates/vm2/src/single_instruction_test/callframe.rs @@ -1,7 +1,7 @@ use arbitrary::Arbitrary; -use eravm_stable_interface::Tracer; -use u256::H160; +use primitive_types::H160; use zkevm_opcode_defs::EVM_SIMULATOR_STIPEND; +use zksync_vm2_interface::Tracer; use super::{ heap::FIRST_AUX_HEAP, diff --git a/src/single_instruction_test/heap.rs b/crates/vm2/src/single_instruction_test/heap.rs similarity index 98% rename from src/single_instruction_test/heap.rs rename to crates/vm2/src/single_instruction_test/heap.rs index 835b339f..6af16884 100644 --- a/src/single_instruction_test/heap.rs +++ b/crates/vm2/src/single_instruction_test/heap.rs @@ -1,8 +1,8 @@ use std::ops::Index; use arbitrary::Arbitrary; -use eravm_stable_interface::HeapId; -use u256::U256; +use primitive_types::U256; +use zksync_vm2_interface::HeapId; use super::mock_array::MockRead; use crate::instruction_handlers::HeapInterface; diff --git a/src/single_instruction_test/into_zk_evm.rs b/crates/vm2/src/single_instruction_test/into_zk_evm.rs similarity index 99% rename from src/single_instruction_test/into_zk_evm.rs rename to crates/vm2/src/single_instruction_test/into_zk_evm.rs index 88611206..e7e4c8cc 100644 --- a/src/single_instruction_test/into_zk_evm.rs +++ b/crates/vm2/src/single_instruction_test/into_zk_evm.rs @@ -1,7 +1,6 @@ use std::sync::Arc; -use eravm_stable_interface::Tracer; -use u256::U256; +use primitive_types::U256; use zk_evm::{ abstractions::{DecommittmentProcessor, Memory, MemoryType, PrecompilesProcessor, Storage}, aux_structures::PubdataCost, @@ -13,6 +12,7 @@ use zk_evm::{ }; use zk_evm_abstractions::vm::EventSink; use zkevm_opcode_defs::{decoding::EncodingModeProduction, TRANSIENT_STORAGE_AUX_BYTE}; +use zksync_vm2_interface::Tracer; use super::{stack::Stack, state_to_zk_evm::vm2_state_to_zk_evm_state, MockWorld}; use crate::{StorageInterface, VirtualMachine}; diff --git a/src/single_instruction_test/mock_array.rs b/crates/vm2/src/single_instruction_test/mock_array.rs similarity index 100% rename from src/single_instruction_test/mock_array.rs rename to crates/vm2/src/single_instruction_test/mock_array.rs diff --git a/src/single_instruction_test/mod.rs b/crates/vm2/src/single_instruction_test/mod.rs similarity index 100% rename from src/single_instruction_test/mod.rs rename to crates/vm2/src/single_instruction_test/mod.rs diff --git a/src/single_instruction_test/print_mock_info.rs b/crates/vm2/src/single_instruction_test/print_mock_info.rs similarity index 100% rename from src/single_instruction_test/print_mock_info.rs rename to crates/vm2/src/single_instruction_test/print_mock_info.rs diff --git a/src/single_instruction_test/program.rs b/crates/vm2/src/single_instruction_test/program.rs similarity index 97% rename from src/single_instruction_test/program.rs rename to crates/vm2/src/single_instruction_test/program.rs index bbdfc441..d7679cb0 100644 --- a/src/single_instruction_test/program.rs +++ b/crates/vm2/src/single_instruction_test/program.rs @@ -1,8 +1,8 @@ use std::{rc::Rc, sync::Arc}; use arbitrary::Arbitrary; -use eravm_stable_interface::Tracer; -use u256::U256; +use primitive_types::U256; +use zksync_vm2_interface::Tracer; use super::mock_array::MockRead; use crate::{decode::decode, Instruction, World}; diff --git a/src/single_instruction_test/stack.rs b/crates/vm2/src/single_instruction_test/stack.rs similarity index 99% rename from src/single_instruction_test/stack.rs rename to crates/vm2/src/single_instruction_test/stack.rs index ece25541..6618bd39 100644 --- a/src/single_instruction_test/stack.rs +++ b/crates/vm2/src/single_instruction_test/stack.rs @@ -1,4 +1,4 @@ -use u256::U256; +use primitive_types::U256; use super::{ mock_array::MockRead, validation::is_valid_tagged_value, vm::arbitrary_register_value, diff --git a/src/single_instruction_test/state_to_zk_evm.rs b/crates/vm2/src/single_instruction_test/state_to_zk_evm.rs similarity index 98% rename from src/single_instruction_test/state_to_zk_evm.rs rename to crates/vm2/src/single_instruction_test/state_to_zk_evm.rs index ac6cb86f..b6127f82 100644 --- a/src/single_instruction_test/state_to_zk_evm.rs +++ b/crates/vm2/src/single_instruction_test/state_to_zk_evm.rs @@ -1,12 +1,12 @@ use std::iter; -use eravm_stable_interface::Tracer; -use u256::U256; +use primitive_types::U256; use zk_evm::{ aux_structures::{MemoryPage, PubdataCost}, vm_state::{execution_stack::CallStackEntry, Callstack, PrimitiveValue, VmLocalState}, }; use zkevm_opcode_defs::decoding::EncodingModeProduction; +use zksync_vm2_interface::Tracer; use crate::callframe::{Callframe, NearCallFrame}; diff --git a/src/single_instruction_test/universal_state.rs b/crates/vm2/src/single_instruction_test/universal_state.rs similarity index 99% rename from src/single_instruction_test/universal_state.rs rename to crates/vm2/src/single_instruction_test/universal_state.rs index fa108b54..4cd5e898 100644 --- a/src/single_instruction_test/universal_state.rs +++ b/crates/vm2/src/single_instruction_test/universal_state.rs @@ -1,4 +1,4 @@ -use u256::{H160, U256}; +use primitive_types::{H160, U256}; use zk_evm::{ reference_impls::event_sink::InMemoryEventSink, vm_state::{CallStackEntry, VmLocalState, VmState}, diff --git a/src/single_instruction_test/validation.rs b/crates/vm2/src/single_instruction_test/validation.rs similarity index 96% rename from src/single_instruction_test/validation.rs rename to crates/vm2/src/single_instruction_test/validation.rs index c32b5646..4b54f23f 100644 --- a/src/single_instruction_test/validation.rs +++ b/crates/vm2/src/single_instruction_test/validation.rs @@ -1,4 +1,4 @@ -use u256::U256; +use primitive_types::U256; use crate::{callframe::Callframe, fat_pointer::FatPointer, State}; diff --git a/src/single_instruction_test/vm.rs b/crates/vm2/src/single_instruction_test/vm.rs similarity index 98% rename from src/single_instruction_test/vm.rs rename to crates/vm2/src/single_instruction_test/vm.rs index a8b96a34..a9e55fa9 100644 --- a/src/single_instruction_test/vm.rs +++ b/crates/vm2/src/single_instruction_test/vm.rs @@ -1,8 +1,8 @@ use std::fmt::Debug; use arbitrary::Arbitrary; -use eravm_stable_interface::Tracer; -use u256::U256; +use primitive_types::U256; +use zksync_vm2_interface::Tracer; use super::{heap::Heaps, stack::StackPool}; use crate::{ diff --git a/src/single_instruction_test/world.rs b/crates/vm2/src/single_instruction_test/world.rs similarity index 92% rename from src/single_instruction_test/world.rs rename to crates/vm2/src/single_instruction_test/world.rs index d5cdcfec..500757c1 100644 --- a/src/single_instruction_test/world.rs +++ b/crates/vm2/src/single_instruction_test/world.rs @@ -1,6 +1,6 @@ use arbitrary::Arbitrary; -use eravm_stable_interface::Tracer; -use u256::{H160, U256}; +use primitive_types::{H160, U256}; +use zksync_vm2_interface::Tracer; use super::mock_array::MockRead; use crate::{Program, StorageInterface, World}; diff --git a/src/stack.rs b/crates/vm2/src/stack.rs similarity index 99% rename from src/stack.rs rename to crates/vm2/src/stack.rs index 201f036b..9664a26b 100644 --- a/src/stack.rs +++ b/crates/vm2/src/stack.rs @@ -3,7 +3,7 @@ use std::{ fmt, }; -use u256::U256; +use primitive_types::U256; use crate::{bitset::Bitset, fat_pointer::FatPointer, hash_for_debugging}; diff --git a/src/state.rs b/crates/vm2/src/state.rs similarity index 99% rename from src/state.rs rename to crates/vm2/src/state.rs index 21c94f5a..248e3066 100644 --- a/src/state.rs +++ b/crates/vm2/src/state.rs @@ -1,4 +1,4 @@ -use u256::{H160, U256}; +use primitive_types::{H160, U256}; use crate::{ addressing_modes::Addressable, diff --git a/src/testworld.rs b/crates/vm2/src/testworld.rs similarity index 90% rename from src/testworld.rs rename to crates/vm2/src/testworld.rs index 7620c98d..0bb0e3c4 100644 --- a/src/testworld.rs +++ b/crates/vm2/src/testworld.rs @@ -3,11 +3,11 @@ use std::{ hash::{Hash, Hasher}, }; -use eravm_stable_interface::Tracer; -use u256::U256; +use primitive_types::{H160, U256}; use zkevm_opcode_defs::{ ethereum_types::Address, system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW, }; +use zksync_vm2_interface::Tracer; use crate::{address_into_u256, Program, StorageInterface, World}; @@ -44,7 +44,7 @@ impl TestWorld { } impl World for TestWorld { - fn decommit(&mut self, hash: u256::U256) -> Program { + fn decommit(&mut self, hash: U256) -> Program { if let Some(program) = self.hash_to_contract.get(&hash) { program.clone() } else { @@ -66,7 +66,7 @@ impl World for TestWorld { } impl StorageInterface for TestWorld { - fn read_storage(&mut self, contract: u256::H160, key: u256::U256) -> Option { + fn read_storage(&mut self, contract: H160, key: U256) -> Option { let deployer_system_contract_address = Address::from_low_u64_be(DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW as u64); @@ -86,7 +86,7 @@ impl StorageInterface for TestWorld { 50 } - fn is_free_storage_slot(&self, _contract: &u256::H160, _key: &U256) -> bool { + fn is_free_storage_slot(&self, _contract: &H160, _key: &U256) -> bool { false } } diff --git a/src/tracing.rs b/crates/vm2/src/tracing.rs similarity index 90% rename from src/tracing.rs rename to crates/vm2/src/tracing.rs index 481f73b3..4c196abb 100644 --- a/src/tracing.rs +++ b/crates/vm2/src/tracing.rs @@ -1,6 +1,7 @@ use std::cmp::Ordering; -use eravm_stable_interface::*; +use primitive_types::{H160, U256}; +use zksync_vm2_interface::*; use crate::{ callframe::{Callframe, NearCallFrame}, @@ -10,14 +11,14 @@ use crate::{ }; impl StateInterface for VirtualMachine { - fn read_register(&self, register: u8) -> (u256::U256, bool) { + fn read_register(&self, register: u8) -> (U256, bool) { ( self.state.registers[register as usize], self.state.register_pointer_flags & (1 << register) != 0, ) } - fn set_register(&mut self, register: u8, value: u256::U256, is_pointer: bool) { + fn set_register(&mut self, register: u8, value: U256, is_pointer: bool) { self.state.registers[register as usize] = value; self.state.register_pointer_flags &= !(1 << register); @@ -101,23 +102,21 @@ impl StateInterface for VirtualMachine { self.state.context_u128 = value; } - fn get_storage_state(&self) -> impl Iterator { + fn get_storage_state(&self) -> impl Iterator { self.world_diff .get_storage_state() .iter() .map(|(key, value)| (*key, *value)) } - fn get_transient_storage_state( - &self, - ) -> impl Iterator { + fn get_transient_storage_state(&self) -> impl Iterator { self.world_diff .get_transient_storage_state() .iter() .map(|(key, value)| (*key, *value)) } - fn get_transient_storage(&self, address: u256::H160, slot: u256::U256) -> u256::U256 { + fn get_transient_storage(&self, address: H160, slot: U256) -> U256 { self.world_diff .get_transient_storage_state() .get(&(address, slot)) @@ -125,12 +124,7 @@ impl StateInterface for VirtualMachine { .unwrap_or_default() } - fn write_transient_storage( - &mut self, - address: u256::H160, - slot: u256::U256, - value: u256::U256, - ) { + fn write_transient_storage(&mut self, address: H160, slot: U256, value: U256) { self.world_diff .write_transient_storage(address, slot, value) } @@ -171,28 +165,28 @@ struct CallframeWrapper<'a, T, W> { } impl CallframeInterface for CallframeWrapper<'_, T, W> { - fn address(&self) -> u256::H160 { + fn address(&self) -> H160 { self.frame.address } - fn set_address(&mut self, address: u256::H160) { + fn set_address(&mut self, address: H160) { self.frame.address = address; self.frame.is_kernel = is_kernel(address); } - fn code_address(&self) -> u256::H160 { + fn code_address(&self) -> H160 { self.frame.code_address } - fn set_code_address(&mut self, address: u256::H160) { + fn set_code_address(&mut self, address: H160) { self.frame.code_address = address; } - fn caller(&self) -> u256::H160 { + fn caller(&self) -> H160 { self.frame.caller } - fn set_caller(&mut self, address: u256::H160) { + fn set_caller(&mut self, address: H160) { self.frame.caller = address; } @@ -216,14 +210,14 @@ impl CallframeInterface for CallframeWrapper<'_, T, W> { self.frame.context_u128 = value; } - fn read_stack(&self, index: u16) -> (u256::U256, bool) { + fn read_stack(&self, index: u16) -> (U256, bool) { ( self.frame.stack.get(index), self.frame.stack.get_pointer_flag(index), ) } - fn write_stack(&mut self, index: u16, value: u256::U256, is_pointer: bool) { + fn write_stack(&mut self, index: u16, value: U256, is_pointer: bool) { self.frame.stack.set(index, value); if is_pointer { self.frame.stack.set_pointer_flag(index); @@ -256,7 +250,7 @@ impl CallframeInterface for CallframeWrapper<'_, T, W> { self.frame.aux_heap_size = value; } - fn read_code_page(&self, slot: u16) -> u256::U256 { + fn read_code_page(&self, slot: u16) -> U256 { self.frame.program.code_page()[slot as usize] } @@ -361,9 +355,9 @@ impl CallframeWrapper<'_, T, W> { #[cfg(all(test, not(feature = "single_instruction_test")))] mod test { - use eravm_stable_interface::HeapId; - use u256::H160; + use primitive_types::H160; use zkevm_opcode_defs::ethereum_types::Address; + use zksync_vm2_interface::HeapId; use super::*; use crate::{initial_decommit, testworld::TestWorld, Instruction, Program, VirtualMachine}; diff --git a/src/vm.rs b/crates/vm2/src/vm.rs similarity index 98% rename from src/vm.rs rename to crates/vm2/src/vm.rs index 9e819aa7..7024ba81 100644 --- a/src/vm.rs +++ b/crates/vm2/src/vm.rs @@ -1,5 +1,5 @@ -use eravm_stable_interface::{opcodes::TypeLevelCallingMode, CallingMode, HeapId, Tracer}; -use u256::H160; +use primitive_types::H160; +use zksync_vm2_interface::{opcodes::TypeLevelCallingMode, CallingMode, HeapId, Tracer}; use crate::{ addressing_modes::Arguments, diff --git a/src/world_diff.rs b/crates/vm2/src/world_diff.rs similarity index 99% rename from src/world_diff.rs rename to crates/vm2/src/world_diff.rs index aaa6fb65..5d747698 100644 --- a/src/world_diff.rs +++ b/crates/vm2/src/world_diff.rs @@ -1,11 +1,11 @@ use std::collections::BTreeMap; -use eravm_stable_interface::{CycleStats, Tracer}; -use u256::{H160, U256}; +use primitive_types::{H160, U256}; use zkevm_opcode_defs::system_params::{ STORAGE_ACCESS_COLD_READ_COST, STORAGE_ACCESS_COLD_WRITE_COST, STORAGE_ACCESS_WARM_READ_COST, STORAGE_ACCESS_WARM_WRITE_COST, }; +use zksync_vm2_interface::{CycleStats, Tracer}; use crate::{ rollback::{Rollback, RollbackableLog, RollbackableMap, RollbackablePod, RollbackableSet}, diff --git a/tests/bytecode_behaviour.rs b/crates/vm2/tests/bytecode_behaviour.rs similarity index 91% rename from tests/bytecode_behaviour.rs rename to crates/vm2/tests/bytecode_behaviour.rs index 436ee6f0..af0023e4 100644 --- a/tests/bytecode_behaviour.rs +++ b/crates/vm2/tests/bytecode_behaviour.rs @@ -1,12 +1,12 @@ #![cfg(not(feature = "single_instruction_test"))] -use eravm_stable_interface::Tracer; -use u256::U256; -use vm2::{ +use primitive_types::U256; +use zkevm_opcode_defs::ethereum_types::Address; +use zksync_vm2::{ decode::decode_program, initial_decommit, testworld::TestWorld, ExecutionEnd, Program, - VirtualMachine, World, + Settings, VirtualMachine, World, }; -use zkevm_opcode_defs::ethereum_types::Address; +use zksync_vm2_interface::Tracer; fn program_from_file>(filename: &str) -> Program { let blob = std::fs::read(filename).unwrap(); @@ -40,7 +40,7 @@ fn call_to_invalid_address() { Address::zero(), vec![], 10000, - vm2::Settings { + Settings { default_aa_code_hash: [0; 32], evm_interpreter_code_hash: [0; 32], hook_address: 0, diff --git a/tests/bytecodes/call_far b/crates/vm2/tests/bytecodes/call_far similarity index 100% rename from tests/bytecodes/call_far rename to crates/vm2/tests/bytecodes/call_far diff --git a/tests/far_call_decommitment.rs b/crates/vm2/tests/far_call_decommitment.rs similarity index 97% rename from tests/far_call_decommitment.rs rename to crates/vm2/tests/far_call_decommitment.rs index 89a758d4..091f349d 100644 --- a/tests/far_call_decommitment.rs +++ b/crates/vm2/tests/far_call_decommitment.rs @@ -2,18 +2,18 @@ use std::collections::HashSet; -use eravm_stable_interface::opcodes; -use u256::{H160, U256}; -use vm2::{ +use primitive_types::{H160, U256}; +use zkevm_opcode_defs::ethereum_types::Address; +use zksync_vm2::{ addressing_modes::{ Arguments, CodePage, Immediate1, Register, Register1, Register2, RegisterAndImmediate, }, initial_decommit, instruction_handlers::Heap, testworld::TestWorld, - ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, VirtualMachine, + ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, Settings, VirtualMachine, }; -use zkevm_opcode_defs::ethereum_types::Address; +use zksync_vm2_interface::opcodes; const GAS_TO_PASS: u32 = 10_000; const LARGE_BYTECODE_LEN: usize = 10_000; @@ -128,7 +128,7 @@ fn test() { Address::zero(), vec![], initial_gas, - vm2::Settings { + Settings { default_aa_code_hash: [0; 32], evm_interpreter_code_hash: [0; 32], hook_address: 0, @@ -164,7 +164,7 @@ fn test_with_initial_out_of_gas_error() { Address::zero(), vec![], 10_000, - vm2::Settings { + Settings { default_aa_code_hash: [0; 32], evm_interpreter_code_hash: [0; 32], hook_address: 0, diff --git a/tests/panic.proptest-regressions b/crates/vm2/tests/panic.proptest-regressions similarity index 100% rename from tests/panic.proptest-regressions rename to crates/vm2/tests/panic.proptest-regressions diff --git a/tests/panic.rs b/crates/vm2/tests/panic.rs similarity index 96% rename from tests/panic.rs rename to crates/vm2/tests/panic.rs index c6721c83..272ac366 100644 --- a/tests/panic.rs +++ b/crates/vm2/tests/panic.rs @@ -1,13 +1,13 @@ #![cfg(not(feature = "single_instruction_test"))] use proptest::prelude::*; -use vm2::{ +use zkevm_opcode_defs::ethereum_types::Address; +use zksync_vm2::{ addressing_modes::{Arguments, Immediate1, Immediate2, Register, Register1}, initial_decommit, testworld::TestWorld, - ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, VirtualMachine, + ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, Settings, VirtualMachine, }; -use zkevm_opcode_defs::ethereum_types::Address; proptest! { #[test] @@ -41,7 +41,7 @@ proptest! { Address::zero(), vec![], 1000, - vm2::Settings { + Settings { default_aa_code_hash: [0; 32], evm_interpreter_code_hash: [0; 32], hook_address: 0, diff --git a/tests/stipend.rs b/crates/vm2/tests/stipend.rs similarity index 97% rename from tests/stipend.rs rename to crates/vm2/tests/stipend.rs index d1832d1d..65dfc746 100644 --- a/tests/stipend.rs +++ b/crates/vm2/tests/stipend.rs @@ -1,8 +1,8 @@ #![cfg(not(feature = "single_instruction_test"))] -use eravm_stable_interface::opcodes; -use u256::U256; -use vm2::{ +use primitive_types::U256; +use zkevm_opcode_defs::ethereum_types::Address; +use zksync_vm2::{ address_into_u256, addressing_modes::{ Arguments, CodePage, Immediate1, Register, Register1, Register2, RegisterAndImmediate, @@ -10,9 +10,9 @@ use vm2::{ initial_decommit, instruction_handlers::Add, testworld::TestWorld, - ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, VirtualMachine, + ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, Settings, VirtualMachine, }; -use zkevm_opcode_defs::ethereum_types::Address; +use zksync_vm2_interface::opcodes; const INITIAL_GAS: u32 = 1000; @@ -113,7 +113,7 @@ fn test_scenario(gas_to_pass: u32) -> (ExecutionEnd, u32) { Address::zero(), vec![], INITIAL_GAS, - vm2::Settings { + Settings { default_aa_code_hash: [0; 32], evm_interpreter_code_hash: interpreter_hash, hook_address: 0, diff --git a/eravm-stable-interface/Cargo.toml b/eravm-stable-interface/Cargo.toml deleted file mode 100644 index 9d0757b2..00000000 --- a/eravm-stable-interface/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "eravm-stable-interface" -version = "0.1.0" -edition.workspace = true -license.workspace = true -authors.workspace = true - -[dependencies] -primitive-types = "0.12.1" diff --git a/afl-fuzz/.gitignore b/tests/afl-fuzz/.gitignore similarity index 100% rename from afl-fuzz/.gitignore rename to tests/afl-fuzz/.gitignore diff --git a/tests/afl-fuzz/Cargo.toml b/tests/afl-fuzz/Cargo.toml new file mode 100644 index 00000000..6a0dbdff --- /dev/null +++ b/tests/afl-fuzz/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "zksync_vm2_afl_fuzz" +version.workspace = true +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +keywords.workspace = true +categories.workspace = true +publish = false + +[dependencies] +afl.workspace = true +arbitrary.workspace = true +pretty_assertions.workspace = true +zkevm_opcode_defs.workspace = true +zksync_vm2_interface.workspace = true +zksync_vm2 = { workspace = true, features = ["single_instruction_test"] } + +[[bin]] +name = "show_testcase" +path = "src/show_testcase.rs" + +[[bin]] +name = "check_input_size" +path = "src/check_input_size.rs" diff --git a/afl-fuzz/README.md b/tests/afl-fuzz/README.md similarity index 100% rename from afl-fuzz/README.md rename to tests/afl-fuzz/README.md diff --git a/afl-fuzz/fuzz.sh b/tests/afl-fuzz/fuzz.sh similarity index 100% rename from afl-fuzz/fuzz.sh rename to tests/afl-fuzz/fuzz.sh diff --git a/afl-fuzz/in/kernel_to_msg_value_far_call_forward_fat_pointer b/tests/afl-fuzz/in/kernel_to_msg_value_far_call_forward_fat_pointer similarity index 100% rename from afl-fuzz/in/kernel_to_msg_value_far_call_forward_fat_pointer rename to tests/afl-fuzz/in/kernel_to_msg_value_far_call_forward_fat_pointer diff --git a/afl-fuzz/in/return_calldata b/tests/afl-fuzz/in/return_calldata similarity index 100% rename from afl-fuzz/in/return_calldata rename to tests/afl-fuzz/in/return_calldata diff --git a/afl-fuzz/show_crash.sh b/tests/afl-fuzz/show_crash.sh similarity index 100% rename from afl-fuzz/show_crash.sh rename to tests/afl-fuzz/show_crash.sh diff --git a/afl-fuzz/src/check_input_size.rs b/tests/afl-fuzz/src/check_input_size.rs similarity index 89% rename from afl-fuzz/src/check_input_size.rs rename to tests/afl-fuzz/src/check_input_size.rs index 72bcedca..9deed3df 100644 --- a/afl-fuzz/src/check_input_size.rs +++ b/tests/afl-fuzz/src/check_input_size.rs @@ -1,6 +1,6 @@ //! Finds out how many bytes of data have to be provided to build the mock state. -use differential_fuzzing::VmAndWorld; +use zksync_vm2_afl_fuzz::VmAndWorld; fn main() { const BYTES_GIVEN: usize = 10000; diff --git a/afl-fuzz/src/lib.rs b/tests/afl-fuzz/src/lib.rs similarity index 60% rename from afl-fuzz/src/lib.rs rename to tests/afl-fuzz/src/lib.rs index 52f33d27..839c5cde 100644 --- a/afl-fuzz/src/lib.rs +++ b/tests/afl-fuzz/src/lib.rs @@ -1,6 +1,6 @@ use arbitrary::Arbitrary; -use eravm_stable_interface::Tracer; -use vm2::{single_instruction_test::MockWorld, VirtualMachine}; +use zksync_vm2::{single_instruction_test::MockWorld, VirtualMachine}; +use zksync_vm2_interface::Tracer; #[derive(Arbitrary, Debug)] pub struct VmAndWorld { diff --git a/afl-fuzz/src/main.rs b/tests/afl-fuzz/src/main.rs similarity index 89% rename from afl-fuzz/src/main.rs rename to tests/afl-fuzz/src/main.rs index a48730a8..e8f3fd25 100644 --- a/afl-fuzz/src/main.rs +++ b/tests/afl-fuzz/src/main.rs @@ -1,5 +1,7 @@ -use differential_fuzzing::VmAndWorld; -use vm2::single_instruction_test::{add_heap_to_zk_evm, vm2_to_zk_evm, NoTracer, UniversalVmState}; +use zksync_vm2::single_instruction_test::{ + add_heap_to_zk_evm, vm2_to_zk_evm, NoTracer, UniversalVmState, +}; +use zksync_vm2_afl_fuzz::VmAndWorld; fn main() { afl::fuzz!(|data: &[u8]| { diff --git a/afl-fuzz/src/show_testcase.rs b/tests/afl-fuzz/src/show_testcase.rs similarity index 90% rename from afl-fuzz/src/show_testcase.rs rename to tests/afl-fuzz/src/show_testcase.rs index 26aab4c9..087bddf8 100644 --- a/afl-fuzz/src/show_testcase.rs +++ b/tests/afl-fuzz/src/show_testcase.rs @@ -1,9 +1,11 @@ use std::{env, fs}; -use differential_fuzzing::VmAndWorld; use pretty_assertions::assert_eq; -use vm2::single_instruction_test::{add_heap_to_zk_evm, vm2_to_zk_evm, NoTracer, UniversalVmState}; use zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; +use zksync_vm2::single_instruction_test::{ + add_heap_to_zk_evm, vm2_to_zk_evm, NoTracer, UniversalVmState, +}; +use zksync_vm2_afl_fuzz::VmAndWorld; fn main() { let filename = env::args() From 274116bb53a7414da0a6cadcda16e8846e17dd38 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 9 Sep 2024 11:53:13 +0300 Subject: [PATCH 3/7] Add more crate metadata --- README.md | 26 ++++++++++++++++++++++++-- crates/vm2-interface/Cargo.toml | 2 ++ crates/vm2-interface/LICENSE-APACHE | 1 + crates/vm2-interface/LICENSE-MIT | 1 + crates/vm2-interface/README.md | 12 ++++++++++++ crates/vm2-interface/src/lib.rs | 6 +++--- crates/vm2/Cargo.toml | 2 ++ crates/vm2/LICENSE-APACHE | 1 + crates/vm2/LICENSE-MIT | 1 + crates/vm2/README.md | 12 ++++++++++++ tests/afl-fuzz/README.md | 4 ++-- 11 files changed, 61 insertions(+), 7 deletions(-) create mode 120000 crates/vm2-interface/LICENSE-APACHE create mode 120000 crates/vm2-interface/LICENSE-MIT create mode 100644 crates/vm2-interface/README.md create mode 120000 crates/vm2/LICENSE-APACHE create mode 120000 crates/vm2/LICENSE-MIT create mode 100644 crates/vm2/README.md diff --git a/README.md b/README.md index 79a369b7..2778e405 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,25 @@ -# zksync-era-vm2 +# High-Performance ZKsync Era VM -A high-performance rewrite of the zksync-era VM. +A high-performance rewrite of the out-of-circuit VM for ZKsync Era. + +## Overview + +This repository contains the following crates: + +- [`zksync_vm2_interface`](crates/vm2-interface): stable VM interface for tracers +- [`zksync_vm2`](crates/vm2): VM implementation itself +- [`zksync_vm2_afl_fuzz`](tests/afl-fuzz): [AFL](https://crates.io/crates/afl)-based fuzzing for the VM. + +## Policies + +- [Security policy](SECURITY.md) +- [Contribution policy](CONTRIBUTING.md) + +## License + +ZKsync Era VM is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) + +at your option. diff --git a/crates/vm2-interface/Cargo.toml b/crates/vm2-interface/Cargo.toml index 298e19be..38a5bece 100644 --- a/crates/vm2-interface/Cargo.toml +++ b/crates/vm2-interface/Cargo.toml @@ -1,5 +1,7 @@ [package] name = "zksync_vm2_interface" +description = "Stable interface for ZKsync VM tracers" +readme = "README.md" version.workspace = true edition.workspace = true authors.workspace = true diff --git a/crates/vm2-interface/LICENSE-APACHE b/crates/vm2-interface/LICENSE-APACHE new file mode 120000 index 00000000..1cd601d0 --- /dev/null +++ b/crates/vm2-interface/LICENSE-APACHE @@ -0,0 +1 @@ +../../LICENSE-APACHE \ No newline at end of file diff --git a/crates/vm2-interface/LICENSE-MIT b/crates/vm2-interface/LICENSE-MIT new file mode 120000 index 00000000..b2cfbdc7 --- /dev/null +++ b/crates/vm2-interface/LICENSE-MIT @@ -0,0 +1 @@ +../../LICENSE-MIT \ No newline at end of file diff --git a/crates/vm2-interface/README.md b/crates/vm2-interface/README.md new file mode 100644 index 00000000..7eda45c3 --- /dev/null +++ b/crates/vm2-interface/README.md @@ -0,0 +1,12 @@ +# Stable Interface for ZKsync Era VM + +This library provides a stable interface for the EraVM. It defines an interface for tracers that will never change but may be extended. + +## License + +ZKsync Era VM is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) + +at your option. diff --git a/crates/vm2-interface/src/lib.rs b/crates/vm2-interface/src/lib.rs index 3d8dfa2f..d3d5449c 100644 --- a/crates/vm2-interface/src/lib.rs +++ b/crates/vm2-interface/src/lib.rs @@ -6,7 +6,7 @@ //! not necessary. In fact, tracers should depend on the oldest version that has the required //! features. //! -//! A struct implementing [Tracer] may read and mutate the VM's state via [StateInterface] +//! A struct implementing [`Tracer`] may read and mutate the VM's state via [`StateInterface`] //! when particular opcodes are executed. //! //! ## Why is extreme backwards compatibility required here? @@ -23,9 +23,9 @@ //! version that you publish and import it from the previous version instead. //! //! This is how you would add a new method to StateInterface and a new opcode. +//! //! ``` -//! # use eravm_stable_interface as eravm_stable_interface_v1; -//! use eravm_stable_interface_v1::{StateInterface as StateInterfaceV1, Tracer as TracerV1, opcodes::NearCall}; +//! use zksync_vm2_interface::{StateInterface as StateInterfaceV1, Tracer as TracerV1, opcodes::NearCall}; //! //! trait StateInterface: StateInterfaceV1 { //! fn get_some_new_field(&self) -> u32; diff --git a/crates/vm2/Cargo.toml b/crates/vm2/Cargo.toml index f3b2a3af..4134bb30 100644 --- a/crates/vm2/Cargo.toml +++ b/crates/vm2/Cargo.toml @@ -1,5 +1,7 @@ [package] name = "zksync_vm2" +description = "High-performance rewrite of the out-of-circuit VM for ZKsync Era" +readme = "README.md" version.workspace = true edition.workspace = true authors.workspace = true diff --git a/crates/vm2/LICENSE-APACHE b/crates/vm2/LICENSE-APACHE new file mode 120000 index 00000000..1cd601d0 --- /dev/null +++ b/crates/vm2/LICENSE-APACHE @@ -0,0 +1 @@ +../../LICENSE-APACHE \ No newline at end of file diff --git a/crates/vm2/LICENSE-MIT b/crates/vm2/LICENSE-MIT new file mode 120000 index 00000000..b2cfbdc7 --- /dev/null +++ b/crates/vm2/LICENSE-MIT @@ -0,0 +1 @@ +../../LICENSE-MIT \ No newline at end of file diff --git a/crates/vm2/README.md b/crates/vm2/README.md new file mode 100644 index 00000000..1c693c4f --- /dev/null +++ b/crates/vm2/README.md @@ -0,0 +1,12 @@ +# High-Performance ZKsync Era VM + +A high-performance rewrite of the out-of-circuit VM for ZKsync Era. + +## License + +ZKsync Era VM is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) + +at your option. diff --git a/tests/afl-fuzz/README.md b/tests/afl-fuzz/README.md index 1439d00d..a68e0929 100644 --- a/tests/afl-fuzz/README.md +++ b/tests/afl-fuzz/README.md @@ -5,9 +5,9 @@ Finds divergences and instructions that put vm2 in an invalid state. Setup: `cargo install cargo-afl` -Use `sh fuzz.sh` (or customize the command to your liking) to start fuzzing. +Use `sh fuzz.sh` (or customize the command to your liking) to start fuzzing. `show_crash.sh` can be used to quickly run one of the found crashes and display all the necessary information for fixing it. The size of the search space is relatively small due to tricks explained in the single_instruction_test module. -`cargo run --bin check_input_size` prints out an estimate of the amount of information in the state in bytes. \ No newline at end of file +`cargo run --bin check_input_size` prints out an estimate of the amount of information in the state in bytes. From 088bf74df4e3393f13b7bd73c111ec0b9e740d87 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 9 Sep 2024 12:57:49 +0300 Subject: [PATCH 4/7] Reduce visibility of some items --- crates/vm2/src/addressing_modes.rs | 2 +- crates/vm2/src/bitset.rs | 3 +- crates/vm2/src/callframe.rs | 2 +- crates/vm2/src/decode.rs | 55 +++++----- crates/vm2/src/decommit.rs | 2 + crates/vm2/src/fat_pointer.rs | 1 + crates/vm2/src/heap.rs | 103 +++++++++--------- crates/vm2/src/instruction.rs | 7 +- .../src/instruction_handlers/heap_access.rs | 79 ++++++++++---- crates/vm2/src/instruction_handlers/mod.rs | 6 +- .../src/instruction_handlers/precompiles.rs | 2 +- crates/vm2/src/instruction_handlers/ret.rs | 4 +- crates/vm2/src/lib.rs | 7 +- crates/vm2/src/program.rs | 2 + crates/vm2/src/rollback.rs | 11 +- .../vm2/src/single_instruction_test/heap.rs | 9 +- crates/vm2/src/single_instruction_test/vm.rs | 11 +- crates/vm2/src/stack.rs | 2 +- crates/vm2/src/state.rs | 13 +-- crates/vm2/tests/far_call_decommitment.rs | 3 +- crates/vm2/tests/stipend.rs | 3 +- 21 files changed, 181 insertions(+), 146 deletions(-) diff --git a/crates/vm2/src/addressing_modes.rs b/crates/vm2/src/addressing_modes.rs index 70b88551..954b74e7 100644 --- a/crates/vm2/src/addressing_modes.rs +++ b/crates/vm2/src/addressing_modes.rs @@ -324,7 +324,7 @@ fn source_stack_address(args: &Arguments, state: &mut impl Addressable) -> u16 { compute_stack_address(state, args.source_registers.register1(), args.immediate1) } -pub fn destination_stack_address(args: &Arguments, state: &mut impl Addressable) -> u16 { +pub(crate) fn destination_stack_address(args: &Arguments, state: &mut impl Addressable) -> u16 { compute_stack_address( state, args.destination_registers.register1(), diff --git a/crates/vm2/src/bitset.rs b/crates/vm2/src/bitset.rs index 5c78f316..2e41ce6a 100644 --- a/crates/vm2/src/bitset.rs +++ b/crates/vm2/src/bitset.rs @@ -1,5 +1,6 @@ +/// Bitset with 1,024 elements. #[derive(Clone, PartialEq, Debug, Hash)] -pub struct Bitset([u64; 1 << 10]); +pub(crate) struct Bitset([u64; 1 << 10]); impl Bitset { #[inline(always)] diff --git a/crates/vm2/src/callframe.rs b/crates/vm2/src/callframe.rs index 727f99ed..b6b690e6 100644 --- a/crates/vm2/src/callframe.rs +++ b/crates/vm2/src/callframe.rs @@ -22,7 +22,7 @@ pub struct Callframe { pub is_static: bool, pub is_kernel: bool, - pub stack: Box, + pub(crate) stack: Box, pub sp: u16, pub gas: u32, diff --git a/crates/vm2/src/decode.rs b/crates/vm2/src/decode.rs index e3b6dc10..99c0ec4c 100644 --- a/crates/vm2/src/decode.rs +++ b/crates/vm2/src/decode.rs @@ -14,12 +14,11 @@ use crate::{ Immediate1, Immediate2, Register, Register1, Register2, RegisterAndImmediate, RelativeStack, Source, SourceWriter, }, - instruction::{ExecutionEnd, ExecutionStatus}, + instruction::{jump_to_beginning, ExecutionEnd, ExecutionStatus}, instruction_handlers::{ - Add, And, AuxHeap, Div, Heap, Mul, Or, PointerAdd, PointerPack, PointerShrink, PointerSub, - RotateLeft, RotateRight, ShiftLeft, ShiftRight, Sub, Xor, + Add, And, Div, Mul, Or, PointerAdd, PointerPack, PointerShrink, PointerSub, RotateLeft, + RotateRight, ShiftLeft, ShiftRight, Sub, Xor, }, - jump_to_beginning, mode_requirements::ModeRequirements, Instruction, Predicate, VirtualMachine, World, }; @@ -48,6 +47,7 @@ fn unimplemented_instruction(variant: Opcode) -> Instruction { arguments, } } + fn unimplemented_handler( vm: &mut VirtualMachine, _: &mut W, @@ -149,25 +149,23 @@ pub(crate) fn decode>(raw: u64, is_bootloader: bool) -> I } match parsed.variant.opcode { - zkevm_opcode_defs::Opcode::Add(_) => binop!(Add, ()), - zkevm_opcode_defs::Opcode::Sub(_) => binop!(Sub, ()), - zkevm_opcode_defs::Opcode::Mul(_) => binop!(Mul, out2), - zkevm_opcode_defs::Opcode::Div(_) => binop!(Div, out2), - zkevm_opcode_defs::Opcode::Binop(x) => match x { + Opcode::Add(_) => binop!(Add, ()), + Opcode::Sub(_) => binop!(Sub, ()), + Opcode::Mul(_) => binop!(Mul, out2), + Opcode::Div(_) => binop!(Div, out2), + Opcode::Binop(x) => match x { zkevm_opcode_defs::BinopOpcode::Xor => binop!(Xor, ()), zkevm_opcode_defs::BinopOpcode::And => binop!(And, ()), zkevm_opcode_defs::BinopOpcode::Or => binop!(Or, ()), }, - zkevm_opcode_defs::Opcode::Shift(x) => match x { + Opcode::Shift(x) => match x { zkevm_opcode_defs::ShiftOpcode::Shl => binop!(ShiftLeft, ()), zkevm_opcode_defs::ShiftOpcode::Shr => binop!(ShiftRight, ()), zkevm_opcode_defs::ShiftOpcode::Rol => binop!(RotateLeft, ()), zkevm_opcode_defs::ShiftOpcode::Ror => binop!(RotateRight, ()), }, - zkevm_opcode_defs::Opcode::Jump(_) => { - Instruction::from_jump(src1, out.try_into().unwrap(), arguments) - } - zkevm_opcode_defs::Opcode::Context(x) => match x { + Opcode::Jump(_) => Instruction::from_jump(src1, out.try_into().unwrap(), arguments), + Opcode::Context(x) => match x { zkevm_opcode_defs::ContextOpcode::This => { Instruction::from_this(out.try_into().unwrap(), arguments) } @@ -199,19 +197,19 @@ pub(crate) fn decode>(raw: u64, is_bootloader: bool) -> I Instruction::from_aux_mutating(arguments) } }, - zkevm_opcode_defs::Opcode::Ptr(x) => match x { + Opcode::Ptr(x) => match x { zkevm_opcode_defs::PtrOpcode::Add => ptr!(PointerAdd), zkevm_opcode_defs::PtrOpcode::Sub => ptr!(PointerSub), zkevm_opcode_defs::PtrOpcode::Pack => ptr!(PointerPack), zkevm_opcode_defs::PtrOpcode::Shrink => ptr!(PointerShrink), }, - zkevm_opcode_defs::Opcode::NearCall(_) => Instruction::from_near_call( + Opcode::NearCall(_) => Instruction::from_near_call( Register1(Register::new(parsed.src0_reg_idx)), Immediate1(parsed.imm_0), Immediate2(parsed.imm_1), arguments, ), - zkevm_opcode_defs::Opcode::FarCall(kind) => { + Opcode::FarCall(kind) => { let constructor = match kind { zkevm_opcode_defs::FarCallOpcode::Normal => { Instruction::from_far_call:: @@ -232,7 +230,7 @@ pub(crate) fn decode>(raw: u64, is_bootloader: bool) -> I arguments, ) } - zkevm_opcode_defs::Opcode::Ret(kind) => { + Opcode::Ret(kind) => { let to_label = parsed.variant.flags[RET_TO_LABEL_BIT_IDX]; let label = if to_label { Some(Immediate1(parsed.imm_0)) @@ -249,7 +247,7 @@ pub(crate) fn decode>(raw: u64, is_bootloader: bool) -> I zkevm_opcode_defs::RetOpcode::Panic => Instruction::from_panic(label, arguments), } } - zkevm_opcode_defs::Opcode::Log(x) => match x { + Opcode::Log(x) => match x { zkevm_opcode_defs::LogOpcode::StorageRead => Instruction::from_sload( src1.try_into().unwrap(), out.try_into().unwrap(), @@ -296,34 +294,33 @@ pub(crate) fn decode>(raw: u64, is_bootloader: bool) -> I arguments, ), }, - zkevm_opcode_defs::Opcode::UMA(x) => { + Opcode::UMA(x) => { let increment = parsed.variant.flags[UMA_INCREMENT_FLAG_IDX]; match x { - zkevm_opcode_defs::UMAOpcode::HeapRead => Instruction::from_load::( + zkevm_opcode_defs::UMAOpcode::HeapRead => Instruction::from_heap_load( src1.try_into().unwrap(), out.try_into().unwrap(), increment.then_some(out2), arguments, ), - zkevm_opcode_defs::UMAOpcode::HeapWrite => Instruction::from_store::( + zkevm_opcode_defs::UMAOpcode::HeapWrite => Instruction::from_heap_store( src1.try_into().unwrap(), src2, increment.then_some(out.try_into().unwrap()), arguments, is_bootloader, ), - zkevm_opcode_defs::UMAOpcode::AuxHeapRead => Instruction::from_load::( + zkevm_opcode_defs::UMAOpcode::AuxHeapRead => Instruction::from_aux_heap_load( src1.try_into().unwrap(), out.try_into().unwrap(), increment.then_some(out2), arguments, ), - zkevm_opcode_defs::UMAOpcode::AuxHeapWrite => Instruction::from_store::( + zkevm_opcode_defs::UMAOpcode::AuxHeapWrite => Instruction::from_aux_heap_store( src1.try_into().unwrap(), src2, increment.then_some(out.try_into().unwrap()), arguments, - false, ), zkevm_opcode_defs::UMAOpcode::FatPointerRead => Instruction::from_load_pointer( src1.try_into().unwrap(), @@ -332,15 +329,15 @@ pub(crate) fn decode>(raw: u64, is_bootloader: bool) -> I arguments, ), zkevm_opcode_defs::UMAOpcode::StaticMemoryRead => unimplemented_instruction( - zkevm_opcode_defs::Opcode::UMA(zkevm_opcode_defs::UMAOpcode::StaticMemoryRead), + Opcode::UMA(zkevm_opcode_defs::UMAOpcode::StaticMemoryRead), ), zkevm_opcode_defs::UMAOpcode::StaticMemoryWrite => unimplemented_instruction( - zkevm_opcode_defs::Opcode::UMA(zkevm_opcode_defs::UMAOpcode::StaticMemoryWrite), + Opcode::UMA(zkevm_opcode_defs::UMAOpcode::StaticMemoryWrite), ), } } - zkevm_opcode_defs::Opcode::Invalid(_) => Instruction::from_invalid(), - zkevm_opcode_defs::Opcode::Nop(_) => { + Opcode::Invalid(_) => Instruction::from_invalid(), + Opcode::Nop(_) => { let no_sp_movement = AdvanceStackPointer(RegisterAndImmediate { immediate: 0, register: Register::new(0), diff --git a/crates/vm2/src/decommit.rs b/crates/vm2/src/decommit.rs index 252508bf..b7aa3796 100644 --- a/crates/vm2/src/decommit.rs +++ b/crates/vm2/src/decommit.rs @@ -141,6 +141,7 @@ pub(crate) struct UnpaidDecommit { /// May be used to load code when the VM first starts up. /// Doesn't check for any errors. /// Doesn't cost anything but also doesn't make the code free in future decommits. +#[doc(hidden)] // should be used only in low-level testing / benches pub fn initial_decommit>(world: &mut W, address: H160) -> Program { let deployer_system_contract_address = Address::from_low_u64_be(DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW as u64); @@ -157,6 +158,7 @@ pub fn initial_decommit>(world: &mut W, address: H160) -> Program world.decommit(code_key) } +#[doc(hidden)] // should be used only in low-level testing / benches pub fn address_into_u256(address: H160) -> U256 { let mut buffer = [0; 32]; buffer[12..].copy_from_slice(address.as_bytes()); diff --git a/crates/vm2/src/fat_pointer.rs b/crates/vm2/src/fat_pointer.rs index 65d02179..8e7b9075 100644 --- a/crates/vm2/src/fat_pointer.rs +++ b/crates/vm2/src/fat_pointer.rs @@ -1,6 +1,7 @@ use primitive_types::U256; use zksync_vm2_interface::HeapId; +/// Fat pointer to a heap location. #[derive(Debug)] #[repr(C)] pub struct FatPointer { diff --git a/crates/vm2/src/heap.rs b/crates/vm2/src/heap.rs index 1a19efac..e2cf9688 100644 --- a/crates/vm2/src/heap.rs +++ b/crates/vm2/src/heap.rs @@ -6,8 +6,6 @@ use std::{ use primitive_types::U256; use zksync_vm2_interface::HeapId; -use crate::instruction_handlers::HeapInterface; - /// Heap page size in bytes. const HEAP_PAGE_SIZE: usize = 1 << 12; @@ -71,55 +69,8 @@ impl Heap { Self { pages } } - /// Needed only by tracers - pub(crate) fn read_byte(&self, address: u32) -> u8 { - let (page, offset) = address_to_page_offset(address); - self.page(page).map(|page| page.0[offset]).unwrap_or(0) - } - - fn page(&self, idx: usize) -> Option<&HeapPage> { - self.pages.get(idx)?.as_ref() - } - - fn get_or_insert_page(&mut self, idx: usize, pagepool: &mut PagePool) -> &mut HeapPage { - if self.pages.len() <= idx { - self.pages.resize(idx + 1, None); - } - self.pages[idx].get_or_insert_with(|| pagepool.allocate_page()) - } - - fn write_u256(&mut self, start_address: u32, value: U256, pagepool: &mut PagePool) { - let (page_idx, offset_in_page) = address_to_page_offset(start_address); - let bytes_in_page = HEAP_PAGE_SIZE - offset_in_page; - let page = self.get_or_insert_page(page_idx, pagepool); - - if bytes_in_page >= 32 { - value.to_big_endian(&mut page.0[offset_in_page..offset_in_page + 32]); - } else { - let mut bytes = [0; 32]; - value.to_big_endian(&mut bytes); - let mut bytes_iter = bytes.into_iter(); - - for (dst, src) in page.0[offset_in_page..].iter_mut().zip(bytes_iter.by_ref()) { - *dst = src; - } - - let page = self.get_or_insert_page(page_idx + 1, pagepool); - for (dst, src) in page.0.iter_mut().zip(bytes_iter) { - *dst = src; - } - } - } -} - -#[inline(always)] -fn address_to_page_offset(address: u32) -> (usize, usize) { - let offset = address as usize; - (offset >> 12, offset & (HEAP_PAGE_SIZE - 1)) -} - -impl HeapInterface for Heap { - fn read_u256(&self, start_address: u32) -> U256 { + // TODO: reduce visibility once `multivm` uses `StateInterface` APIs + pub fn read_u256(&self, start_address: u32) -> U256 { let (page_idx, offset_in_page) = address_to_page_offset(start_address); let bytes_in_page = HEAP_PAGE_SIZE - offset_in_page; @@ -145,7 +96,7 @@ impl HeapInterface for Heap { } } - fn read_u256_partially(&self, range: Range) -> U256 { + pub(crate) fn read_u256_partially(&self, range: Range) -> U256 { let (page_idx, offset_in_page) = address_to_page_offset(range.start); let length = range.len(); let bytes_in_page = length.min(HEAP_PAGE_SIZE - offset_in_page); @@ -167,7 +118,7 @@ impl HeapInterface for Heap { U256::from_big_endian(&result) } - fn read_range_big_endian(&self, range: Range) -> Vec { + pub fn read_range_big_endian(&self, range: Range) -> Vec { let length = range.len(); let (mut page_idx, mut offset_in_page) = address_to_page_offset(range.start); @@ -184,6 +135,52 @@ impl HeapInterface for Heap { } result } + + /// Needed only by tracers + pub(crate) fn read_byte(&self, address: u32) -> u8 { + let (page, offset) = address_to_page_offset(address); + self.page(page).map(|page| page.0[offset]).unwrap_or(0) + } + + fn page(&self, idx: usize) -> Option<&HeapPage> { + self.pages.get(idx)?.as_ref() + } + + fn get_or_insert_page(&mut self, idx: usize, pagepool: &mut PagePool) -> &mut HeapPage { + if self.pages.len() <= idx { + self.pages.resize(idx + 1, None); + } + self.pages[idx].get_or_insert_with(|| pagepool.allocate_page()) + } + + fn write_u256(&mut self, start_address: u32, value: U256, pagepool: &mut PagePool) { + let (page_idx, offset_in_page) = address_to_page_offset(start_address); + let bytes_in_page = HEAP_PAGE_SIZE - offset_in_page; + let page = self.get_or_insert_page(page_idx, pagepool); + + if bytes_in_page >= 32 { + value.to_big_endian(&mut page.0[offset_in_page..offset_in_page + 32]); + } else { + let mut bytes = [0; 32]; + value.to_big_endian(&mut bytes); + let mut bytes_iter = bytes.into_iter(); + + for (dst, src) in page.0[offset_in_page..].iter_mut().zip(bytes_iter.by_ref()) { + *dst = src; + } + + let page = self.get_or_insert_page(page_idx + 1, pagepool); + for (dst, src) in page.0.iter_mut().zip(bytes_iter) { + *dst = src; + } + } + } +} + +#[inline(always)] +fn address_to_page_offset(address: u32) -> (usize, usize) { + let offset = address as usize; + (offset >> 12, offset & (HEAP_PAGE_SIZE - 1)) } #[derive(Debug, Clone)] diff --git a/crates/vm2/src/instruction.rs b/crates/vm2/src/instruction.rs index 2625f59d..261b5e05 100644 --- a/crates/vm2/src/instruction.rs +++ b/crates/vm2/src/instruction.rs @@ -4,6 +4,7 @@ use crate::{ addressing_modes::Arguments, mode_requirements::ModeRequirements, vm::VirtualMachine, Predicate, }; +#[doc(hidden)] // should only be used for low-level testing / benchmarking pub struct Instruction { pub(crate) handler: Handler, pub(crate) arguments: Arguments, @@ -19,7 +20,9 @@ impl fmt::Debug for Instruction { } pub(crate) type Handler = fn(&mut VirtualMachine, &mut W, &mut T) -> ExecutionStatus; -pub enum ExecutionStatus { + +#[derive(Debug)] +pub(crate) enum ExecutionStatus { Running, Stopped(ExecutionEnd), } @@ -34,7 +37,7 @@ pub enum ExecutionEnd { SuspendedOnHook(u32), } -pub fn jump_to_beginning() -> Instruction { +pub(crate) fn jump_to_beginning() -> Instruction { Instruction { handler: jump_to_beginning_handler, arguments: Arguments::new(Predicate::Always, 0, ModeRequirements::none()), diff --git a/crates/vm2/src/instruction_handlers/heap_access.rs b/crates/vm2/src/instruction_handlers/heap_access.rs index 19843ae2..70aba1ea 100644 --- a/crates/vm2/src/instruction_handlers/heap_access.rs +++ b/crates/vm2/src/instruction_handlers/heap_access.rs @@ -1,5 +1,3 @@ -use std::ops::Range; - use primitive_types::U256; use zksync_vm2_interface::{opcodes, OpcodeType, Tracer}; @@ -15,42 +13,42 @@ use crate::{ ExecutionEnd, HeapId, Instruction, VirtualMachine, }; -// FIXME: reduce visibility -pub trait HeapInterface { - fn read_u256(&self, start_address: u32) -> U256; - fn read_u256_partially(&self, range: Range) -> U256; - fn read_range_big_endian(&self, range: Range) -> Vec; -} +pub(crate) trait HeapFromState { + type Read: OpcodeType; + type Write: OpcodeType; -pub trait HeapFromState { fn get_heap(state: &State) -> HeapId; fn get_heap_size(state: &mut State) -> &mut u32; - type Read: OpcodeType; - type Write: OpcodeType; } -pub struct Heap; +pub(crate) struct Heap; + impl HeapFromState for Heap { + type Read = opcodes::HeapRead; + type Write = opcodes::HeapWrite; + fn get_heap(state: &State) -> HeapId { state.current_frame.heap } + fn get_heap_size(state: &mut State) -> &mut u32 { &mut state.current_frame.heap_size } - type Read = opcodes::HeapRead; - type Write = opcodes::HeapWrite; } -pub struct AuxHeap; +pub(crate) struct AuxHeap; + impl HeapFromState for AuxHeap { + type Read = opcodes::AuxHeapRead; + type Write = opcodes::AuxHeapWrite; + fn get_heap(state: &State) -> HeapId { state.current_frame.aux_heap } + fn get_heap_size(state: &mut State) -> &mut u32 { &mut state.current_frame.aux_heap_size } - type Read = opcodes::AuxHeapRead; - type Write = opcodes::AuxHeapWrite; } /// The last address to which 32 can be added without overflow. @@ -149,7 +147,7 @@ fn store< /// Pays for more heap space. Doesn't acually grow the heap. /// That distinction is necessary because the bootloader gets u32::MAX heap for free. -pub fn grow_heap( +pub(crate) fn grow_heap( state: &mut State, new_bound: u32, ) -> Result<(), ()> { @@ -201,7 +199,27 @@ use super::monomorphization::*; impl Instruction { #[inline(always)] - pub fn from_load( + pub fn from_heap_load( + src: RegisterOrImmediate, + out: Register1, + incremented_out: Option, + arguments: Arguments, + ) -> Self { + Self::from_load::(src, out, incremented_out, arguments) + } + + #[inline(always)] + pub fn from_aux_heap_load( + src: RegisterOrImmediate, + out: Register1, + incremented_out: Option, + arguments: Arguments, + ) -> Self { + Self::from_load::(src, out, incremented_out, arguments) + } + + #[inline(always)] + fn from_load( src: RegisterOrImmediate, out: Register1, incremented_out: Option, @@ -221,7 +239,28 @@ impl Instruction { } #[inline(always)] - pub fn from_store( + pub fn from_heap_store( + src1: RegisterOrImmediate, + src2: Register2, + incremented_out: Option, + arguments: Arguments, + should_hook: bool, + ) -> Self { + Self::from_store::(src1, src2, incremented_out, arguments, should_hook) + } + + #[inline(always)] + pub fn from_aux_heap_store( + src1: RegisterOrImmediate, + src2: Register2, + incremented_out: Option, + arguments: Arguments, + ) -> Self { + Self::from_store::(src1, src2, incremented_out, arguments, false) + } + + #[inline(always)] + fn from_store( src1: RegisterOrImmediate, src2: Register2, incremented_out: Option, diff --git a/crates/vm2/src/instruction_handlers/mod.rs b/crates/vm2/src/instruction_handlers/mod.rs index 54d84ab4..9b62fabe 100644 --- a/crates/vm2/src/instruction_handlers/mod.rs +++ b/crates/vm2/src/instruction_handlers/mod.rs @@ -3,8 +3,10 @@ pub use zksync_vm2_interface::opcodes::{ RotateRight, ShiftLeft, ShiftRight, Sub, Xor, }; -pub use self::heap_access::{AuxHeap, Heap, HeapInterface}; -pub(crate) use self::ret::{invalid_instruction, RETURN_COST}; +pub(crate) use self::{ + heap_access::{AuxHeap, Heap}, + ret::{invalid_instruction, RETURN_COST}, +}; mod binop; mod common; diff --git a/crates/vm2/src/instruction_handlers/precompiles.rs b/crates/vm2/src/instruction_handlers/precompiles.rs index 664fb7da..4d4d549d 100644 --- a/crates/vm2/src/instruction_handlers/precompiles.rs +++ b/crates/vm2/src/instruction_handlers/precompiles.rs @@ -16,7 +16,7 @@ use zkevm_opcode_defs::{ }; use zksync_vm2_interface::{opcodes, CycleStats, HeapId, Tracer}; -use super::{common::boilerplate_ext, HeapInterface}; +use super::common::boilerplate_ext; use crate::{ addressing_modes::{Arguments, Destination, Register1, Register2, Source}, heap::Heaps, diff --git a/crates/vm2/src/instruction_handlers/ret.rs b/crates/vm2/src/instruction_handlers/ret.rs index 84823abc..f423bf8f 100644 --- a/crates/vm2/src/instruction_handlers/ret.rs +++ b/crates/vm2/src/instruction_handlers/ret.rs @@ -4,9 +4,7 @@ use zksync_vm2_interface::{ ReturnType, Tracer, }; -use super::{ - common::full_boilerplate, far_call::get_far_call_calldata, monomorphization::*, HeapInterface, -}; +use super::{common::full_boilerplate, far_call::get_far_call_calldata, monomorphization::*}; use crate::{ addressing_modes::{Arguments, Immediate1, Register1, Source, INVALID_INSTRUCTION_COST}, callframe::FrameRemnant, diff --git a/crates/vm2/src/lib.rs b/crates/vm2/src/lib.rs index 8e65838f..f0733960 100644 --- a/crates/vm2/src/lib.rs +++ b/crates/vm2/src/lib.rs @@ -10,8 +10,9 @@ pub use zksync_vm2_interface::{ pub(crate) use self::single_instruction_test::{heap, program, stack}; pub use self::{ decommit::{address_into_u256, initial_decommit}, + fat_pointer::FatPointer, heap::FIRST_HEAP, - instruction::{jump_to_beginning, ExecutionEnd, Instruction}, + instruction::{ExecutionEnd, Instruction}, mode_requirements::ModeRequirements, predication::Predicate, program::Program, @@ -27,11 +28,11 @@ mod bitset; mod callframe; pub mod decode; mod decommit; -pub mod fat_pointer; +mod fat_pointer; #[cfg(not(feature = "single_instruction_test"))] mod heap; mod instruction; -pub mod instruction_handlers; +mod instruction_handlers; mod mode_requirements; mod predication; #[cfg(not(feature = "single_instruction_test"))] diff --git a/crates/vm2/src/program.rs b/crates/vm2/src/program.rs index 84c6ef2d..d33a9589 100644 --- a/crates/vm2/src/program.rs +++ b/crates/vm2/src/program.rs @@ -4,6 +4,8 @@ use primitive_types::U256; use crate::{hash_for_debugging, Instruction}; +/// Compiled ZKsync Era VM bytecode. +/// /// Cloning this is cheap. It is a handle to memory similar to [`Arc`]. pub struct Program { // An internal representation that doesn't need two Arcs would be better diff --git a/crates/vm2/src/rollback.rs b/crates/vm2/src/rollback.rs index 2b1c9f6d..a04b2c30 100644 --- a/crates/vm2/src/rollback.rs +++ b/crates/vm2/src/rollback.rs @@ -9,7 +9,7 @@ pub(crate) trait Rollback { } #[derive(Default)] -pub struct RollbackableMap { +pub(crate) struct RollbackableMap { map: BTreeMap, old_entries: Vec<(K, Option)>, } @@ -64,8 +64,8 @@ impl AsRef> for RollbackableMap { } } -#[derive(Default)] -pub struct RollbackableSet { +#[derive(Debug, Default)] +pub(crate) struct RollbackableSet { map: BTreeMap, old_entries: Vec, } @@ -105,7 +105,8 @@ impl AsRef> for RollbackableSet { } } -pub struct RollbackableLog { +#[derive(Debug)] +pub(crate) struct RollbackableLog { entries: Vec, } @@ -149,7 +150,7 @@ impl AsRef<[T]> for RollbackableLog { /// Rollbackable Plain Old Data simply stores copies of itself in snapshots. #[derive(Default, Copy, Clone)] -pub struct RollbackablePod(pub T); +pub(crate) struct RollbackablePod(pub T); impl Rollback for RollbackablePod { type Snapshot = T; diff --git a/crates/vm2/src/single_instruction_test/heap.rs b/crates/vm2/src/single_instruction_test/heap.rs index 6af16884..a8ed5ca1 100644 --- a/crates/vm2/src/single_instruction_test/heap.rs +++ b/crates/vm2/src/single_instruction_test/heap.rs @@ -5,7 +5,6 @@ use primitive_types::U256; use zksync_vm2_interface::HeapId; use super::mock_array::MockRead; -use crate::instruction_handlers::HeapInterface; #[derive(Debug, Clone)] pub struct Heap { @@ -22,15 +21,13 @@ impl Heap { pub(crate) fn read_byte(&self, _: u32) -> u8 { unimplemented!() } -} -impl HeapInterface for Heap { - fn read_u256(&self, start_address: u32) -> U256 { + pub(crate) fn read_u256(&self, start_address: u32) -> U256 { assert!(self.write.is_none()); U256::from_little_endian(self.read.get(start_address)) } - fn read_u256_partially(&self, range: std::ops::Range) -> U256 { + pub(crate) fn read_u256_partially(&self, range: std::ops::Range) -> U256 { assert!(self.write.is_none()); let mut result = *self.read.get(range.start); for byte in &mut result[0..32 - range.len()] { @@ -39,7 +36,7 @@ impl HeapInterface for Heap { U256::from_little_endian(&result) } - fn read_range_big_endian(&self, _: std::ops::Range) -> Vec { + pub(crate) fn read_range_big_endian(&self, _: std::ops::Range) -> Vec { // This is wrong, but this method is only used to get the final return value. vec![] } diff --git a/crates/vm2/src/single_instruction_test/vm.rs b/crates/vm2/src/single_instruction_test/vm.rs index a9e55fa9..5585a23a 100644 --- a/crates/vm2/src/single_instruction_test/vm.rs +++ b/crates/vm2/src/single_instruction_test/vm.rs @@ -6,14 +6,15 @@ use zksync_vm2_interface::Tracer; use super::{heap::Heaps, stack::StackPool}; use crate::{ - addressing_modes::Arguments, callframe::Callframe, fat_pointer::FatPointer, - instruction::ExecutionStatus, HeapId, Instruction, ModeRequirements, Predicate, Settings, - State, VirtualMachine, World, + addressing_modes::Arguments, callframe::Callframe, fat_pointer::FatPointer, HeapId, + Instruction, ModeRequirements, Predicate, Settings, State, VirtualMachine, World, }; impl VirtualMachine { - pub fn run_single_instruction(&mut self, world: &mut W, tracer: &mut T) -> ExecutionStatus { - unsafe { ((*self.state.current_frame.pc).handler)(self, world, tracer) } + pub fn run_single_instruction(&mut self, world: &mut W, tracer: &mut T) { + unsafe { + ((*self.state.current_frame.pc).handler)(self, world, tracer); + } } pub fn is_in_valid_state(&self) -> bool { diff --git a/crates/vm2/src/stack.rs b/crates/vm2/src/stack.rs index 9664a26b..6236b47e 100644 --- a/crates/vm2/src/stack.rs +++ b/crates/vm2/src/stack.rs @@ -8,7 +8,7 @@ use primitive_types::U256; use crate::{bitset::Bitset, fat_pointer::FatPointer, hash_for_debugging}; #[derive(PartialEq)] -pub struct Stack { +pub(crate) struct Stack { /// set of slots that may be interpreted as [`FatPointer`]. pointer_flags: Bitset, dirty_areas: u64, diff --git a/crates/vm2/src/state.rs b/crates/vm2/src/state.rs index 248e3066..c3cb86c6 100644 --- a/crates/vm2/src/state.rs +++ b/crates/vm2/src/state.rs @@ -11,23 +11,18 @@ use crate::{ world_diff::Snapshot, }; +// TODO: reduce visibility once `multivm` uses `StateInterface` APIs #[derive(Debug)] pub struct State { - pub registers: [U256; 16], + pub(crate) registers: [U256; 16], pub(crate) register_pointer_flags: u16, - - pub flags: Flags, - + pub(crate) flags: Flags, pub current_frame: Callframe, - /// Contains indices to the far call instructions currently being executed. /// They are needed to continue execution from the correct spot upon return. pub previous_frames: Vec>, - pub heaps: Heaps, - - pub transaction_number: u16, - + pub(crate) transaction_number: u16, pub(crate) context_u128: u128, } diff --git a/crates/vm2/tests/far_call_decommitment.rs b/crates/vm2/tests/far_call_decommitment.rs index 091f349d..3452934e 100644 --- a/crates/vm2/tests/far_call_decommitment.rs +++ b/crates/vm2/tests/far_call_decommitment.rs @@ -9,7 +9,6 @@ use zksync_vm2::{ Arguments, CodePage, Immediate1, Register, Register1, Register2, RegisterAndImmediate, }, initial_decommit, - instruction_handlers::Heap, testworld::TestWorld, ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, Settings, VirtualMachine, }; @@ -68,7 +67,7 @@ fn create_test_world() -> TestWorld<()> { Arguments::new(Predicate::Always, 200, ModeRequirements::none()), ), // 3: Hook (0) - Instruction::from_store::( + Instruction::from_heap_store( Register1(r0).into(), Register2(r0), None, diff --git a/crates/vm2/tests/stipend.rs b/crates/vm2/tests/stipend.rs index 65dfc746..65470b51 100644 --- a/crates/vm2/tests/stipend.rs +++ b/crates/vm2/tests/stipend.rs @@ -8,11 +8,10 @@ use zksync_vm2::{ Arguments, CodePage, Immediate1, Register, Register1, Register2, RegisterAndImmediate, }, initial_decommit, - instruction_handlers::Add, testworld::TestWorld, ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, Settings, VirtualMachine, }; -use zksync_vm2_interface::opcodes; +use zksync_vm2_interface::opcodes::{self, Add}; const INITIAL_GAS: u32 = 1000; From dcf1a3e67fa4c090c3c6d530ec463c0ff8c8c2c3 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 9 Sep 2024 14:19:45 +0300 Subject: [PATCH 5/7] Fix doc tests --- crates/vm2-interface/src/tracer_interface.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/vm2-interface/src/tracer_interface.rs b/crates/vm2-interface/src/tracer_interface.rs index c12fe67b..3aa75306 100644 --- a/crates/vm2-interface/src/tracer_interface.rs +++ b/crates/vm2-interface/src/tracer_interface.rs @@ -193,10 +193,12 @@ impl OpcodeType for opcodes::Ret { /// counter has advanced. /// /// # Examples +/// /// Here `FarCallCounter` counts the number of far calls. /// ``` -/// use eravm_stable_interface::{Tracer, StateInterface, OpcodeType, Opcode}; +/// # use zksync_vm2_interface::{Tracer, StateInterface, OpcodeType, Opcode}; /// struct FarCallCounter(usize); +/// /// impl Tracer for FarCallCounter { /// fn before_instruction(&mut self, state: &mut S) { /// match OP::VALUE { From 8149eecf62ea7533b2cf36312e1f89527e6cccf3 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 9 Sep 2024 14:20:02 +0300 Subject: [PATCH 6/7] Add fuzzing and doc testing to CI --- .github/workflows/ci.yml | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f4df401..128a53b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,18 +22,25 @@ jobs: steps: - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4 - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 + - name: Install Rust + uses: dtolnay/rust-toolchain@master with: toolchain: stable - override: true + components: rustfmt, clippy, rust-src - name: Rust Cache uses: Swatinem/rust-cache@v2 + - name: Install cargo-afl + run: cargo install cargo-afl --version=^0.15 --force + - name: Build project run: | - cargo build + # AFL fuzzing requires a separate command + cargo build --workspace --all-targets --exclude zksync_vm2_afl_fuzz + + - name: Build fuzzer + run: cargo afl build -p zksync_vm2_afl_fuzz # Two runs are needed. One for normal VM, another for the mocked version - name: Run clippy @@ -47,6 +54,14 @@ jobs: run: | cargo fmt --check -- --config imports_granularity=Crate --config group_imports=StdExternalCrate - - name: Run Tests + - name: Run tests run: | cargo test -p zksync_vm2_interface -p zksync_vm2 --all-targets + + - name: Run doc tests + run: cargo test --workspace --doc + + - name: Run fuzzer for a bit + run: | + AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 \ + cargo afl fuzz -i tests/afl-fuzz/in -o tests/afl-fuzz/out -V 60 target/debug/zksync_vm2_afl_fuzz From 23236717d1e9b5bae468749bfbaddbdaa3deaaf5 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 9 Sep 2024 16:34:06 +0300 Subject: [PATCH 7/7] Fix doc comments --- crates/vm2-interface/src/lib.rs | 5 ++++- crates/vm2/src/bitset.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/vm2-interface/src/lib.rs b/crates/vm2-interface/src/lib.rs index d3d5449c..1a83f2f6 100644 --- a/crates/vm2-interface/src/lib.rs +++ b/crates/vm2-interface/src/lib.rs @@ -25,7 +25,10 @@ //! This is how you would add a new method to StateInterface and a new opcode. //! //! ``` -//! use zksync_vm2_interface::{StateInterface as StateInterfaceV1, Tracer as TracerV1, opcodes::NearCall}; +//! # use zksync_vm2_interface as zksync_vm2_interface_v1; +//! use zksync_vm2_interface_v1::{ +//! StateInterface as StateInterfaceV1, Tracer as TracerV1, opcodes::NearCall, +//! }; //! //! trait StateInterface: StateInterfaceV1 { //! fn get_some_new_field(&self) -> u32; diff --git a/crates/vm2/src/bitset.rs b/crates/vm2/src/bitset.rs index 2e41ce6a..ad1b4f8d 100644 --- a/crates/vm2/src/bitset.rs +++ b/crates/vm2/src/bitset.rs @@ -1,4 +1,4 @@ -/// Bitset with 1,024 elements. +/// Bitset with `1 << 16` elements. Used to store pointer flags for VM [`Stack`](crate::stack::Stack). #[derive(Clone, PartialEq, Debug, Hash)] pub(crate) struct Bitset([u64; 1 << 10]);