Skip to content

Commit

Permalink
use generic statics for panic as well
Browse files Browse the repository at this point in the history
  • Loading branch information
joonazan committed Sep 18, 2024
1 parent d4e92c1 commit 6a11381
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 32 deletions.
13 changes: 7 additions & 6 deletions crates/vm2/src/instruction_handlers/heap_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use zksync_vm2_interface::{opcodes, HeapId, OpcodeType, Tracer};
use super::{
common::{boilerplate, full_boilerplate},
monomorphization::{match_boolean, match_reg_imm, monomorphize, parameterize},
ret::spontaneous_panic,
};
use crate::{
addressing_modes::{
Expand Down Expand Up @@ -77,15 +78,15 @@ fn load<T: Tracer, W, H: HeapFromState, In: Source, const INCREMENT: bool>(

let new_bound = address.wrapping_add(32);
if grow_heap::<_, _, H>(&mut vm.state, new_bound).is_err() {
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return;
};

// The heap is always grown even when the index nonsensical.
// TODO PLA-974 revert to not growing the heap on failure as soon as zk_evm is fixed
if bigger_than_last_address(pointer) {
let _ = vm.state.use_gas(u32::MAX);
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return;
}

Expand Down Expand Up @@ -119,15 +120,15 @@ where

let new_bound = address.wrapping_add(32);
if grow_heap::<_, _, H>(&mut vm.state, new_bound).is_err() {
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return ExecutionStatus::Running;
}

// The heap is always grown even when the index nonsensical.
// TODO PLA-974 revert to not growing the heap on failure as soon as zk_evm is fixed
if bigger_than_last_address(pointer) {
let _ = vm.state.use_gas(u32::MAX);
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return ExecutionStatus::Running;
}

Expand Down Expand Up @@ -170,7 +171,7 @@ fn load_pointer<T: Tracer, W, const INCREMENT: bool>(
boilerplate::<opcodes::PointerRead, _, _>(vm, world, tracer, |vm, args| {
let (input, input_is_pointer) = Register1::get_with_pointer_flag(args, &mut vm.state);
if !input_is_pointer {
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return;
}
let pointer = FatPointer::from(input);
Expand All @@ -179,7 +180,7 @@ fn load_pointer<T: Tracer, W, const INCREMENT: bool>(
// but if offset + 32 is not representable, we panic, even if we could've read some bytes.
// This is not a bug, this is how it must work to be backwards compatible.
if pointer.offset > LAST_ADDRESS {
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return;
};

Expand Down
5 changes: 4 additions & 1 deletion crates/vm2/src/instruction_handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
pub(crate) use self::{
context::address_into_u256,
heap_access::{AuxHeap, Heap},
ret::{invalid_instruction, RETURN_COST},
ret::invalid_instruction,
};

#[cfg(feature = "single_instruction_test")]
pub(crate) use ret::spontaneous_panic;

mod binop;
mod common;
mod context;
Expand Down
5 changes: 3 additions & 2 deletions crates/vm2/src/instruction_handlers/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use super::{
monomorphization::{
match_boolean, match_destination, match_source, monomorphize, parameterize,
},
ret::spontaneous_panic,
};
use crate::{
addressing_modes::{
Expand Down Expand Up @@ -39,12 +40,12 @@ fn ptr<T: Tracer, W, Op: PtrOp, In1: Source, Out: Destination, const SWAP: bool>
};

if !a_is_pointer || b_is_pointer {
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return;
}

let Some(result) = Op::perform(a, b) else {
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return;
};

Expand Down
4 changes: 2 additions & 2 deletions crates/vm2/src/instruction_handlers/precompiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use zkevm_opcode_defs::{
};
use zksync_vm2_interface::{opcodes, CycleStats, HeapId, Tracer};

use super::common::boilerplate_ext;
use super::{common::boilerplate_ext, ret::spontaneous_panic};
use crate::{
addressing_modes::{Arguments, Destination, Register1, Register2, Source},
heap::Heaps,
Expand All @@ -35,7 +35,7 @@ fn precompile_call<T: Tracer, W>(
// This is safe because system contracts are trusted
let aux_data = PrecompileAuxData::from_u256(Register2::get(args, &mut vm.state));
let Ok(()) = vm.state.use_gas(aux_data.extra_ergs_cost) else {
vm.state.current_frame.pc = &*vm.panic;
vm.state.current_frame.pc = spontaneous_panic();
return;
};

Expand Down
13 changes: 13 additions & 0 deletions crates/vm2/src/instruction_handlers/ret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,26 @@ fn invalid<T: Tracer, W>(
}

trait GenericStatics<T, W> {
const PANIC: Instruction<T, W>;
const INVALID: Instruction<T, W>;
}

impl<T: Tracer, W> GenericStatics<T, W> for () {
const PANIC: Instruction<T, W> = Instruction {
handler: ret::<T, W, Panic, false>,
arguments: Arguments::new(Predicate::Always, RETURN_COST, ModeRequirements::none()),
};
const INVALID: Instruction<T, W> = Instruction::from_invalid();
}

// The following functions return references that live for 'static.
// They aren't marked as such because returning any lifetime is more ergonomic.

/// Point the program counter at this instruction when a panic occurs during the logic of and instruction.
pub(crate) fn spontaneous_panic<'a, T: Tracer, W>() -> &'a Instruction<T, W> {
&<()>::PANIC
}

/// Panics, burning all available gas.
pub(crate) fn invalid_instruction<'a, T: Tracer, W>() -> &'a Instruction<T, W> {
&<()>::INVALID
Expand Down
2 changes: 1 addition & 1 deletion crates/vm2/src/single_instruction_test/into_zk_evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn vm2_to_zk_evm<T: Tracer, W: World<T>>(
event_sink.start_frame(zk_evm::aux_structures::Timestamp(0));

VmState {
local_state: vm2_state_to_zk_evm_state(&vm.state, &*vm.panic),
local_state: vm2_state_to_zk_evm_state(&vm.state),
block_properties: BlockProperties {
default_aa_code_hash: U256::from_big_endian(&vm.settings.default_aa_code_hash),
evm_simulator_code_hash: U256::from_big_endian(&vm.settings.evm_interpreter_code_hash),
Expand Down
8 changes: 4 additions & 4 deletions crates/vm2/src/single_instruction_test/state_to_zk_evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ use zk_evm::{
vm_state::{execution_stack::CallStackEntry, Callstack, PrimitiveValue, VmLocalState},
};
use zkevm_opcode_defs::decoding::EncodingModeProduction;
use zksync_vm2_interface::Tracer;

use crate::{
callframe::{Callframe, NearCallFrame},
instruction_handlers::spontaneous_panic,
state::State,
Instruction,
};

pub(crate) fn vm2_state_to_zk_evm_state<T, W>(
pub(crate) fn vm2_state_to_zk_evm_state<T: Tracer, W>(
state: &State<T, W>,
panic: &Instruction<T, W>,
) -> VmLocalState<8, EncodingModeProduction> {
// zk_evm requires an unused bottom frame
let mut callframes: Vec<_> = iter::once(CallStackEntry::empty_context())
Expand Down Expand Up @@ -51,7 +51,7 @@ pub(crate) fn vm2_state_to_zk_evm_state<T, W>(
memory_page_counter: 3000,
absolute_execution_step: 0,
tx_number_in_block: state.transaction_number,
pending_exception: state.current_frame.pc == panic,
pending_exception: state.current_frame.pc == spontaneous_panic(),
previous_super_pc: 0, // Same as current pc so the instruction is read from previous_code_word
context_u128_register: state.context_u128,
callstack: Callstack {
Expand Down
8 changes: 2 additions & 6 deletions crates/vm2/src/single_instruction_test/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use zksync_vm2_interface::{HeapId, Tracer};

use super::{heap::Heaps, stack::StackPool};
use crate::{
addressing_modes::Arguments, callframe::Callframe, fat_pointer::FatPointer, state::State,
Instruction, ModeRequirements, Predicate, Settings, VirtualMachine, World, WorldDiff,
callframe::Callframe, fat_pointer::FatPointer, state::State, Settings, VirtualMachine, World,
WorldDiff,
};

impl<T: Tracer, W> VirtualMachine<T, W> {
Expand Down Expand Up @@ -79,10 +79,6 @@ impl<'a, T: Tracer, W: World<T>> Arbitrary<'a> for VirtualMachine<T, W> {
settings: u.arbitrary()?,
world_diff: WorldDiff::default(),
stack_pool: StackPool {},
panic: Box::new(Instruction::from_panic(
None,
Arguments::new(Predicate::Always, 5, ModeRequirements::none()),
)),
snapshot: None,
})
}
Expand Down
11 changes: 1 addition & 10 deletions crates/vm2/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ use primitive_types::H160;
use zksync_vm2_interface::{opcodes::TypeLevelCallingMode, CallingMode, HeapId, Tracer};

use crate::{
addressing_modes::Arguments,
callframe::{Callframe, FrameRemnant},
decommit::u256_into_address,
instruction::ExecutionStatus,
instruction_handlers::RETURN_COST,
stack::StackPool,
state::{State, StateSnapshot},
world_diff::{ExternalSnapshot, Snapshot, WorldDiff},
ExecutionEnd, Instruction, ModeRequirements, Predicate, Program, World,
ExecutionEnd, Program, World,
};

/// [`VirtualMachine`] settings.
Expand All @@ -33,9 +31,6 @@ pub struct VirtualMachine<T, W> {
pub(crate) state: State<T, W>,
pub(crate) settings: Settings,
pub(crate) stack_pool: StackPool,
/// Instruction that is jumped to when things go wrong while executing another.
/// Boxed, so the pointer isn't invalidated by moves.
pub(crate) panic: Box<Instruction<T, W>>,
pub(crate) snapshot: Option<VmSnapshot>,
}

Expand Down Expand Up @@ -66,10 +61,6 @@ impl<T: Tracer, W: World<T>> VirtualMachine<T, W> {
),
settings,
stack_pool,
panic: Box::new(Instruction::from_panic(
None,
Arguments::new(Predicate::Always, RETURN_COST, ModeRequirements::none()),
)),
snapshot: None,
}
}
Expand Down

0 comments on commit 6a11381

Please sign in to comment.