1use std::sync::{Arc, RwLock};
2use zksync_multivm::{
3 interface::tracer::VmExecutionStopReason, tracers::dynamic::vm_1_5_2::DynTracer,
4 IntoOldVmTracer,
5};
6
7use zksync_multivm::interface::storage::WriteStorage;
8use zksync_multivm::tracers::old::OldTracers;
9use zksync_multivm::vm_latest::{
10 constants::BOOTLOADER_HEAP_PAGE, BootloaderState, HistoryMode, SimpleMemory, VmTracer,
11 ZkSyncVmState,
12};
13use zksync_types::U256;
14
15const DEBUG_START_SENTINEL: u64 = 1337;
18
19const MAX_MEMORY_BYTES: usize = 63_800_000;
21
22const MAX_TRANSACTIONS: usize = 10000;
24
25const RESULTS_BYTES_OFFSET: usize = MAX_MEMORY_BYTES - MAX_TRANSACTIONS * 32;
26
27const VM_HOOKS_PARAMS: usize = 3;
28
29const VM_HOOKS_START: usize = RESULTS_BYTES_OFFSET - (VM_HOOKS_PARAMS + 1) * 32;
30
31const DEBUG_SLOTS: usize = 32;
32const DEBUG_START_BYTE: usize = VM_HOOKS_START - DEBUG_SLOTS * 32;
33
34const DEBUG_START_SLOT: usize = DEBUG_START_BYTE / 32;
35
36#[derive(Debug, Clone)]
40pub struct BootloaderDebug {
41 pub total_gas_limit_from_user: U256,
43 pub reserved_gas: U256,
45 pub gas_per_pubdata: U256,
47 pub gas_limit_after_intrinsic: U256,
49 pub gas_after_validation: U256,
51 pub gas_spent_on_execution: U256,
53
54 pub gas_spent_on_bytecode_preparation: U256,
56
57 pub refund_computed: U256,
59 pub refund_by_operator: U256,
61
62 pub intrinsic_overhead: U256,
64
65 pub required_overhead: U256,
69
70 pub operator_overhead: U256,
72
73 pub overhead_for_length: U256,
75 pub overhead_for_slot: U256,
77}
78
79#[derive(Debug, Clone)]
82pub struct BootloaderDebugTracer {
83 pub result: Arc<RwLock<Result<BootloaderDebug, String>>>,
84}
85
86impl BootloaderDebugTracer {
87 pub fn new(result: Arc<RwLock<Result<BootloaderDebug, String>>>) -> Self {
88 Self { result }
89 }
90}
91
92impl<S, H: HistoryMode> DynTracer<S, SimpleMemory<H>> for BootloaderDebugTracer {}
93
94fn load_debug_slot<H: HistoryMode>(memory: &SimpleMemory<H>, slot: usize) -> U256 {
95 memory
96 .read_slot(BOOTLOADER_HEAP_PAGE as usize, DEBUG_START_SLOT + slot)
97 .value
98}
99
100impl<S: WriteStorage, H: HistoryMode> VmTracer<S, H> for BootloaderDebugTracer {
101 fn after_vm_execution(
102 &mut self,
103 state: &mut ZkSyncVmState<S, H>,
104 _bootloader_state: &BootloaderState,
105 _stop_reason: VmExecutionStopReason,
106 ) {
107 *self.result.write().unwrap() = BootloaderDebug::load_from_memory(&state.memory);
108 }
109}
110
111impl BootloaderDebug {
112 pub fn load_from_memory<H: HistoryMode>(memory: &SimpleMemory<H>) -> Result<Self, String> {
113 if load_debug_slot(memory, 0) != U256::from(DEBUG_START_SENTINEL) {
114 Err(
115 "Debug slot has wrong value. Probably bootloader slot mapping has changed."
116 .to_owned(),
117 )
118 } else {
119 Ok(BootloaderDebug {
120 total_gas_limit_from_user: load_debug_slot(memory, 1),
121 reserved_gas: load_debug_slot(memory, 2),
122 gas_per_pubdata: load_debug_slot(memory, 3),
123 gas_limit_after_intrinsic: load_debug_slot(memory, 4),
124 gas_after_validation: load_debug_slot(memory, 5),
125 gas_spent_on_execution: load_debug_slot(memory, 6),
126 gas_spent_on_bytecode_preparation: load_debug_slot(memory, 7),
127 refund_computed: load_debug_slot(memory, 8),
128 refund_by_operator: load_debug_slot(memory, 9),
129 intrinsic_overhead: load_debug_slot(memory, 10),
130 operator_overhead: load_debug_slot(memory, 11),
131 required_overhead: load_debug_slot(memory, 12),
132 overhead_for_length: load_debug_slot(memory, 13),
133 overhead_for_slot: load_debug_slot(memory, 14),
134 })
135 }
136 }
137}
138
139impl<S, H: zksync_multivm::vm_1_4_1::HistoryMode>
146 zksync_multivm::tracers::dynamic::vm_1_4_1::DynTracer<
147 S,
148 zksync_multivm::vm_1_4_1::SimpleMemory<H>,
149 > for BootloaderDebugTracer
150{
151}
152
153impl<S: WriteStorage, H: zksync_multivm::vm_1_4_1::HistoryMode>
154 zksync_multivm::vm_1_4_1::VmTracer<S, H> for BootloaderDebugTracer
155{
156 fn after_vm_execution(
157 &mut self,
158 _state: &mut zksync_multivm::vm_1_4_1::ZkSyncVmState<S, H>,
159 _bootloader_state: &zksync_multivm::vm_1_4_1::BootloaderState,
160 _stop_reason: VmExecutionStopReason,
161 ) {
162 todo!()
163 }
164}
165
166impl<S, H: zksync_multivm::vm_1_4_2::HistoryMode>
167 zksync_multivm::tracers::dynamic::vm_1_4_1::DynTracer<
168 S,
169 zksync_multivm::vm_1_4_2::SimpleMemory<H>,
170 > for BootloaderDebugTracer
171{
172}
173
174impl<S: WriteStorage, H: zksync_multivm::vm_1_4_2::HistoryMode>
175 zksync_multivm::vm_1_4_2::VmTracer<S, H> for BootloaderDebugTracer
176{
177 fn after_vm_execution(
178 &mut self,
179 _state: &mut zksync_multivm::vm_1_4_2::ZkSyncVmState<S, H>,
180 _bootloader_state: &zksync_multivm::vm_1_4_2::BootloaderState,
181 _stop_reason: VmExecutionStopReason,
182 ) {
183 todo!()
184 }
185}
186
187impl<S: WriteStorage, H: zksync_multivm::vm_boojum_integration::HistoryMode>
188 zksync_multivm::tracers::dynamic::vm_1_4_0::DynTracer<
189 S,
190 zksync_multivm::vm_boojum_integration::SimpleMemory<H>,
191 > for BootloaderDebugTracer
192{
193}
194
195impl<S: WriteStorage, H: zksync_multivm::vm_boojum_integration::HistoryMode>
196 zksync_multivm::vm_boojum_integration::VmTracer<S, H> for BootloaderDebugTracer
197{
198 fn after_vm_execution(
199 &mut self,
200 _state: &mut zksync_multivm::vm_boojum_integration::ZkSyncVmState<S, H>,
201 _bootloader_state: &zksync_multivm::vm_boojum_integration::BootloaderState,
202 _stop_reason: VmExecutionStopReason,
203 ) {
204 todo!()
205 }
206}
207
208impl<S: WriteStorage, H: zksync_multivm::vm_refunds_enhancement::HistoryMode>
209 zksync_multivm::tracers::dynamic::vm_1_3_3::DynTracer<
210 S,
211 zksync_multivm::vm_refunds_enhancement::SimpleMemory<H>,
212 > for BootloaderDebugTracer
213{
214}
215
216impl<S: WriteStorage, H: zksync_multivm::vm_refunds_enhancement::HistoryMode>
217 zksync_multivm::vm_refunds_enhancement::VmTracer<S, H> for BootloaderDebugTracer
218{
219 fn after_vm_execution(
220 &mut self,
221 _state: &mut zksync_multivm::vm_refunds_enhancement::ZkSyncVmState<S, H>,
222 _bootloader_state: &zksync_multivm::vm_refunds_enhancement::BootloaderState,
223 _stop_reason: VmExecutionStopReason,
224 ) {
225 todo!()
226 }
227}
228
229impl<S: WriteStorage, H: zksync_multivm::vm_virtual_blocks::HistoryMode>
230 zksync_multivm::tracers::dynamic::vm_1_3_3::DynTracer<
231 S,
232 zksync_multivm::vm_virtual_blocks::SimpleMemory<H>,
233 > for BootloaderDebugTracer
234{
235}
236
237impl<H: zksync_multivm::vm_virtual_blocks::HistoryMode>
238 zksync_multivm::vm_virtual_blocks::ExecutionEndTracer<H> for BootloaderDebugTracer
239{
240}
241
242impl<S: WriteStorage, H: zksync_multivm::vm_virtual_blocks::HistoryMode>
243 zksync_multivm::vm_virtual_blocks::ExecutionProcessing<S, H> for BootloaderDebugTracer
244{
245}
246
247impl<S: WriteStorage, H: zksync_multivm::vm_virtual_blocks::HistoryMode>
248 zksync_multivm::vm_virtual_blocks::VmTracer<S, H> for BootloaderDebugTracer
249{
250}
251
252impl IntoOldVmTracer for BootloaderDebugTracer {
253 fn old_tracer(&self) -> OldTracers {
254 todo!()
255 }
256}