use std::sync::{Arc, RwLock};
use zksync_multivm::{
interface::tracer::VmExecutionStopReason, tracers::dynamic::vm_1_5_0::DynTracer,
IntoOldVmTracer,
};
use zksync_multivm::interface::storage::WriteStorage;
use zksync_multivm::tracers::old::OldTracers;
use zksync_multivm::vm_latest::{
constants::BOOTLOADER_HEAP_PAGE, BootloaderState, HistoryMode, SimpleMemory, VmTracer,
ZkSyncVmState,
};
use zksync_types::U256;
const DEBUG_START_SENTINEL: u64 = 1337;
const MAX_MEMORY_BYTES: usize = 63_800_000;
const MAX_TRANSACTIONS: usize = 10000;
const RESULTS_BYTES_OFFSET: usize = MAX_MEMORY_BYTES - MAX_TRANSACTIONS * 32;
const VM_HOOKS_PARAMS: usize = 3;
const VM_HOOKS_START: usize = RESULTS_BYTES_OFFSET - (VM_HOOKS_PARAMS + 1) * 32;
const DEBUG_SLOTS: usize = 32;
const DEBUG_START_BYTE: usize = VM_HOOKS_START - DEBUG_SLOTS * 32;
const DEBUG_START_SLOT: usize = DEBUG_START_BYTE / 32;
#[derive(Debug, Clone)]
pub struct BootloaderDebug {
pub total_gas_limit_from_user: U256,
pub reserved_gas: U256,
pub gas_per_pubdata: U256,
pub gas_limit_after_intrinsic: U256,
pub gas_after_validation: U256,
pub gas_spent_on_execution: U256,
pub gas_spent_on_bytecode_preparation: U256,
pub refund_computed: U256,
pub refund_by_operator: U256,
pub intrinsic_overhead: U256,
pub required_overhead: U256,
pub operator_overhead: U256,
pub overhead_for_length: U256,
pub overhead_for_slot: U256,
}
#[derive(Debug, Clone)]
pub struct BootloaderDebugTracer {
pub result: Arc<RwLock<Result<BootloaderDebug, String>>>,
}
impl BootloaderDebugTracer {
pub fn new(result: Arc<RwLock<Result<BootloaderDebug, String>>>) -> Self {
Self { result }
}
}
impl<S, H: HistoryMode> DynTracer<S, SimpleMemory<H>> for BootloaderDebugTracer {}
fn load_debug_slot<H: HistoryMode>(memory: &SimpleMemory<H>, slot: usize) -> U256 {
memory
.read_slot(BOOTLOADER_HEAP_PAGE as usize, DEBUG_START_SLOT + slot)
.value
}
impl<S: WriteStorage, H: HistoryMode> VmTracer<S, H> for BootloaderDebugTracer {
fn after_vm_execution(
&mut self,
state: &mut ZkSyncVmState<S, H>,
_bootloader_state: &BootloaderState,
_stop_reason: VmExecutionStopReason,
) {
*self.result.write().unwrap() = BootloaderDebug::load_from_memory(&state.memory);
}
}
impl BootloaderDebug {
pub fn load_from_memory<H: HistoryMode>(memory: &SimpleMemory<H>) -> Result<Self, String> {
if load_debug_slot(memory, 0) != U256::from(DEBUG_START_SENTINEL) {
Err(
"Debug slot has wrong value. Probably bootloader slot mapping has changed."
.to_owned(),
)
} else {
Ok(BootloaderDebug {
total_gas_limit_from_user: load_debug_slot(memory, 1),
reserved_gas: load_debug_slot(memory, 2),
gas_per_pubdata: load_debug_slot(memory, 3),
gas_limit_after_intrinsic: load_debug_slot(memory, 4),
gas_after_validation: load_debug_slot(memory, 5),
gas_spent_on_execution: load_debug_slot(memory, 6),
gas_spent_on_bytecode_preparation: load_debug_slot(memory, 7),
refund_computed: load_debug_slot(memory, 8),
refund_by_operator: load_debug_slot(memory, 9),
intrinsic_overhead: load_debug_slot(memory, 10),
operator_overhead: load_debug_slot(memory, 11),
required_overhead: load_debug_slot(memory, 12),
overhead_for_length: load_debug_slot(memory, 13),
overhead_for_slot: load_debug_slot(memory, 14),
})
}
}
}
impl<S, H: zksync_multivm::vm_1_4_1::HistoryMode>
zksync_multivm::tracers::dynamic::vm_1_4_1::DynTracer<
S,
zksync_multivm::vm_1_4_1::SimpleMemory<H>,
> for BootloaderDebugTracer
{
}
impl<S: WriteStorage, H: zksync_multivm::vm_1_4_1::HistoryMode>
zksync_multivm::vm_1_4_1::VmTracer<S, H> for BootloaderDebugTracer
{
fn after_vm_execution(
&mut self,
_state: &mut zksync_multivm::vm_1_4_1::ZkSyncVmState<S, H>,
_bootloader_state: &zksync_multivm::vm_1_4_1::BootloaderState,
_stop_reason: VmExecutionStopReason,
) {
todo!()
}
}
impl<S, H: zksync_multivm::vm_1_4_2::HistoryMode>
zksync_multivm::tracers::dynamic::vm_1_4_1::DynTracer<
S,
zksync_multivm::vm_1_4_2::SimpleMemory<H>,
> for BootloaderDebugTracer
{
}
impl<S: WriteStorage, H: zksync_multivm::vm_1_4_2::HistoryMode>
zksync_multivm::vm_1_4_2::VmTracer<S, H> for BootloaderDebugTracer
{
fn after_vm_execution(
&mut self,
_state: &mut zksync_multivm::vm_1_4_2::ZkSyncVmState<S, H>,
_bootloader_state: &zksync_multivm::vm_1_4_2::BootloaderState,
_stop_reason: VmExecutionStopReason,
) {
todo!()
}
}
impl<S: WriteStorage, H: zksync_multivm::vm_boojum_integration::HistoryMode>
zksync_multivm::tracers::dynamic::vm_1_4_0::DynTracer<
S,
zksync_multivm::vm_boojum_integration::SimpleMemory<H>,
> for BootloaderDebugTracer
{
}
impl<S: WriteStorage, H: zksync_multivm::vm_boojum_integration::HistoryMode>
zksync_multivm::vm_boojum_integration::VmTracer<S, H> for BootloaderDebugTracer
{
fn after_vm_execution(
&mut self,
_state: &mut zksync_multivm::vm_boojum_integration::ZkSyncVmState<S, H>,
_bootloader_state: &zksync_multivm::vm_boojum_integration::BootloaderState,
_stop_reason: VmExecutionStopReason,
) {
todo!()
}
}
impl<S: WriteStorage, H: zksync_multivm::vm_refunds_enhancement::HistoryMode>
zksync_multivm::tracers::dynamic::vm_1_3_3::DynTracer<
S,
zksync_multivm::vm_refunds_enhancement::SimpleMemory<H>,
> for BootloaderDebugTracer
{
}
impl<S: WriteStorage, H: zksync_multivm::vm_refunds_enhancement::HistoryMode>
zksync_multivm::vm_refunds_enhancement::VmTracer<S, H> for BootloaderDebugTracer
{
fn after_vm_execution(
&mut self,
_state: &mut zksync_multivm::vm_refunds_enhancement::ZkSyncVmState<S, H>,
_bootloader_state: &zksync_multivm::vm_refunds_enhancement::BootloaderState,
_stop_reason: VmExecutionStopReason,
) {
todo!()
}
}
impl<S: WriteStorage, H: zksync_multivm::vm_virtual_blocks::HistoryMode>
zksync_multivm::tracers::dynamic::vm_1_3_3::DynTracer<
S,
zksync_multivm::vm_virtual_blocks::SimpleMemory<H>,
> for BootloaderDebugTracer
{
}
impl<H: zksync_multivm::vm_virtual_blocks::HistoryMode>
zksync_multivm::vm_virtual_blocks::ExecutionEndTracer<H> for BootloaderDebugTracer
{
}
impl<S: WriteStorage, H: zksync_multivm::vm_virtual_blocks::HistoryMode>
zksync_multivm::vm_virtual_blocks::ExecutionProcessing<S, H> for BootloaderDebugTracer
{
}
impl<S: WriteStorage, H: zksync_multivm::vm_virtual_blocks::HistoryMode>
zksync_multivm::vm_virtual_blocks::VmTracer<S, H> for BootloaderDebugTracer
{
}
impl IntoOldVmTracer for BootloaderDebugTracer {
fn old_tracer(&self) -> OldTracers {
todo!()
}
}