use zk_evm_abstractions::aux::PubdataCost;
use crate::zkevm_opcode_defs::NearCallABI;
use super::*;
impl<const N: usize, E: VmEncodingMode<N>> DecodedOpcode<N, E> {
pub fn near_call_opcode_apply<
S: zk_evm_abstractions::vm::Storage,
M: zk_evm_abstractions::vm::Memory,
EV: zk_evm_abstractions::vm::EventSink,
PP: zk_evm_abstractions::vm::PrecompilesProcessor,
DP: zk_evm_abstractions::vm::DecommittmentProcessor,
WT: crate::witness_trace::VmWitnessTracer<N, E>,
>(
&self,
vm_state: &mut VmState<S, M, EV, PP, DP, WT, N, E>,
prestate: PreState<N, E>,
) {
let PreState { src0, new_pc, .. } = prestate;
let PrimitiveValue {
value: src0,
is_pointer: _,
} = src0;
vm_state.reset_flags();
let dst = self.imm_0;
let exception_handler_location = self.imm_1;
let mut near_call_abi = NearCallABI::from_u256(src0);
near_call_abi.ergs_passed = if let Some(non_overflowing) =
near_call_abi.ergs_passed.checked_mul(
zkevm_opcode_defs::system_params::INTERNAL_ERGS_TO_VISIBLE_ERGS_CONVERSION_CONSTANT,
) {
non_overflowing
} else {
u32::MAX
};
let pass_all_ergs = near_call_abi.ergs_passed == 0;
let current_callstack_entry = vm_state.local_state.callstack.get_current_stack();
let remaining_ergs = current_callstack_entry.ergs_remaining;
let (passed_ergs, remaining_ergs_for_this_context) = if pass_all_ergs {
(remaining_ergs, 0u32)
} else {
let (remaining_for_this_context, uf) =
remaining_ergs.overflowing_sub(near_call_abi.ergs_passed);
if uf {
(remaining_ergs, 0u32)
} else {
(near_call_abi.ergs_passed, remaining_for_this_context)
}
};
vm_state
.local_state
.callstack
.get_current_stack_mut()
.ergs_remaining = remaining_ergs_for_this_context;
vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc;
let current_stack = vm_state.local_state.callstack.get_current_stack();
let mut new_stack = *current_stack;
new_stack.pc = dst;
new_stack.exception_handler_location = exception_handler_location;
new_stack.ergs_remaining = passed_ergs;
new_stack.is_local_frame = true;
new_stack.total_pubdata_spent = PubdataCost(0i32);
vm_state.start_frame(vm_state.local_state.monotonic_cycle_counter, new_stack);
}
}