Skip to content

Commit

Permalink
feat(vm): Return compressed bytecodes from push_transaction() (#3126)
Browse files Browse the repository at this point in the history
## What ❔

Returns compressed bytecodes from `VmInterface::push_transaction()`.

## Why ❔

This can be used by some external VM users. It is a more idiomatic
replacement of removed
`VmInterface::get_last_tx_compressed_bytecodes()`, and it's more
efficient for newer VMs (doesn't clone bytecodes, instead providing a
reference from the bootloader state).

## 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 `zkstack dev fmt` and `zkstack dev
lint`.
  • Loading branch information
slowli authored Oct 18, 2024
1 parent 5d5214b commit 37f209f
Show file tree
Hide file tree
Showing 19 changed files with 191 additions and 95 deletions.
14 changes: 11 additions & 3 deletions core/lib/multivm/src/versions/testonly/bytecode_publishing.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use zksync_test_account::{DeployContractsTx, TxType};
use zksync_test_account::TxType;

use super::{read_test_contract, tester::VmTesterBuilder, TestedVm};
use crate::{
Expand All @@ -20,8 +20,16 @@ pub(crate) fn test_bytecode_publishing<VM: TestedVm>() {

let compressed_bytecode = bytecode::compress(counter.clone()).unwrap().compressed;

let DeployContractsTx { tx, .. } = account.get_deploy_tx(&counter, None, TxType::L2);
vm.vm.push_transaction(tx);
let tx = account.get_deploy_tx(&counter, None, TxType::L2).tx;
assert_eq!(tx.execute.factory_deps.len(), 1); // The deployed bytecode is the only dependency
let push_result = vm.vm.push_transaction(tx);
assert_eq!(push_result.compressed_bytecodes.len(), 1);
assert_eq!(push_result.compressed_bytecodes[0].original, counter);
assert_eq!(
push_result.compressed_bytecodes[0].compressed,
compressed_bytecode
);

let result = vm.vm.execute(VmExecutionMode::OneTx);
assert!(!result.result.is_failed(), "Transaction wasn't successful");

Expand Down
23 changes: 14 additions & 9 deletions core/lib/multivm/src/versions/vm_1_3_2/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use crate::{
interface::{
storage::{StoragePtr, WriteStorage},
BytecodeCompressionError, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv,
L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmExecutionResultAndLogs,
VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics,
L2BlockEnv, PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
VmMemoryMetrics,
},
tracers::old::TracerDispatcher,
utils::bytecode,
Expand Down Expand Up @@ -44,13 +45,17 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher;

fn push_transaction(&mut self, tx: Transaction) {
crate::vm_1_3_2::vm_with_bootloader::push_transaction_to_bootloader_memory(
&mut self.vm,
&tx,
self.system_env.execution_mode.glue_into(),
None,
)
fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> {
let compressed_bytecodes =
crate::vm_1_3_2::vm_with_bootloader::push_transaction_to_bootloader_memory(
&mut self.vm,
&tx,
self.system_env.execution_mode.glue_into(),
None,
);
PushTransactionResult {
compressed_bytecodes: compressed_bytecodes.into(),
}
}

fn inspect(
Expand Down
19 changes: 10 additions & 9 deletions core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ pub fn get_bootloader_memory(
let mut previous_compressed: usize = 0;
let mut already_included_txs_size = 0;
for (tx_index_in_block, tx) in txs.into_iter().enumerate() {
let compressed_bytecodes = predefined_compressed_bytecodes[tx_index_in_block].clone();
let compressed_bytecodes = &predefined_compressed_bytecodes[tx_index_in_block];

let mut total_compressed_len_words = 0;
for i in compressed_bytecodes.iter() {
Expand Down Expand Up @@ -475,7 +475,7 @@ pub fn push_transaction_to_bootloader_memory<H: HistoryMode, S: WriteStorage>(
tx: &Transaction,
execution_mode: TxExecutionMode,
explicit_compressed_bytecodes: Option<Vec<CompressedBytecodeInfo>>,
) {
) -> Vec<CompressedBytecodeInfo> {
let tx: TransactionData = tx.clone().into();
let block_gas_per_pubdata_byte = vm.block_context.context.block_gas_price_per_pubdata();
let overhead = tx.overhead_gas(block_gas_per_pubdata_byte as u32);
Expand All @@ -485,7 +485,7 @@ pub fn push_transaction_to_bootloader_memory<H: HistoryMode, S: WriteStorage>(
execution_mode,
overhead,
explicit_compressed_bytecodes,
);
)
}

pub fn push_raw_transaction_to_bootloader_memory<H: HistoryMode, S: WriteStorage>(
Expand All @@ -494,7 +494,7 @@ pub fn push_raw_transaction_to_bootloader_memory<H: HistoryMode, S: WriteStorage
execution_mode: TxExecutionMode,
predefined_overhead: u32,
explicit_compressed_bytecodes: Option<Vec<CompressedBytecodeInfo>>,
) {
) -> Vec<CompressedBytecodeInfo> {
let tx_index_in_block = vm.bootloader_state.free_tx_index();
let already_included_txs_size = vm.bootloader_state.free_tx_offset();

Expand Down Expand Up @@ -555,7 +555,7 @@ pub fn push_raw_transaction_to_bootloader_memory<H: HistoryMode, S: WriteStorage
predefined_overhead,
trusted_ergs_limit,
previous_bytecodes,
compressed_bytecodes,
&compressed_bytecodes,
);

vm.state.memory.populate_page(
Expand All @@ -566,6 +566,7 @@ pub fn push_raw_transaction_to_bootloader_memory<H: HistoryMode, S: WriteStorage
vm.bootloader_state.add_tx_data(encoded_tx_size);
vm.bootloader_state
.add_compressed_bytecode(compressed_bytecodes_encoding_len_words);
compressed_bytecodes
}

#[allow(clippy::too_many_arguments)]
Expand All @@ -577,7 +578,7 @@ fn get_bootloader_memory_for_tx(
predefined_refund: u32,
block_gas_per_pubdata: u32,
previous_compressed_bytecode_size: usize,
compressed_bytecodes: Vec<CompressedBytecodeInfo>,
compressed_bytecodes: &[CompressedBytecodeInfo],
) -> Vec<(usize, U256)> {
let overhead_gas = tx.overhead_gas(block_gas_per_pubdata);
let trusted_gas_limit = tx.trusted_gas_limit(block_gas_per_pubdata);
Expand All @@ -604,7 +605,7 @@ pub(crate) fn get_bootloader_memory_for_encoded_tx(
predefined_overhead: u32,
trusted_gas_limit: u32,
previous_compressed_bytecode_size: usize,
compressed_bytecodes: Vec<CompressedBytecodeInfo>,
compressed_bytecodes: &[CompressedBytecodeInfo],
) -> Vec<(usize, U256)> {
let mut memory: Vec<(usize, U256)> = Vec::default();
let bootloader_description_offset =
Expand Down Expand Up @@ -640,8 +641,8 @@ pub(crate) fn get_bootloader_memory_for_encoded_tx(
COMPRESSED_BYTECODES_OFFSET + 1 + previous_compressed_bytecode_size;

let memory_addition: Vec<_> = compressed_bytecodes
.into_iter()
.flat_map(|x| bytecode::encode_call(&x))
.iter()
.flat_map(bytecode::encode_call)
.collect();

let memory_addition = bytes_to_be_words(memory_addition);
Expand Down
11 changes: 8 additions & 3 deletions core/lib/multivm/src/versions/vm_1_4_1/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
interface::{
storage::{StoragePtr, WriteStorage},
BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
},
utils::events::extract_l2tol1logs_from_l1_messenger,
Expand Down Expand Up @@ -81,9 +81,14 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher<S, H::Vm1_4_1>;

/// Push tx into memory for the future execution
fn push_transaction(&mut self, tx: Transaction) {
fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> {
self.push_transaction_with_compression(tx, true);
PushTransactionResult {
compressed_bytecodes: self
.bootloader_state
.get_last_tx_compressed_bytecodes()
.into(),
}
}

/// Execute VM with custom tracers.
Expand Down
11 changes: 8 additions & 3 deletions core/lib/multivm/src/versions/vm_1_4_2/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
interface::{
storage::{StoragePtr, WriteStorage},
BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
},
utils::events::extract_l2tol1logs_from_l1_messenger,
Expand Down Expand Up @@ -83,9 +83,14 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher<S, H::Vm1_4_2>;

/// Push tx into memory for the future execution
fn push_transaction(&mut self, tx: Transaction) {
fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> {
self.push_transaction_with_compression(tx, true);
PushTransactionResult {
compressed_bytecodes: self
.bootloader_state
.get_last_tx_compressed_bytecodes()
.into(),
}
}

/// Execute VM with custom tracers.
Expand Down
11 changes: 8 additions & 3 deletions core/lib/multivm/src/versions/vm_boojum_integration/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
interface::{
storage::{StoragePtr, WriteStorage},
BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
},
utils::events::extract_l2tol1logs_from_l1_messenger,
Expand Down Expand Up @@ -81,9 +81,14 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher<S, H::VmBoojumIntegration>;

/// Push tx into memory for the future execution
fn push_transaction(&mut self, tx: Transaction) {
fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult {
self.push_transaction_with_compression(tx, true);
PushTransactionResult {
compressed_bytecodes: self
.bootloader_state
.get_last_tx_compressed_bytecodes()
.into(),
}
}

/// Execute VM with custom tracers.
Expand Down
18 changes: 12 additions & 6 deletions core/lib/multivm/src/versions/vm_fast/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use zksync_types::{
BYTES_PER_ENUMERATION_INDEX,
},
AccountTreeId, StorageKey, StorageLog, StorageLogKind, StorageLogWithPreviousValue,
BOOTLOADER_ADDRESS, H160, H256, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS,
Transaction, BOOTLOADER_ADDRESS, H160, H256, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS,
L2_BASE_TOKEN_ADDRESS, U256,
};
use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256};
Expand All @@ -35,10 +35,10 @@ use crate::{
interface::{
storage::{ImmutableStorageView, ReadStorage, StoragePtr, StorageView},
BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState,
ExecutionResult, FinishedL1Batch, Halt, L1BatchEnv, L2BlockEnv, Refunds, SystemEnv,
TxRevertReason, VmEvent, VmExecutionLogs, VmExecutionMode, VmExecutionResultAndLogs,
VmExecutionStatistics, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmRevertReason,
VmTrackingContracts,
ExecutionResult, FinishedL1Batch, Halt, L1BatchEnv, L2BlockEnv, PushTransactionResult,
Refunds, SystemEnv, TxRevertReason, VmEvent, VmExecutionLogs, VmExecutionMode,
VmExecutionResultAndLogs, VmExecutionStatistics, VmFactory, VmInterface,
VmInterfaceHistoryEnabled, VmRevertReason, VmTrackingContracts,
},
is_supported_by_fast_vm,
utils::events::extract_l2tol1logs_from_l1_messenger,
Expand Down Expand Up @@ -553,8 +553,14 @@ where
impl<S: ReadStorage, Tr: Tracer + Default + 'static> VmInterface for Vm<S, Tr> {
type TracerDispatcher = Tr;

fn push_transaction(&mut self, tx: zksync_types::Transaction) {
fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> {
self.push_transaction_inner(tx, 0, true);
PushTransactionResult {
compressed_bytecodes: self
.bootloader_state
.get_last_tx_compressed_bytecodes()
.into(),
}
}

fn inspect(
Expand Down
11 changes: 8 additions & 3 deletions core/lib/multivm/src/versions/vm_latest/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
interface::{
storage::{StoragePtr, WriteStorage},
BytecodeCompressionError, BytecodeCompressionResult, CurrentExecutionState,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, SystemEnv, VmExecutionMode,
FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
VmTrackingContracts,
},
Expand Down Expand Up @@ -134,9 +134,14 @@ impl<S: WriteStorage, H: HistoryMode> Vm<S, H> {
impl<S: WriteStorage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher<S, H::Vm1_5_0>;

/// Push tx into memory for the future execution
fn push_transaction(&mut self, tx: Transaction) {
fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> {
self.push_transaction_with_compression(tx, true);
PushTransactionResult {
compressed_bytecodes: self
.bootloader_state
.get_last_tx_compressed_bytecodes()
.into(),
}
}

/// Execute VM with custom tracers.
Expand Down
12 changes: 8 additions & 4 deletions core/lib/multivm/src/versions/vm_m5/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use crate::{
glue::{history_mode::HistoryMode, GlueInto},
interface::{
storage::StoragePtr, BytecodeCompressionResult, FinishedL1Batch, L1BatchEnv, L2BlockEnv,
SystemEnv, TxExecutionMode, VmExecutionMode, VmExecutionResultAndLogs, VmFactory,
VmInterface, VmInterfaceHistoryEnabled, VmMemoryMetrics,
PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
VmMemoryMetrics,
},
vm_m5::{
storage::Storage,
Expand Down Expand Up @@ -60,12 +61,15 @@ impl<S: Storage, H: HistoryMode> VmInterface for Vm<S, H> {
/// Tracers are not supported for here we use `()` as a placeholder
type TracerDispatcher = ();

fn push_transaction(&mut self, tx: Transaction) {
fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> {
crate::vm_m5::vm_with_bootloader::push_transaction_to_bootloader_memory(
&mut self.vm,
&tx,
self.system_env.execution_mode.glue_into(),
)
);
PushTransactionResult {
compressed_bytecodes: (&[]).into(), // bytecode compression isn't supported
}
}

fn inspect(
Expand Down
20 changes: 12 additions & 8 deletions core/lib/multivm/src/versions/vm_m6/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
glue::{history_mode::HistoryMode, GlueInto},
interface::{
storage::StoragePtr, BytecodeCompressionError, BytecodeCompressionResult, FinishedL1Batch,
L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode,
L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, TxExecutionMode, VmExecutionMode,
VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled,
VmMemoryMetrics,
},
Expand Down Expand Up @@ -72,13 +72,17 @@ impl<S: Storage, H: HistoryMode> Vm<S, H> {
impl<S: Storage, H: HistoryMode> VmInterface for Vm<S, H> {
type TracerDispatcher = TracerDispatcher;

fn push_transaction(&mut self, tx: Transaction) {
crate::vm_m6::vm_with_bootloader::push_transaction_to_bootloader_memory(
&mut self.vm,
&tx,
self.system_env.execution_mode.glue_into(),
None,
)
fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult {
let compressed_bytecodes =
crate::vm_m6::vm_with_bootloader::push_transaction_to_bootloader_memory(
&mut self.vm,
&tx,
self.system_env.execution_mode.glue_into(),
None,
);
PushTransactionResult {
compressed_bytecodes: compressed_bytecodes.into(),
}
}

fn inspect(
Expand Down
Loading

0 comments on commit 37f209f

Please sign in to comment.