From 23b5343636226f340a1c9bb61de25023bb5757a9 Mon Sep 17 00:00:00 2001 From: Joonatan Saarhelo Date: Fri, 20 Sep 2024 12:34:09 +0200 Subject: [PATCH] fix vm_latest calltracer bug --- .../multivm/src/tracers/call_tracer/mod.rs | 3 +++ .../src/tracers/call_tracer/vm_latest/mod.rs | 6 ++++-- core/lib/multivm/src/utils/mod.rs | 2 ++ core/lib/multivm/src/utils/testonly.rs | 21 +++++++++++++++++++ .../src/versions/vm_fast/tests/call_tracer.rs | 6 ++---- .../versions/vm_latest/tests/call_tracer.rs | 6 ++---- 6 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 core/lib/multivm/src/utils/testonly.rs diff --git a/core/lib/multivm/src/tracers/call_tracer/mod.rs b/core/lib/multivm/src/tracers/call_tracer/mod.rs index 44f27487603..20beb10642d 100644 --- a/core/lib/multivm/src/tracers/call_tracer/mod.rs +++ b/core/lib/multivm/src/tracers/call_tracer/mod.rs @@ -17,6 +17,8 @@ pub mod vm_virtual_blocks; #[derive(Debug, Clone)] pub struct CallTracer { stack: Vec, + finished_calls: Vec, + result: Arc>>, max_stack_depth: usize, @@ -41,6 +43,7 @@ impl CallTracer { pub fn new(result: Arc>>) -> Self { Self { stack: vec![], + finished_calls: vec![], result, max_stack_depth: 0, max_near_calls: 0, diff --git a/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs b/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs index ed18a3eca47..c7266b41e9d 100644 --- a/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs +++ b/core/lib/multivm/src/tracers/call_tracer/vm_latest/mod.rs @@ -67,7 +67,9 @@ impl VmTracer for CallTracer { _bootloader_state: &BootloaderState, _stop_reason: VmExecutionStopReason, ) { - self.store_result() + let result = std::mem::take(&mut self.finished_calls); + let cell = self.result.as_ref(); + cell.set(result).unwrap(); } } @@ -199,7 +201,7 @@ impl CallTracer { if let Some(parent_call) = self.stack.last_mut() { parent_call.farcall.calls.push(current_call.farcall); } else { - self.push_call_and_update_stats(current_call.farcall, current_call.near_calls_after); + self.finished_calls.push(current_call.farcall); } } } diff --git a/core/lib/multivm/src/utils/mod.rs b/core/lib/multivm/src/utils/mod.rs index 5d8fba7a2ac..76571bb5119 100644 --- a/core/lib/multivm/src/utils/mod.rs +++ b/core/lib/multivm/src/utils/mod.rs @@ -10,6 +10,8 @@ use crate::interface::L1BatchEnv; pub(crate) mod bytecode; mod deduplicator; pub(crate) mod events; +#[cfg(test)] +pub(crate) mod testonly; /// Calculates the base fee and gas per pubdata for the given L1 gas price. pub fn derive_base_fee_and_gas_per_pubdata( diff --git a/core/lib/multivm/src/utils/testonly.rs b/core/lib/multivm/src/utils/testonly.rs new file mode 100644 index 00000000000..34569192730 --- /dev/null +++ b/core/lib/multivm/src/utils/testonly.rs @@ -0,0 +1,21 @@ +use zksync_types::zk_evm_types::FarCallOpcode; +use zksync_vm_interface::{Call, CallType}; + +pub(crate) fn check_call_tracer_test_result(call_tracer_result: &[Call]) { + assert!(call_tracer_result.len() > 10); + + for call in call_tracer_result { + check_call(call); + } +} + +fn check_call(call: &Call) { + assert!(call.gas_used > call.calls.iter().map(|call| call.gas_used).sum::()); + + for subcall in &call.calls { + if subcall.r#type != CallType::Call(FarCallOpcode::Mimic) { + assert_eq!(call.to, subcall.from); + } + check_call(subcall); + } +} diff --git a/core/lib/multivm/src/versions/vm_fast/tests/call_tracer.rs b/core/lib/multivm/src/versions/vm_fast/tests/call_tracer.rs index 9f37ac1fe11..15d007b4e2c 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/call_tracer.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/call_tracer.rs @@ -2,6 +2,7 @@ use zksync_types::{Address, Execute}; use crate::{ interface::{TxExecutionMode, VmExecutionMode, VmInterface}, + utils::testonly::check_call_tracer_test_result, versions::testonly::ContractToDeploy, vm_fast::{ call_tracer::CallTracer, @@ -79,9 +80,6 @@ fn test_basic_behavior() { let call_tracer_result = call_tracer.result(); - assert_eq!(call_tracer_result.len(), 1); - // Expect that there are a plenty of subcalls underneath. - let subcall = &call_tracer_result[0].calls; - assert!(subcall.len() > 10); + check_call_tracer_test_result(&call_tracer_result); assert!(!res.result.is_failed()); } diff --git a/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs index e7f26b7faf8..581b0dcf032 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/call_tracer.rs @@ -6,6 +6,7 @@ use zksync_types::{Address, Execute}; use crate::{ interface::{TxExecutionMode, VmExecutionMode, VmInterface}, tracers::CallTracer, + utils::testonly::check_call_tracer_test_result, vm_latest::{ constants::BATCH_COMPUTATIONAL_GAS_LIMIT, tests::{ @@ -88,9 +89,6 @@ fn test_basic_behavior() { let call_tracer_result = result.get().unwrap(); - assert_eq!(call_tracer_result.len(), 1); - // Expect that there are a plenty of subcalls underneath. - let subcall = &call_tracer_result[0].calls; - assert!(subcall.len() > 10); + check_call_tracer_test_result(call_tracer_result); assert!(!res.result.is_failed()); }