From bc0d7d5935c8f5409a8e53f1c04c5141409aef31 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Wed, 4 Sep 2024 18:23:39 +0300 Subject: [PATCH] perf(vm): Fix VM performance regression on CI loadtest (#2782) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Fixes VM performance regression on CI loadtest introduced in https://github.com/matter-labs/zksync-era/pull/2760. ## Why ❔ Changes in the VM interface made the VM eagerly clone compressed bytecodes if compression hasn't failed. Compressed bytecodes aren't used during sandboxed VM execution in the API server (the sandbox only checks that compression is successful).For new VMs, bytecodes can be borrowed from the VM state, which is what this PR does using `Cow`. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted via `zk fmt` and `zk lint`. --- .github/workflows/ci-core-reusable.yml | 9 ++++--- core/lib/multivm/src/versions/shadow.rs | 2 +- core/lib/multivm/src/versions/vm_1_3_2/vm.rs | 4 +-- .../vm_1_4_1/bootloader_state/state.rs | 6 ++--- core/lib/multivm/src/versions/vm_1_4_1/vm.rs | 7 +++-- .../vm_1_4_2/bootloader_state/state.rs | 6 ++--- core/lib/multivm/src/versions/vm_1_4_2/vm.rs | 7 +++-- .../bootloader_state/state.rs | 6 ++--- .../src/versions/vm_boojum_integration/vm.rs | 7 +++-- .../vm_fast/bootloader_state/state.rs | 6 ++--- core/lib/multivm/src/versions/vm_fast/vm.rs | 12 ++++----- .../vm_latest/bootloader_state/state.rs | 6 ++--- core/lib/multivm/src/versions/vm_latest/vm.rs | 7 +++-- core/lib/multivm/src/versions/vm_m5/vm.rs | 4 +-- core/lib/multivm/src/versions/vm_m6/vm.rs | 4 +-- .../bootloader_state/state.rs | 6 ++--- .../src/versions/vm_refunds_enhancement/vm.rs | 7 +++-- .../bootloader_state/state.rs | 6 ++--- .../src/versions/vm_virtual_blocks/vm.rs | 7 +++-- core/lib/multivm/src/vm_instance.rs | 2 +- core/lib/vm_executor/src/batch/factory.rs | 9 ++++--- .../src/types/errors/bytecode_compression.rs | 5 +++- core/lib/vm_interface/src/vm.rs | 4 +-- core/lib/web3_decl/src/client/mod.rs | 26 ++++++++++++++----- core/tests/loadnext/src/account/mod.rs | 11 +++++--- core/tests/loadnext/src/account_pool.rs | 2 ++ core/tests/loadnext/src/constants.rs | 4 +-- core/tests/loadnext/src/executor.rs | 6 ++--- core/tests/loadnext/src/sdk/ethereum/mod.rs | 1 + core/tests/loadnext/src/sdk/wallet.rs | 1 + 30 files changed, 118 insertions(+), 72 deletions(-) diff --git a/.github/workflows/ci-core-reusable.yml b/.github/workflows/ci-core-reusable.yml index c6e3dc31d65e..53bd1ab7a518 100644 --- a/.github/workflows/ci-core-reusable.yml +++ b/.github/workflows/ci-core-reusable.yml @@ -87,8 +87,10 @@ jobs: - name: Loadtest configuration run: | - echo EXPECTED_TX_COUNT=${{ matrix.vm_mode == 'new' && 22000 || 16000 }} >> .env - echo ACCOUNTS_AMOUNT="150" >> .env + echo EXPECTED_TX_COUNT=${{ matrix.vm_mode == 'new' && 21000 || 16000 }} >> .env + echo ACCOUNTS_AMOUNT="100" >> .env + echo MAX_INFLIGHT_TXS="10" >> .env + echo SYNC_API_REQUESTS_LIMIT="15" >> .env echo FAIL_FAST=true >> .env echo IN_DOCKER=1 >> .env echo DATABASE_MERKLE_TREE_MODE=lightweight >> .env @@ -112,7 +114,8 @@ jobs: - name: Run server run: | EXPERIMENTAL_VM_STATE_KEEPER_FAST_VM_MODE=${{ matrix.vm_mode }} \ - PASSED_ENV_VARS="EXPERIMENTAL_VM_STATE_KEEPER_FAST_VM_MODE" \ + CHAIN_MEMPOOL_DELAY_INTERVAL=50 \ + PASSED_ENV_VARS="EXPERIMENTAL_VM_STATE_KEEPER_FAST_VM_MODE,CHAIN_MEMPOOL_DELAY_INTERVAL" \ ci_run zk server --uring --components api,tree,eth,state_keeper,housekeeper,commitment_generator,vm_runner_protective_reads &>server.log & ci_run sleep 60 diff --git a/core/lib/multivm/src/versions/shadow.rs b/core/lib/multivm/src/versions/shadow.rs index 32a4463c425d..871258f43b85 100644 --- a/core/lib/multivm/src/versions/shadow.rs +++ b/core/lib/multivm/src/versions/shadow.rs @@ -77,7 +77,7 @@ where tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { let tx_hash = tx.hash(); let main_result = self.main.inspect_transaction_with_bytecode_compression( tracer, diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs index eb1ae45542db..8068e4847b83 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs @@ -83,7 +83,7 @@ impl VmInterface for Vm { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { if let Some(storage_invocations) = tracer.storage_invocations { self.vm .execution_mode @@ -156,7 +156,7 @@ impl VmInterface for Vm { result, ) } else { - (Ok(compressed_bytecodes), result) + (Ok(compressed_bytecodes.into()), result) } } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/state.rs index 22d7b2814cf6..241054ae0345 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/state.rs @@ -191,11 +191,11 @@ impl BootloaderState { l2_block.first_tx_index + l2_block.txs.len() } - pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> Vec { + pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> &[CompressedBytecodeInfo] { if let Some(tx) = self.last_l2_block().txs.last() { - tx.compressed_bytecodes.clone() + &tx.compressed_bytecodes } else { - vec![] + &[] } } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/vm.rs b/core/lib/multivm/src/versions/vm_1_4_1/vm.rs index 8e63afd8e1ca..2c1a4ba5e36b 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/vm.rs @@ -105,7 +105,7 @@ impl VmInterface for Vm { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx, None); if self.has_unpublished_bytecodes() { @@ -115,7 +115,10 @@ impl VmInterface for Vm { ) } else { ( - Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + Ok(self + .bootloader_state + .get_last_tx_compressed_bytecodes() + .into()), result, ) } diff --git a/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/state.rs index e692c8a2640d..c0d94bd685c4 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/state.rs @@ -191,11 +191,11 @@ impl BootloaderState { l2_block.first_tx_index + l2_block.txs.len() } - pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> Vec { + pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> &[CompressedBytecodeInfo] { if let Some(tx) = self.last_l2_block().txs.last() { - tx.compressed_bytecodes.clone() + &tx.compressed_bytecodes } else { - vec![] + &[] } } diff --git a/core/lib/multivm/src/versions/vm_1_4_2/vm.rs b/core/lib/multivm/src/versions/vm_1_4_2/vm.rs index e7a1f69fa424..71633dd3fca3 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/vm.rs @@ -105,7 +105,7 @@ impl VmInterface for Vm { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx, None); if self.has_unpublished_bytecodes() { @@ -115,7 +115,10 @@ impl VmInterface for Vm { ) } else { ( - Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + Ok(self + .bootloader_state + .get_last_tx_compressed_bytecodes() + .into()), result, ) } diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/state.rs index 8a605978a1ed..830fe482320b 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/state.rs @@ -191,11 +191,11 @@ impl BootloaderState { l2_block.first_tx_index + l2_block.txs.len() } - pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> Vec { + pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> &[CompressedBytecodeInfo] { if let Some(tx) = self.last_l2_block().txs.last() { - tx.compressed_bytecodes.clone() + &tx.compressed_bytecodes } else { - vec![] + &[] } } diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs b/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs index 4b6b6931dd22..c7b4a5537acb 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs @@ -106,7 +106,7 @@ impl VmInterface for Vm { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx); if self.has_unpublished_bytecodes() { @@ -116,7 +116,10 @@ impl VmInterface for Vm { ) } else { ( - Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + Ok(self + .bootloader_state + .get_last_tx_compressed_bytecodes() + .into()), result, ) } diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs index ce37636d2cda..15b4daf02a77 100644 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_fast/bootloader_state/state.rs @@ -189,11 +189,11 @@ impl BootloaderState { l2_block.first_tx_index + l2_block.txs.len() } - pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> Vec { + pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> &[CompressedBytecodeInfo] { if let Some(tx) = self.last_l2_block().txs.last() { - tx.compressed_bytecodes.clone() + &tx.compressed_bytecodes } else { - vec![] + &[] } } diff --git a/core/lib/multivm/src/versions/vm_fast/vm.rs b/core/lib/multivm/src/versions/vm_fast/vm.rs index 4bb570c0275a..d8816cfaf2a6 100644 --- a/core/lib/multivm/src/versions/vm_fast/vm.rs +++ b/core/lib/multivm/src/versions/vm_fast/vm.rs @@ -31,7 +31,7 @@ use super::{ use crate::{ glue::GlueInto, interface::{ - storage::ReadStorage, BytecodeCompressionError, CompressedBytecodeInfo, + storage::ReadStorage, BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState, ExecutionResult, FinishedL1Batch, Halt, L1BatchEnv, L2BlockEnv, Refunds, SystemEnv, TxRevertReason, VmEvent, VmExecutionLogs, VmExecutionMode, VmExecutionResultAndLogs, VmExecutionStatistics, VmInterface, VmInterfaceHistoryEnabled, @@ -585,17 +585,17 @@ impl VmInterface for Vm { (): Self::TracerDispatcher, tx: zksync_types::Transaction, with_compression: bool, - ) -> ( - Result, BytecodeCompressionError>, - VmExecutionResultAndLogs, - ) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_inner(tx, 0, with_compression); let result = self.inspect((), VmExecutionMode::OneTx); let compression_result = if self.has_unpublished_bytecodes() { Err(BytecodeCompressionError::BytecodeCompressionFailed) } else { - Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()) + Ok(self + .bootloader_state + .get_last_tx_compressed_bytecodes() + .into()) }; (compression_result, result) } diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs index f15199a74f84..4ba27b14bad6 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader_state/state.rs @@ -191,11 +191,11 @@ impl BootloaderState { l2_block.first_tx_index + l2_block.txs.len() } - pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> Vec { + pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> &[CompressedBytecodeInfo] { if let Some(tx) = self.last_l2_block().txs.last() { - tx.compressed_bytecodes.clone() + &tx.compressed_bytecodes } else { - vec![] + &[] } } diff --git a/core/lib/multivm/src/versions/vm_latest/vm.rs b/core/lib/multivm/src/versions/vm_latest/vm.rs index c0c13669c2ef..a445a1d51402 100644 --- a/core/lib/multivm/src/versions/vm_latest/vm.rs +++ b/core/lib/multivm/src/versions/vm_latest/vm.rs @@ -141,7 +141,7 @@ impl VmInterface for Vm { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx, None); if self.has_unpublished_bytecodes() { @@ -151,7 +151,10 @@ impl VmInterface for Vm { ) } else { ( - Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + Ok(self + .bootloader_state + .get_last_tx_compressed_bytecodes() + .into()), result, ) } diff --git a/core/lib/multivm/src/versions/vm_m5/vm.rs b/core/lib/multivm/src/versions/vm_m5/vm.rs index 4282f3f0cf4a..df4baccaf156 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm.rs @@ -93,14 +93,14 @@ impl VmInterface for Vm { _tracer: Self::TracerDispatcher, tx: Transaction, _with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { crate::vm_m5::vm_with_bootloader::push_transaction_to_bootloader_memory( &mut self.vm, &tx, self.system_env.execution_mode.glue_into(), ); // Bytecode compression isn't supported - (Ok(vec![]), self.inspect((), VmExecutionMode::OneTx)) + (Ok(vec![].into()), self.inspect((), VmExecutionMode::OneTx)) } fn record_vm_memory_metrics(&self) -> VmMemoryMetrics { diff --git a/core/lib/multivm/src/versions/vm_m6/vm.rs b/core/lib/multivm/src/versions/vm_m6/vm.rs index 520abd930555..7e19076a5202 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm.rs @@ -109,7 +109,7 @@ impl VmInterface for Vm { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { if let Some(storage_invocations) = tracer.storage_invocations { self.vm .execution_mode @@ -182,7 +182,7 @@ impl VmInterface for Vm { result, ) } else { - (Ok(compressed_bytecodes), result) + (Ok(compressed_bytecodes.into()), result) } } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/state.rs index 12aab3c7364c..b428851c9383 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/state.rs @@ -167,11 +167,11 @@ impl BootloaderState { l2_block.first_tx_index + l2_block.txs.len() } - pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> Vec { + pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> &[CompressedBytecodeInfo] { if let Some(tx) = self.last_l2_block().txs.last() { - tx.compressed_bytecodes.clone() + &tx.compressed_bytecodes } else { - vec![] + &[] } } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs index 2aa3ba05e662..119abf052b9f 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs @@ -99,7 +99,7 @@ impl VmInterface for Vm { dispatcher: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect(dispatcher, VmExecutionMode::OneTx); if self.has_unpublished_bytecodes() { @@ -109,7 +109,10 @@ impl VmInterface for Vm { ) } else { ( - Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + Ok(self + .bootloader_state + .get_last_tx_compressed_bytecodes() + .into()), result, ) } diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/state.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/state.rs index 562d74513710..7e9af0ed6b82 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/state.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/state.rs @@ -167,11 +167,11 @@ impl BootloaderState { l2_block.first_tx_index + l2_block.txs.len() } - pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> Vec { + pub(crate) fn get_last_tx_compressed_bytecodes(&self) -> &[CompressedBytecodeInfo] { if let Some(tx) = self.last_l2_block().txs.last() { - tx.compressed_bytecodes.clone() + &tx.compressed_bytecodes } else { - vec![] + &[] } } diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs index 6080df2bf2f1..0ecdd6797f4b 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs @@ -99,7 +99,7 @@ impl VmInterface for Vm { tracer: TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_with_compression(tx, with_compression); let result = self.inspect_inner(tracer, VmExecutionMode::OneTx); if self.has_unpublished_bytecodes() { @@ -109,7 +109,10 @@ impl VmInterface for Vm { ) } else { ( - Ok(self.bootloader_state.get_last_tx_compressed_bytecodes()), + Ok(self + .bootloader_state + .get_last_tx_compressed_bytecodes() + .into()), result, ) } diff --git a/core/lib/multivm/src/vm_instance.rs b/core/lib/multivm/src/vm_instance.rs index 0fc626d9ac48..cedb4bc8276d 100644 --- a/core/lib/multivm/src/vm_instance.rs +++ b/core/lib/multivm/src/vm_instance.rs @@ -74,7 +74,7 @@ impl VmInterface for VmInstance { dispatcher: Self::TracerDispatcher, tx: zksync_types::Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { dispatch_vm!(self.inspect_transaction_with_bytecode_compression( dispatcher.into(), tx, diff --git a/core/lib/vm_executor/src/batch/factory.rs b/core/lib/vm_executor/src/batch/factory.rs index 17b125b0c41a..d02014584467 100644 --- a/core/lib/vm_executor/src/batch/factory.rs +++ b/core/lib/vm_executor/src/batch/factory.rs @@ -250,7 +250,7 @@ impl CommandReceiver { .unwrap_or_default(); return Ok(BatchTransactionExecutionResult { tx_result: Box::new(tx_result), - compressed_bytecodes, + compressed_bytecodes: compressed_bytecodes.into_owned(), call_traces, }); } @@ -269,8 +269,9 @@ impl CommandReceiver { let (compression_result, tx_result) = vm.inspect_transaction_with_bytecode_compression(tracer.into(), tx.clone(), false); - let compressed_bytecodes = - compression_result.context("compression failed when it wasn't applied")?; + let compressed_bytecodes = compression_result + .context("compression failed when it wasn't applied")? + .into_owned(); // TODO implement tracer manager which will be responsible // for collecting result from all tracers and save it to the database @@ -308,7 +309,7 @@ impl CommandReceiver { .unwrap_or_default(); Ok(BatchTransactionExecutionResult { tx_result: Box::new(tx_result), - compressed_bytecodes, + compressed_bytecodes: compressed_bytecodes.into_owned(), call_traces, }) } else { diff --git a/core/lib/vm_interface/src/types/errors/bytecode_compression.rs b/core/lib/vm_interface/src/types/errors/bytecode_compression.rs index 1dd69dc7398d..c0c6e8737bbe 100644 --- a/core/lib/vm_interface/src/types/errors/bytecode_compression.rs +++ b/core/lib/vm_interface/src/types/errors/bytecode_compression.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use crate::CompressedBytecodeInfo; /// Errors related to bytecode compression. @@ -9,4 +11,5 @@ pub enum BytecodeCompressionError { } /// Result of compressing bytecodes used by a transaction. -pub type BytecodeCompressionResult = Result, BytecodeCompressionError>; +pub type BytecodeCompressionResult<'a> = + Result, BytecodeCompressionError>; diff --git a/core/lib/vm_interface/src/vm.rs b/core/lib/vm_interface/src/vm.rs index b6be2c7581f7..f70be52bd86a 100644 --- a/core/lib/vm_interface/src/vm.rs +++ b/core/lib/vm_interface/src/vm.rs @@ -41,7 +41,7 @@ pub trait VmInterface { tracer: Self::TracerDispatcher, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs); + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs); /// Record VM memory metrics. fn record_vm_memory_metrics(&self) -> VmMemoryMetrics; @@ -63,7 +63,7 @@ pub trait VmInterfaceExt: VmInterface { &mut self, tx: Transaction, with_compression: bool, - ) -> (BytecodeCompressionResult, VmExecutionResultAndLogs) { + ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.inspect_transaction_with_bytecode_compression( Self::TracerDispatcher::default(), tx, diff --git a/core/lib/web3_decl/src/client/mod.rs b/core/lib/web3_decl/src/client/mod.rs index a8246216eca3..7f0de4f3bca9 100644 --- a/core/lib/web3_decl/src/client/mod.rs +++ b/core/lib/web3_decl/src/client/mod.rs @@ -318,6 +318,7 @@ pub struct ClientBuilder { client: C, url: SensitiveUrl, rate_limit: (usize, Duration), + report_config: bool, network: Net, } @@ -328,6 +329,7 @@ impl fmt::Debug for ClientBuilder { .field("client", &any::type_name::()) .field("url", &self.url) .field("rate_limit", &self.rate_limit) + .field("report_config", &self.report_config) .field("network", &self.network) .finish_non_exhaustive() } @@ -340,6 +342,7 @@ impl ClientBuilder { client, url, rate_limit: (1, Duration::ZERO), + report_config: true, network: Net::default(), } } @@ -366,16 +369,25 @@ impl ClientBuilder { self } + /// Allows switching off config reporting for this client in logs and metrics. This is useful if a client is a short-living one + /// and is not injected as a dependency. + pub fn report_config(mut self, report: bool) -> Self { + self.report_config = report; + self + } + /// Builds the client. pub fn build(self) -> Client { - tracing::info!( - "Creating JSON-RPC client for network {:?} with inner client: {:?} and rate limit: {:?}", - self.network, - self.client, - self.rate_limit - ); let rate_limit = SharedRateLimit::new(self.rate_limit.0, self.rate_limit.1); - METRICS.observe_config(self.network.metric_label(), &rate_limit); + if self.report_config { + tracing::info!( + "Creating JSON-RPC client for network {:?} with inner client: {:?} and rate limit: {:?}", + self.network, + self.client, + self.rate_limit + ); + METRICS.observe_config(self.network.metric_label(), &rate_limit); + } Client { inner: self.client, diff --git a/core/tests/loadnext/src/account/mod.rs b/core/tests/loadnext/src/account/mod.rs index 5dcd5167165e..0f418bf12676 100644 --- a/core/tests/loadnext/src/account/mod.rs +++ b/core/tests/loadnext/src/account/mod.rs @@ -5,6 +5,7 @@ use std::{ }; use futures::{channel::mpsc, SinkExt}; +use rand::Rng; use tokio::sync::RwLock; use zksync_contracts::test_contracts::LoadnextContractExecutionParams; use zksync_types::{api::TransactionReceipt, Address, Nonce, H256, U256, U64}; @@ -75,6 +76,8 @@ pub struct AccountLifespan { inflight_txs: VecDeque, /// Current account nonce, it is None at the beginning and will be set after the first transaction current_nonce: Option, + /// Randomly assigned polling interval. + polling_interval: Duration, } impl AccountLifespan { @@ -82,11 +85,12 @@ impl AccountLifespan { config: &LoadtestConfig, contract_execution_params: LoadnextContractExecutionParams, addresses: AddressPool, - test_account: TestWallet, + mut test_account: TestWallet, report_sink: mpsc::Sender, main_l2_token: Address, paymaster_address: Address, ) -> Self { + let polling_interval = test_account.rng.gen_range(POLLING_INTERVAL); Self { wallet: test_account, config: config.clone(), @@ -99,6 +103,7 @@ impl AccountLifespan { report_sink, inflight_txs: Default::default(), current_nonce: None, + polling_interval, } } @@ -132,7 +137,7 @@ impl AccountLifespan { self.execute_command(deploy_command.clone()).await?; self.wait_for_all_inflight_tx().await?; - let mut timer = tokio::time::interval(POLLING_INTERVAL); + let mut timer = tokio::time::interval(self.polling_interval); let mut l1_tx_count = 0; loop { let command = self.generate_command(); @@ -157,7 +162,7 @@ impl AccountLifespan { } async fn wait_for_all_inflight_tx(&mut self) -> Result<(), Aborted> { - let mut timer = tokio::time::interval(POLLING_INTERVAL); + let mut timer = tokio::time::interval(self.polling_interval); while !self.inflight_txs.is_empty() { timer.tick().await; self.check_inflight_txs().await?; diff --git a/core/tests/loadnext/src/account_pool.rs b/core/tests/loadnext/src/account_pool.rs index 7b5e277e139b..3fa3141553cd 100644 --- a/core/tests/loadnext/src/account_pool.rs +++ b/core/tests/loadnext/src/account_pool.rs @@ -101,7 +101,9 @@ impl AccountPool { .context("invalid L2 RPC URL")?, )? .for_network(l2_chain_id.into()) + .report_config(false) .build(); + // Perform a health check: check whether ZKsync server is alive. let mut server_alive = false; for _ in 0usize..3 { diff --git a/core/tests/loadnext/src/constants.rs b/core/tests/loadnext/src/constants.rs index 7ac66ab7e1e7..6b989b16feb1 100644 --- a/core/tests/loadnext/src/constants.rs +++ b/core/tests/loadnext/src/constants.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use std::{ops, time::Duration}; /// Normally, block is committed on Ethereum every 15 seconds; however there are no guarantees that our transaction /// will be included in the next block right after sending. @@ -14,7 +14,7 @@ pub const ETH_POLLING_INTERVAL: Duration = Duration::from_secs(10); pub const COMMIT_TIMEOUT: Duration = Duration::from_secs(600); /// We don't want to overload the server with too many requests; given the fact that blocks are expected to be created /// every couple of seconds, chosen value seems to be adequate to provide the result in one or two calls at average. -pub const POLLING_INTERVAL: Duration = Duration::from_secs(3); +pub const POLLING_INTERVAL: ops::Range = Duration::from_secs(2)..Duration::from_secs(3); pub const MAX_OUTSTANDING_NONCE: usize = 20; diff --git a/core/tests/loadnext/src/executor.rs b/core/tests/loadnext/src/executor.rs index a573583ed318..43a1be164b64 100644 --- a/core/tests/loadnext/src/executor.rs +++ b/core/tests/loadnext/src/executor.rs @@ -244,7 +244,7 @@ impl Executor { }); priority_op_handle - .polling_interval(POLLING_INTERVAL) + .polling_interval(POLLING_INTERVAL.end) .unwrap(); priority_op_handle .commit_timeout(COMMIT_TIMEOUT) @@ -313,7 +313,7 @@ impl Executor { }); priority_op_handle - .polling_interval(POLLING_INTERVAL) + .polling_interval(POLLING_INTERVAL.end) .unwrap(); priority_op_handle .commit_timeout(COMMIT_TIMEOUT) @@ -463,7 +463,7 @@ impl Executor { // Wait for transactions to be committed, if at least one of them fails, // return error. for mut handle in handles { - handle.polling_interval(POLLING_INTERVAL).unwrap(); + handle.polling_interval(POLLING_INTERVAL.end).unwrap(); let result = handle .commit_timeout(COMMIT_TIMEOUT) diff --git a/core/tests/loadnext/src/sdk/ethereum/mod.rs b/core/tests/loadnext/src/sdk/ethereum/mod.rs index 4b7bb00a3080..4557c2c43200 100644 --- a/core/tests/loadnext/src/sdk/ethereum/mod.rs +++ b/core/tests/loadnext/src/sdk/ethereum/mod.rs @@ -102,6 +102,7 @@ impl EthereumProvider { let query_client = Client::http(eth_web3_url) .map_err(|err| ClientError::NetworkError(err.to_string()))? .for_network(sl_chain_id.into()) + .report_config(false) .build(); let query_client: Box> = Box::new(query_client); let eth_client = SigningClient::new( diff --git a/core/tests/loadnext/src/sdk/wallet.rs b/core/tests/loadnext/src/sdk/wallet.rs index 9d3bd73a9bf2..551d0d8e385f 100644 --- a/core/tests/loadnext/src/sdk/wallet.rs +++ b/core/tests/loadnext/src/sdk/wallet.rs @@ -45,6 +45,7 @@ where let client = Client::http(rpc_address) .map_err(|err| ClientError::NetworkError(err.to_string()))? .for_network(signer.chain_id.into()) + .report_config(false) .build(); Ok(Wallet {