zksync_vm2/instruction_handlers/
decommit.rs1use primitive_types::U256;
2use zkevm_opcode_defs::{BlobSha256Format, ContractCodeSha256Format, VersionedHashLen32};
3use zksync_vm2_interface::{opcodes, Tracer};
4
5use super::common::boilerplate_ext;
6use crate::{
7 addressing_modes::{Arguments, Destination, Register1, Register2, Source},
8 decommit::materialize_decommit_page,
9 fat_pointer::FatPointer,
10 instruction::ExecutionStatus,
11 DecommitOpcodeOutcome, Instruction, VirtualMachine, World,
12};
13
14fn decommit<T: Tracer, W: World<T>>(
15 vm: &mut VirtualMachine<T, W>,
16 world: &mut W,
17 tracer: &mut T,
18) -> ExecutionStatus {
19 boilerplate_ext::<opcodes::Decommit, _, _>(vm, world, tracer, |vm, args, world, tracer| {
20 let code_hash = Register1::get(args, &mut vm.state);
21 let extra_cost = Register2::get(args, &mut vm.state).low_u32();
22
23 let mut buffer = [0u8; 32];
24 code_hash.to_big_endian(&mut buffer);
25
26 let preimage_len_in_bytes =
27 zkevm_opcode_defs::system_params::NEW_KERNEL_FRAME_MEMORY_STIPEND;
28
29 if vm.state.use_gas(extra_cost).is_err()
30 || (!ContractCodeSha256Format::is_valid(&buffer)
31 && !BlobSha256Format::is_valid(&buffer))
32 {
33 Register1::set(args, &mut vm.state, U256::zero());
34 return;
35 }
36
37 let heap = match vm.world_diff.decommit_opcode(world, tracer, code_hash) {
38 DecommitOpcodeOutcome::Fresh(code) => {
39 materialize_decommit_page(vm, code_hash, &code, vm.state.current_frame.heap)
40 }
41 DecommitOpcodeOutcome::Cached(heap) => {
42 vm.state.current_frame.gas += extra_cost;
44 heap
45 }
46 };
47
48 let value = FatPointer {
49 offset: 0,
50 memory_page: heap,
51 start: 0,
52 length: preimage_len_in_bytes,
53 };
54 let value = value.into_u256();
55 Register1::set_fat_ptr(args, &mut vm.state, value);
56 })
57}
58
59impl<T: Tracer, W: World<T>> Instruction<T, W> {
60 pub fn from_decommit(
62 abi: Register1,
63 burn: Register2,
64 out: Register1,
65 arguments: Arguments,
66 ) -> Self {
67 Self {
68 arguments: arguments
69 .write_source(&abi)
70 .write_source(&burn)
71 .write_destination(&out),
72 handler: decommit,
73 }
74 }
75}