From af149a01e6ce0c62d4b8a6acf9481e807ac24a8f Mon Sep 17 00:00:00 2001 From: Joonatan Saarhelo Date: Thu, 19 Dec 2024 10:21:30 +0000 Subject: [PATCH 1/3] feat: vm2 account validation (#2863) Implements an account validation gas limit and the validation tracer for vm2, along with better tests for validation. Instead of a second gas limit like in vm_latest, the normal gas limit is used. Unfortunately this means that the VM is not safe to use in the sequencer until we forbid the use of gasleft. I didn't do it here because it requires something like taint analysis and could break existing contracts that didn't know that gasleft is forbidden. --------- Co-authored-by: Alex Ostrovski Co-authored-by: Alex Ostrovski --- core/lib/contracts/src/lib.rs | 2 +- core/lib/multivm/src/tracers/mod.rs | 7 +- core/lib/multivm/src/tracers/validator/mod.rs | 12 +- .../src/tracers/validator/vm_latest/mod.rs | 12 +- core/lib/multivm/src/versions/shadow/mod.rs | 2 +- .../testonly/account_validation_rules.rs | 59 ++ .../src/versions/testonly/l1_messenger.rs | 4 +- core/lib/multivm/src/versions/testonly/mod.rs | 5 +- .../src/versions/testonly/require_eip712.rs | 41 +- .../src/versions/testonly/tester/mod.rs | 21 + .../multivm/src/versions/vm_fast/bytecode.rs | 2 +- core/lib/multivm/src/versions/vm_fast/hook.rs | 6 +- core/lib/multivm/src/versions/vm_fast/mod.rs | 8 +- .../vm_fast/tests/account_validation_rules.rs | 7 + .../multivm/src/versions/vm_fast/tests/mod.rs | 39 +- .../circuits.rs} | 0 .../evm_deploy.rs} | 6 +- .../src/versions/vm_fast/tracers/mod.rs | 86 +++ .../versions/vm_fast/tracers/validation.rs | 296 ++++++++++ core/lib/multivm/src/versions/vm_fast/vm.rs | 528 ++++++++++-------- .../tests/account_validation_rules.rs | 8 + .../src/versions/vm_latest/tests/mod.rs | 36 +- core/lib/multivm/src/vm_instance.rs | 62 +- .../validation-rule-breaker.sol | 149 +++++ core/lib/test_contracts/src/contracts.rs | 6 + core/lib/vm_executor/src/batch/factory.rs | 4 +- core/lib/vm_executor/src/oneshot/mod.rs | 137 +++-- core/lib/vm_interface/src/types/tracer.rs | 6 +- core/lib/vm_interface/src/utils/shadow.rs | 28 +- core/lib/vm_interface/src/vm.rs | 1 - core/node/eth_watch/src/tests/mod.rs | 14 +- .../src/tree_data_fetcher/provider/tests.rs | 2 +- core/tests/vm-benchmark/src/vm.rs | 7 +- 33 files changed, 1220 insertions(+), 383 deletions(-) create mode 100644 core/lib/multivm/src/versions/testonly/account_validation_rules.rs create mode 100644 core/lib/multivm/src/versions/vm_fast/tests/account_validation_rules.rs rename core/lib/multivm/src/versions/vm_fast/{circuits_tracer.rs => tracers/circuits.rs} (100%) rename core/lib/multivm/src/versions/vm_fast/{evm_deploy_tracer.rs => tracers/evm_deploy.rs} (94%) create mode 100644 core/lib/multivm/src/versions/vm_fast/tracers/mod.rs create mode 100644 core/lib/multivm/src/versions/vm_fast/tracers/validation.rs create mode 100644 core/lib/multivm/src/versions/vm_latest/tests/account_validation_rules.rs create mode 100644 core/lib/test_contracts/contracts/custom-account/validation-rule-breaker.sol diff --git a/core/lib/contracts/src/lib.rs b/core/lib/contracts/src/lib.rs index e60fdb0e59f3..4669fc2b86b8 100644 --- a/core/lib/contracts/src/lib.rs +++ b/core/lib/contracts/src/lib.rs @@ -180,7 +180,7 @@ pub fn l1_messenger_contract() -> Contract { /// Reads bytecode from the path RELATIVE to the Cargo workspace location. pub fn read_bytecode(relative_path: impl AsRef + std::fmt::Debug) -> Vec { - read_bytecode_from_path(relative_path).expect("Exists") + read_bytecode_from_path(relative_path).expect("Failed to open file") } pub fn eth_contract() -> Contract { diff --git a/core/lib/multivm/src/tracers/mod.rs b/core/lib/multivm/src/tracers/mod.rs index 35224d993a17..b888c3730118 100644 --- a/core/lib/multivm/src/tracers/mod.rs +++ b/core/lib/multivm/src/tracers/mod.rs @@ -1,6 +1,9 @@ pub use self::{ - call_tracer::CallTracer, multivm_dispatcher::TracerDispatcher, prestate_tracer::PrestateTracer, - storage_invocation::StorageInvocations, validator::ValidationTracer, + call_tracer::CallTracer, + multivm_dispatcher::TracerDispatcher, + prestate_tracer::PrestateTracer, + storage_invocation::StorageInvocations, + validator::{ValidationTracer, TIMESTAMP_ASSERTER_FUNCTION_SELECTOR}, }; mod call_tracer; diff --git a/core/lib/multivm/src/tracers/validator/mod.rs b/core/lib/multivm/src/tracers/validator/mod.rs index 88249467a575..c1dd311d9fd3 100644 --- a/core/lib/multivm/src/tracers/validator/mod.rs +++ b/core/lib/multivm/src/tracers/validator/mod.rs @@ -5,6 +5,7 @@ use std::{ }; use once_cell::sync::OnceCell; +pub use vm_latest::TIMESTAMP_ASSERTER_FUNCTION_SELECTOR; use zksync_system_constants::{ ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS, CONTRACT_DEPLOYER_ADDRESS, L2_BASE_TOKEN_ADDRESS, MSG_VALUE_SIMULATOR_ADDRESS, SYSTEM_CONTEXT_ADDRESS, @@ -13,10 +14,7 @@ use zksync_types::{ address_to_u256, u256_to_h256, vm::VmVersion, web3::keccak256, AccountTreeId, Address, StorageKey, H256, U256, }; -use zksync_vm_interface::{ - tracer::{TimestampAsserterParams, ValidationTraces}, - L1BatchEnv, -}; +use zksync_vm_interface::tracer::{TimestampAsserterParams, ValidationTraces}; use self::types::{NewTrustedValidationItems, ValidationTracerMode}; use crate::{ @@ -54,7 +52,7 @@ pub struct ValidationTracer { computational_gas_limit: u32, timestamp_asserter_params: Option, vm_version: VmVersion, - l1_batch_env: L1BatchEnv, + l1_batch_timestamp: u64, pub result: Arc>, pub traces: Arc>, _marker: PhantomData H>, @@ -65,7 +63,7 @@ type ValidationRoundResult = Result ValidationTracer { const MAX_ALLOWED_SLOT_OFFSET: u32 = 127; - pub fn new(params: ValidationParams, vm_version: VmVersion, l1_batch_env: L1BatchEnv) -> Self { + pub fn new(params: ValidationParams, vm_version: VmVersion, l1_batch_timestamp: u64) -> Self { Self { validation_mode: ValidationTracerMode::NoValidation, auxilary_allowed_slots: Default::default(), @@ -83,7 +81,7 @@ impl ValidationTracer { result: Arc::new(OnceCell::new()), traces: Arc::new(Mutex::new(ValidationTraces::default())), _marker: Default::default(), - l1_batch_env, + l1_batch_timestamp, } } diff --git a/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs b/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs index 3c819384137f..5588dd144e95 100644 --- a/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs @@ -1,6 +1,6 @@ use zk_evm_1_5_0::{ tracing::{BeforeExecutionData, VmLocalStateData}, - zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, + zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode, RetOpcode}, }; use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS; use zksync_types::{ @@ -116,8 +116,7 @@ impl ValidationTracer { // using self.l1_batch_env.timestamp is ok here because the tracer is always // used in a oneshot execution mode if end - < self.l1_batch_env.timestamp - + params.min_time_till_end.as_secs() + < self.l1_batch_timestamp + params.min_time_till_end.as_secs() { return Err( ViolatedValidationRule::TimestampAssertionCloseToRangeEnd, @@ -168,6 +167,13 @@ impl ValidationTracer { }); } } + + Opcode::Ret(RetOpcode::Panic) + if state.vm_local_state.callstack.current.ergs_remaining == 0 => + { + // Actual gas limit was reached, not the validation gas limit. + return Err(ViolatedValidationRule::TookTooManyComputationalGas(0)); + } _ => {} } diff --git a/core/lib/multivm/src/versions/shadow/mod.rs b/core/lib/multivm/src/versions/shadow/mod.rs index a335d0fe5906..1ad5bdba5a7b 100644 --- a/core/lib/multivm/src/versions/shadow/mod.rs +++ b/core/lib/multivm/src/versions/shadow/mod.rs @@ -25,7 +25,7 @@ use crate::{ mod tests; type ReferenceVm = vm_latest::Vm, HistoryEnabled>; -type ShadowedFastVm = crate::vm_instance::ShadowedFastVm; +type ShadowedFastVm = crate::vm_instance::ShadowedFastVm; fn hash_block(block_env: L2BlockEnv, tx_hashes: &[H256]) -> H256 { let mut hasher = L2BlockHasher::new( diff --git a/core/lib/multivm/src/versions/testonly/account_validation_rules.rs b/core/lib/multivm/src/versions/testonly/account_validation_rules.rs new file mode 100644 index 000000000000..b2beb050ad41 --- /dev/null +++ b/core/lib/multivm/src/versions/testonly/account_validation_rules.rs @@ -0,0 +1,59 @@ +use assert_matches::assert_matches; +use zksync_test_contracts::TestContract; +use zksync_types::{u256_to_h256, AccountTreeId, Address, StorageKey}; +use zksync_vm_interface::tracer::ViolatedValidationRule; + +use super::{ + get_empty_storage, require_eip712::make_aa_transaction, tester::VmTesterBuilder, + ContractToDeploy, TestedVm, TestedVmForValidation, +}; +use crate::interface::TxExecutionMode; + +/// Checks that every limitation imposed on account validation results in an appropriate error. +/// The actual misbehavior cases are found in "validation-rule-breaker.sol". +pub(crate) fn test_account_validation_rules() { + assert_matches!(test_rule::(0), None); + assert_matches!( + test_rule::(1), + Some(ViolatedValidationRule::TouchedDisallowedStorageSlots(_, _)) + ); + assert_matches!( + test_rule::(2), + Some(ViolatedValidationRule::CalledContractWithNoCode(_)) + ); + assert_matches!(test_rule::(3), None); + assert_matches!( + test_rule::(4), + Some(ViolatedValidationRule::TookTooManyComputationalGas(_)) + ) +} + +fn test_rule(rule: u32) -> Option { + let aa_address = Address::repeat_byte(0x10); + let beneficiary_address = Address::repeat_byte(0x20); + + // Set the type of misbehaviour of the AA contract + let mut storage_with_rule_break_set = get_empty_storage(); + storage_with_rule_break_set.set_value( + StorageKey::new(AccountTreeId::new(aa_address), u256_to_h256(0.into())), + u256_to_h256(rule.into()), + ); + + let bytecode = TestContract::validation_test().bytecode.to_vec(); + let mut vm = VmTesterBuilder::new() + .with_empty_in_memory_storage() + .with_custom_contracts(vec![ + ContractToDeploy::account(bytecode, aa_address).funded() + ]) + .with_storage(storage_with_rule_break_set) + .with_execution_mode(TxExecutionMode::VerifyExecute) + .with_rich_accounts(1) + .build::(); + + let private_account = vm.rich_accounts[0].clone(); + + vm.vm.run_validation( + make_aa_transaction(aa_address, beneficiary_address, &private_account), + 55, + ) +} diff --git a/core/lib/multivm/src/versions/testonly/l1_messenger.rs b/core/lib/multivm/src/versions/testonly/l1_messenger.rs index daf07b2750f7..5d602b1e7d66 100644 --- a/core/lib/multivm/src/versions/testonly/l1_messenger.rs +++ b/core/lib/multivm/src/versions/testonly/l1_messenger.rs @@ -99,9 +99,7 @@ pub(crate) fn test_rollup_da_output_hash_match() { // Firstly, deploy tx. It should publish the bytecode of the "test contract" let counter_bytecode = TestContract::counter().bytecode; - let tx = account - .get_deploy_tx(&counter_bytecode, None, TxType::L2) - .tx; + let tx = account.get_deploy_tx(counter_bytecode, None, TxType::L2).tx; // We do not use compression here, to have the bytecode published in full. let (_, result) = vm .vm diff --git a/core/lib/multivm/src/versions/testonly/mod.rs b/core/lib/multivm/src/versions/testonly/mod.rs index a0f08546197c..5ab13df87337 100644 --- a/core/lib/multivm/src/versions/testonly/mod.rs +++ b/core/lib/multivm/src/versions/testonly/mod.rs @@ -24,12 +24,15 @@ use zksync_vm_interface::{ pubdata::PubdataBuilder, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, }; -pub(super) use self::tester::{TestedVm, VmTester, VmTesterBuilder}; +pub(super) use self::tester::{ + validation_params, TestedVm, TestedVmForValidation, VmTester, VmTesterBuilder, +}; use crate::{ interface::storage::InMemoryStorage, pubdata_builders::RollupPubdataBuilder, vm_latest::constants::BATCH_COMPUTATIONAL_GAS_LIMIT, }; +pub(super) mod account_validation_rules; pub(super) mod block_tip; pub(super) mod bootloader; pub(super) mod bytecode_publishing; diff --git a/core/lib/multivm/src/versions/testonly/require_eip712.rs b/core/lib/multivm/src/versions/testonly/require_eip712.rs index 7a934c570aea..2f17a3e7823e 100644 --- a/core/lib/multivm/src/versions/testonly/require_eip712.rs +++ b/core/lib/multivm/src/versions/testonly/require_eip712.rs @@ -1,6 +1,6 @@ use ethabi::Token; use zksync_eth_signer::TransactionParameters; -use zksync_test_contracts::TestContract; +use zksync_test_contracts::{Account, TestContract}; use zksync_types::{ fee::Fee, l2::L2Tx, transaction_request::TransactionRequest, Address, Eip712Domain, Execute, L2ChainId, Nonce, Transaction, U256, @@ -30,7 +30,6 @@ pub(crate) fn test_require_eip712() { .with_rich_accounts(1) .build::(); assert_eq!(vm.get_eth_balance(beneficiary_address), U256::from(0)); - let chain_id: u32 = 270; let mut private_account = vm.rich_accounts[0].clone(); // First, let's set the owners of the AA account to the `private_address`. @@ -97,7 +96,30 @@ pub(crate) fn test_require_eip712() { vm.get_eth_balance(private_account.address) ); - // // Now send the 'classic' EIP712 transaction + // Now send the 'classic' EIP712 transaction + + let transaction: Transaction = + make_aa_transaction(aa_address, beneficiary_address, &private_account).into(); + vm.vm.push_transaction(transaction); + vm.vm.execute(InspectExecutionMode::OneTx); + + assert_eq!( + vm.get_eth_balance(beneficiary_address), + U256::from(916375026) + ); + assert_eq!( + private_account_balance, + vm.get_eth_balance(private_account.address) + ); +} + +pub(crate) fn make_aa_transaction( + aa_address: Address, + beneficiary_address: Address, + private_account: &Account, +) -> L2Tx { + let chain_id: u32 = 270; + let tx_712 = L2Tx::new( Some(beneficiary_address), vec![], @@ -130,16 +152,5 @@ pub(crate) fn test_require_eip712() { let mut l2_tx = L2Tx::from_request(aa_txn_request, 100000, false).unwrap(); l2_tx.set_input(encoded_tx, aa_hash); - let transaction: Transaction = l2_tx.into(); - vm.vm.push_transaction(transaction); - vm.vm.execute(InspectExecutionMode::OneTx); - - assert_eq!( - vm.get_eth_balance(beneficiary_address), - U256::from(916375026) - ); - assert_eq!( - private_account_balance, - vm.get_eth_balance(private_account.address) - ); + l2_tx } diff --git a/core/lib/multivm/src/versions/testonly/tester/mod.rs b/core/lib/multivm/src/versions/testonly/tester/mod.rs index d3cf2d6f782f..c29f2dbbf8f3 100644 --- a/core/lib/multivm/src/versions/testonly/tester/mod.rs +++ b/core/lib/multivm/src/versions/testonly/tester/mod.rs @@ -3,6 +3,7 @@ use std::{collections::HashSet, fmt, rc::Rc}; use zksync_contracts::BaseSystemContracts; use zksync_test_contracts::{Account, TestContract, TxType}; use zksync_types::{ + l2::L2Tx, utils::{deployed_address_create, storage_key_for_eth_balance}, writes::StateDiffRecord, Address, L1BatchNumber, StorageKey, Transaction, H256, U256, @@ -14,6 +15,7 @@ use crate::{ interface::{ pubdata::{PubdataBuilder, PubdataInput}, storage::{InMemoryStorage, StoragePtr, StorageView}, + tracer::{ValidationParams, ViolatedValidationRule}, CurrentExecutionState, InspectExecutionMode, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterfaceExt, VmInterfaceHistoryEnabled, @@ -231,3 +233,22 @@ pub(crate) trait TestedVm: /// Returns pubdata input. fn pubdata_input(&self) -> PubdataInput; } + +pub(crate) trait TestedVmForValidation { + fn run_validation(&mut self, tx: L2Tx, timestamp: u64) -> Option; +} + +pub(crate) fn validation_params(tx: &L2Tx, system: &SystemEnv) -> ValidationParams { + let user_address = tx.common_data.initiator_address; + let paymaster_address = tx.common_data.paymaster_params.paymaster; + ValidationParams { + user_address, + paymaster_address, + trusted_slots: Default::default(), + trusted_addresses: Default::default(), + // field `trustedAddress` of ValidationRuleBreaker + trusted_address_slots: [(Address::repeat_byte(0x10), 2.into())].into(), + computational_gas_limit: system.default_validation_computational_gas_limit, + timestamp_asserter_params: None, + } +} diff --git a/core/lib/multivm/src/versions/vm_fast/bytecode.rs b/core/lib/multivm/src/versions/vm_fast/bytecode.rs index 4dc52951c16c..aec5ed9ae301 100644 --- a/core/lib/multivm/src/versions/vm_fast/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_fast/bytecode.rs @@ -7,7 +7,7 @@ use crate::{ utils::bytecode, }; -impl Vm { +impl Vm { /// Checks the last transaction has successfully published compressed bytecodes and returns `true` if there is at least one is still unknown. pub(crate) fn has_unpublished_bytecodes(&mut self) -> bool { self.bootloader_state diff --git a/core/lib/multivm/src/versions/vm_fast/hook.rs b/core/lib/multivm/src/versions/vm_fast/hook.rs index 8d385f94f3e1..b138c6d496d9 100644 --- a/core/lib/multivm/src/versions/vm_fast/hook.rs +++ b/core/lib/multivm/src/versions/vm_fast/hook.rs @@ -1,8 +1,8 @@ -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub(crate) enum Hook { AccountValidationEntered, PaymasterValidationEntered, - AccountValidationExited, + ValidationExited, ValidationStepEnded, TxHasEnded, DebugLog, @@ -22,7 +22,7 @@ impl Hook { match hook { 0 => Hook::AccountValidationEntered, 1 => Hook::PaymasterValidationEntered, - 2 => Hook::AccountValidationExited, + 2 => Hook::ValidationExited, 3 => Hook::ValidationStepEnded, 4 => Hook::TxHasEnded, 5 => Hook::DebugLog, diff --git a/core/lib/multivm/src/versions/vm_fast/mod.rs b/core/lib/multivm/src/versions/vm_fast/mod.rs index 840653b63b08..dca575138553 100644 --- a/core/lib/multivm/src/versions/vm_fast/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/mod.rs @@ -1,19 +1,21 @@ pub use zksync_vm2::interface; pub(crate) use self::version::FastVmVersion; -pub use self::vm::Vm; +pub use self::{ + tracers::{FullValidationTracer, ValidationTracer}, + vm::Vm, +}; mod bootloader_state; mod bytecode; -mod circuits_tracer; mod events; -mod evm_deploy_tracer; mod glue; mod hook; mod initial_bootloader_memory; mod refund; #[cfg(test)] mod tests; +mod tracers; mod transaction_data; mod utils; mod version; diff --git a/core/lib/multivm/src/versions/vm_fast/tests/account_validation_rules.rs b/core/lib/multivm/src/versions/vm_fast/tests/account_validation_rules.rs new file mode 100644 index 000000000000..fa4b634a22f6 --- /dev/null +++ b/core/lib/multivm/src/versions/vm_fast/tests/account_validation_rules.rs @@ -0,0 +1,7 @@ +use super::TestedFastVm; +use crate::versions::testonly::account_validation_rules::test_account_validation_rules; + +#[test] +fn test_account_validation_rules_fast() { + test_account_validation_rules::>(); +} diff --git a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs index 2093d0ec496f..e148444922ba 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs @@ -1,22 +1,25 @@ use std::{any::Any, collections::HashSet, fmt, rc::Rc}; use zksync_types::{ - h256_to_u256, writes::StateDiffRecord, StorageKey, Transaction, H160, H256, U256, + h256_to_u256, l2::L2Tx, writes::StateDiffRecord, StorageKey, Transaction, H160, H256, U256, }; -use zksync_vm2::interface::{Event, HeapId, StateInterface}; +use zksync_vm2::interface::{Event, HeapId, StateInterface, Tracer}; use zksync_vm_interface::{ pubdata::{PubdataBuilder, PubdataInput}, storage::ReadStorage, - CurrentExecutionState, L2BlockEnv, VmExecutionMode, VmExecutionResultAndLogs, VmInterface, + tracer::ViolatedValidationRule, + CurrentExecutionState, InspectExecutionMode, L2BlockEnv, VmExecutionMode, + VmExecutionResultAndLogs, VmInterface, }; -use super::{circuits_tracer::CircuitsTracer, Vm}; +use super::{FullValidationTracer, ValidationTracer, Vm}; use crate::{ interface::storage::{ImmutableStorageView, InMemoryStorage}, - versions::testonly::TestedVm, - vm_fast::evm_deploy_tracer::{DynamicBytecodes, EvmDeployTracer}, + versions::testonly::{validation_params, TestedVm, TestedVmForValidation}, + vm_fast::tracers::WithBuiltinTracers, }; +mod account_validation_rules; mod block_tip; mod bootloader; mod bytecode_publishing; @@ -80,7 +83,13 @@ impl PartialEq for VmStateDump { } } -impl TestedVm for Vm> { +pub(crate) type TestedFastVm = Vm, Tr, Val>; + +impl TestedVm for TestedFastVm +where + Tr: 'static + Tracer + Default + fmt::Debug, + Val: 'static + ValidationTracer + fmt::Debug, +{ type StateDump = VmStateDump; fn dump_state(&self) -> Self::StateDump { @@ -126,13 +135,9 @@ impl TestedVm for Vm> { } fn manually_decommit(&mut self, code_hash: H256) -> bool { - let mut tracer = ( - ((), CircuitsTracer::default()), - EvmDeployTracer::new(DynamicBytecodes::default()), - ); let (_, is_fresh) = self.inner.world_diff_mut().decommit_opcode( &mut self.world, - &mut tracer, + &mut WithBuiltinTracers::mock(), h256_to_u256(code_hash), ); is_fresh @@ -174,3 +179,13 @@ impl TestedVm for Vm> { self.bootloader_state.get_pubdata_information().clone() } } + +impl TestedVmForValidation for Vm, (), FullValidationTracer> { + fn run_validation(&mut self, tx: L2Tx, timestamp: u64) -> Option { + let validation_params = validation_params(&tx, &self.system_env); + self.push_transaction(tx.into()); + let mut tracer = ((), FullValidationTracer::new(validation_params, timestamp)); + self.inspect(&mut tracer, InspectExecutionMode::OneTx); + tracer.1.validation_error() + } +} diff --git a/core/lib/multivm/src/versions/vm_fast/circuits_tracer.rs b/core/lib/multivm/src/versions/vm_fast/tracers/circuits.rs similarity index 100% rename from core/lib/multivm/src/versions/vm_fast/circuits_tracer.rs rename to core/lib/multivm/src/versions/vm_fast/tracers/circuits.rs diff --git a/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs b/core/lib/multivm/src/versions/vm_fast/tracers/evm_deploy.rs similarity index 94% rename from core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs rename to core/lib/multivm/src/versions/vm_fast/tracers/evm_deploy.rs index c443c99ccf9a..0fbf9dec7215 100644 --- a/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs +++ b/core/lib/multivm/src/versions/vm_fast/tracers/evm_deploy.rs @@ -8,14 +8,14 @@ use zksync_vm2::interface::{ CallframeInterface, CallingMode, GlobalStateInterface, Opcode, OpcodeType, ShouldStop, Tracer, }; -use super::utils::read_fat_pointer; +use crate::vm_fast::utils::read_fat_pointer; /// Container for dynamic bytecodes added by [`EvmDeployTracer`]. #[derive(Debug, Clone, Default)] -pub(super) struct DynamicBytecodes(Rc>>>); +pub(crate) struct DynamicBytecodes(Rc>>>); impl DynamicBytecodes { - pub(super) fn map(&self, hash: U256, f: impl FnOnce(&[u8]) -> R) -> Option { + pub(crate) fn map(&self, hash: U256, f: impl FnOnce(&[u8]) -> R) -> Option { self.0.borrow().get(&hash).map(|code| f(code)) } diff --git a/core/lib/multivm/src/versions/vm_fast/tracers/mod.rs b/core/lib/multivm/src/versions/vm_fast/tracers/mod.rs new file mode 100644 index 000000000000..3d9602536743 --- /dev/null +++ b/core/lib/multivm/src/versions/vm_fast/tracers/mod.rs @@ -0,0 +1,86 @@ +//! Tracers for the fast VM. + +use zksync_vm2::interface::{CycleStats, GlobalStateInterface, OpcodeType, ShouldStop, Tracer}; + +pub(super) use self::evm_deploy::DynamicBytecodes; +pub use self::validation::{FullValidationTracer, ValidationTracer}; +use self::{circuits::CircuitsTracer, evm_deploy::EvmDeployTracer}; +use crate::interface::CircuitStatistic; + +mod circuits; +mod evm_deploy; +mod validation; + +#[derive(Debug)] +pub(super) struct WithBuiltinTracers { + pub external: Ext, + pub validation: Val, + circuits: CircuitsTracer, + evm_deploy_tracer: EvmDeployTracer, +} + +impl WithBuiltinTracers { + pub(super) fn new(external: Tr, validation: Val, dynamic_bytecodes: DynamicBytecodes) -> Self { + Self { + external, + validation, + circuits: CircuitsTracer::default(), + evm_deploy_tracer: EvmDeployTracer::new(dynamic_bytecodes), + } + } + + pub(super) fn circuit_statistic(&self) -> CircuitStatistic { + self.circuits.circuit_statistic() + } +} + +#[cfg(test)] +impl WithBuiltinTracers { + pub(super) fn mock() -> Self { + Self::new(Tr::default(), Val::default(), DynamicBytecodes::default()) + } +} + +impl Tracer for WithBuiltinTracers { + #[inline(always)] + fn before_instruction(&mut self, state: &mut S) { + self.validation.before_instruction::(state); + self.external.before_instruction::(state); + self.circuits.before_instruction::(state); + self.evm_deploy_tracer.before_instruction::(state); + } + + #[inline(always)] + fn after_instruction( + &mut self, + state: &mut S, + ) -> ShouldStop { + if matches!( + self.validation.after_instruction::(state), + ShouldStop::Stop + ) { + return ShouldStop::Stop; + } + if matches!( + self.external.after_instruction::(state), + ShouldStop::Stop + ) { + return ShouldStop::Stop; + } + if matches!( + self.circuits.after_instruction::(state), + ShouldStop::Stop + ) { + return ShouldStop::Stop; + } + self.evm_deploy_tracer.after_instruction::(state) + } + + #[inline(always)] + fn on_extra_prover_cycles(&mut self, stats: CycleStats) { + self.validation.on_extra_prover_cycles(stats); + self.external.on_extra_prover_cycles(stats); + self.circuits.on_extra_prover_cycles(stats); + self.evm_deploy_tracer.on_extra_prover_cycles(stats); + } +} diff --git a/core/lib/multivm/src/versions/vm_fast/tracers/validation.rs b/core/lib/multivm/src/versions/vm_fast/tracers/validation.rs new file mode 100644 index 000000000000..52b0a4747b7d --- /dev/null +++ b/core/lib/multivm/src/versions/vm_fast/tracers/validation.rs @@ -0,0 +1,296 @@ +use std::collections::HashSet; + +use zk_evm_1_3_1::address_to_u256; +use zksync_types::{ + u256_to_address, Address, ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS, + CONTRACT_DEPLOYER_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, L2_BASE_TOKEN_ADDRESS, + MSG_VALUE_SIMULATOR_ADDRESS, SYSTEM_CONTEXT_ADDRESS, U256, +}; +use zksync_vm2::interface::{ + CallframeInterface, GlobalStateInterface, Opcode::*, OpcodeType, ReturnType::*, ShouldStop, + Tracer, +}; +use zksync_vm_interface::tracer::{ + TimestampAsserterParams, ValidationParams, ValidationTraces, ViolatedValidationRule, +}; + +use crate::{tracers::TIMESTAMP_ASSERTER_FUNCTION_SELECTOR, vm_fast::utils::read_fat_pointer}; + +/// [`Tracer`] used for account validation per [EIP-4337] and [EIP-7562]. +/// +/// [EIP-4337]: https://eips.ethereum.org/EIPS/eip-4337 +/// [EIP-7562]: https://eips.ethereum.org/EIPS/eip-7562 +pub trait ValidationTracer: Tracer + Default { + /// Should the execution stop after validation is complete? + const STOP_AFTER_VALIDATION: bool; + /// Hook called when account validation is entered. + fn account_validation_entered(&mut self); + /// Hook called when account validation is exited. + fn validation_exited(&mut self); +} + +impl ValidationTracer for () { + const STOP_AFTER_VALIDATION: bool = false; + fn account_validation_entered(&mut self) {} + fn validation_exited(&mut self) {} +} + +/// Account abstraction exposes a chain to denial of service attacks because someone who fails to +/// authenticate does not pay for the failed transaction. Otherwise, people could empty other's +/// wallets for free! +/// +/// If some address repeatedly posts transactions that validate during preliminary checks but fail +/// to validate during the actual execution, that address is considered a spammer. However, when +/// the spam comes from multiple addresses, that doesn't work. +/// +/// We want to ensure that a spammer has to pay for every account that fails validation. This is +/// achieved by limiting what the code of a custom account is allowed to do. If we allowed access +/// to things like time, a validation that fails in the sequencer could be crafted for free, so we +/// don't. +/// +/// However, we want to give access to storage. A spammer has to pay for changing storage but +/// could change just one storage slot to invalidate transactions from many accounts. To prevent +/// that, we make sure that the storage slots accessed by different accounts are disjoint by only +/// allowing access to storage in the account itself and slots derived from the account's address. +/// +/// Our rules are an extension of the rules are outlined in [EIP-7562]. +/// +/// This tracer enforces the rules by checking what the code does at runtime, even though the +/// properties checked are supposed to always hold for a well-written custom account. Proving +/// that a contract adheres to the rules ahead of time would be challenging or even impossible, +/// considering that contracts that the code depends on may get upgraded. +/// +/// [EIP-7562]: https://eips.ethereum.org/EIPS/eip-7562 +#[derive(Debug, Default)] +pub struct FullValidationTracer { + in_validation: bool, + add_return_value_to_allowed_slots: bool, + + slots_obtained_via_keccak: HashSet, + trusted_addresses: HashSet
, + + user_address: Address, + trusted_storage: HashSet<(Address, U256)>, + /// These location's values are added to [Self::trusted_addresses] to support upgradeable proxies. + storage_containing_trusted_addresses: HashSet<(Address, U256)>, + timestamp_asserter_params: Option, + l1_batch_timestamp: u64, + + validation_error: Option, + traces: ValidationTraces, +} + +impl ValidationTracer for FullValidationTracer { + const STOP_AFTER_VALIDATION: bool = true; + + fn account_validation_entered(&mut self) { + self.in_validation = true; + } + + fn validation_exited(&mut self) { + self.in_validation = false; + } +} + +impl Tracer for FullValidationTracer { + fn before_instruction(&mut self, state: &mut S) { + if !self.in_validation { + return; + } + + match OP::VALUE { + // Out of gas once means out of gas for the whole validation, as the EIP forbids handling out of gas errors + Ret(Panic) if state.current_frame().gas() == 0 => { + self.set_error(ViolatedValidationRule::TookTooManyComputationalGas(0)) + } + + ContextMeta => self.set_error(ViolatedValidationRule::TouchedDisallowedContext), + + StorageRead => { + let address = state.current_frame().address(); + let caller = state.current_frame().caller(); + + // Can unwrap because the instruction pointer does not point to a panic instruction + let pc = state.current_frame().program_counter().unwrap(); + let word = pc / 4; + let part = pc % 4; + let instruction = + state.current_frame().read_contract_code(word).0[3 - part as usize]; + let slot = state.read_register((instruction >> 16) as u8 & 0b1111).0; + + if self + .storage_containing_trusted_addresses + .contains(&(address, slot)) + { + self.trusted_addresses + .insert(u256_to_address(&state.get_storage(address, slot))); + } else if !self.is_valid_storage_read( + address, + caller, + slot, + state.get_storage(address, slot), + ) { + self.set_error(ViolatedValidationRule::TouchedDisallowedStorageSlots( + address, slot, + )) + } + } + + _ => {} + } + } + + fn after_instruction( + &mut self, + state: &mut S, + ) -> ShouldStop { + if !self.in_validation { + return ShouldStop::Continue; + } + + if self.validation_error.is_some() { + return ShouldStop::Stop; + } + + match OP::VALUE { + FarCall(_) => { + // Intercept calls to keccak, whitelist storage slots corresponding to the hash + let code_address = state.current_frame().code_address(); + if code_address == KECCAK256_PRECOMPILE_ADDRESS { + let calldata = read_fat_pointer(state, state.read_register(1).0); + if calldata.len() != 64 { + return ShouldStop::Continue; + } + + // Solidity mappings store values at the keccak256 hash of `key ++ slot_of_mapping` + let (key, mapping) = calldata.split_at(32); + + let mapping_is_allowed = + self.slots_obtained_via_keccak.contains(&mapping.into()); + + if U256::from(key) == address_to_u256(&self.user_address) || mapping_is_allowed + { + self.add_return_value_to_allowed_slots = true; + } + } else if code_address != self.user_address + && state + .get_storage(ACCOUNT_CODE_STORAGE_ADDRESS, address_to_u256(&code_address)) + .is_zero() + { + self.set_error(ViolatedValidationRule::CalledContractWithNoCode( + code_address, + )); + return ShouldStop::Stop; + } + + if let Some(ref params) = self.timestamp_asserter_params { + if code_address == params.address { + let calldata = read_fat_pointer(state, state.read_register(1).0); + if calldata.len() == 68 + && calldata[..4] == TIMESTAMP_ASSERTER_FUNCTION_SELECTOR + { + // start and end need to be capped to u64::MAX to avoid overflow + let start = U256::from_big_endian( + &calldata[calldata.len() - 64..calldata.len() - 32], + ) + .try_into() + .unwrap_or(u64::MAX); + let end = U256::from_big_endian(&calldata[calldata.len() - 32..]) + .try_into() + .unwrap_or(u64::MAX); + + // using self.l1_batch_env.timestamp is ok here because the tracer is always + // used in a oneshot execution mode + if end < self.l1_batch_timestamp + params.min_time_till_end.as_secs() { + self.set_error( + ViolatedValidationRule::TimestampAssertionCloseToRangeEnd, + ); + return ShouldStop::Stop; + } + + self.traces.apply_timestamp_asserter_range(start..end); + } + } + } + } + Ret(kind) => { + if self.add_return_value_to_allowed_slots && kind == Normal { + let return_value = read_fat_pointer(state, state.read_register(1).0); + self.slots_obtained_via_keccak + .insert(return_value.as_slice().into()); + } + self.add_return_value_to_allowed_slots = false; + } + _ => {} + } + + ShouldStop::Continue + } +} + +impl FullValidationTracer { + pub fn new(params: ValidationParams, l1_batch_timestamp: u64) -> Self { + let ValidationParams { + user_address, + trusted_slots, + trusted_addresses, + trusted_address_slots, + timestamp_asserter_params, + .. + } = params; + Self { + user_address, + trusted_storage: trusted_slots, + trusted_addresses, + storage_containing_trusted_addresses: trusted_address_slots, + l1_batch_timestamp, + timestamp_asserter_params, + + ..Self::default() + } + } + + fn is_valid_storage_read( + &self, + address: Address, + caller: Address, + slot: U256, + value: U256, + ) -> bool { + // allow reading own slots + address == self.user_address + // allow reading slot + || slot == address_to_u256(&self.user_address) + || self.slots_obtained_via_keccak.contains(&slot) + // some storage locations are always allowed + || self.trusted_addresses.contains(&address) + || self.trusted_storage.contains(&(address, slot)) + // certain system contracts are allowed to transfer ETH + || address == L2_BASE_TOKEN_ADDRESS + && (caller == MSG_VALUE_SIMULATOR_ADDRESS + || caller == CONTRACT_DEPLOYER_ADDRESS + || caller == BOOTLOADER_ADDRESS) + // allow getting chain_id + || address == SYSTEM_CONTEXT_ADDRESS && slot == U256::zero() + // allow reading code hashes of existing contracts + || address == ACCOUNT_CODE_STORAGE_ADDRESS && !value.is_zero() + // allow TimestampAsserter to do its job + || self.timestamp_asserter_params.as_ref() + .map(|p| p.address == caller) + .unwrap_or_default() + } + + fn set_error(&mut self, error: ViolatedValidationRule) { + if self.validation_error.is_none() { + self.validation_error = Some(error); + } + } + + pub fn validation_error(&self) -> Option { + self.validation_error.clone() + } + + pub fn traces(&self) -> ValidationTraces { + self.traces.clone() + } +} diff --git a/core/lib/multivm/src/versions/vm_fast/vm.rs b/core/lib/multivm/src/versions/vm_fast/vm.rs index c935b1c0e7f5..e2310c254e96 100644 --- a/core/lib/multivm/src/versions/vm_fast/vm.rs +++ b/core/lib/multivm/src/versions/vm_fast/vm.rs @@ -27,10 +27,9 @@ use zksync_vm2::{ use super::{ bootloader_state::{BootloaderState, BootloaderStateSnapshot}, bytecode::compress_bytecodes, - circuits_tracer::CircuitsTracer, - evm_deploy_tracer::{DynamicBytecodes, EvmDeployTracer}, hook::Hook, initial_bootloader_memory::bootloader_initial_memory, + tracers::{DynamicBytecodes, ValidationTracer, WithBuiltinTracers}, transaction_data::TransactionData, }; use crate::{ @@ -58,8 +57,6 @@ use crate::{ VmVersion, }; -type FullTracer = ((Tr, CircuitsTracer), EvmDeployTracer); - #[derive(Debug)] struct VmRunResult { execution_result: ExecutionResult, @@ -85,15 +82,18 @@ impl VmRunResult { } } +type InnerVm = + VirtualMachine, World>>; + /// Fast VM wrapper. /// -/// The wrapper is parametric by the storage and tracer types. Besides the [`Tracer`] trait, a tracer must have `'static` lifetime -/// and implement [`Default`] (the latter is necessary to complete batches). [`CircuitsTracer`] is currently always enabled; -/// you don't need to specify it explicitly. -pub struct Vm { - pub(super) world: World>, - pub(super) inner: VirtualMachine, World>>, - gas_for_account_validation: u32, +/// The wrapper is parametric by the storage and tracer types. Besides the [`Tracer`] trait, the tracer must implement [`Default`] +/// (the latter is necessary to complete batches). Validation is encapsulated in a separate type param. It should be set to `()` +/// for "standard" validation (not stopping after validation; no validation-specific checks), or [`FullValidationTracer`](super::FullValidationTracer) +/// for full validation (stopping after validation; validation-specific checks). +pub struct Vm { + pub(super) world: World>, + pub(super) inner: InnerVm, pub(super) bootloader_state: BootloaderState, pub(super) batch_env: L1BatchEnv, pub(super) system_env: SystemEnv, @@ -103,7 +103,7 @@ pub struct Vm { enforced_state_diffs: Option>, } -impl Vm { +impl Vm { pub fn custom(batch_env: L1BatchEnv, system_env: SystemEnv, storage: S) -> Self { let vm_version: FastVmVersion = VmVersion::from(system_env.version) .try_into() @@ -161,7 +161,6 @@ impl Vm { let mut this = Self { world: World::new(storage, program_cache), inner, - gas_for_account_validation: system_env.default_validation_computational_gas_limit, bootloader_state: BootloaderState::new( system_env.execution_mode, bootloader_memory.clone(), @@ -179,13 +178,218 @@ impl Vm { this } + fn get_hook_params(&self) -> [U256; 3] { + (get_vm_hook_params_start_position(self.vm_version.into()) + ..get_vm_hook_params_start_position(self.vm_version.into()) + VM_HOOK_PARAMS_COUNT) + .map(|word| self.read_word_from_bootloader_heap(word as usize)) + .collect::>() + .try_into() + .unwrap() + } + + fn get_tx_result(&self) -> U256 { + let tx_idx = self.bootloader_state.current_tx(); + let slot = get_result_success_first_slot(self.vm_version.into()) as usize + tx_idx; + self.read_word_from_bootloader_heap(slot) + } + + fn get_debug_log(&self) -> (String, String) { + let hook_params = self.get_hook_params(); + let mut msg = u256_to_h256(hook_params[0]).as_bytes().to_vec(); + // Trim 0 byte padding at the end. + while msg.last() == Some(&0) { + msg.pop(); + } + + let data = hook_params[1]; + let msg = String::from_utf8(msg).expect("Invalid debug message"); + + // For long data, it is better to use hex-encoding for greater readability + let data_str = if data > U256::from(u64::MAX) { + format!("0x{data:x}") + } else { + data.to_string() + }; + (msg, data_str) + } + + /// Should only be used when the bootloader is executing (e.g., when handling hooks). + pub(crate) fn read_word_from_bootloader_heap(&self, word: usize) -> U256 { + let start_address = word as u32 * 32; + self.inner.read_heap_u256(HeapId::FIRST, start_address) + } + + fn read_bytes_from_heap(&self, ptr: FatPointer) -> Vec { + assert_eq!(ptr.offset, 0); + (ptr.start..ptr.start + ptr.length) + .map(|addr| self.inner.read_heap_byte(ptr.memory_page, addr)) + .collect() + } + + pub(crate) fn has_previous_far_calls(&mut self) -> bool { + let callframe_count = self.inner.number_of_callframes(); + (1..callframe_count).any(|i| !self.inner.callframe(i).is_near_call()) + } + + /// Should only be used when the bootloader is executing (e.g., when handling hooks). + pub(crate) fn write_to_bootloader_heap( + &mut self, + memory: impl IntoIterator, + ) { + assert!( + !self.has_previous_far_calls(), + "Cannot write to bootloader heap when not in root call frame" + ); + + for (slot, value) in memory { + let start_address = slot as u32 * 32; + self.inner + .write_heap_u256(HeapId::FIRST, start_address, value); + } + } + + pub(crate) fn insert_bytecodes<'a>(&mut self, bytecodes: impl IntoIterator) { + for code in bytecodes { + let hash = BytecodeHash::for_bytecode(code).value_u256(); + self.world.bytecode_cache.insert(hash, code.into()); + } + } + + pub(crate) fn push_transaction_inner( + &mut self, + tx: zksync_types::Transaction, + refund: u64, + with_compression: bool, + ) { + let tx: TransactionData = tx.into(); + let overhead = tx.overhead_gas(); + + self.insert_bytecodes(tx.factory_deps.iter().map(|dep| &dep[..])); + + let compressed_bytecodes = if is_l1_tx_type(tx.tx_type) || !with_compression { + // L1 transactions do not need compression + vec![] + } else { + compress_bytecodes(&tx.factory_deps, |hash| { + self.inner + .world_diff() + .get_storage_state() + .get(&(KNOWN_CODES_STORAGE_ADDRESS, h256_to_u256(hash))) + .map(|x| !x.is_zero()) + .unwrap_or_else(|| self.world.storage.is_bytecode_known(&hash)) + }) + }; + + let trusted_ergs_limit = tx.trusted_ergs_limit(); + + let memory = self.bootloader_state.push_tx( + tx, + overhead, + refund, + compressed_bytecodes, + trusted_ergs_limit, + self.system_env.chain_id, + ); + + self.write_to_bootloader_heap(memory); + } + + #[cfg(test)] + pub(super) fn enforce_state_diffs(&mut self, diffs: Vec) { + self.enforced_state_diffs = Some(diffs); + } + + fn compute_state_diffs(&mut self) -> Vec { + #[cfg(test)] + if let Some(enforced_diffs) = self.enforced_state_diffs.take() { + return enforced_diffs; + } + + let storage = &mut self.world.storage; + let diffs = + self.inner + .world_diff() + .get_storage_changes() + .map(move |((address, key), change)| { + let storage_key = + StorageKey::new(AccountTreeId::new(address), u256_to_h256(key)); + StateDiffRecord { + address, + key, + derived_key: LogQuery::derive_final_address_for_params(&address, &key), + enumeration_index: storage + .get_enumeration_index(&storage_key) + .unwrap_or_default(), + initial_value: change.before, + final_value: change.after, + } + }); + diffs + .filter(|diff| diff.address != L1_MESSENGER_ADDRESS) + .collect() + } + + pub(crate) fn decommitted_hashes(&self) -> impl Iterator + '_ { + self.inner.world_diff().decommitted_hashes() + } + + pub(super) fn gas_remaining(&mut self) -> u32 { + self.inner.current_frame().gas() + } + + // visible for testing + pub(super) fn get_current_execution_state(&self) -> CurrentExecutionState { + let world_diff = self.inner.world_diff(); + let vm = &self.inner; + let events = merge_events(vm.events(), self.batch_env.number); + + let user_l2_to_l1_logs = extract_l2tol1logs_from_l1_messenger(&events) + .into_iter() + .map(Into::into) + .map(UserL2ToL1Log) + .collect(); + + CurrentExecutionState { + events, + deduplicated_storage_logs: world_diff + .get_storage_changes() + .map(|((address, key), change)| StorageLog { + key: StorageKey::new(AccountTreeId::new(address), u256_to_h256(key)), + value: u256_to_h256(change.after), + kind: StorageLogKind::RepeatedWrite, // Initialness doesn't matter here + }) + .collect(), + used_contract_hashes: self.decommitted_hashes().collect(), + system_logs: vm.l2_to_l1_logs().map(GlueInto::glue_into).collect(), + user_l2_to_l1_logs, + storage_refunds: world_diff.storage_refunds().to_vec(), + pubdata_costs: world_diff.pubdata_costs().to_vec(), + } + } +} + +struct AccountValidationGasSplit { + gas_given: u32, + gas_hidden: u32, +} + +impl Vm +where + S: ReadStorage, + Tr: Tracer + Default, + Val: ValidationTracer, +{ fn run( &mut self, execution_mode: VmExecutionMode, - tracer: &mut FullTracer, + tracer: &mut WithBuiltinTracers, track_refunds: bool, pubdata_builder: Option<&dyn PubdataBuilder>, ) -> VmRunResult { + let mut gas_left_for_account_validation = + self.system_env.default_validation_computational_gas_limit; + let mut account_validation_gas_split = None; + let mut refunds = Refunds { gas_refunded: 0, operator_suggested_refund: 0, @@ -227,10 +431,47 @@ impl Vm { } }; - match Hook::from_u32(hook) { - Hook::AccountValidationEntered | Hook::AccountValidationExited => { - // TODO (PLA-908): implement account validation + let hook = Hook::from_u32(hook); + match hook { + Hook::AccountValidationEntered => { + assert!( + account_validation_gas_split.is_none(), + "Account validation can't be nested" + ); + tracer.validation.account_validation_entered(); + + let gas = self.gas_remaining(); + let gas_given = gas.min(gas_left_for_account_validation); + account_validation_gas_split = Some(AccountValidationGasSplit { + gas_given, + gas_hidden: gas - gas_given, + }); + // As long as gasleft is allowed during account validation, + // the VM must not be used in the sequencer because a malicious + // account cause proving failure by checking if gasleft > 100k + self.inner.current_frame().set_gas(gas_given); + } + + Hook::ValidationExited => { + tracer.validation.validation_exited(); + + if let Some(AccountValidationGasSplit { + gas_given, + gas_hidden, + }) = account_validation_gas_split.take() + { + let gas_left = self.inner.current_frame().gas(); + gas_left_for_account_validation -= gas_given - gas_left; + self.inner.current_frame().set_gas(gas_left + gas_hidden); + } } + + Hook::ValidationStepEnded => { + if Val::STOP_AFTER_VALIDATION { + break (ExecutionResult::Success { output: vec![] }, true); + } + } + Hook::TxHasEnded => { if let VmExecutionMode::OneTx = execution_mode { // The bootloader may invoke `TxHasEnded` hook without posting a tx result previously. One case when this can happen @@ -355,6 +596,10 @@ impl Vm { state_diffs: self.compute_state_diffs(), }; + // Save the pubdata for the future initial bootloader memory building + self.bootloader_state + .set_pubdata_input(pubdata_input.clone()); + // Apply the pubdata to the current memory let mut memory_to_apply = vec![]; @@ -365,12 +610,9 @@ impl Vm { self.system_env.version, ); self.write_to_bootloader_heap(memory_to_apply); - - // Save the pubdata for the future initial bootloader memory building - self.bootloader_state.set_pubdata_input(pubdata_input); } - Hook::PaymasterValidationEntered | Hook::ValidationStepEnded => { /* unused */ } + Hook::PaymasterValidationEntered => { /* unused */ } Hook::DebugLog => { let (log, log_arg) = self.get_debug_log(); let last_tx = self.bootloader_state.last_l2_block().txs.last(); @@ -391,198 +633,9 @@ impl Vm { } } - fn get_hook_params(&self) -> [U256; 3] { - (get_vm_hook_params_start_position(self.vm_version.into()) - ..get_vm_hook_params_start_position(self.vm_version.into()) + VM_HOOK_PARAMS_COUNT) - .map(|word| self.read_word_from_bootloader_heap(word as usize)) - .collect::>() - .try_into() - .unwrap() - } - - fn get_tx_result(&self) -> U256 { - let tx_idx = self.bootloader_state.current_tx(); - let slot = get_result_success_first_slot(self.vm_version.into()) as usize + tx_idx; - self.read_word_from_bootloader_heap(slot) - } - - fn get_debug_log(&self) -> (String, String) { - let hook_params = self.get_hook_params(); - let mut msg = u256_to_h256(hook_params[0]).as_bytes().to_vec(); - // Trim 0 byte padding at the end. - while msg.last() == Some(&0) { - msg.pop(); - } - - let data = hook_params[1]; - let msg = String::from_utf8(msg).expect("Invalid debug message"); - - // For long data, it is better to use hex-encoding for greater readability - let data_str = if data > U256::from(u64::MAX) { - format!("0x{data:x}") - } else { - data.to_string() - }; - (msg, data_str) - } - - /// Should only be used when the bootloader is executing (e.g., when handling hooks). - pub(crate) fn read_word_from_bootloader_heap(&self, word: usize) -> U256 { - let start_address = word as u32 * 32; - self.inner.read_heap_u256(HeapId::FIRST, start_address) - } - - fn read_bytes_from_heap(&self, ptr: FatPointer) -> Vec { - assert_eq!(ptr.offset, 0); - (ptr.start..ptr.start + ptr.length) - .map(|addr| self.inner.read_heap_byte(ptr.memory_page, addr)) - .collect() - } - - pub(crate) fn has_previous_far_calls(&mut self) -> bool { - let callframe_count = self.inner.number_of_callframes(); - (1..callframe_count).any(|i| !self.inner.callframe(i).is_near_call()) - } - - /// Should only be used when the bootloader is executing (e.g., when handling hooks). - pub(crate) fn write_to_bootloader_heap( - &mut self, - memory: impl IntoIterator, - ) { - assert!( - !self.has_previous_far_calls(), - "Cannot write to bootloader heap when not in root call frame" - ); - - for (slot, value) in memory { - let start_address = slot as u32 * 32; - self.inner - .write_heap_u256(HeapId::FIRST, start_address, value); - } - } - - pub(crate) fn insert_bytecodes<'a>(&mut self, bytecodes: impl IntoIterator) { - for code in bytecodes { - let hash = BytecodeHash::for_bytecode(code).value_u256(); - self.world.bytecode_cache.insert(hash, code.into()); - } - } - - pub(crate) fn push_transaction_inner( - &mut self, - tx: zksync_types::Transaction, - refund: u64, - with_compression: bool, - ) { - let tx: TransactionData = tx.into(); - let overhead = tx.overhead_gas(); - - self.insert_bytecodes(tx.factory_deps.iter().map(|dep| &dep[..])); - - let compressed_bytecodes = if is_l1_tx_type(tx.tx_type) || !with_compression { - // L1 transactions do not need compression - vec![] - } else { - compress_bytecodes(&tx.factory_deps, |hash| { - self.inner - .world_diff() - .get_storage_state() - .get(&(KNOWN_CODES_STORAGE_ADDRESS, h256_to_u256(hash))) - .map(|x| !x.is_zero()) - .unwrap_or_else(|| self.world.storage.is_bytecode_known(&hash)) - }) - }; - - let trusted_ergs_limit = tx.trusted_ergs_limit(); - - let memory = self.bootloader_state.push_tx( - tx, - overhead, - refund, - compressed_bytecodes, - trusted_ergs_limit, - self.system_env.chain_id, - ); - - self.write_to_bootloader_heap(memory); - } - - #[cfg(test)] - pub(super) fn enforce_state_diffs(&mut self, diffs: Vec) { - self.enforced_state_diffs = Some(diffs); - } - - fn compute_state_diffs(&mut self) -> Vec { - #[cfg(test)] - if let Some(enforced_diffs) = self.enforced_state_diffs.take() { - return enforced_diffs; - } - - let storage = &mut self.world.storage; - let diffs = - self.inner - .world_diff() - .get_storage_changes() - .map(move |((address, key), change)| { - let storage_key = - StorageKey::new(AccountTreeId::new(address), u256_to_h256(key)); - StateDiffRecord { - address, - key, - derived_key: LogQuery::derive_final_address_for_params(&address, &key), - enumeration_index: storage - .get_enumeration_index(&storage_key) - .unwrap_or_default(), - initial_value: change.before, - final_value: change.after, - } - }); - diffs - .filter(|diff| diff.address != L1_MESSENGER_ADDRESS) - .collect() - } - - pub(crate) fn decommitted_hashes(&self) -> impl Iterator + '_ { - self.inner.world_diff().decommitted_hashes() - } - - pub(super) fn gas_remaining(&mut self) -> u32 { - self.inner.current_frame().gas() - } - - // visible for testing - pub(super) fn get_current_execution_state(&self) -> CurrentExecutionState { - let world_diff = self.inner.world_diff(); - let vm = &self.inner; - let events = merge_events(vm.events(), self.batch_env.number); - - let user_l2_to_l1_logs = extract_l2tol1logs_from_l1_messenger(&events) - .into_iter() - .map(Into::into) - .map(UserL2ToL1Log) - .collect(); - - CurrentExecutionState { - events, - deduplicated_storage_logs: world_diff - .get_storage_changes() - .map(|((address, key), change)| StorageLog { - key: StorageKey::new(AccountTreeId::new(address), u256_to_h256(key)), - value: u256_to_h256(change.after), - kind: StorageLogKind::RepeatedWrite, // Initialness doesn't matter here - }) - .collect(), - used_contract_hashes: self.decommitted_hashes().collect(), - system_logs: vm.l2_to_l1_logs().map(GlueInto::glue_into).collect(), - user_l2_to_l1_logs, - storage_refunds: world_diff.storage_refunds().to_vec(), - pubdata_costs: world_diff.pubdata_costs().to_vec(), - } - } - pub(crate) fn inspect_inner( &mut self, - tracer: &mut Tr, + tracer: &mut (Tr, Val), execution_mode: VmExecutionMode, pubdata_builder: Option<&dyn PubdataBuilder>, ) -> VmExecutionResultAndLogs { @@ -595,19 +648,18 @@ impl Vm { let start = self.inner.world_diff().snapshot(); let gas_before = self.gas_remaining(); + let (external, validation) = mem::take(tracer); + let mut full_tracer = + WithBuiltinTracers::new(external, validation, self.world.dynamic_bytecodes.clone()); - let mut full_tracer = ( - (mem::take(tracer), CircuitsTracer::default()), - EvmDeployTracer::new(self.world.dynamic_bytecodes.clone()), - ); let result = self.run( execution_mode, &mut full_tracer, track_refunds, pubdata_builder, ); - let ((external_tracer, circuits_tracer), _) = full_tracer; - *tracer = external_tracer; // place the tracer back + let circuit_statistic = full_tracer.circuit_statistic(); + *tracer = (full_tracer.external, full_tracer.validation); let ignore_world_diff = matches!(execution_mode, VmExecutionMode::OneTx) && result.should_ignore_vm_logs(); @@ -680,7 +732,7 @@ impl Vm { gas_remaining, computational_gas_used: gas_used, // since 1.5.0, this always has the same value as `gas_used` pubdata_published: result.pubdata_published, - circuit_statistic: circuits_tracer.circuit_statistic(), + circuit_statistic, contracts_used: 0, cycles_used: 0, total_log_queries: 0, @@ -691,10 +743,11 @@ impl Vm { } } -impl VmFactory> for Vm, Tr> +impl VmFactory> for Vm, Tr, Val> where S: ReadStorage, - Tr: Tracer + Default + 'static, + Tr: Tracer + Default, + Val: ValidationTracer, { fn new( batch_env: L1BatchEnv, @@ -706,8 +759,13 @@ where } } -impl VmInterface for Vm { - type TracerDispatcher = Tr; +impl VmInterface for Vm +where + S: ReadStorage, + Tr: Tracer + Default, + Val: ValidationTracer, +{ + type TracerDispatcher = (Tr, Val); fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> { self.push_transaction_inner(tx, 0, true); @@ -730,7 +788,7 @@ impl VmInterface for Vm { fn inspect_transaction_with_bytecode_compression( &mut self, tracer: &mut Self::TracerDispatcher, - tx: zksync_types::Transaction, + tx: Transaction, with_compression: bool, ) -> (BytecodeCompressionResult<'_>, VmExecutionResultAndLogs) { self.push_transaction_inner(tx, 0, with_compression); @@ -753,7 +811,7 @@ impl VmInterface for Vm { fn finish_batch(&mut self, pubdata_builder: Rc) -> FinishedL1Batch { let result = self.inspect_inner( - &mut Tr::default(), + &mut Default::default(), VmExecutionMode::Batch, Some(pubdata_builder.as_ref()), ); @@ -782,10 +840,14 @@ impl VmInterface for Vm { #[derive(Debug)] struct VmSnapshot { bootloader_snapshot: BootloaderStateSnapshot, - gas_for_account_validation: u32, } -impl VmInterfaceHistoryEnabled for Vm { +impl VmInterfaceHistoryEnabled for Vm +where + S: ReadStorage, + Tr: Tracer + Default, + Val: ValidationTracer, +{ fn make_snapshot(&mut self) { assert!( self.snapshot.is_none(), @@ -795,19 +857,16 @@ impl VmInterfaceHistoryEnabled f self.inner.make_snapshot(); self.snapshot = Some(VmSnapshot { bootloader_snapshot: self.bootloader_state.get_snapshot(), - gas_for_account_validation: self.gas_for_account_validation, }); } fn rollback_to_the_latest_snapshot(&mut self) { let VmSnapshot { bootloader_snapshot, - gas_for_account_validation, } = self.snapshot.take().expect("no snapshots to rollback to"); self.inner.rollback(); self.bootloader_state.apply_snapshot(bootloader_snapshot); - self.gas_for_account_validation = gas_for_account_validation; } fn pop_snapshot_no_rollback(&mut self) { @@ -816,19 +875,18 @@ impl VmInterfaceHistoryEnabled f } } -impl VmTrackingContracts for Vm { +impl VmTrackingContracts for Vm +where + Self: VmInterface, +{ fn used_contract_hashes(&self) -> Vec { self.decommitted_hashes().map(u256_to_h256).collect() } } -impl fmt::Debug for Vm { +impl fmt::Debug for Vm { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Vm") - .field( - "gas_for_account_validation", - &self.gas_for_account_validation, - ) .field("bootloader_state", &self.bootloader_state) .field("storage", &self.world.storage) .field("program_cache", &self.world.program_cache) diff --git a/core/lib/multivm/src/versions/vm_latest/tests/account_validation_rules.rs b/core/lib/multivm/src/versions/vm_latest/tests/account_validation_rules.rs new file mode 100644 index 000000000000..8ee6c06c1c69 --- /dev/null +++ b/core/lib/multivm/src/versions/vm_latest/tests/account_validation_rules.rs @@ -0,0 +1,8 @@ +use crate::{ + versions::testonly::account_validation_rules::test_account_validation_rules, vm_latest::Vm, +}; + +#[test] +fn test_account_validation_rules_legacy() { + test_account_validation_rules::>(); +} diff --git a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs index aac3b1655b3a..0a89ddb0bf50 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs @@ -1,6 +1,7 @@ use std::{ collections::{HashMap, HashSet}, rc::Rc, + sync::Arc, }; use zk_evm_1_5_0::{ @@ -9,19 +10,24 @@ use zk_evm_1_5_0::{ zkevm_opcode_defs::{ContractCodeSha256Format, VersionedHashLen32}, }; use zksync_types::{ - bytecode::BytecodeHash, writes::StateDiffRecord, StorageKey, StorageValue, Transaction, H256, - U256, + bytecode::BytecodeHash, l2::L2Tx, vm::VmVersion, writes::StateDiffRecord, StorageKey, + StorageValue, Transaction, H256, U256, }; +use zksync_vm_interface::VmInterface; -use super::{HistoryEnabled, Vm}; +use super::{HistoryEnabled, ToTracerPointer, Vm}; use crate::{ interface::{ pubdata::{PubdataBuilder, PubdataInput}, storage::{InMemoryStorage, ReadStorage, StorageView, WriteStorage}, + tracer::ViolatedValidationRule, CurrentExecutionState, L2BlockEnv, VmExecutionMode, VmExecutionResultAndLogs, }, + tracers::ValidationTracer, utils::bytecode::bytes_to_be_words, - versions::testonly::{filter_out_base_system_contracts, TestedVm}, + versions::testonly::{ + filter_out_base_system_contracts, validation_params, TestedVm, TestedVmForValidation, + }, vm_latest::{ constants::BOOTLOADER_HEAP_PAGE, old_vm::{event_sink::InMemoryEventSink, history_recorder::HistoryRecorder}, @@ -36,6 +42,7 @@ mod bootloader; mod default_aa; // TODO - fix this test // `mod invalid_bytecode;` +mod account_validation_rules; mod block_tip; mod bytecode_publishing; mod call_tracer; @@ -195,6 +202,27 @@ impl TestedVm for TestedLatestVm { } } +impl TestedVmForValidation for TestedLatestVm { + fn run_validation(&mut self, tx: L2Tx, timestamp: u64) -> Option { + let validation_params = validation_params(&tx, &self.system_env); + self.push_transaction(tx.into()); + + let tracer = ValidationTracer::::new( + validation_params, + VmVersion::Vm1_5_0IncreasedBootloaderMemory, + timestamp, + ); + let mut failures = tracer.get_result(); + + self.inspect_inner( + &mut tracer.into_tracer_pointer().into(), + VmExecutionMode::OneTx, + None, + ); + Arc::make_mut(&mut failures).take() + } +} + #[derive(Clone, Debug)] pub(crate) struct ModifiedKeysMap(HashMap); diff --git a/core/lib/multivm/src/vm_instance.rs b/core/lib/multivm/src/vm_instance.rs index 9de99a7eb116..97af38ea0347 100644 --- a/core/lib/multivm/src/vm_instance.rs +++ b/core/lib/multivm/src/vm_instance.rs @@ -1,7 +1,6 @@ use std::{mem, rc::Rc}; use zksync_types::{vm::VmVersion, ProtocolVersionId, Transaction}; -use zksync_vm2::interface::Tracer; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ @@ -14,8 +13,8 @@ use crate::{ VmMemoryMetrics, }, tracers::TracerDispatcher, - vm_fast::FastVmVersion, - vm_latest::HistoryEnabled, + vm_fast::{self, interface::Tracer, FastVmVersion}, + vm_latest::{self, HistoryEnabled}, }; /// Enumeration encompassing all supported legacy VM versions. @@ -35,7 +34,7 @@ pub enum LegacyVmInstance { VmBoojumIntegration(crate::vm_boojum_integration::Vm, H>), Vm1_4_1(crate::vm_1_4_1::Vm, H>), Vm1_4_2(crate::vm_1_4_2::Vm, H>), - Vm1_5_0(crate::vm_latest::Vm, H>), + Vm1_5_0(vm_latest::Vm, H>), } macro_rules! dispatch_legacy_vm { @@ -191,29 +190,29 @@ impl LegacyVmInstance { Self::Vm1_4_2(vm) } VmVersion::Vm1_5_0SmallBootloaderMemory => { - let vm = crate::vm_latest::Vm::new_with_subversion( + let vm = vm_latest::Vm::new_with_subversion( l1_batch_env, system_env, storage_view, - crate::vm_latest::MultiVmSubversion::SmallBootloaderMemory, + vm_latest::MultiVmSubversion::SmallBootloaderMemory, ); Self::Vm1_5_0(vm) } VmVersion::Vm1_5_0IncreasedBootloaderMemory => { - let vm = crate::vm_latest::Vm::new_with_subversion( + let vm = vm_latest::Vm::new_with_subversion( l1_batch_env, system_env, storage_view, - crate::vm_latest::MultiVmSubversion::IncreasedBootloaderMemory, + vm_latest::MultiVmSubversion::IncreasedBootloaderMemory, ); Self::Vm1_5_0(vm) } VmVersion::VmGateway => { - let vm = crate::vm_latest::Vm::new_with_subversion( + let vm = vm_latest::Vm::new_with_subversion( l1_batch_env, system_env, storage_view, - crate::vm_latest::MultiVmSubversion::Gateway, + vm_latest::MultiVmSubversion::Gateway, ); Self::Vm1_5_0(vm) } @@ -227,19 +226,19 @@ impl LegacyVmInstance { } /// Fast VM shadowed by the latest legacy VM. -pub type ShadowedFastVm = ShadowVm< +pub type ShadowedFastVm = ShadowVm< S, - crate::vm_latest::Vm, HistoryEnabled>, - crate::vm_fast::Vm, Tr>, + vm_latest::Vm, HistoryEnabled>, + vm_fast::Vm, Tr, Val>, >; /// Fast VM variants. #[derive(Debug)] -pub enum FastVmInstance { +pub enum FastVmInstance { /// Fast VM running in isolation. - Fast(crate::vm_fast::Vm, Tr>), + Fast(vm_fast::Vm, Tr, Val>), /// Fast VM shadowed by the latest legacy VM. - Shadowed(ShadowedFastVm), + Shadowed(ShadowedFastVm), } macro_rules! dispatch_fast_vm { @@ -251,10 +250,15 @@ macro_rules! dispatch_fast_vm { }; } -impl VmInterface for FastVmInstance { +impl VmInterface for FastVmInstance +where + S: ReadStorage, + Tr: Tracer + Default, + Val: vm_fast::ValidationTracer, +{ type TracerDispatcher = ( - crate::vm_latest::TracerDispatcher, HistoryEnabled>, - Tr, + vm_latest::TracerDispatcher, HistoryEnabled>, + (Tr, Val), ); fn push_transaction(&mut self, tx: Transaction) -> PushTransactionResult<'_> { @@ -299,8 +303,11 @@ impl VmInterface for FastVmInsta } } -impl VmInterfaceHistoryEnabled - for FastVmInstance +impl VmInterfaceHistoryEnabled for FastVmInstance +where + S: ReadStorage, + Tr: Tracer + Default, + Val: vm_fast::ValidationTracer, { fn make_snapshot(&mut self) { dispatch_fast_vm!(self.make_snapshot()); @@ -315,18 +322,19 @@ impl VmInterfaceHistoryEnabled } } -impl FastVmInstance { +impl FastVmInstance +where + S: ReadStorage, + Tr: Tracer + Default, + Val: vm_fast::ValidationTracer, +{ /// Creates an isolated fast VM. pub fn fast( l1_batch_env: L1BatchEnv, system_env: SystemEnv, storage_view: StoragePtr>, ) -> Self { - Self::Fast(crate::vm_fast::Vm::new( - l1_batch_env, - system_env, - storage_view, - )) + Self::Fast(vm_fast::Vm::new(l1_batch_env, system_env, storage_view)) } /// Creates a shadowed fast VM. diff --git a/core/lib/test_contracts/contracts/custom-account/validation-rule-breaker.sol b/core/lib/test_contracts/contracts/custom-account/validation-rule-breaker.sol new file mode 100644 index 000000000000..45961f705be7 --- /dev/null +++ b/core/lib/test_contracts/contracts/custom-account/validation-rule-breaker.sol @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 + +pragma solidity ^0.8.0; + +import "./Constants.sol"; +import "./TransactionHelper.sol"; + +import "./SystemContractsCaller.sol"; + +import "./interfaces/IAccount.sol"; + +contract ValidationRuleBreaker is IAccount { + using TransactionHelper for Transaction; + + uint32 public typeOfRuleBreak; + address public trustedAddress = address(0x800a); + + constructor() { + typeOfRuleBreak = 0; + } + + function setTypeOfRuleBreak(uint32 _typeOfRuleBreak) external { + typeOfRuleBreak = _typeOfRuleBreak; + } + + function validateTransaction( + bytes32 _txHash, + bytes32 _suggestedSignedTxHash, + Transaction calldata _transaction + ) external payable override returns (bytes4 magic) { + // By default we consider the transaction as successful + magic = VALIDATION_SUCCESS_MAGIC; + + if (typeOfRuleBreak == 1) { + // The balance of another account may not be read + // I'm writing assertions because otherwise the compiler would optimize away the access + require(BOOTLOADER_FORMAL_ADDRESS.balance != 0); + } else if (typeOfRuleBreak == 2) { + // May not call an EOA + address(1234567890).call(""); + } else if (typeOfRuleBreak == 3) { + // This should succeed because a trustedAddress is marked as a slot that grants access to the address it contains + require(trustedAddress == address(0x800a)); + require(BOOTLOADER_FORMAL_ADDRESS.balance != 0); + } else if (typeOfRuleBreak == 4) { + // This should still fail; EIP-4337 defines out of gas as an immediate failure + address(this).call( + abi.encodeWithSignature("_runOutOfGasButCatchThePanic()") + ); + } + + _validateTransaction(_suggestedSignedTxHash, _transaction); + } + + function _runOutOfGasButCatchThePanic() external { + address(this).call( + abi.encodeWithSignature("_runOutOfGasButCatchThePanic()") + ); + } + + function _validateTransaction( + bytes32 _suggestedSignedTxHash, + Transaction calldata _transaction + ) internal { + SystemContractsCaller.systemCallWithPropagatedRevert( + uint32(gasleft()), + address(NONCE_HOLDER_SYSTEM_CONTRACT), + 0, + abi.encodeCall( + INonceHolder.incrementMinNonceIfEquals, + (_transaction.nonce) + ) + ); + } + + function executeTransaction( + bytes32, + bytes32, + Transaction calldata _transaction + ) external payable override { + _execute(_transaction); + } + + function executeTransactionFromOutside( + Transaction calldata _transaction + ) external payable override { + _validateTransaction(bytes32(0), _transaction); + _execute(_transaction); + } + + function _execute(Transaction calldata _transaction) internal { + address to = address(uint160(_transaction.to)); + uint256 value = _transaction.reserved[1]; + bytes memory data = _transaction.data; + + if (to == address(DEPLOYER_SYSTEM_CONTRACT)) { + // We allow calling ContractDeployer with any calldata + SystemContractsCaller.systemCallWithPropagatedRevert( + uint32(gasleft()), + to, + uint128(_transaction.reserved[1]), // By convention, reserved[1] is `value` + _transaction.data + ); + } else { + bool success; + assembly { + success := call( + gas(), + to, + value, + add(data, 0x20), + mload(data), + 0, + 0 + ) + } + require(success); + } + } + + // Here, the user pays the bootloader for the transaction + function payForTransaction( + bytes32, + bytes32, + Transaction calldata _transaction + ) external payable { + bool success = _transaction.payToTheBootloader(); + require(success, "Failed to pay the fee to the operator"); + } + + // Here, the user should prepare for the transaction to be paid for by a paymaster + // Here, the account should set the allowance for the smart contracts + function prepareForPaymaster( + bytes32, + bytes32, + Transaction calldata _transaction + ) external payable { + _transaction.processPaymasterInput(); + } + + fallback() external payable { + // fallback of default AA shouldn't be called by bootloader under no circumstances + assert(msg.sender != BOOTLOADER_FORMAL_ADDRESS); + + // If the contract is called directly, behave like an EOA + } + + receive() external payable {} +} diff --git a/core/lib/test_contracts/src/contracts.rs b/core/lib/test_contracts/src/contracts.rs index 36d758c46de2..a997f70f6870 100644 --- a/core/lib/test_contracts/src/contracts.rs +++ b/core/lib/test_contracts/src/contracts.rs @@ -115,6 +115,12 @@ impl TestContract { &CONTRACT } + pub fn validation_test() -> &'static Self { + static CONTRACT: Lazy = + Lazy::new(|| TestContract::new(raw::custom_account::ValidationRuleBreaker)); + &CONTRACT + } + /// Returns a contract testing precompiles. pub fn precompiles_test() -> &'static Self { static CONTRACT: Lazy = diff --git a/core/lib/vm_executor/src/batch/factory.rs b/core/lib/vm_executor/src/batch/factory.rs index 76ef244401bd..9797e1681032 100644 --- a/core/lib/vm_executor/src/batch/factory.rs +++ b/core/lib/vm_executor/src/batch/factory.rs @@ -37,7 +37,7 @@ pub trait BatchTracer: fmt::Debug + 'static + Send + Sealed { const TRACE_CALLS: bool; /// Tracer for the fast VM. #[doc(hidden)] - type Fast: vm_fast::interface::Tracer + Default + 'static; + type Fast: vm_fast::interface::Tracer + Default; } impl Sealed for () {} @@ -228,7 +228,7 @@ impl BatchVm { with_compression, ), Self::Fast(vm) => { - let mut tracer = (legacy_tracer.into(), ::default()); + let mut tracer = (legacy_tracer.into(), Default::default()); vm.inspect_transaction_with_bytecode_compression(&mut tracer, tx, with_compression) } }; diff --git a/core/lib/vm_executor/src/oneshot/mod.rs b/core/lib/vm_executor/src/oneshot/mod.rs index 0dfdb67bff52..e52a88e3e9c5 100644 --- a/core/lib/vm_executor/src/oneshot/mod.rs +++ b/core/lib/vm_executor/src/oneshot/mod.rs @@ -17,9 +17,9 @@ use once_cell::sync::OnceCell; use zksync_multivm::{ interface::{ executor::{OneshotExecutor, TransactionValidator}, - storage::{ReadStorage, StorageView, StorageWithOverrides}, + storage::{ReadStorage, StorageView, StorageWithOverrides, WriteStorage}, tracer::{ValidationError, ValidationParams, ValidationTraces}, - utils::{DivergenceHandler, ShadowVm}, + utils::{DivergenceHandler, ShadowMut, ShadowVm}, Call, ExecutionResult, InspectExecutionMode, OneshotEnv, OneshotTracingParams, OneshotTransactionExecutionResult, StoredL2BlockEnv, TxExecutionArgs, TxExecutionMode, VmFactory, VmInterface, @@ -27,9 +27,10 @@ use zksync_multivm::{ is_supported_by_fast_vm, tracers::{CallTracer, StorageInvocations, TracerDispatcher, ValidationTracer}, utils::adjust_pubdata_price_for_tx, + vm_fast, vm_latest::{HistoryDisabled, HistoryEnabled}, zk_evm_latest::ethereum_types::U256, - FastVmInstance, HistoryMode, LegacyVmInstance, MultiVmTracer, + FastVmInstance, HistoryMode, LegacyVmInstance, MultiVmTracer, VmVersion, }; use zksync_types::{ block::pack_block_info, @@ -180,7 +181,11 @@ where let l1_batch_env = env.l1_batch.clone(); let sandbox = VmSandbox { - fast_vm_mode: FastVmMode::Old, + fast_vm_mode: if !is_supported_by_fast_vm(env.system.version) { + FastVmMode::Old // the fast VM doesn't support old protocol versions + } else { + self.fast_vm_mode + }, panic_on_divergence: self.panic_on_divergence, storage, env, @@ -189,31 +194,35 @@ where }; tokio::task::spawn_blocking(move || { - let validation_tracer = ValidationTracer::::new( - validation_params, - sandbox.env.system.version.into(), - l1_batch_env, - ); - let mut validation_result = validation_tracer.get_result(); - let validation_traces = validation_tracer.get_traces(); - let tracers = vec![validation_tracer.into_tracer_pointer()]; - - let exec_result = sandbox.execute_in_vm(|vm, transaction| { - let Vm::Legacy(vm) = vm else { - unreachable!("Fast VM is never used for validation yet"); - }; - vm.push_transaction(transaction); - vm.inspect(&mut tracers.into(), InspectExecutionMode::OneTx) - }); - let validation_result = Arc::make_mut(&mut validation_result) - .take() - .map_or(Ok(()), Err); - - match (exec_result.result, validation_result) { - (_, Err(violated_rule)) => Err(ValidationError::ViolatedRule(violated_rule)), - (ExecutionResult::Halt { reason }, _) => Err(ValidationError::FailedTx(reason)), - _ => Ok(validation_traces.lock().unwrap().clone()), - } + let version = sandbox.env.system.version.into(); + let batch_timestamp = l1_batch_env.timestamp; + + sandbox.execute_in_vm(|vm, transaction| match vm { + Vm::Legacy(vm) => { + vm.push_transaction(transaction); + validate_legacy(vm, version, validation_params, batch_timestamp) + } + + Vm::Fast(FastVmInstance::Fast(vm)) => { + vm.push_transaction(transaction); + validate_fast(vm, validation_params, batch_timestamp) + } + + Vm::Fast(FastVmInstance::Shadowed(vm)) => { + vm.push_transaction(transaction); + vm.get_custom_mut("validation result", |vm| match vm { + ShadowMut::Main(vm) => validate_legacy::<_, HistoryEnabled>( + vm, + version, + validation_params.clone(), + batch_timestamp, + ), + ShadowMut::Shadow(vm) => { + validate_fast(vm, validation_params.clone(), batch_timestamp) + } + }) + } + }) }) .await .context("VM execution panicked") @@ -221,12 +230,12 @@ where } #[derive(Debug)] -enum Vm { +enum Vm { Legacy(LegacyVmInstance), - Fast(FastVmInstance), + Fast(FastVmInstance), } -impl Vm { +impl Vm { fn inspect_transaction_with_bytecode_compression( &mut self, missed_storage_invocation_limit: usize, @@ -252,7 +261,7 @@ impl Vm { missed_storage_invocation_limit, None, ); - let mut full_tracer = (legacy_tracers.into(), ()); + let mut full_tracer = (legacy_tracers.into(), ((), ())); vm.inspect_transaction_with_bytecode_compression( &mut full_tracer, tx, @@ -282,6 +291,57 @@ impl Vm { } } +fn validate_fast( + vm: &mut vm_fast::Vm, + validation_params: ValidationParams, + batch_timestamp: u64, +) -> Result { + let validation = vm_fast::FullValidationTracer::new(validation_params, batch_timestamp); + let mut tracer = ((), validation); + let result_and_logs = vm.inspect(&mut tracer, InspectExecutionMode::OneTx); + if let Some(violation) = tracer.1.validation_error() { + return Err(ValidationError::ViolatedRule(violation)); + } + + match result_and_logs.result { + ExecutionResult::Halt { reason } => Err(ValidationError::FailedTx(reason)), + ExecutionResult::Revert { .. } => { + unreachable!("Revert can only happen at the end of a transaction") + } + ExecutionResult::Success { .. } => Ok(tracer.1.traces()), + } +} + +fn validate_legacy( + vm: &mut impl VmInterface>>, + version: VmVersion, + validation_params: ValidationParams, + batch_timestamp: u64, +) -> Result +where + S: WriteStorage, + H: 'static + HistoryMode, + ValidationTracer: MultiVmTracer, +{ + let validation_tracer = ValidationTracer::::new(validation_params, version, batch_timestamp); + let mut validation_result = validation_tracer.get_result(); + let validation_traces = validation_tracer.get_traces(); + let validation_tracer: Box> = validation_tracer.into_tracer_pointer(); + let tracers = TracerDispatcher::from(validation_tracer); + + let exec_result = vm.inspect(&mut tracers.into(), InspectExecutionMode::OneTx); + + let validation_result = Arc::make_mut(&mut validation_result) + .take() + .map_or(Ok(()), Err); + + match (exec_result.result, validation_result) { + (_, Err(violated_rule)) => Err(ValidationError::ViolatedRule(violated_rule)), + (ExecutionResult::Halt { reason }, _) => Err(ValidationError::FailedTx(reason)), + _ => Ok(validation_traces.lock().unwrap().clone()), + } +} + /// Full parameters necessary to instantiate a VM for oneshot execution. #[derive(Debug)] struct VmSandbox { @@ -342,11 +402,14 @@ impl VmSandbox { } } - /// This method is blocking. - fn execute_in_vm( + fn execute_in_vm( mut self, - action: impl FnOnce(&mut Vm>, Transaction) -> T, - ) -> T { + action: impl FnOnce(&mut Vm, Tr, Val>, Transaction) -> T, + ) -> T + where + Tr: vm_fast::interface::Tracer + Default, + Val: vm_fast::ValidationTracer, + { Self::setup_storage( &mut self.storage, &self.execution_args, diff --git a/core/lib/vm_interface/src/types/tracer.rs b/core/lib/vm_interface/src/types/tracer.rs index 1c3f65f443ef..168834f28cef 100644 --- a/core/lib/vm_interface/src/types/tracer.rs +++ b/core/lib/vm_interface/src/types/tracer.rs @@ -71,7 +71,7 @@ pub struct TimestampAsserterParams { } /// Rules that can be violated when validating a transaction. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum ViolatedValidationRule { /// The transaction touched disallowed storage slots during validation. TouchedDisallowedStorageSlots(Address, U256), @@ -112,7 +112,7 @@ impl fmt::Display for ViolatedValidationRule { } /// Errors returned when validating a transaction. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum ValidationError { /// VM execution was halted during validation. FailedTx(Halt), @@ -124,7 +124,7 @@ pub enum ValidationError { /// For instance, the `timestamp_asserter_range` represent the range within which the transaction might make /// assertions on `block.timestamp`. This information is crucial for the caller, as expired transactions should /// be excluded from the mempool. -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, PartialEq)] pub struct ValidationTraces { pub timestamp_asserter_range: Option>, } diff --git a/core/lib/vm_interface/src/utils/shadow.rs b/core/lib/vm_interface/src/utils/shadow.rs index 0883971f4de8..d6a6d16c77a0 100644 --- a/core/lib/vm_interface/src/utils/shadow.rs +++ b/core/lib/vm_interface/src/utils/shadow.rs @@ -13,6 +13,7 @@ use super::dump::{DumpingVm, VmDump}; use crate::{ pubdata::PubdataBuilder, storage::{ReadStorage, StoragePtr, StorageView}, + tracer::{ValidationError, ValidationTraces}, BytecodeCompressionResult, CurrentExecutionState, FinishedL1Batch, InspectExecutionMode, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmTrackingContracts, @@ -224,6 +225,14 @@ impl CheckDivergence for FinishedL1Batch { } } +impl CheckDivergence for Result { + fn check_divergence(&self, other: &Self) -> DivergenceErrors { + let mut errors = DivergenceErrors::new(); + errors.check_match("validation result", self, other); + errors + } +} + /// Shadowed VM that executes 2 VMs for each operation and compares their outputs. /// /// If a divergence is detected, the VM state is dumped using [a pluggable handler](Self::set_dump_handler()), @@ -238,7 +247,6 @@ impl ShadowVm where S: ReadStorage, Main: VmTrackingContracts, - Shadow: VmInterface, { /// Sets the divergence handler to be used by this VM. pub fn set_divergence_handler(&mut self, handler: DivergenceHandler) { @@ -247,6 +255,18 @@ where } } + /// Dumps the current VM state. + pub fn dump_state(&self) -> VmDump { + self.main.dump_state() + } +} + +impl ShadowVm +where + S: ReadStorage, + Main: VmTrackingContracts, + Shadow: VmInterface, +{ /// Mutable ref is not necessary, but it automatically drops potential borrows. fn report(&mut self, err: DivergenceErrors) { self.report_shared(err); @@ -260,11 +280,6 @@ where .report(err, self.main.dump_state()); } - /// Dumps the current VM state. - pub fn dump_state(&self) -> VmDump { - self.main.dump_state() - } - /// Gets the specified value from both the main and shadow VM, checking whether it matches on both. pub fn get(&self, name: &str, mut action: impl FnMut(ShadowRef<'_, Main, Shadow>) -> R) -> R where @@ -330,7 +345,6 @@ impl ShadowVm where S: ReadStorage, Main: VmFactory> + VmTrackingContracts, - Shadow: VmInterface, { /// Creates a VM with a custom shadow storage. pub fn with_custom_shadow( diff --git a/core/lib/vm_interface/src/vm.rs b/core/lib/vm_interface/src/vm.rs index 2c25d729e318..f347bb54f550 100644 --- a/core/lib/vm_interface/src/vm.rs +++ b/core/lib/vm_interface/src/vm.rs @@ -22,7 +22,6 @@ use crate::{ }; pub trait VmInterface { - /// Lifetime is used to be able to define `Option<&mut _>` as a dispatcher. type TracerDispatcher: Default; /// Pushes a transaction to bootloader memory for future execution with bytecode compression (if it's supported by the VM). diff --git a/core/node/eth_watch/src/tests/mod.rs b/core/node/eth_watch/src/tests/mod.rs index df91074beb18..0b34a34ab63f 100644 --- a/core/node/eth_watch/src/tests/mod.rs +++ b/core/node/eth_watch/src/tests/mod.rs @@ -480,7 +480,7 @@ async fn test_batch_root_processor_from_genesis() { .await .unwrap() .unwrap(); - let proof1 = hex::encode(&bincode::serialize(&proof1).unwrap()); + let proof1 = hex::encode(bincode::serialize(&proof1).unwrap()); assert_eq!(proof1, "000000000600000000000000420000000000000030783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303042000000000000003078303030303030303030303030303030303030303030303030303030303030303530303030303030303030303030303030303030303030303030303030303030334200000000000000307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316639420000000000000030783031303230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303042000000000000003078303932343932386331333737613663663234633339633264343666386562396466323365383131623236646333353237653534383339366664346531373362314200000000000000307833373561356266393039636230323134336533363935636136353865303634316537333961613539306630303034646261393335373263343463646239643264"); sl_client.set_last_finalized_block_number(11).await; @@ -492,7 +492,7 @@ async fn test_batch_root_processor_from_genesis() { .await .unwrap() .unwrap(); - let proof2 = hex::encode(&bincode::serialize(&proof2).unwrap()); + let proof2 = hex::encode(bincode::serialize(&proof2).unwrap()); assert_eq!(proof2, "0100000007000000000000004200000000000000307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031420000000000000030783130613265663736653730396433313862343539626534396631653864376630326437313230663262353031626330616664646439333566316138313363363742000000000000003078303030303030303030303030303030303030303030303030303030303030303930303030303030303030303030303030303030303030303030303030303030334200000000000000307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316639420000000000000030783031303230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303042000000000000003078303932343932386331333737613663663234633339633264343666386562396466323365383131623236646333353237653534383339366664346531373362314200000000000000307861333738613230636132376237616533303731643162643763326164613030343639616263353765343239646436663438613833303932646237303539613138"); let proof3 = connection @@ -501,7 +501,7 @@ async fn test_batch_root_processor_from_genesis() { .await .unwrap() .unwrap(); - let proof3 = hex::encode(&bincode::serialize(&proof3).unwrap()); + let proof3 = hex::encode(bincode::serialize(&proof3).unwrap()); assert_eq!(proof3, "02000000080000000000000042000000000000003078303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030324200000000000000307834363730306234643430616335633335616632633232646461323738376139316562353637623036633932346138666238616539613035623230633038633231420000000000000030786530633333333066363734623662326435373866393538613164626436366631363464303638623062623561396662303737656361303133393736666461366642000000000000003078303030303030303030303030303030303030303030303030303030303030306230303030303030303030303030303030303030303030303030303030303030334200000000000000307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316639420000000000000030783031303230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303042000000000000003078303932343932386331333737613663663234633339633264343666386562396466323365383131623236646333353237653534383339366664346531373362314200000000000000307833373561356266393039636230323134336533363935636136353865303634316537333961613539306630303034646261393335373263343463646239643264"); } @@ -567,7 +567,7 @@ async fn test_batch_root_processor_restart() { .await .unwrap() .unwrap(); - let proof = hex::encode(&bincode::serialize(&proof).unwrap()); + let proof = hex::encode(bincode::serialize(&proof).unwrap()); assert_eq!(proof, "02000000080000000000000042000000000000003078303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030324200000000000000307834363730306234643430616335633335616632633232646461323738376139316562353637623036633932346138666238616539613035623230633038633231420000000000000030786530633333333066363734623662326435373866393538613164626436366631363464303638623062623561396662303737656361303133393736666461366642000000000000003078303030303030303030303030303030303030303030303030303030303030306230303030303030303030303030303030303030303030303030303030303030334200000000000000307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316639420000000000000030783031303230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303042000000000000003078303932343932386331333737613663663234633339633264343666386562396466323365383131623236646333353237653534383339366664346531373362314200000000000000307833373561356266393039636230323134336533363935636136353865303634316537333961613539306630303034646261393335373263343463646239643264"); let proof = connection @@ -576,7 +576,7 @@ async fn test_batch_root_processor_restart() { .await .unwrap() .unwrap(); - let proof = hex::encode(&bincode::serialize(&proof).unwrap()); + let proof = hex::encode(bincode::serialize(&proof).unwrap()); assert_eq!(proof, "02000000080000000000000042000000000000003078303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030334200000000000000307837623765373735373139343639366666393634616233353837393131373362636337663735356132656161393334653935373061636533393139383435313265420000000000000030786530633333333066363734623662326435373866393538613164626436366631363464303638623062623561396662303737656361303133393736666461366642000000000000003078303030303030303030303030303030303030303030303030303030303030306430303030303030303030303030303030303030303030303030303030303030334200000000000000307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316639420000000000000030783031303230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303042000000000000003078303932343932386331333737613663663234633339633264343666386562396466323365383131623236646333353237653534383339366664346531373362314200000000000000307835353063313735316338653764626166633839303939326634353532333636663064643565623665343362653535353936386264616338633732656466316261"); let proof = connection @@ -585,7 +585,7 @@ async fn test_batch_root_processor_restart() { .await .unwrap() .unwrap(); - let proof = hex::encode(&bincode::serialize(&proof).unwrap()); + let proof = hex::encode(bincode::serialize(&proof).unwrap()); assert_eq!(proof, "030000000900000000000000420000000000000030783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303442000000000000003078303235663065363031353230366661626364326263613930316432633438396536336263356564346231356266356330633963363066396531363735383564614200000000000000307863633463343165646230633230333133343862323932623736386539626163316565386339326330396566386133323737633265636534303963313264383661420000000000000030783533656463316635616437396335393939626435373864666331333566396335316562643766616661343538356236346637316431356232646365316237323842000000000000003078303030303030303030303030303030303030303030303030303030303030306530303030303030303030303030303030303030303030303030303030303030334200000000000000307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316639420000000000000030783031303230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303042000000000000003078303932343932386331333737613663663234633339633264343666386562396466323365383131623236646333353237653534383339366664346531373362314200000000000000307833373561356266393039636230323134336533363935636136353865303634316537333961613539306630303034646261393335373263343463646239643264"); let proof = connection @@ -594,7 +594,7 @@ async fn test_batch_root_processor_restart() { .await .unwrap() .unwrap(); - let proof = hex::encode(&bincode::serialize(&proof).unwrap()); + let proof = hex::encode(bincode::serialize(&proof).unwrap()); assert_eq!(proof, "030000000900000000000000420000000000000030783030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303542000000000000003078323465653435363834376535373364313635613832333634306632303834383139636331613865333433316562633635633865363064333435343266313637324200000000000000307863633463343165646230633230333133343862323932623736386539626163316565386339326330396566386133323737633265636534303963313264383661420000000000000030783533656463316635616437396335393939626435373864666331333566396335316562643766616661343538356236346637316431356232646365316237323842000000000000003078303030303030303030303030303030303030303030303030303030303030306530303030303030303030303030303030303030303030303030303030303030334200000000000000307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316639420000000000000030783031303230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303042000000000000003078303932343932386331333737613663663234633339633264343666386562396466323365383131623236646333353237653534383339366664346531373362314200000000000000307833373561356266393039636230323134336533363935636136353865303634316537333961613539306630303034646261393335373263343463646239643264"); } diff --git a/core/node/node_sync/src/tree_data_fetcher/provider/tests.rs b/core/node/node_sync/src/tree_data_fetcher/provider/tests.rs index 75bf96092335..e8c855359390 100644 --- a/core/node/node_sync/src/tree_data_fetcher/provider/tests.rs +++ b/core/node/node_sync/src/tree_data_fetcher/provider/tests.rs @@ -418,7 +418,7 @@ async fn using_different_settlement_layers() { .batch_details(number, &get_last_l2_block(&mut storage, number).await) .await .unwrap() - .expect(&format!("no root hash for batch #{number}")); + .unwrap_or_else(|err| panic!("no root hash for batch #{number}: {err:?}")); assert_eq!(root_hash, H256::repeat_byte(number.0 as u8)); let past_l1_batch = provider.past_l1_batch.unwrap(); diff --git a/core/tests/vm-benchmark/src/vm.rs b/core/tests/vm-benchmark/src/vm.rs index e69e7ca1e909..a4b61ee54809 100644 --- a/core/tests/vm-benchmark/src/vm.rs +++ b/core/tests/vm-benchmark/src/vm.rs @@ -113,12 +113,11 @@ impl CountInstructions for Fast { } let (system_env, l1_batch_env) = test_env(); - let mut vm = - vm_fast::Vm::<_, InstructionCount>::custom(l1_batch_env, system_env, &*STORAGE); + let mut vm = vm_fast::Vm::custom(l1_batch_env, system_env, &*STORAGE); vm.push_transaction(tx.clone()); - let mut tracer = InstructionCount(0); + let mut tracer = (InstructionCount(0), ()); vm.inspect(&mut tracer, InspectExecutionMode::OneTx); - tracer.0 + tracer.0 .0 } } From cbee99d8661b38aa6b49784c3934b8070a743fb4 Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 19 Dec 2024 16:58:31 +0400 Subject: [PATCH 2/3] feat: Support stable compiler for VM (and some other crates) (#3248) tbd --------- Co-authored-by: zksync-admin-bot2 <91326834+zksync-admin-bot2@users.noreply.github.com> Co-authored-by: Lech <88630083+Artemka374@users.noreply.github.com> --- Cargo.lock | 238 +++------------ Cargo.toml | 13 +- core/lib/multivm/Cargo.toml | 6 +- .../src/glue/types/vm/vm_block_result.rs | 44 +-- core/lib/multivm/src/lib.rs | 2 +- core/lib/multivm/src/utils/mod.rs | 17 +- .../src/versions/testonly/precompiles.rs | 12 +- .../src/versions/vm_1_3_2/pubdata_utils.rs | 16 +- .../versions/vm_1_3_2/vm_with_bootloader.rs | 2 +- .../vm_1_4_1/tracers/circuits_capacity.rs | 4 +- .../vm_1_4_1/tracers/pubdata_tracer.rs | 5 +- .../vm_1_4_1/types/internals/vm_state.rs | 2 +- core/lib/multivm/src/versions/vm_1_4_1/vm.rs | 12 +- .../src/versions/vm_1_4_2/constants.rs | 2 +- .../vm_1_4_2/tracers/circuits_capacity.rs | 4 +- .../vm_1_4_2/tracers/pubdata_tracer.rs | 5 +- .../vm_1_4_2/types/internals/vm_state.rs | 2 +- core/lib/multivm/src/versions/vm_1_4_2/vm.rs | 12 +- .../tracers/circuits_capacity.rs | 4 +- .../tracers/pubdata_tracer.rs | 5 +- .../types/internals/vm_state.rs | 2 +- .../src/versions/vm_boojum_integration/vm.rs | 12 +- .../src/versions/vm_fast/tracers/circuits.rs | 4 +- .../src/versions/vm_latest/constants.rs | 2 +- .../vm_latest/tracers/circuits_capacity.rs | 4 +- .../vm_latest/tracers/pubdata_tracer.rs | 4 +- .../vm_latest/types/internals/vm_state.rs | 2 +- core/lib/multivm/src/versions/vm_latest/vm.rs | 4 +- .../src/versions/vm_m5/pubdata_utils.rs | 14 +- .../src/versions/vm_m5/vm_with_bootloader.rs | 2 +- .../src/versions/vm_m6/pubdata_utils.rs | 14 +- .../src/versions/vm_m6/vm_with_bootloader.rs | 2 +- .../types/internals/vm_state.rs | 2 +- .../src/versions/vm_refunds_enhancement/vm.rs | 11 +- .../vm_virtual_blocks/tracers/refunds.rs | 10 +- .../types/internals/vm_state.rs | 2 +- .../src/versions/vm_virtual_blocks/vm.rs | 11 +- core/lib/prover_interface/Cargo.toml | 2 +- core/lib/prover_interface/src/outputs.rs | 2 +- .../tests/job_serialization.rs | 2 +- core/lib/state/src/storage_overrides.rs | 0 core/lib/utils/Cargo.toml | 1 + .../src/web3/namespaces/unstable/utils.rs | 3 +- core/node/commitment_generator/Cargo.toml | 6 +- core/node/commitment_generator/src/utils.rs | 103 +------ core/node/genesis/src/utils.rs | 2 +- prover/Cargo.lock | 287 +++++------------- prover/Cargo.toml | 11 +- .../src/gpu_prover_job_processor.rs | 4 +- prover/crates/bin/prover_fri/src/lib.rs | 2 +- prover/crates/bin/prover_fri/src/main.rs | 2 +- .../src/rounds/basic_circuits/mod.rs | 2 +- .../src/rounds/basic_circuits/utils.rs | 10 +- .../lib/circuit_prover_service/src/lib.rs | 2 +- .../src/types/circuit.rs | 6 +- prover/crates/lib/keystore/Cargo.toml | 3 +- prover/crates/lib/keystore/src/lib.rs | 13 +- .../lib/keystore/src/setup_data_generator.rs | 39 ++- prover/setup-data-gpu-keys.json | 6 +- zkstack_cli/Cargo.lock | 26 +- 60 files changed, 359 insertions(+), 684 deletions(-) delete mode 100644 core/lib/state/src/storage_overrides.rs diff --git a/Cargo.lock b/Cargo.lock index 71ca2e960995..019e2afdf334 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1289,9 +1289,9 @@ dependencies = [ [[package]] name = "boojum" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ec2f007ff8f90cc459f03e9f30ca1065440170f013c868823646e2e48d0234" +checksum = "4337dc7b196fc3e5e55e2857bc21638b7441429ee1a953201a9cd2be187b764e" dependencies = [ "arrayvec 0.7.6", "bincode", @@ -1690,117 +1690,26 @@ dependencies = [ [[package]] name = "circuit_encodings" -version = "0.140.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf6b7cc842eadb4c250cdc6a8bc1dd97624d9f08bbe54db3e11fb23c3a72be07" -dependencies = [ - "derivative", - "serde", - "zk_evm 0.140.0", - "zkevm_circuits 0.140.3", -] - -[[package]] -name = "circuit_encodings" -version = "0.141.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7898ffbf3cd413576b4b674fe1545a35488c67eb16bd5a4148425e42c2a2b65b" -dependencies = [ - "derivative", - "serde", - "zk_evm 0.141.0", - "zkevm_circuits 0.141.2", -] - -[[package]] -name = "circuit_encodings" -version = "0.142.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8364ecafcc4b2c896023f8d3af952c52a500aa55f14fd268bb5d9ab07f837369" -dependencies = [ - "derivative", - "serde", - "zk_evm 0.141.0", - "zkevm_circuits 0.141.2", -] - -[[package]] -name = "circuit_encodings" -version = "0.150.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2501cc688ef391013019495ae7035cfd54f86987e36d10f73976ce4c5d413c5a" -dependencies = [ - "derivative", - "serde", - "zk_evm 0.150.7", - "zkevm_circuits 0.150.7", -] - -[[package]] -name = "circuit_sequencer_api" -version = "0.133.1" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb959b1f8c6bbd8be711994d182e85452a26a5d2213a709290b71c8262af1331" +checksum = "e3dcfcb4aaa17e6a81ebd2db688d980aff50aa643d9b506d4d11c84976dbc03f" dependencies = [ "derivative", - "rayon", "serde", - "zk_evm 0.133.0", - "zksync_bellman", + "zk_evm 0.150.18", + "zkevm_circuits", ] [[package]] name = "circuit_sequencer_api" -version = "0.140.3" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa5f22311ce609d852d7d9f4943535ea4610aeb785129ae6ff83d5201c4fb387" +checksum = "d13ed70909e8390a4f2599d5a76d9ac4189e5bbbf16146d11b7999788740f291" dependencies = [ - "circuit_encodings 0.140.3", - "derivative", - "rayon", - "serde", - "zk_evm 0.140.0", - "zksync_bellman", -] - -[[package]] -name = "circuit_sequencer_api" -version = "0.141.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c47c71d6ba83a8beb0af13af70beffd627f5497caf3d44c6f96363e788b07ea" -dependencies = [ - "circuit_encodings 0.141.2", - "derivative", - "rayon", - "serde", - "zk_evm 0.141.0", - "zksync_bellman", -] - -[[package]] -name = "circuit_sequencer_api" -version = "0.142.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e264723359e6a1aad98110bdccf1ae3ad596e93e7d31da9e40f6adc07e4add54" -dependencies = [ - "circuit_encodings 0.142.2", - "derivative", - "rayon", - "serde", - "zk_evm 0.141.0", - "zksync_bellman", -] - -[[package]] -name = "circuit_sequencer_api" -version = "0.150.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917d27db531fdd98a51e42ea465bc097f48cc849e7fad68d7856087d15125be1" -dependencies = [ - "circuit_encodings 0.150.7", "derivative", "rayon", "serde", + "zk_evm 0.150.18", "zksync_bellman", ] @@ -3332,9 +3241,9 @@ dependencies = [ [[package]] name = "franklin-crypto" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "971289216ea5c91872e5e0bb6989214b537bbce375d09fabea5c3ccfe031b204" +checksum = "5c128e2cf791053b3aefdd7b07d6e5ffdc7cf5dd779ca270d727a403057dfb68" dependencies = [ "arr_macro", "bit-vec", @@ -7318,9 +7227,9 @@ dependencies = [ [[package]] name = "rescue_poseidon" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82900c877a0ba5362ac5756efbd82c5b795dc509011c1253e2389d8708f1389d" +checksum = "b62e4ce7543582ab2df1d9544674a55897e168a23afe938a57e1547d2981a7f4" dependencies = [ "addchain", "arrayvec 0.7.6", @@ -11208,9 +11117,9 @@ dependencies = [ [[package]] name = "zk_evm" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc74fbe2b45fd19e95c59ea792c795feebdb616ebaa463f0ac567f495f47387" +checksum = "3278d0f75408ab35d25998e1124124cd108b48b2a81ed8e71e892ddc5a6be0aa" dependencies = [ "anyhow", "lazy_static", @@ -11218,7 +11127,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 0.150.7", + "zk_evm_abstractions 0.150.18", ] [[package]] @@ -11249,25 +11158,24 @@ dependencies = [ [[package]] name = "zk_evm_abstractions" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37f333a3b059899df09e40deb041af881bc03e496fda5eec618ffb5e854ee7df" +checksum = "88b4e5a89cfe1594b6476be16c8c1d45f22ce12bff31c49e077b381a398edd8a" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 0.150.7", + "zkevm_opcode_defs 0.150.18", ] [[package]] name = "zkevm_circuits" -version = "0.140.3" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c365c801e0c6eda83fbd153df45575172beb406bfb663d386f9154b4325eda" +checksum = "8b94288d2e246aecd6eecd22ef27db0d1f29a91cb4f59b9e339a45237131a9ff" dependencies = [ "arrayvec 0.7.6", - "bincode", "boojum", "derivative", "hex", @@ -11276,51 +11184,8 @@ dependencies = [ "rand 0.8.5", "seq-macro", "serde", - "serde_json", "smallvec", - "zkevm_opcode_defs 0.132.0", - "zksync_cs_derive", -] - -[[package]] -name = "zkevm_circuits" -version = "0.141.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ccd0352e122a4e6f0046d2163b7e692e627b23fc3264faa77331a21b65833fd" -dependencies = [ - "arrayvec 0.7.6", - "bincode", - "boojum", - "derivative", - "hex", - "itertools 0.10.5", - "rand 0.4.6", - "rand 0.8.5", - "seq-macro", - "serde", - "serde_json", - "smallvec", - "zkevm_opcode_defs 0.141.0", - "zksync_cs_derive", -] - -[[package]] -name = "zkevm_circuits" -version = "0.150.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06fb35b00699d25175a2ad447f86a9088af8b0bc698bb57086fb04c13e52eab" -dependencies = [ - "arrayvec 0.7.6", - "boojum", - "derivative", - "hex", - "itertools 0.10.5", - "rand 0.4.6", - "rand 0.8.5", - "seq-macro", - "serde", - "smallvec", - "zkevm_opcode_defs 0.150.7", + "zkevm_opcode_defs 0.150.18", "zksync_cs_derive", ] @@ -11368,9 +11233,9 @@ dependencies = [ [[package]] name = "zkevm_opcode_defs" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b83f3b279248af4ca86dec20a54127f02110b45570f3f6c1d13df49ba75c28a5" +checksum = "5bad437d4891536fdcc0054a3f04562c408817ff19d83b6c27569217692e6e74" dependencies = [ "bitflags 2.6.0", "blake2 0.10.6", @@ -11429,9 +11294,9 @@ dependencies = [ [[package]] name = "zksync_bellman" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffa03efe9bdb137a4b36b97d1a74237e18c9ae42b755163d903a9d48c1a5d80" +checksum = "6b7c0061db44757522f2d82cad02f45dc98267210ac362071234ed08e30fd4d6" dependencies = [ "arrayvec 0.7.6", "bit-vec", @@ -11493,9 +11358,7 @@ name = "zksync_commitment_generator" version = "0.1.0" dependencies = [ "anyhow", - "circuit_sequencer_api 0.140.3", - "circuit_sequencer_api 0.141.2", - "circuit_sequencer_api 0.150.7", + "circuit_encodings", "futures 0.3.31", "itertools 0.10.5", "num_cpus", @@ -11505,9 +11368,7 @@ dependencies = [ "tokio", "tracing", "vise", - "zk_evm 0.133.0", - "zk_evm 0.141.0", - "zk_evm 0.150.7", + "zk_evm 0.150.18", "zksync_contracts", "zksync_dal", "zksync_eth_client", @@ -11852,9 +11713,9 @@ dependencies = [ [[package]] name = "zksync_cs_derive" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5939e2df4288c263c706ff18ac718e984149223ad4289d6d957d767dcfc04c81" +checksum = "63296ce43c432d5d0111604173e874b2f2a856e1cb1c76378fa0bb5ac6018c27" dependencies = [ "proc-macro-error", "proc-macro2 1.0.92", @@ -12181,9 +12042,9 @@ dependencies = [ [[package]] name = "zksync_ff" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9524b06780b5e164e84b38840c7c428c739f051f35af6efc4d1285f629ceb88e" +checksum = "e6a500c97d9286f73540c26b63ae33b159bd48fec0c8bd206b4a9b4fe1217b8a" dependencies = [ "byteorder", "hex", @@ -12194,9 +12055,9 @@ dependencies = [ [[package]] name = "zksync_ff_derive" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f91e58e75d65877f09f83bc3dca8f054847ae7ec4f3e64bfa610a557edd8e8e" +checksum = "97bd48f18ebf350623093022d86be2f1ce23af332efa91890b751209aec8617a" dependencies = [ "num-bigint 0.4.6", "num-integer", @@ -12239,9 +12100,9 @@ dependencies = [ [[package]] name = "zksync_kzg" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc58af8e4e4ad1a851ffd2275e6a44ead0f15a7eaac9dc9d60a56b3b9c9b08e8" +checksum = "6384d2475e4a7e6ed4e2a703724cac1d8972d9ec40c49fdd17bf37942a81a635" dependencies = [ "boojum", "derivative", @@ -12251,7 +12112,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "zkevm_circuits 0.150.7", + "zkevm_circuits", ] [[package]] @@ -12372,11 +12233,7 @@ version = "0.1.0" dependencies = [ "anyhow", "assert_matches", - "circuit_sequencer_api 0.133.1", - "circuit_sequencer_api 0.140.3", - "circuit_sequencer_api 0.141.2", - "circuit_sequencer_api 0.142.2", - "circuit_sequencer_api 0.150.7", + "circuit_sequencer_api", "ethabi", "hex", "itertools 0.10.5", @@ -12391,7 +12248,7 @@ dependencies = [ "zk_evm 0.133.0", "zk_evm 0.140.0", "zk_evm 0.141.0", - "zk_evm 0.150.7", + "zk_evm 0.150.18", "zksync_contracts", "zksync_eth_signer", "zksync_mini_merkle_tree", @@ -12431,7 +12288,7 @@ dependencies = [ "tower-http 0.5.2", "tracing", "vise", - "zk_evm 0.150.7", + "zk_evm 0.150.18", "zksync_config", "zksync_consensus_roles", "zksync_contracts", @@ -12727,9 +12584,9 @@ dependencies = [ [[package]] name = "zksync_pairing" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8412ae5574472fa567a097e183f9a01974b99dd0b5da3bfa1bbe6c57c579aa2" +checksum = "3b91b38db3a3f0f80d8b1f2342c77751ee8d63b746268e5719abbb5dfb150a8c" dependencies = [ "byteorder", "cfg-if", @@ -12826,7 +12683,7 @@ version = "0.1.0" dependencies = [ "bincode", "chrono", - "circuit_sequencer_api 0.150.7", + "circuit_sequencer_api", "serde", "serde_json", "serde_with", @@ -12936,9 +12793,9 @@ dependencies = [ [[package]] name = "zksync_solidity_vk_codegen" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b310ab8a21681270e73f177ddf7974cabb7a96f0624ab8b008fd6ee1f9b4f687" +checksum = "6f03e137db1b29be36abfa1e1e682dd3864b0335c68282c8dab68c2d397b8cbd" dependencies = [ "ethereum-types", "franklin-crypto", @@ -13140,6 +12997,7 @@ dependencies = [ "once_cell", "reqwest 0.12.9", "serde_json", + "sha2 0.10.8", "tokio", "tracing", "zksync_vlog", @@ -13177,8 +13035,8 @@ source = "git+https://github.com/matter-labs/vm2.git?rev=457d8a7eea9093af9440662 dependencies = [ "enum_dispatch", "primitive-types", - "zk_evm_abstractions 0.150.7", - "zkevm_opcode_defs 0.150.7", + "zk_evm_abstractions 0.150.18", + "zkevm_opcode_defs 0.150.18", "zksync_vm2_interface", ] diff --git a/Cargo.toml b/Cargo.toml index 99f6abdf85e2..80e74f05c087 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -228,19 +228,16 @@ tokio-stream = "0.1.16" # We *always* pin the latest version of protocol to disallow accidental changes in the execution logic. # However, for the historical version of protocol crates, we have lax requirements. Otherwise, # Bumping a crypto dependency like `boojum` would require us to republish all the historical packages. -circuit_sequencer_api_1_3_3 = { package = "circuit_sequencer_api", version = "0.133" } -circuit_sequencer_api_1_4_0 = { package = "circuit_sequencer_api", version = "0.140" } -circuit_sequencer_api_1_4_1 = { package = "circuit_sequencer_api", version = "0.141" } -circuit_sequencer_api_1_4_2 = { package = "circuit_sequencer_api", version = "0.142" } -circuit_sequencer_api_1_5_0 = { package = "circuit_sequencer_api", version = "=0.150.7" } -crypto_codegen = { package = "zksync_solidity_vk_codegen", version = "=0.30.1" } -kzg = { package = "zksync_kzg", version = "=0.150.7" } +circuit_encodings = { package = "circuit_encodings", version = "=0.150.18" } +circuit_sequencer_api = { package = "circuit_sequencer_api", version = "=0.150.18" } +crypto_codegen = { package = "zksync_solidity_vk_codegen", version = "=0.30.11" } +kzg = { package = "zksync_kzg", version = "=0.150.18" } zk_evm = { version = "=0.133.0" } zk_evm_1_3_1 = { package = "zk_evm", version = "0.131.0-rc.2" } zk_evm_1_3_3 = { package = "zk_evm", version = "0.133" } zk_evm_1_4_0 = { package = "zk_evm", version = "0.140" } zk_evm_1_4_1 = { package = "zk_evm", version = "0.141" } -zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.7" } +zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.18" } # New VM; pinned to a specific commit because of instability zksync_vm2 = { git = "https://github.com/matter-labs/vm2.git", rev = "457d8a7eea9093af9440662e33e598c13ba41633" } diff --git a/core/lib/multivm/Cargo.toml b/core/lib/multivm/Cargo.toml index 128e6fc0c4af..107a168e305a 100644 --- a/core/lib/multivm/Cargo.toml +++ b/core/lib/multivm/Cargo.toml @@ -18,11 +18,7 @@ zk_evm_1_3_3.workspace = true zk_evm_1_3_1.workspace = true zksync_vm2.workspace = true -circuit_sequencer_api_1_3_3.workspace = true -circuit_sequencer_api_1_4_0.workspace = true -circuit_sequencer_api_1_4_1.workspace = true -circuit_sequencer_api_1_4_2.workspace = true -circuit_sequencer_api_1_5_0.workspace = true +circuit_sequencer_api.workspace = true zksync_types.workspace = true zksync_contracts.workspace = true diff --git a/core/lib/multivm/src/glue/types/vm/vm_block_result.rs b/core/lib/multivm/src/glue/types/vm/vm_block_result.rs index c4eb0b1741aa..1cbb9f261ad2 100644 --- a/core/lib/multivm/src/glue/types/vm/vm_block_result.rs +++ b/core/lib/multivm/src/glue/types/vm/vm_block_result.rs @@ -1,8 +1,6 @@ use std::collections::HashMap; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries as sort_storage_access_queries_1_3_3; -use itertools::Itertools; -use zk_evm_1_3_1::aux_structures::LogQuery as LogQuery_1_3_1; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zksync_types::l2_to_l1_log::UserL2ToL1Log; use crate::{ @@ -11,6 +9,7 @@ use crate::{ CurrentExecutionState, ExecutionResult, Refunds, VmExecutionLogs, VmExecutionResultAndLogs, VmExecutionStatistics, }, + utils::glue_log_query, }; // Note: In version after vm `VmVirtualBlocks` the bootloader memory knowledge is encapsulated into the VM. @@ -21,18 +20,12 @@ use crate::{ impl GlueFrom for crate::interface::FinishedL1Batch { fn glue_from(value: crate::vm_m5::vm_instance::VmBlockResult) -> Self { let storage_log_queries = value.full_result.storage_log_queries.clone(); - let deduplicated_storage_logs: Vec = sort_storage_access_queries_1_3_3( - &storage_log_queries + let deduplicated_storage_logs = sort_storage_access_queries( + storage_log_queries .iter() - .map(|log| { - GlueInto::::glue_into(log.log_query) - }) - .collect_vec(), + .map(|log| glue_log_query(log.log_query)), ) - .1 - .into_iter() - .map(GlueInto::::glue_into) - .collect(); + .1; crate::interface::FinishedL1Batch { block_tip_execution_result: VmExecutionResultAndLogs { @@ -78,18 +71,12 @@ impl GlueFrom for crate::interface::Fi impl GlueFrom for crate::interface::FinishedL1Batch { fn glue_from(value: crate::vm_m6::vm_instance::VmBlockResult) -> Self { let storage_log_queries = value.full_result.storage_log_queries.clone(); - let deduplicated_storage_logs: Vec = sort_storage_access_queries_1_3_3( - &storage_log_queries + let deduplicated_storage_logs = sort_storage_access_queries( + storage_log_queries .iter() - .map(|log| { - GlueInto::::glue_into(log.log_query) - }) - .collect_vec(), + .map(|log| glue_log_query(log.log_query)), ) - .1 - .into_iter() - .map(GlueInto::::glue_into) - .collect(); + .1; crate::interface::FinishedL1Batch { block_tip_execution_result: VmExecutionResultAndLogs { @@ -135,11 +122,12 @@ impl GlueFrom for crate::interface::Fi impl GlueFrom for crate::interface::FinishedL1Batch { fn glue_from(value: crate::vm_1_3_2::vm_instance::VmBlockResult) -> Self { let storage_log_queries = value.full_result.storage_log_queries.clone(); - let deduplicated_storage_logs = - circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries( - storage_log_queries.iter().map(|log| &log.log_query), - ) - .1; + let deduplicated_storage_logs = sort_storage_access_queries( + storage_log_queries + .iter() + .map(|log| glue_log_query(log.log_query)), + ) + .1; crate::interface::FinishedL1Batch { block_tip_execution_result: VmExecutionResultAndLogs { diff --git a/core/lib/multivm/src/lib.rs b/core/lib/multivm/src/lib.rs index fc4085d9b021..202d7ce95d14 100644 --- a/core/lib/multivm/src/lib.rs +++ b/core/lib/multivm/src/lib.rs @@ -2,7 +2,7 @@ #![warn(unused_extern_crates)] #![warn(unused_imports)] -pub use circuit_sequencer_api_1_5_0 as circuit_sequencer_api_latest; +pub use circuit_sequencer_api as circuit_sequencer_api_latest; pub use zk_evm_1_5_0 as zk_evm_latest; pub use zksync_types::vm::VmVersion; pub use zksync_vm_interface as interface; diff --git a/core/lib/multivm/src/utils/mod.rs b/core/lib/multivm/src/utils/mod.rs index 4332c0327ff1..6f350084d22a 100644 --- a/core/lib/multivm/src/utils/mod.rs +++ b/core/lib/multivm/src/utils/mod.rs @@ -5,12 +5,27 @@ use zksync_types::{ }; pub use self::deduplicator::{ModifiedSlot, StorageWritesDeduplicator}; -use crate::interface::L1BatchEnv; +use crate::{ + glue::{GlueFrom, GlueInto}, + interface::L1BatchEnv, +}; pub(crate) mod bytecode; mod deduplicator; pub(crate) mod events; +/// Allows to convert `LogQuery` between two different versions, even if they don't provide +/// direct conversion between each other. +/// It transforms the input query to the `LogQuery` from `zksync_types` (for which most of the +/// `zk_evm` versions provide conversion) and then converts it to the target version. +pub fn glue_log_query(l: L) -> R +where + L: GlueInto, + R: GlueFrom, +{ + R::glue_from(l.glue_into()) +} + /// Calculates the base fee and gas per pubdata for the given L1 gas price. pub fn derive_base_fee_and_gas_per_pubdata( batch_fee_input: BatchFeeInput, diff --git a/core/lib/multivm/src/versions/testonly/precompiles.rs b/core/lib/multivm/src/versions/testonly/precompiles.rs index e525bd627646..dee60686a4f0 100644 --- a/core/lib/multivm/src/versions/testonly/precompiles.rs +++ b/core/lib/multivm/src/versions/testonly/precompiles.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_5_0::geometry_config::get_geometry_config; +use circuit_sequencer_api::geometry_config::ProtocolGeometry; use zksync_test_contracts::TestContract; use zksync_types::{Address, Execute}; @@ -41,7 +41,9 @@ pub(crate) fn test_keccak() { assert!(!exec_result.result.is_failed(), "{exec_result:#?}"); let keccak_count = exec_result.statistics.circuit_statistic.keccak256 - * get_geometry_config().cycles_per_keccak256_circuit as f32; + * ProtocolGeometry::V1_5_0 + .config() + .cycles_per_keccak256_circuit as f32; assert!(keccak_count >= 1000.0, "{keccak_count}"); } @@ -77,7 +79,7 @@ pub(crate) fn test_sha256() { assert!(!exec_result.result.is_failed(), "{exec_result:#?}"); let sha_count = exec_result.statistics.circuit_statistic.sha256 - * get_geometry_config().cycles_per_sha256_circuit as f32; + * ProtocolGeometry::V1_5_0.config().cycles_per_sha256_circuit as f32; assert!(sha_count >= 1000.0, "{sha_count}"); } @@ -106,6 +108,8 @@ pub(crate) fn test_ecrecover() { assert!(!exec_result.result.is_failed(), "{exec_result:#?}"); let ecrecover_count = exec_result.statistics.circuit_statistic.ecrecover - * get_geometry_config().cycles_per_ecrecover_circuit as f32; + * ProtocolGeometry::V1_5_0 + .config() + .cycles_per_ecrecover_circuit as f32; assert!((ecrecover_count - 1.0).abs() < 1e-4, "{ecrecover_count}"); } diff --git a/core/lib/multivm/src/versions/vm_1_3_2/pubdata_utils.rs b/core/lib/multivm/src/versions/vm_1_3_2/pubdata_utils.rs index 3c10bd8c48be..f0be10d72077 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/pubdata_utils.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/pubdata_utils.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zk_evm_1_3_3::aux_structures::Timestamp; use zksync_types::{StorageKey, PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; use crate::{ interface::{storage::WriteStorage, VmEvent}, - utils::bytecode::bytecode_len_in_bytes, + utils::{bytecode::bytecode_len_in_bytes, glue_log_query}, vm_1_3_2::{history_recorder::HistoryMode, oracles::storage::storage_key_of_log, VmInstance}, }; @@ -71,16 +71,20 @@ impl VmInstance { .state .storage .storage_log_queries_after_timestamp(from_timestamp); - let (_, deduplicated_logs) = - sort_storage_access_queries(storage_logs.iter().map(|log| &log.log_query)); + let (_, deduplicated_logs) = sort_storage_access_queries( + storage_logs.iter().map(|log| glue_log_query(log.log_query)), + ); deduplicated_logs .into_iter() .filter_map(|log| { if log.rw_flag { - let key = storage_key_of_log(&log); + let key = storage_key_of_log(&glue_log_query(log)); let pre_paid = pre_paid_before_tx(&key); - let to_pay_by_user = self.state.storage.base_price_for_write(&log); + let to_pay_by_user = self + .state + .storage + .base_price_for_write(&glue_log_query(log)); if to_pay_by_user > pre_paid { Some(to_pay_by_user - pre_paid) diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs index ca9ba097d472..6515228903f6 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use itertools::Itertools; use zk_evm_1_3_3::{ aux_structures::{MemoryPage, Timestamp}, diff --git a/core/lib/multivm/src/versions/vm_1_4_1/tracers/circuits_capacity.rs b/core/lib/multivm/src/versions/vm_1_4_1/tracers/circuits_capacity.rs index a32328bbc18c..5ef359248b85 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/tracers/circuits_capacity.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/tracers/circuits_capacity.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_4_1::{geometry_config::get_geometry_config, toolset::GeometryConfig}; +use circuit_sequencer_api::geometry_config::{GeometryConfig, ProtocolGeometry}; use crate::{interface::CircuitStatistic, utils::CircuitCycleStatistic}; @@ -40,7 +40,7 @@ pub(crate) const UMA_READ_RAM_CYCLES: u32 = 3; pub(crate) const PRECOMPILE_RAM_CYCLES: u32 = 1; pub(crate) const PRECOMPILE_LOG_DEMUXER_CYCLES: u32 = 1; -const GEOMETRY_CONFIG: GeometryConfig = get_geometry_config(); +const GEOMETRY_CONFIG: GeometryConfig = ProtocolGeometry::V1_4_1.config(); pub(crate) fn circuit_statistic_from_cycles(cycles: CircuitCycleStatistic) -> CircuitStatistic { CircuitStatistic { diff --git a/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs index a51c5ce46197..344cacbd903e 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use circuit_sequencer_api_1_4_1::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zk_evm_1_4_1::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, @@ -24,6 +24,7 @@ use crate::{ extract_bytecode_publication_requests_from_l1_messenger, extract_l2tol1logs_from_l1_messenger, }, + glue_log_query, }, vm_1_4_1::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, @@ -130,7 +131,7 @@ impl PubdataTracer { storage .storage_log_queries_after_timestamp(Timestamp(0)) .iter() - .map(|log| &log.log_query), + .map(|log| glue_log_query(log.log_query)), ) .1 .into_iter() diff --git a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/vm_state.rs index 9c3ecd9741a3..cc1ec75d51c2 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/vm_state.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use zk_evm_1_4_1::{ aux_structures::{MemoryPage, Timestamp}, block_properties::BlockProperties, 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 af483feedd7e..7f17f65cac07 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 @@ -1,6 +1,6 @@ use std::rc::Rc; -use circuit_sequencer_api_1_4_1::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zksync_types::{ l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, Transaction, @@ -15,7 +15,7 @@ use crate::{ FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, }, - utils::events::extract_l2tol1logs_from_l1_messenger, + utils::{events::extract_l2tol1logs_from_l1_messenger, glue_log_query}, vm_1_4_1::{ bootloader_state::BootloaderState, old_vm::events::merge_events, @@ -60,8 +60,12 @@ impl Vm { let storage_log_queries = self.state.storage.get_final_log_queries(); - let deduped_storage_log_queries = - sort_storage_access_queries(storage_log_queries.iter().map(|log| &log.log_query)).1; + let deduped_storage_log_queries = sort_storage_access_queries( + storage_log_queries + .iter() + .map(|log| glue_log_query(log.log_query)), + ) + .1; CurrentExecutionState { events, diff --git a/core/lib/multivm/src/versions/vm_1_4_2/constants.rs b/core/lib/multivm/src/versions/vm_1_4_2/constants.rs index 79f20660c149..35266358a742 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/constants.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/constants.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_4_2::{BLOB_CHUNK_SIZE, ELEMENTS_PER_4844_BLOCK}; +use circuit_sequencer_api::{BLOB_CHUNK_SIZE, ELEMENTS_PER_4844_BLOCK}; use zk_evm_1_4_1::aux_structures::MemoryPage; pub use zk_evm_1_4_1::zkevm_opcode_defs::system_params::{ ERGS_PER_CIRCUIT, INITIAL_STORAGE_WRITE_PUBDATA_BYTES, diff --git a/core/lib/multivm/src/versions/vm_1_4_2/tracers/circuits_capacity.rs b/core/lib/multivm/src/versions/vm_1_4_2/tracers/circuits_capacity.rs index 974e07577213..e56d57246982 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/tracers/circuits_capacity.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/tracers/circuits_capacity.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_4_2::{geometry_config::get_geometry_config, toolset::GeometryConfig}; +use circuit_sequencer_api::geometry_config::{GeometryConfig, ProtocolGeometry}; use crate::{interface::CircuitStatistic, utils::CircuitCycleStatistic}; @@ -41,7 +41,7 @@ pub(crate) const UMA_READ_RAM_CYCLES: u32 = 3; pub(crate) const PRECOMPILE_RAM_CYCLES: u32 = 1; pub(crate) const PRECOMPILE_LOG_DEMUXER_CYCLES: u32 = 1; -const GEOMETRY_CONFIG: GeometryConfig = get_geometry_config(); +const GEOMETRY_CONFIG: GeometryConfig = ProtocolGeometry::V1_4_2.config(); pub(crate) fn circuit_statistic_from_cycles(cycles: CircuitCycleStatistic) -> CircuitStatistic { CircuitStatistic { diff --git a/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs index 58318f5d845e..8f9bbb94b9d4 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use circuit_sequencer_api_1_4_2::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zk_evm_1_4_1::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, @@ -24,6 +24,7 @@ use crate::{ extract_bytecode_publication_requests_from_l1_messenger, extract_l2tol1logs_from_l1_messenger, }, + glue_log_query, }, vm_1_4_2::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, @@ -150,7 +151,7 @@ impl PubdataTracer { storage .storage_log_queries_after_timestamp(Timestamp(0)) .iter() - .map(|log| &log.log_query), + .map(|log| glue_log_query(log.log_query)), ) .1 .into_iter() diff --git a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/vm_state.rs index 52a0dc61d740..00833e4e5e89 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/vm_state.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use zk_evm_1_4_1::{ aux_structures::{MemoryPage, Timestamp}, block_properties::BlockProperties, 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 e7c8e7acdd95..ce649c221f39 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 @@ -1,6 +1,6 @@ use std::{mem, rc::Rc}; -use circuit_sequencer_api_1_4_2::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zksync_types::{ l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, Transaction, @@ -15,7 +15,7 @@ use crate::{ FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, }, - utils::events::extract_l2tol1logs_from_l1_messenger, + utils::{events::extract_l2tol1logs_from_l1_messenger, glue_log_query}, vm_1_4_2::{ bootloader_state::BootloaderState, old_vm::events::merge_events, @@ -60,8 +60,12 @@ impl Vm { let storage_log_queries = self.state.storage.get_final_log_queries(); - let deduped_storage_log_queries = - sort_storage_access_queries(storage_log_queries.iter().map(|log| &log.log_query)).1; + let deduped_storage_log_queries = sort_storage_access_queries( + storage_log_queries + .iter() + .map(|log| glue_log_query(log.log_query)), + ) + .1; CurrentExecutionState { events, diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/circuits_capacity.rs b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/circuits_capacity.rs index a9e5e17e7973..bcc0ec48be0a 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/circuits_capacity.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/circuits_capacity.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_4_0::{geometry_config::get_geometry_config, toolset::GeometryConfig}; +use circuit_sequencer_api::geometry_config::{GeometryConfig, ProtocolGeometry}; use crate::{interface::CircuitStatistic, utils::CircuitCycleStatistic}; @@ -40,7 +40,7 @@ pub(crate) const UMA_READ_RAM_CYCLES: u32 = 3; pub(crate) const PRECOMPILE_RAM_CYCLES: u32 = 1; pub(crate) const PRECOMPILE_LOG_DEMUXER_CYCLES: u32 = 1; -const GEOMETRY_CONFIG: GeometryConfig = get_geometry_config(); +const GEOMETRY_CONFIG: GeometryConfig = ProtocolGeometry::V1_4_0.config(); pub(crate) fn circuit_statistic_from_cycles(cycles: CircuitCycleStatistic) -> CircuitStatistic { CircuitStatistic { diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs index 6396d143b401..c442f5705d2e 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use circuit_sequencer_api_1_4_0::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zk_evm_1_4_0::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, @@ -24,6 +24,7 @@ use crate::{ extract_bytecode_publication_requests_from_l1_messenger, extract_l2tol1logs_from_l1_messenger, }, + glue_log_query, }, vm_boojum_integration::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, @@ -121,7 +122,7 @@ impl PubdataTracer { storage .storage_log_queries_after_timestamp(Timestamp(0)) .iter() - .map(|log| &log.log_query), + .map(|log| glue_log_query(log.log_query)), ) .1 .into_iter() diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/vm_state.rs index dc41926c4485..f225a91506ee 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/vm_state.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use zk_evm_1_4_0::{ aux_structures::{MemoryPage, Timestamp}, block_properties::BlockProperties, 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 43c9900486db..42129ab5a9e6 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/vm.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use circuit_sequencer_api_1_4_0::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zksync_types::{ l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, Transaction, @@ -15,7 +15,7 @@ use crate::{ FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, }, - utils::events::extract_l2tol1logs_from_l1_messenger, + utils::{events::extract_l2tol1logs_from_l1_messenger, glue_log_query}, vm_boojum_integration::{ bootloader_state::BootloaderState, old_vm::events::merge_events, @@ -60,8 +60,12 @@ impl Vm { let storage_log_queries = self.state.storage.get_final_log_queries(); - let deduped_storage_log_queries = - sort_storage_access_queries(storage_log_queries.iter().map(|log| &log.log_query)).1; + let deduped_storage_log_queries = sort_storage_access_queries( + storage_log_queries + .iter() + .map(|log| glue_log_query(log.log_query)), + ) + .1; CurrentExecutionState { events, diff --git a/core/lib/multivm/src/versions/vm_fast/tracers/circuits.rs b/core/lib/multivm/src/versions/vm_fast/tracers/circuits.rs index 9c1c0b7dfb7f..5acf6c490abf 100644 --- a/core/lib/multivm/src/versions/vm_fast/tracers/circuits.rs +++ b/core/lib/multivm/src/versions/vm_fast/tracers/circuits.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_5_0::{geometry_config::get_geometry_config, toolset::GeometryConfig}; +use circuit_sequencer_api::geometry_config::{GeometryConfig, ProtocolGeometry}; use zksync_vm2::interface::{ CycleStats, GlobalStateInterface, Opcode, OpcodeType, ShouldStop, Tracer, }; @@ -164,4 +164,4 @@ impl CircuitsTracer { } } -const GEOMETRY_CONFIG: GeometryConfig = get_geometry_config(); +const GEOMETRY_CONFIG: GeometryConfig = ProtocolGeometry::V1_5_0.config(); diff --git a/core/lib/multivm/src/versions/vm_latest/constants.rs b/core/lib/multivm/src/versions/vm_latest/constants.rs index c95771f9e849..1578965d7a66 100644 --- a/core/lib/multivm/src/versions/vm_latest/constants.rs +++ b/core/lib/multivm/src/versions/vm_latest/constants.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_5_0::{BLOB_CHUNK_SIZE, ELEMENTS_PER_4844_BLOCK}; +use circuit_sequencer_api::{BLOB_CHUNK_SIZE, ELEMENTS_PER_4844_BLOCK}; use zk_evm_1_5_0::aux_structures::MemoryPage; pub use zk_evm_1_5_0::zkevm_opcode_defs::system_params::{ ERGS_PER_CIRCUIT, INITIAL_STORAGE_WRITE_PUBDATA_BYTES, diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/circuits_capacity.rs b/core/lib/multivm/src/versions/vm_latest/tracers/circuits_capacity.rs index 0977a323d191..58cbf45407d5 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/circuits_capacity.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/circuits_capacity.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_5_0::{geometry_config::get_geometry_config, toolset::GeometryConfig}; +use circuit_sequencer_api::geometry_config::{GeometryConfig, ProtocolGeometry}; use crate::{interface::CircuitStatistic, utils::CircuitCycleStatistic}; @@ -52,7 +52,7 @@ pub(crate) const PRECOMPILE_LOG_DEMUXER_CYCLES: u32 = 1; pub(crate) const LOG_DECOMMIT_RAM_CYCLES: u32 = 1; pub(crate) const LOG_DECOMMIT_DECOMMITTER_SORTER_CYCLES: u32 = 1; -const GEOMETRY_CONFIG: GeometryConfig = get_geometry_config(); +const GEOMETRY_CONFIG: GeometryConfig = ProtocolGeometry::V1_5_0.config(); pub(crate) fn circuit_statistic_from_cycles(cycles: CircuitCycleStatistic) -> CircuitStatistic { CircuitStatistic { diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs index 3698914630dd..7c55dd38561d 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs @@ -1,6 +1,6 @@ use std::{marker::PhantomData, rc::Rc}; -use circuit_sequencer_api_1_5_0::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zk_evm_1_5_0::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, @@ -162,7 +162,7 @@ impl PubdataTracer { storage .storage_log_queries_after_timestamp(Timestamp(0)) .iter() - .map(|log| &log.log_query), + .map(|log| log.log_query), ) .1 .into_iter() diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs index 03f306f36c52..63f06f4fd846 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use zk_evm_1_5_0::{ aux_structures::{MemoryPage, PubdataCost, Timestamp}, block_properties::BlockProperties, diff --git a/core/lib/multivm/src/versions/vm_latest/vm.rs b/core/lib/multivm/src/versions/vm_latest/vm.rs index ada20af9fa3c..1db369d4ae20 100644 --- a/core/lib/multivm/src/versions/vm_latest/vm.rs +++ b/core/lib/multivm/src/versions/vm_latest/vm.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, rc::Rc}; -use circuit_sequencer_api_1_5_0::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zksync_types::{ h256_to_u256, l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, @@ -124,7 +124,7 @@ impl Vm { let storage_log_queries = self.state.storage.get_final_log_queries(); let deduped_storage_log_queries = - sort_storage_access_queries(storage_log_queries.iter().map(|log| &log.log_query)).1; + sort_storage_access_queries(storage_log_queries.iter().map(|log| log.log_query)).1; CurrentExecutionState { events, diff --git a/core/lib/multivm/src/versions/vm_m5/pubdata_utils.rs b/core/lib/multivm/src/versions/vm_m5/pubdata_utils.rs index 8eca2ef5cd86..0cf208e2a40e 100644 --- a/core/lib/multivm/src/versions/vm_m5/pubdata_utils.rs +++ b/core/lib/multivm/src/versions/vm_m5/pubdata_utils.rs @@ -1,14 +1,13 @@ use std::collections::HashMap; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; -use itertools::Itertools; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zk_evm_1_3_1::aux_structures::{LogQuery, Timestamp}; use zksync_types::{StorageKey, PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; use crate::{ glue::GlueInto, interface::VmEvent, - utils::bytecode::bytecode_len_in_bytes, + utils::{bytecode::bytecode_len_in_bytes, glue_log_query}, vm_m5::{ oracles::storage::storage_key_of_log, storage::Storage, utils::collect_storage_log_queries_after_timestamp, vm_instance::VmInstance, @@ -86,16 +85,11 @@ impl VmInstance { // To allow calling the `vm-1.3.3`s. method, the `v1.3.1`'s `LogQuery` has to be converted // to the `vm-1.3.3`'s `LogQuery`. Then, we need to convert it back. let deduplicated_logs: Vec = sort_storage_access_queries( - &storage_logs - .iter() - .map(|log| { - GlueInto::::glue_into(log.log_query) - }) - .collect_vec(), + storage_logs.iter().map(|log| glue_log_query(log.log_query)), ) .1 .into_iter() - .map(GlueInto::::glue_into) + .map(glue_log_query) .collect(); deduplicated_logs diff --git a/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs index 0a7df48df80f..c137dcac0bd1 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use zk_evm_1_3_1::{ abstractions::{MAX_HEAP_PAGE_SIZE_IN_WORDS, MAX_MEMORY_BYTES}, aux_structures::{MemoryPage, Timestamp}, diff --git a/core/lib/multivm/src/versions/vm_m6/pubdata_utils.rs b/core/lib/multivm/src/versions/vm_m6/pubdata_utils.rs index 97bf290a2162..fb3e82a28243 100644 --- a/core/lib/multivm/src/versions/vm_m6/pubdata_utils.rs +++ b/core/lib/multivm/src/versions/vm_m6/pubdata_utils.rs @@ -1,14 +1,13 @@ use std::collections::HashMap; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; -use itertools::Itertools; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zk_evm_1_3_1::aux_structures::{LogQuery, Timestamp}; use zksync_types::{StorageKey, PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; use crate::{ glue::GlueInto, interface::VmEvent, - utils::bytecode::bytecode_len_in_bytes, + utils::{bytecode::bytecode_len_in_bytes, glue_log_query}, vm_m6::{ history_recorder::HistoryMode, oracles::storage::storage_key_of_log, storage::Storage, utils::collect_storage_log_queries_after_timestamp, VmInstance, @@ -80,16 +79,11 @@ impl VmInstance { // To allow calling the `vm-1.3.3`s. method, the `v1.3.1`'s `LogQuery` has to be converted // to the `vm-1.3.3`'s `LogQuery`. Then, we need to convert it back. let deduplicated_logs: Vec = sort_storage_access_queries( - &storage_logs - .iter() - .map(|log| { - GlueInto::::glue_into(log.log_query) - }) - .collect_vec(), + storage_logs.iter().map(|log| glue_log_query(log.log_query)), ) .1 .into_iter() - .map(GlueInto::::glue_into) + .map(glue_log_query) .collect(); deduplicated_logs diff --git a/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs index ff83abc45fcf..4b2eb8212e61 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use zk_evm_1_3_1::{ abstractions::{MAX_HEAP_PAGE_SIZE_IN_WORDS, MAX_MEMORY_BYTES}, aux_structures::{MemoryPage, Timestamp}, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/vm_state.rs index 6776bc37c9d5..1c31c63d6893 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/vm_state.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use zk_evm_1_3_3::{ aux_structures::{MemoryPage, Timestamp}, block_properties::BlockProperties, 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 81b0c52cce5e..bfe35b1189f8 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/vm.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zksync_types::{l2_to_l1_log::UserL2ToL1Log, Transaction}; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; @@ -12,6 +12,7 @@ use crate::{ FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, }, + utils::glue_log_query, vm_latest::HistoryEnabled, vm_refunds_enhancement::{ bootloader_state::BootloaderState, @@ -56,8 +57,12 @@ impl Vm { let storage_log_queries = self.state.storage.get_final_log_queries(); - let deduped_storage_log_queries = - sort_storage_access_queries(storage_log_queries.iter().map(|log| &log.log_query)).1; + let deduped_storage_log_queries = sort_storage_access_queries( + storage_log_queries + .iter() + .map(|log| glue_log_query(log.log_query)), + ) + .1; CurrentExecutionState { events, diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs index 59aa837cd8fb..28d80b3d1116 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use vise::{Buckets, EncodeLabelSet, EncodeLabelValue, Family, Histogram, Metrics}; use zk_evm_1_3_3::{ aux_structures::Timestamp, @@ -18,7 +18,7 @@ use crate::{ L1BatchEnv, Refunds, VmEvent, VmExecutionResultAndLogs, }, tracers::dynamic::vm_1_3_3::DynTracer, - utils::bytecode::bytecode_len_in_bytes, + utils::{bytecode::bytecode_len_in_bytes, glue_log_query}, vm_virtual_blocks::{ bootloader_state::BootloaderState, constants::{BOOTLOADER_HEAP_PAGE, OPERATOR_REFUNDS_OFFSET, TX_GAS_LIMIT_OFFSET}, @@ -372,15 +372,15 @@ fn pubdata_published_for_writes( .storage .storage_log_queries_after_timestamp(from_timestamp); let (_, deduplicated_logs) = - sort_storage_access_queries(storage_logs.iter().map(|log| &log.log_query)); + sort_storage_access_queries(storage_logs.iter().map(|log| glue_log_query(log.log_query))); deduplicated_logs .into_iter() .filter_map(|log| { if log.rw_flag { - let key = storage_key_of_log(&log); + let key = storage_key_of_log(&glue_log_query(log)); let pre_paid = pre_paid_before_tx(&key); - let to_pay_by_user = state.storage.base_price_for_write(&log); + let to_pay_by_user = state.storage.base_price_for_write(&glue_log_query(log)); if to_pay_by_user > pre_paid { Some(to_pay_by_user - pre_paid) diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/vm_state.rs index d1509bd016d8..c7ab344849f2 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/vm_state.rs @@ -1,4 +1,4 @@ -use circuit_sequencer_api_1_3_3::INITIAL_MONOTONIC_CYCLE_COUNTER; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; use zk_evm_1_3_3::{ aux_structures::{MemoryPage, Timestamp}, block_properties::BlockProperties, 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 a2d18e10de44..cc255f550c55 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/vm.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries; +use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries; use zksync_types::{l2_to_l1_log::UserL2ToL1Log, Transaction}; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; @@ -12,6 +12,7 @@ use crate::{ FinishedL1Batch, L1BatchEnv, L2BlockEnv, PushTransactionResult, SystemEnv, VmExecutionMode, VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, }, + utils::glue_log_query, vm_latest::HistoryEnabled, vm_virtual_blocks::{ bootloader_state::BootloaderState, @@ -56,8 +57,12 @@ impl Vm { let storage_log_queries = self.state.storage.get_final_log_queries(); - let deduped_storage_log_queries = - sort_storage_access_queries(storage_log_queries.iter().map(|log| &log.log_query)).1; + let deduped_storage_log_queries = sort_storage_access_queries( + storage_log_queries + .iter() + .map(|log| glue_log_query(log.log_query)), + ) + .1; CurrentExecutionState { events, diff --git a/core/lib/prover_interface/Cargo.toml b/core/lib/prover_interface/Cargo.toml index 50671fb3acb4..3ed8a9ff558f 100644 --- a/core/lib/prover_interface/Cargo.toml +++ b/core/lib/prover_interface/Cargo.toml @@ -16,7 +16,7 @@ zksync_object_store.workspace = true zksync_types.workspace = true # We can use the newest api to send proofs to L1. -circuit_sequencer_api_1_5_0.workspace = true +circuit_sequencer_api.workspace = true serde.workspace = true strum = { workspace = true, features = ["derive"] } diff --git a/core/lib/prover_interface/src/outputs.rs b/core/lib/prover_interface/src/outputs.rs index 60a9eaba760b..b6422473cea3 100644 --- a/core/lib/prover_interface/src/outputs.rs +++ b/core/lib/prover_interface/src/outputs.rs @@ -1,6 +1,6 @@ use core::fmt; -use circuit_sequencer_api_1_5_0::proof::FinalProof; +use circuit_sequencer_api::proof::FinalProof; use serde::{Deserialize, Serialize}; use serde_with::{hex::Hex, serde_as}; use zksync_object_store::{serialize_using_bincode, Bucket, StoredObject}; diff --git a/core/lib/prover_interface/tests/job_serialization.rs b/core/lib/prover_interface/tests/job_serialization.rs index ead59749abe3..d170520798d1 100644 --- a/core/lib/prover_interface/tests/job_serialization.rs +++ b/core/lib/prover_interface/tests/job_serialization.rs @@ -1,6 +1,6 @@ //! Integration tests for object store serialization of job objects. -use circuit_sequencer_api_1_5_0::proof::FinalProof; +use circuit_sequencer_api::proof::FinalProof; use tokio::fs; use zksync_object_store::{Bucket, MockObjectStore}; use zksync_prover_interface::{ diff --git a/core/lib/state/src/storage_overrides.rs b/core/lib/state/src/storage_overrides.rs deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/core/lib/utils/Cargo.toml b/core/lib/utils/Cargo.toml index 216f3b12d426..fb08afc59b70 100644 --- a/core/lib/utils/Cargo.toml +++ b/core/lib/utils/Cargo.toml @@ -20,6 +20,7 @@ futures.workspace = true reqwest = { workspace = true, features = ["blocking"] } serde_json.workspace = true once_cell.workspace = true +sha2.workspace = true [dev-dependencies] tokio = { workspace = true, features = ["macros", "rt"] } diff --git a/core/node/api_server/src/web3/namespaces/unstable/utils.rs b/core/node/api_server/src/web3/namespaces/unstable/utils.rs index 2d3187fab6b8..b1071aee28c4 100644 --- a/core/node/api_server/src/web3/namespaces/unstable/utils.rs +++ b/core/node/api_server/src/web3/namespaces/unstable/utils.rs @@ -1,12 +1,11 @@ use zksync_dal::{Connection, Core, CoreDal, DalError}; -use zksync_multivm::circuit_sequencer_api_latest::boojum::ethereum_types::U256; use zksync_system_constants::{ message_root::{CHAIN_COUNT_KEY, CHAIN_INDEX_TO_ID_KEY, CHAIN_TREE_KEY}, L2_MESSAGE_ROOT_ADDRESS, }; use zksync_types::{ h256_to_u256, l2_to_l1_log::CHAIN_ID_LEAF_PADDING, u256_to_h256, web3::keccak256, - AccountTreeId, L2BlockNumber, StorageKey, H256, + AccountTreeId, L2BlockNumber, StorageKey, H256, U256, }; use zksync_web3_decl::error::Web3Error; diff --git a/core/node/commitment_generator/Cargo.toml b/core/node/commitment_generator/Cargo.toml index f0b4046bab42..8a1af52e589d 100644 --- a/core/node/commitment_generator/Cargo.toml +++ b/core/node/commitment_generator/Cargo.toml @@ -20,13 +20,9 @@ zksync_eth_client.workspace = true zksync_contracts.workspace = true zksync_multivm.workspace = true zksync_system_constants.workspace = true -circuit_sequencer_api_1_4_0.workspace = true -circuit_sequencer_api_1_4_1.workspace = true -circuit_sequencer_api_1_5_0.workspace = true +circuit_encodings.workspace = true zk_evm_1_5_0.workspace = true -zk_evm_1_4_1.workspace = true -zk_evm_1_3_3.workspace = true tokio = { workspace = true, features = ["time"] } futures.workspace = true diff --git a/core/node/commitment_generator/src/utils.rs b/core/node/commitment_generator/src/utils.rs index cc44d7a03c71..b0a0562d8ec5 100644 --- a/core/node/commitment_generator/src/utils.rs +++ b/core/node/commitment_generator/src/utils.rs @@ -4,14 +4,6 @@ use std::fmt; use anyhow::Context; use itertools::Itertools; -use zk_evm_1_3_3::{ - aux_structures::Timestamp as Timestamp_1_3_3, - zk_evm_abstractions::queries::LogQuery as LogQuery_1_3_3, -}; -use zk_evm_1_4_1::{ - aux_structures::Timestamp as Timestamp_1_4_1, - zk_evm_abstractions::queries::LogQuery as LogQuery_1_4_1, -}; use zk_evm_1_5_0::{ aux_structures::Timestamp as Timestamp_1_5_0, zk_evm_abstractions::queries::LogQuery as LogQuery_1_5_0, @@ -22,7 +14,6 @@ use zksync_multivm::{interface::VmEvent, utils::get_used_bootloader_memory_bytes use zksync_system_constants::message_root::{AGG_TREE_HEIGHT_KEY, AGG_TREE_NODES_KEY}; use zksync_types::{ address_to_u256, h256_to_u256, u256_to_h256, - vm::VmVersion, web3::keccak256, zk_evm_types::{LogQuery, Timestamp}, AccountTreeId, L1BatchNumber, ProtocolVersionId, StorageKey, EVENT_WRITER_ADDRESS, H256, @@ -54,37 +45,15 @@ impl CommitmentComputer for RealCommitmentComputer { fn events_queue_commitment( &self, events_queue: &[LogQuery], - protocol_version: ProtocolVersionId, + _protocol_version: ProtocolVersionId, ) -> anyhow::Result { - match VmVersion::from(protocol_version) { - VmVersion::VmBoojumIntegration => Ok(H256( - circuit_sequencer_api_1_4_0::commitments::events_queue_commitment_fixed( - &events_queue - .iter() - .map(|x| to_log_query_1_3_3(*x)) - .collect(), - ), - )), - VmVersion::Vm1_4_1 | VmVersion::Vm1_4_2 => Ok(H256( - circuit_sequencer_api_1_4_1::commitments::events_queue_commitment_fixed( - &events_queue - .iter() - .map(|x| to_log_query_1_4_1(*x)) - .collect(), - ), - )), - VmVersion::Vm1_5_0SmallBootloaderMemory - | VmVersion::Vm1_5_0IncreasedBootloaderMemory - | VmVersion::VmGateway => Ok(H256( - circuit_sequencer_api_1_5_0::commitments::events_queue_commitment_fixed( - &events_queue - .iter() - .map(|x| to_log_query_1_5_0(*x)) - .collect(), - ), - )), - _ => anyhow::bail!("Unsupported protocol version: {protocol_version:?}"), - } + let commitment = circuit_encodings::commitments::events_queue_commitment_fixed( + &events_queue + .iter() + .map(|x| to_log_query_1_5_0(*x)) + .collect(), + ); + Ok(H256(commitment)) } fn bootloader_initial_content_commitment( @@ -100,27 +69,10 @@ impl CommitmentComputer for RealCommitmentComputer { let full_bootloader_memory = expand_memory_contents(initial_bootloader_contents, expanded_memory_size); - - match VmVersion::from(protocol_version) { - VmVersion::VmBoojumIntegration => Ok(H256( - circuit_sequencer_api_1_4_0::commitments::initial_heap_content_commitment_fixed( - &full_bootloader_memory, - ), - )), - VmVersion::Vm1_4_1 | VmVersion::Vm1_4_2 => Ok(H256( - circuit_sequencer_api_1_4_1::commitments::initial_heap_content_commitment_fixed( - &full_bootloader_memory, - ), - )), - VmVersion::Vm1_5_0SmallBootloaderMemory - | VmVersion::Vm1_5_0IncreasedBootloaderMemory - | VmVersion::VmGateway => Ok(H256( - circuit_sequencer_api_1_5_0::commitments::initial_heap_content_commitment_fixed( - &full_bootloader_memory, - ), - )), - _ => unreachable!(), - } + let commitment = circuit_encodings::commitments::initial_heap_content_commitment_fixed( + &full_bootloader_memory, + ); + Ok(H256(commitment)) } } @@ -133,37 +85,6 @@ fn expand_memory_contents(packed: &[(usize, U256)], memory_size_bytes: usize) -> result } -fn to_log_query_1_3_3(log_query: LogQuery) -> LogQuery_1_3_3 { - LogQuery_1_3_3 { - timestamp: Timestamp_1_3_3(log_query.timestamp.0), - tx_number_in_block: log_query.tx_number_in_block, - aux_byte: log_query.aux_byte, - shard_id: log_query.shard_id, - address: log_query.address, - key: log_query.key, - read_value: log_query.read_value, - written_value: log_query.written_value, - rw_flag: log_query.rw_flag, - rollback: log_query.rollback, - is_service: log_query.is_service, - } -} - -fn to_log_query_1_4_1(log_query: LogQuery) -> LogQuery_1_4_1 { - LogQuery_1_4_1 { - timestamp: Timestamp_1_4_1(log_query.timestamp.0), - tx_number_in_block: log_query.tx_number_in_block, - aux_byte: log_query.aux_byte, - shard_id: log_query.shard_id, - address: log_query.address, - key: log_query.key, - read_value: log_query.read_value, - written_value: log_query.written_value, - rw_flag: log_query.rw_flag, - rollback: log_query.rollback, - is_service: log_query.is_service, - } -} fn to_log_query_1_5_0(log_query: LogQuery) -> LogQuery_1_5_0 { LogQuery_1_5_0 { diff --git a/core/node/genesis/src/utils.rs b/core/node/genesis/src/utils.rs index a9b0831b31bc..ac3435835e80 100644 --- a/core/node/genesis/src/utils.rs +++ b/core/node/genesis/src/utils.rs @@ -99,7 +99,7 @@ pub fn get_deduped_log_queries(storage_logs: &[StorageLog]) -> Vec { }) .collect(); - let deduped_log_queries: Vec = sort_storage_access_queries(&log_queries) + let deduped_log_queries: Vec = sort_storage_access_queries(log_queries) .1 .into_iter() .map(|log_query| LogQuery { diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 185f68367c6b..fa8de019c740 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -625,9 +625,9 @@ dependencies = [ [[package]] name = "boojum" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ec2f007ff8f90cc459f03e9f30ca1065440170f013c868823646e2e48d0234" +checksum = "4337dc7b196fc3e5e55e2857bc21638b7441429ee1a953201a9cd2be187b764e" dependencies = [ "arrayvec 0.7.6", "bincode", @@ -657,9 +657,9 @@ dependencies = [ [[package]] name = "boojum-cuda" -version = "0.151.1" +version = "0.152.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b63a717789f92f16fd566c78655d64017c690be59e473c3e769080c975a1f9e" +checksum = "380468fadcba5dcc4021f18f4516a7aa4f4d0ec598c76cd7e7c5f2ff6a56733f" dependencies = [ "boojum", "cmake", @@ -667,6 +667,7 @@ dependencies = [ "era_cudart_sys", "itertools 0.13.0", "lazy_static", + "snark_wrapper", ] [[package]] @@ -804,11 +805,11 @@ dependencies = [ [[package]] name = "circuit_definitions" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76be9ee6e75f1f948d175ab9820ecc7189f72154c95ca503a1974012356f5363" +checksum = "931448074d9dad8aa7cf8f8f8d67101d4b2aac4d1f4699708b0744a9c000fc0b" dependencies = [ - "circuit_encodings 0.150.7", + "circuit_encodings", "crossbeam", "derivative", "seq-macro", @@ -818,117 +819,26 @@ dependencies = [ [[package]] name = "circuit_encodings" -version = "0.140.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf6b7cc842eadb4c250cdc6a8bc1dd97624d9f08bbe54db3e11fb23c3a72be07" -dependencies = [ - "derivative", - "serde", - "zk_evm 0.140.0", - "zkevm_circuits 0.140.3", -] - -[[package]] -name = "circuit_encodings" -version = "0.141.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7898ffbf3cd413576b4b674fe1545a35488c67eb16bd5a4148425e42c2a2b65b" -dependencies = [ - "derivative", - "serde", - "zk_evm 0.141.0", - "zkevm_circuits 0.141.2", -] - -[[package]] -name = "circuit_encodings" -version = "0.142.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8364ecafcc4b2c896023f8d3af952c52a500aa55f14fd268bb5d9ab07f837369" -dependencies = [ - "derivative", - "serde", - "zk_evm 0.141.0", - "zkevm_circuits 0.141.2", -] - -[[package]] -name = "circuit_encodings" -version = "0.150.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2501cc688ef391013019495ae7035cfd54f86987e36d10f73976ce4c5d413c5a" -dependencies = [ - "derivative", - "serde", - "zk_evm 0.150.7", - "zkevm_circuits 0.150.7", -] - -[[package]] -name = "circuit_sequencer_api" -version = "0.133.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb959b1f8c6bbd8be711994d182e85452a26a5d2213a709290b71c8262af1331" -dependencies = [ - "derivative", - "rayon", - "serde", - "zk_evm 0.133.0", - "zksync_bellman", -] - -[[package]] -name = "circuit_sequencer_api" -version = "0.140.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa5f22311ce609d852d7d9f4943535ea4610aeb785129ae6ff83d5201c4fb387" -dependencies = [ - "circuit_encodings 0.140.3", - "derivative", - "rayon", - "serde", - "zk_evm 0.140.0", - "zksync_bellman", -] - -[[package]] -name = "circuit_sequencer_api" -version = "0.141.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c47c71d6ba83a8beb0af13af70beffd627f5497caf3d44c6f96363e788b07ea" -dependencies = [ - "circuit_encodings 0.141.2", - "derivative", - "rayon", - "serde", - "zk_evm 0.141.0", - "zksync_bellman", -] - -[[package]] -name = "circuit_sequencer_api" -version = "0.142.2" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e264723359e6a1aad98110bdccf1ae3ad596e93e7d31da9e40f6adc07e4add54" +checksum = "e3dcfcb4aaa17e6a81ebd2db688d980aff50aa643d9b506d4d11c84976dbc03f" dependencies = [ - "circuit_encodings 0.142.2", "derivative", - "rayon", "serde", - "zk_evm 0.141.0", - "zksync_bellman", + "zk_evm 0.150.18", + "zkevm_circuits", ] [[package]] name = "circuit_sequencer_api" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917d27db531fdd98a51e42ea465bc097f48cc849e7fad68d7856087d15125be1" +checksum = "d13ed70909e8390a4f2599d5a76d9ac4189e5bbbf16146d11b7999788740f291" dependencies = [ - "circuit_encodings 0.150.7", "derivative", "rayon", "serde", + "zk_evm 0.150.18", "zksync_bellman", ] @@ -1796,9 +1706,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "era_cudart" -version = "0.151.1" +version = "0.152.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad950752eeb44f8938be405b95a1630f82e903f4a7adda355d92aad135fcd382" +checksum = "ac345935bc5d367922a8e44f8b9b8f909f564b4cdc922567e9d3fe6b0fafab28" dependencies = [ "bitflags 2.6.0", "era_cudart_sys", @@ -1807,9 +1717,9 @@ dependencies = [ [[package]] name = "era_cudart_sys" -version = "0.151.1" +version = "0.152.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38607d52509b5db97cc4447c8644d6c5ca84f22ff8a9254f984669b1eb82ed4" +checksum = "50eca396c549365468fa210b0c9c4a38895e4bff4ae5ce6f6626c337010de143" dependencies = [ "serde_json", ] @@ -2030,9 +1940,9 @@ dependencies = [ [[package]] name = "franklin-crypto" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "971289216ea5c91872e5e0bb6989214b537bbce375d09fabea5c3ccfe031b204" +checksum = "5c128e2cf791053b3aefdd7b07d6e5ffdc7cf5dd779ca270d727a403057dfb68" dependencies = [ "arr_macro", "bit-vec 0.6.3", @@ -5109,9 +5019,9 @@ dependencies = [ [[package]] name = "rescue_poseidon" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82900c877a0ba5362ac5756efbd82c5b795dc509011c1253e2389d8708f1389d" +checksum = "b62e4ce7543582ab2df1d9544674a55897e168a23afe938a57e1547d2981a7f4" dependencies = [ "addchain", "arrayvec 0.7.6", @@ -5899,12 +5809,11 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "shivini" -version = "0.151.1" +version = "0.152.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2ac4440b6c23005c43a81cf064b9aa123fbeb992ac91cd04c7d485abb1fbea" +checksum = "2673af97e7ea5aef8d1d2ad395e3833a2a9fd8aca6361c2516c44734c0ed92e2" dependencies = [ "bincode", - "blake2 0.10.6", "boojum", "boojum-cuda", "circuit_definitions", @@ -5912,9 +5821,9 @@ dependencies = [ "era_cudart", "era_cudart_sys", "hex", + "itertools 0.13.0", "rand 0.8.5", "serde", - "sha2 0.10.8", "smallvec", ] @@ -5991,13 +5900,14 @@ dependencies = [ [[package]] name = "snark_wrapper" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5dfdc3eed51d79541adff827593743750fe6626a65006814f8cfa4273371de" +checksum = "74645922ea9e18fbd4b6ae9c58e6a7080403edd81e558b610cf5b9dc60a90351" dependencies = [ "derivative", "rand 0.4.6", "rescue_poseidon", + "serde", ] [[package]] @@ -7878,9 +7788,9 @@ dependencies = [ [[package]] name = "zk_evm" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc74fbe2b45fd19e95c59ea792c795feebdb616ebaa463f0ac567f495f47387" +checksum = "3278d0f75408ab35d25998e1124124cd108b48b2a81ed8e71e892ddc5a6be0aa" dependencies = [ "anyhow", "lazy_static", @@ -7888,7 +7798,7 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 0.150.7", + "zk_evm_abstractions 0.150.18", ] [[package]] @@ -7919,22 +7829,22 @@ dependencies = [ [[package]] name = "zk_evm_abstractions" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37f333a3b059899df09e40deb041af881bc03e496fda5eec618ffb5e854ee7df" +checksum = "88b4e5a89cfe1594b6476be16c8c1d45f22ce12bff31c49e077b381a398edd8a" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 0.150.7", + "zkevm_opcode_defs 0.150.18", ] [[package]] name = "zkevm-assembly" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf011a0c83cbfb175f1e60811f0e0cd56551c9e35df596a762556662c638deb9" +checksum = "b4fdb2b380c43157160ec5f3f4f6912c6c9923e2a00886e79b7f5464f59108a7" dependencies = [ "env_logger 0.9.3", "hex", @@ -7947,58 +7857,14 @@ dependencies = [ "smallvec", "structopt", "thiserror 1.0.69", - "zkevm_opcode_defs 0.150.7", -] - -[[package]] -name = "zkevm_circuits" -version = "0.140.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c365c801e0c6eda83fbd153df45575172beb406bfb663d386f9154b4325eda" -dependencies = [ - "arrayvec 0.7.6", - "bincode", - "boojum", - "derivative", - "hex", - "itertools 0.10.5", - "rand 0.4.6", - "rand 0.8.5", - "seq-macro", - "serde", - "serde_json", - "smallvec", - "zkevm_opcode_defs 0.132.0", - "zksync_cs_derive", -] - -[[package]] -name = "zkevm_circuits" -version = "0.141.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ccd0352e122a4e6f0046d2163b7e692e627b23fc3264faa77331a21b65833fd" -dependencies = [ - "arrayvec 0.7.6", - "bincode", - "boojum", - "derivative", - "hex", - "itertools 0.10.5", - "rand 0.4.6", - "rand 0.8.5", - "seq-macro", - "serde", - "serde_json", - "smallvec", - "zkevm_opcode_defs 0.141.0", - "zksync_cs_derive", + "zkevm_opcode_defs 0.150.18", ] [[package]] name = "zkevm_circuits" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06fb35b00699d25175a2ad447f86a9088af8b0bc698bb57086fb04c13e52eab" +checksum = "8b94288d2e246aecd6eecd22ef27db0d1f29a91cb4f59b9e339a45237131a9ff" dependencies = [ "arrayvec 0.7.6", "boojum", @@ -8010,7 +7876,7 @@ dependencies = [ "seq-macro", "serde", "smallvec", - "zkevm_opcode_defs 0.150.7", + "zkevm_opcode_defs 0.150.18", "zksync_cs_derive", ] @@ -8058,9 +7924,9 @@ dependencies = [ [[package]] name = "zkevm_opcode_defs" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b83f3b279248af4ca86dec20a54127f02110b45570f3f6c1d13df49ba75c28a5" +checksum = "5bad437d4891536fdcc0054a3f04562c408817ff19d83b6c27569217692e6e74" dependencies = [ "bitflags 2.6.0", "blake2 0.10.6", @@ -8075,13 +7941,14 @@ dependencies = [ [[package]] name = "zkevm_test_harness" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c801aa17e9009699aacf654588d6adfaeeb8a490b2d9121847c201e2766803" +checksum = "9bd2de75d0bf68137ba150e05dd5d36baad03e682e06b8616643c72b3fcce05d" dependencies = [ "bincode", "circuit_definitions", - "circuit_sequencer_api 0.150.7", + "circuit_encodings", + "circuit_sequencer_api", "codegen", "crossbeam", "derivative", @@ -8102,9 +7969,9 @@ dependencies = [ [[package]] name = "zksync-gpu-ffi" -version = "0.151.1" +version = "0.152.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5688dc060456f6c1e790d589f3abd6d9e9a11eb393d7383fbeb23b55961951e0" +checksum = "bc1f77eb5f1a513357e53fba148f46a03fdbea222dc71f270123984059c285bf" dependencies = [ "cmake", "crossbeam", @@ -8117,9 +7984,9 @@ dependencies = [ [[package]] name = "zksync-gpu-prover" -version = "0.151.1" +version = "0.152.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5714848e6f8361820346483246dd68b4e7fb05ec41dd6610a8b53fb5c3ca7f3a" +checksum = "3cc0c452445a120c5928e0ac89d47242f407b303ee819e3b7b2a97f6ce7491e4" dependencies = [ "bit-vec 0.6.3", "cfg-if", @@ -8134,9 +8001,9 @@ dependencies = [ [[package]] name = "zksync-wrapper-prover" -version = "0.151.1" +version = "0.152.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a6a1863818d939d445c53af57e53c222f11c2c94b9a94c3612dd938a3d983c" +checksum = "972dc1059d4a97ad075ab5a3589722b16d22c5241ba6e711ac18a73195aa6584" dependencies = [ "circuit_definitions", "zkevm_test_harness", @@ -8166,9 +8033,9 @@ dependencies = [ [[package]] name = "zksync_bellman" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffa03efe9bdb137a4b36b97d1a74237e18c9ae42b755163d903a9d48c1a5d80" +checksum = "6b7c0061db44757522f2d82cad02f45dc98267210ac362071234ed08e30fd4d6" dependencies = [ "arrayvec 0.7.6", "bit-vec 0.6.3", @@ -8392,9 +8259,9 @@ dependencies = [ [[package]] name = "zksync_cs_derive" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5939e2df4288c263c706ff18ac718e984149223ad4289d6d957d767dcfc04c81" +checksum = "63296ce43c432d5d0111604173e874b2f2a856e1cb1c76378fa0bb5ac6018c27" dependencies = [ "proc-macro-error", "proc-macro2 1.0.92", @@ -8494,9 +8361,9 @@ dependencies = [ [[package]] name = "zksync_ff" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9524b06780b5e164e84b38840c7c428c739f051f35af6efc4d1285f629ceb88e" +checksum = "e6a500c97d9286f73540c26b63ae33b159bd48fec0c8bd206b4a9b4fe1217b8a" dependencies = [ "byteorder", "hex", @@ -8507,9 +8374,9 @@ dependencies = [ [[package]] name = "zksync_ff_derive" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f91e58e75d65877f09f83bc3dca8f054847ae7ec4f3e64bfa610a557edd8e8e" +checksum = "97bd48f18ebf350623093022d86be2f1ce23af332efa91890b751209aec8617a" dependencies = [ "num-bigint 0.4.6", "num-integer", @@ -8522,9 +8389,9 @@ dependencies = [ [[package]] name = "zksync_kzg" -version = "0.150.7" +version = "0.150.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc58af8e4e4ad1a851ffd2275e6a44ead0f15a7eaac9dc9d60a56b3b9c9b08e8" +checksum = "6384d2475e4a7e6ed4e2a703724cac1d8972d9ec40c49fdd17bf37942a81a635" dependencies = [ "boojum", "derivative", @@ -8534,7 +8401,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "zkevm_circuits 0.150.7", + "zkevm_circuits", ] [[package]] @@ -8566,11 +8433,7 @@ name = "zksync_multivm" version = "0.1.0" dependencies = [ "anyhow", - "circuit_sequencer_api 0.133.1", - "circuit_sequencer_api 0.140.3", - "circuit_sequencer_api 0.141.2", - "circuit_sequencer_api 0.142.2", - "circuit_sequencer_api 0.150.7", + "circuit_sequencer_api", "ethabi", "hex", "itertools 0.10.5", @@ -8582,7 +8445,7 @@ dependencies = [ "zk_evm 0.133.0", "zk_evm 0.140.0", "zk_evm 0.141.0", - "zk_evm 0.150.7", + "zk_evm 0.150.18", "zksync_contracts", "zksync_mini_merkle_tree", "zksync_system_constants", @@ -8616,9 +8479,9 @@ dependencies = [ [[package]] name = "zksync_pairing" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8412ae5574472fa567a097e183f9a01974b99dd0b5da3bfa1bbe6c57c579aa2" +checksum = "3b91b38db3a3f0f80d8b1f2342c77751ee8d63b746268e5719abbb5dfb150a8c" dependencies = [ "byteorder", "cfg-if", @@ -8634,7 +8497,7 @@ dependencies = [ "anyhow", "async-trait", "bincode", - "circuit_sequencer_api 0.150.7", + "circuit_sequencer_api", "clap 4.5.23", "ctrlc", "futures 0.3.31", @@ -8859,7 +8722,7 @@ name = "zksync_prover_interface" version = "0.1.0" dependencies = [ "chrono", - "circuit_sequencer_api 0.150.7", + "circuit_sequencer_api", "serde", "serde_with", "strum", @@ -8911,6 +8774,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bincode", + "boojum-cuda", "circuit_definitions", "futures 0.3.31", "hex", @@ -8942,9 +8806,9 @@ dependencies = [ [[package]] name = "zksync_solidity_vk_codegen" -version = "0.30.1" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b310ab8a21681270e73f177ddf7974cabb7a96f0624ab8b008fd6ee1f9b4f687" +checksum = "6f03e137db1b29be36abfa1e1e682dd3864b0335c68282c8dab68c2d397b8cbd" dependencies = [ "ethereum-types", "franklin-crypto", @@ -9005,6 +8869,7 @@ dependencies = [ "once_cell", "reqwest 0.12.9", "serde_json", + "sha2 0.10.8", "tokio", "tracing", "zksync_vlog", @@ -9062,8 +8927,8 @@ source = "git+https://github.com/matter-labs/vm2.git?rev=457d8a7eea9093af9440662 dependencies = [ "enum_dispatch", "primitive-types", - "zk_evm_abstractions 0.150.7", - "zkevm_opcode_defs 0.150.7", + "zk_evm_abstractions 0.150.18", + "zkevm_opcode_defs 0.150.18", "zksync_vm2_interface", ] diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 15e819d77f7d..aea458cb9e48 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -67,13 +67,14 @@ url = "2.5.2" vise = "0.2.0" # Proving dependencies -circuit_definitions = "=0.150.7" -circuit_sequencer_api = "=0.150.7" -zkevm_test_harness = "=0.150.7" +circuit_definitions = "=0.150.18" +circuit_sequencer_api = "=0.150.18" +zkevm_test_harness = "=0.150.18" # GPU proving dependencies -wrapper_prover = { package = "zksync-wrapper-prover", version = "=0.151.1" } -shivini = "=0.151.1" +wrapper_prover = { package = "zksync-wrapper-prover", version = "=0.152.9" } +shivini = "=0.152.9" +boojum-cuda = "=0.152.9" # Core workspace dependencies zksync_multivm = { path = "../core/lib/multivm", version = "0.1.0" } diff --git a/prover/crates/bin/prover_fri/src/gpu_prover_job_processor.rs b/prover/crates/bin/prover_fri/src/gpu_prover_job_processor.rs index cfd588c26662..9817362c9fea 100644 --- a/prover/crates/bin/prover_fri/src/gpu_prover_job_processor.rs +++ b/prover/crates/bin/prover_fri/src/gpu_prover_job_processor.rs @@ -1,6 +1,6 @@ #[cfg(feature = "gpu")] pub mod gpu_prover { - use std::{collections::HashMap, sync::Arc, time::Instant}; + use std::{alloc::Global, collections::HashMap, sync::Arc, time::Instant}; use anyhow::Context as _; use shivini::{ @@ -174,7 +174,7 @@ pub mod gpu_prover { DefaultTranscript, DefaultTreeHasher, NoPow, - _, + Global, >( &gpu_proof_config, &witness_vector, diff --git a/prover/crates/bin/prover_fri/src/lib.rs b/prover/crates/bin/prover_fri/src/lib.rs index 39757795d980..76a97f119f4b 100644 --- a/prover/crates/bin/prover_fri/src/lib.rs +++ b/prover/crates/bin/prover_fri/src/lib.rs @@ -1,5 +1,5 @@ #![allow(incomplete_features)] // We have to use generic const exprs. -#![feature(generic_const_exprs)] +#![feature(generic_const_exprs, allocator_api)] mod metrics; pub mod prover_job_processor; pub mod utils; diff --git a/prover/crates/bin/prover_fri/src/main.rs b/prover/crates/bin/prover_fri/src/main.rs index cbba8d0ddb4f..d464cb630be2 100644 --- a/prover/crates/bin/prover_fri/src/main.rs +++ b/prover/crates/bin/prover_fri/src/main.rs @@ -1,5 +1,5 @@ #![allow(incomplete_features)] // We have to use generic const exprs. -#![feature(generic_const_exprs)] +#![feature(generic_const_exprs, allocator_api)] use std::{future::Future, sync::Arc, time::Duration}; diff --git a/prover/crates/bin/witness_generator/src/rounds/basic_circuits/mod.rs b/prover/crates/bin/witness_generator/src/rounds/basic_circuits/mod.rs index adb2bf72d04f..233e59877cb8 100644 --- a/prover/crates/bin/witness_generator/src/rounds/basic_circuits/mod.rs +++ b/prover/crates/bin/witness_generator/src/rounds/basic_circuits/mod.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use circuit_definitions::zkevm_circuits::scheduler::{ block_header::BlockAuxilaryOutputWitness, input::SchedulerCircuitInstanceWitness, }; -use zksync_multivm::circuit_sequencer_api_latest::boojum::{ +use zkevm_test_harness::boojum::{ field::goldilocks::{GoldilocksExt2, GoldilocksField}, gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge, }; diff --git a/prover/crates/bin/witness_generator/src/rounds/basic_circuits/utils.rs b/prover/crates/bin/witness_generator/src/rounds/basic_circuits/utils.rs index 31dc54814103..348ba1dcd996 100644 --- a/prover/crates/bin/witness_generator/src/rounds/basic_circuits/utils.rs +++ b/prover/crates/bin/witness_generator/src/rounds/basic_circuits/utils.rs @@ -11,11 +11,11 @@ use circuit_definitions::{ }; use tokio::sync::Semaphore; use tracing::Instrument; -use zkevm_test_harness::witness::oracle::WitnessGenerationArtifact; +use zkevm_test_harness::{ + boojum::field::goldilocks::GoldilocksField, witness::oracle::WitnessGenerationArtifact, +}; use zksync_multivm::{ - circuit_sequencer_api_latest::{ - boojum::field::goldilocks::GoldilocksField, geometry_config::get_geometry_config, - }, + circuit_sequencer_api_latest::geometry_config::ProtocolGeometry, interface::storage::StorageView, vm_latest::{constants::MAX_CYCLES_FOR_TX, HistoryDisabled, StorageOracle as VmStorageOracle}, zk_evm_latest::ethereum_types::Address, @@ -52,7 +52,7 @@ pub(super) async fn generate_witness( input.merkle_paths, input.previous_batch_metadata.root_hash.0, ); - let geometry_config = get_geometry_config(); + let geometry_config = ProtocolGeometry::V1_5_0.config(); let mut hasher = DefaultHasher::new(); geometry_config.hash(&mut hasher); tracing::info!( diff --git a/prover/crates/lib/circuit_prover_service/src/lib.rs b/prover/crates/lib/circuit_prover_service/src/lib.rs index 0d7b146cc43b..bbf1f9733f6f 100644 --- a/prover/crates/lib/circuit_prover_service/src/lib.rs +++ b/prover/crates/lib/circuit_prover_service/src/lib.rs @@ -1,5 +1,5 @@ #![allow(incomplete_features)] // Crypto code uses generic const exprs -#![feature(generic_const_exprs)] +#![feature(generic_const_exprs, allocator_api)] mod gpu_circuit_prover; pub mod job_runner; mod metrics; diff --git a/prover/crates/lib/circuit_prover_service/src/types/circuit.rs b/prover/crates/lib/circuit_prover_service/src/types/circuit.rs index 19c05666b2c5..264daba63b7d 100644 --- a/prover/crates/lib/circuit_prover_service/src/types/circuit.rs +++ b/prover/crates/lib/circuit_prover_service/src/types/circuit.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{alloc::Global, sync::Arc}; use anyhow::Context; use shivini::{gpu_proof_config::GpuProofConfig, gpu_prove_from_external_witness_data}; @@ -84,7 +84,7 @@ impl Circuit { let span = tracing::info_span!("prove_base_circuit").entered(); let gpu_proof_config = GpuProofConfig::from_base_layer_circuit(circuit); let boojum_proof_config = base_layer_proof_config(); - let proof = gpu_prove_from_external_witness_data::( + let proof = gpu_prove_from_external_witness_data::( &gpu_proof_config, &witness_vector, boojum_proof_config, @@ -113,7 +113,7 @@ impl Circuit { let span = tracing::info_span!("prove_recursive_circuit").entered(); let gpu_proof_config = GpuProofConfig::from_recursive_layer_circuit(circuit); let boojum_proof_config = recursion_layer_proof_config(); - let proof = gpu_prove_from_external_witness_data::( + let proof = gpu_prove_from_external_witness_data::( &gpu_proof_config, &witness_vector, boojum_proof_config, diff --git a/prover/crates/lib/keystore/Cargo.toml b/prover/crates/lib/keystore/Cargo.toml index 4d9addc26bc0..8dac09b782c0 100644 --- a/prover/crates/lib/keystore/Cargo.toml +++ b/prover/crates/lib/keystore/Cargo.toml @@ -17,6 +17,7 @@ zksync_prover_fri_types.workspace = true zkevm_test_harness.workspace = true circuit_definitions = { workspace = true, features = ["log_tracing"] } shivini = { workspace = true, optional = true } +boojum-cuda = { workspace = true, optional = true } anyhow.workspace = true tracing.workspace = true @@ -32,4 +33,4 @@ futures = { workspace = true, features = ["compat"] } [features] default = [] -gpu = ["shivini"] +gpu = ["shivini", "boojum-cuda"] diff --git a/prover/crates/lib/keystore/src/lib.rs b/prover/crates/lib/keystore/src/lib.rs index 7e60e3fa29cd..543b7b18ffe5 100644 --- a/prover/crates/lib/keystore/src/lib.rs +++ b/prover/crates/lib/keystore/src/lib.rs @@ -1,6 +1,8 @@ #![feature(allocator_api)] use serde::{Deserialize, Serialize}; +#[cfg(feature = "gpu")] +use shivini::cs::GpuSetup; use zkevm_test_harness::compute_setups::CircuitSetupData; use zksync_prover_fri_types::circuit_definitions::boojum::{ algebraic_props::{round_function::AbsorptionModeOverwrite, sponge::GenericAlgebraicSponge}, @@ -19,8 +21,6 @@ use zksync_prover_fri_types::circuit_definitions::boojum::{ }, implementations::poseidon2::Poseidon2Goldilocks, }; -#[cfg(feature = "gpu")] -use {shivini::cs::GpuSetup, std::alloc::Global}; pub mod commitment_utils; pub mod keystore; @@ -84,11 +84,12 @@ impl From for GoldilocksProverSetupData { #[cfg(feature = "gpu")] #[derive(Debug, Serialize, Deserialize)] #[serde(bound = "F: serde::Serialize + serde::de::DeserializeOwned")] -pub struct GpuProverSetupData> { - pub setup: GpuSetup, +pub struct GpuProverSetupData> +{ + pub setup: GpuSetup, #[serde(bound( - serialize = "H::Output: serde::Serialize", - deserialize = "H::Output: serde::de::DeserializeOwned" + serialize = ">::Output: serde::Serialize", + deserialize = ">::Output: serde::de::DeserializeOwned" ))] pub vk: VerificationKey, pub finalization_hint: FinalizationHintsForProver, diff --git a/prover/crates/lib/keystore/src/setup_data_generator.rs b/prover/crates/lib/keystore/src/setup_data_generator.rs index c4790d67feaa..0bbd6cb5d14d 100644 --- a/prover/crates/lib/keystore/src/setup_data_generator.rs +++ b/prover/crates/lib/keystore/src/setup_data_generator.rs @@ -5,13 +5,17 @@ use std::collections::HashMap; use anyhow::Context as _; use zkevm_test_harness::{ - compute_setups::{generate_circuit_setup_data, CircuitSetupData}, + compute_setups::{ + generate_circuit_setup_data, light::generate_light_circuit_setup_data, CircuitSetupData, + }, data_source::SetupDataSource, }; use zksync_prover_fri_types::ProverServiceDataKey; #[cfg(feature = "gpu")] use { - crate::GpuProverSetupData, shivini::cs::setup::GpuSetup, shivini::ProverContext, + crate::GpuProverSetupData, + boojum_cuda::poseidon2::GLHasher, + shivini::{cs::gpu_setup_and_vk_from_base_setup_vk_params_and_hints, ProverContext}, zksync_prover_fri_types::circuit_definitions::boojum::worker::Worker, }; @@ -25,7 +29,7 @@ pub fn generate_setup_data_common( ) -> anyhow::Result { let mut data_source = keystore.load_keys_to_data_source()?; let circuit_setup_data = generate_circuit_setup_data( - circuit.is_base_layer(), + circuit.round as u8, // TODO: Actually it's called "ProvingStage" now circuit.circuit_id, &mut data_source, ) @@ -151,20 +155,29 @@ impl SetupDataGenerator for GPUSetupDataGenerator { { let _context = ProverContext::create().context("failed initializing gpu prover context")?; - let circuit_setup_data = generate_setup_data_common(&self.keystore, circuit)?; - let worker = Worker::new(); - let gpu_setup_data = GpuSetup::from_setup_and_hints( - circuit_setup_data.setup_base, - circuit_setup_data.setup_tree, - circuit_setup_data.vars_hint.clone(), - circuit_setup_data.wits_hint, - &worker, + let mut data_source = self.keystore.load_keys_to_data_source()?; + let circuit_setup_data = generate_light_circuit_setup_data( + circuit.round as u8, + circuit.circuit_id, + &mut data_source, ) - .context("failed creating GPU base layer setup data")?; + .unwrap(); + + let worker = Worker::new(); + // TODO: add required assertions + let (gpu_setup_data, vk) = + gpu_setup_and_vk_from_base_setup_vk_params_and_hints::( + circuit_setup_data.setup_base, + circuit_setup_data.vk_geometry, + circuit_setup_data.vars_hint.clone(), + circuit_setup_data.wits_hint, + &worker, + ) + .context("failed creating GPU base layer setup data")?; let gpu_prover_setup_data = GpuProverSetupData { setup: gpu_setup_data, - vk: circuit_setup_data.vk, + vk: vk.clone(), finalization_hint: circuit_setup_data.finalization_hint, }; // Serialization should always succeed. diff --git a/prover/setup-data-gpu-keys.json b/prover/setup-data-gpu-keys.json index 4acc51b9add0..8a3bdeb262c1 100644 --- a/prover/setup-data-gpu-keys.json +++ b/prover/setup-data-gpu-keys.json @@ -1,5 +1,5 @@ { - "us": "gs://matterlabs-setup-data-us/ffc5da2-gpu/", - "europe": "gs://matterlabs-setup-data-europe/ffc5da2-gpu/", - "asia": "gs://matterlabs-setup-data-asia/ffc5da2-gpu/" + "us": "gs://matterlabs-setup-data-us/dc3bba7-gpu/", + "europe": "gs://matterlabs-setup-data-europe/dc3bba7-gpu/", + "asia": "gs://matterlabs-setup-data-asia/dc3bba7-gpu/" } diff --git a/zkstack_cli/Cargo.lock b/zkstack_cli/Cargo.lock index 900ac677fd61..4e9bb4b1c76c 100644 --- a/zkstack_cli/Cargo.lock +++ b/zkstack_cli/Cargo.lock @@ -6771,9 +6771,9 @@ dependencies = [ [[package]] name = "zksync_concurrency" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24c9a056499823227503dd9e5fb3037d93bcc3ae9b06c1ac0a47334c6283af" +checksum = "e8312ab73d3caa55775bd531795b507fa8f76bd9dabfaeb0954fe43e8fc1323b" dependencies = [ "anyhow", "once_cell", @@ -6804,9 +6804,9 @@ dependencies = [ [[package]] name = "zksync_consensus_crypto" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da303b01f24283e93f80f361bf62c3df4a761d061c8b38b4faebeebf26362fc" +checksum = "86b539960de98df3c3bd27d2d9b97de862027686bbb3bdfc5aaad5b74bb929a1" dependencies = [ "anyhow", "blst", @@ -6825,9 +6825,9 @@ dependencies = [ [[package]] name = "zksync_consensus_roles" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f07db2a8ec2d2cda5cb4c5ac408101e81c8fa5d95c9f3302829dafae78d11c" +checksum = "c49949546895a10431b9daec6ec4208ef0917ace006446d304b51f5b234ba462" dependencies = [ "anyhow", "bit-vec", @@ -6847,9 +6847,9 @@ dependencies = [ [[package]] name = "zksync_consensus_utils" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3222410c67617a86edb192e0c4bb48afc254a17052200a0a839c90e8b0378842" +checksum = "723e2a4b056cc5af192a83163c89a6951ee75c098cc5c4a4cdc435f4232d88bd" dependencies = [ "anyhow", "rand", @@ -6897,9 +6897,9 @@ dependencies = [ [[package]] name = "zksync_protobuf" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05755c38b134b409736008bfdfd0fdb42bfa061947be93be4c78069aa10c9b3" +checksum = "e8986ad796f8e00d8999fee72effba1a21bce40f5f877d681ac9cd89a94834d8" dependencies = [ "anyhow", "bit-vec", @@ -6918,9 +6918,9 @@ dependencies = [ [[package]] name = "zksync_protobuf_build" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c3930a73ca667780be6dcd94e469d40a93fa52f4654c9ab732991b62238cb5" +checksum = "8d870b31995e3acb8e47afeb68ebeeffcf6121e70020e65b3d5d31692115d236" dependencies = [ "anyhow", "heck", @@ -6946,6 +6946,7 @@ dependencies = [ "serde_yaml", "tracing", "zksync_basic_types", + "zksync_concurrency", "zksync_config", "zksync_protobuf", "zksync_protobuf_build", @@ -7000,6 +7001,7 @@ dependencies = [ "once_cell", "reqwest 0.12.9", "serde_json", + "sha2", "tokio", "tracing", "zksync_vlog", From 3ce7e8a6f695c8a04e718a4953ac919319f9572d Mon Sep 17 00:00:00 2001 From: zksync-era-bot <147085853+zksync-era-bot@users.noreply.github.com> Date: Thu, 19 Dec 2024 18:16:33 +0400 Subject: [PATCH 3/3] chore(main): release core 25.4.0 (#3379) :robot: I have created a release *beep* *boop* --- ## [25.4.0](https://github.com/matter-labs/zksync-era/compare/core-v25.3.0...core-v25.4.0) (2024-12-19) ### Features * add support for custom genesis state ([#3259](https://github.com/matter-labs/zksync-era/issues/3259)) ([3cffdb2](https://github.com/matter-labs/zksync-era/commit/3cffdb2d5e144f2e3d8617fa22aacf6cce5998a2)) * **consensus:** Added view_timeout to consensus config ([#3383](https://github.com/matter-labs/zksync-era/issues/3383)) ([fc02a8f](https://github.com/matter-labs/zksync-era/commit/fc02a8f1c9f0bffb438fb27769d6dced3ce14cd9)) * Support stable compiler for VM (and some other crates) ([#3248](https://github.com/matter-labs/zksync-era/issues/3248)) ([cbee99d](https://github.com/matter-labs/zksync-era/commit/cbee99d8661b38aa6b49784c3934b8070a743fb4)) * vm2 account validation ([#2863](https://github.com/matter-labs/zksync-era/issues/2863)) ([af149a0](https://github.com/matter-labs/zksync-era/commit/af149a01e6ce0c62d4b8a6acf9481e807ac24a8f)) ### Bug Fixes * **contract-verifier:** Fix version extraction in gh resolver ([#3378](https://github.com/matter-labs/zksync-era/issues/3378)) ([9a10dcf](https://github.com/matter-labs/zksync-era/commit/9a10dcf764e25c4e60b7ae5ddfa728c9cf576248)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: zksync-era-bot --- .github/release-please/manifest.json | 2 +- Cargo.lock | 2 +- core/CHANGELOG.md | 15 +++++++++++++++ core/bin/external_node/Cargo.toml | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/release-please/manifest.json b/.github/release-please/manifest.json index ddf856a98e26..c43a992917e1 100644 --- a/.github/release-please/manifest.json +++ b/.github/release-please/manifest.json @@ -1,5 +1,5 @@ { - "core": "25.3.0", + "core": "25.4.0", "prover": "17.1.1", "zkstack_cli": "0.1.2" } diff --git a/Cargo.lock b/Cargo.lock index 019e2afdf334..e5e83db18937 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11949,7 +11949,7 @@ dependencies = [ [[package]] name = "zksync_external_node" -version = "25.3.0" +version = "25.4.0" dependencies = [ "anyhow", "assert_matches", diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index acdd2fefb1ab..12d1169f84a3 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [25.4.0](https://github.com/matter-labs/zksync-era/compare/core-v25.3.0...core-v25.4.0) (2024-12-19) + + +### Features + +* add support for custom genesis state ([#3259](https://github.com/matter-labs/zksync-era/issues/3259)) ([3cffdb2](https://github.com/matter-labs/zksync-era/commit/3cffdb2d5e144f2e3d8617fa22aacf6cce5998a2)) +* **consensus:** Added view_timeout to consensus config ([#3383](https://github.com/matter-labs/zksync-era/issues/3383)) ([fc02a8f](https://github.com/matter-labs/zksync-era/commit/fc02a8f1c9f0bffb438fb27769d6dced3ce14cd9)) +* Support stable compiler for VM (and some other crates) ([#3248](https://github.com/matter-labs/zksync-era/issues/3248)) ([cbee99d](https://github.com/matter-labs/zksync-era/commit/cbee99d8661b38aa6b49784c3934b8070a743fb4)) +* vm2 account validation ([#2863](https://github.com/matter-labs/zksync-era/issues/2863)) ([af149a0](https://github.com/matter-labs/zksync-era/commit/af149a01e6ce0c62d4b8a6acf9481e807ac24a8f)) + + +### Bug Fixes + +* **contract-verifier:** Fix version extraction in gh resolver ([#3378](https://github.com/matter-labs/zksync-era/issues/3378)) ([9a10dcf](https://github.com/matter-labs/zksync-era/commit/9a10dcf764e25c4e60b7ae5ddfa728c9cf576248)) + ## [25.3.0](https://github.com/matter-labs/zksync-era/compare/core-v25.2.0...core-v25.3.0) (2024-12-11) diff --git a/core/bin/external_node/Cargo.toml b/core/bin/external_node/Cargo.toml index f56af827bc45..799108f30723 100644 --- a/core/bin/external_node/Cargo.toml +++ b/core/bin/external_node/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zksync_external_node" description = "Non-validator ZKsync node" -version = "25.3.0" # x-release-please-version +version = "25.4.0" # x-release-please-version edition.workspace = true authors.workspace = true homepage.workspace = true