From 76cacae07afbcb846e503c4a07c7a5595b77353a Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Wed, 29 Nov 2023 13:56:18 +0200 Subject: [PATCH 1/7] Encapsulate miniblock hashing into a struct --- core/lib/types/src/block.rs | 93 +++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/core/lib/types/src/block.rs b/core/lib/types/src/block.rs index b4026468868..67cdc700b6e 100644 --- a/core/lib/types/src/block.rs +++ b/core/lib/types/src/block.rs @@ -8,6 +8,7 @@ use zksync_basic_types::{H2048, H256, U256}; use zksync_consensus_roles::validator; use zksync_contracts::BaseSystemContractsHashes; use zksync_protobuf::{read_required, ProtoFmt}; +use zksync_utils::concat_and_hash; use crate::{ l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, @@ -230,30 +231,65 @@ impl ops::AddAssign for BlockGasCount { } } -/// Returns the hash of the miniblock. -/// `txs_rolling_hash` of the miniblock is calculated the following way: -/// If the miniblock has 0 transactions, then `txs_rolling_hash` is equal to `H256::zero()`. -/// If the miniblock has i transactions, then `txs_rolling_hash` is equal to `H(H_{i-1}, H(tx_i))`, where -/// `H_{i-1}` is the `txs_rolling_hash` of the first i-1 transactions. -pub fn miniblock_hash( - miniblock_number: MiniblockNumber, - miniblock_timestamp: u64, +/// Hasher of miniblock contents used by the VM. +#[derive(Debug)] +pub struct MiniblockHasher { + number: MiniblockNumber, + timestamp: u64, prev_miniblock_hash: H256, txs_rolling_hash: H256, -) -> H256 { - let mut digest: [u8; 128] = [0u8; 128]; - U256::from(miniblock_number.0).to_big_endian(&mut digest[0..32]); - U256::from(miniblock_timestamp).to_big_endian(&mut digest[32..64]); - digest[64..96].copy_from_slice(prev_miniblock_hash.as_bytes()); - digest[96..128].copy_from_slice(txs_rolling_hash.as_bytes()); - - H256(keccak256(&digest)) } -/// At the beginning of the zkSync, the hashes of the blocks could be calculated as the hash of their number. -/// This method returns the hash of such miniblocks. -pub fn legacy_miniblock_hash(miniblock_number: MiniblockNumber) -> H256 { - H256(keccak256(&miniblock_number.0.to_be_bytes())) +impl MiniblockHasher { + /// At the beginning of the zkSync, the hashes of the blocks could be calculated as the hash of their number. + /// This method returns the hash of such miniblocks. + pub fn legacy_hash(miniblock_number: MiniblockNumber) -> H256 { + H256(keccak256(&miniblock_number.0.to_be_bytes())) + } + + /// Creates a new hasher with the specified params. This assumes a miniblock without transactions; + /// transaction hashes can be supplied using [`Self::push_tx_hash()`]. + pub fn new(number: MiniblockNumber, timestamp: u64, prev_miniblock_hash: H256) -> Self { + Self { + number, + timestamp, + prev_miniblock_hash, + txs_rolling_hash: H256::zero(), + } + } + + /// Updates this hasher with a transaction hash. This should be called for all transactions in the block + /// in the order of their execution. + pub fn push_tx_hash(&mut self, tx_hash: H256) { + self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash); + } + + /// Returns the hash of the miniblock. + /// + /// For newer protocol versions, the hash is computed as + /// + /// ```text + /// keccak256(u256_be(number) ++ u256_be(timestamp) ++ prev_miniblock_hash ++ txs_rolling_hash) + /// ``` + /// + /// Here, `u256_be` is the big-endian 256-bit serialization of a number, and `txs_rolling_hash` + /// is *the rolling hash* of miniblock transactions. `txs_rolling_hash` is calculated the following way: + /// + /// - If the miniblock has 0 transactions, then `txs_rolling_hash` is equal to `H256::zero()`. + /// - If the miniblock has i transactions, then `txs_rolling_hash` is equal to `H(H_{i-1}, H(tx_i))`, where + /// `H_{i-1}` is the `txs_rolling_hash` of the first i-1 transactions. + pub fn finalize(self, protocol_version: ProtocolVersionId) -> H256 { + if protocol_version >= ProtocolVersionId::Version13 { + let mut digest = [0_u8; 128]; + U256::from(self.number.0).to_big_endian(&mut digest[0..32]); + U256::from(self.timestamp).to_big_endian(&mut digest[32..64]); + digest[64..96].copy_from_slice(self.prev_miniblock_hash.as_bytes()); + digest[96..128].copy_from_slice(self.txs_rolling_hash.as_bytes()); + H256(keccak256(&digest)) + } else { + Self::legacy_hash(self.number) + } + } } /// Returns block.number/timestamp based on the block's information @@ -279,9 +315,7 @@ pub fn unpack_block_upgrade_info(info: U256) -> (u64, u64) { #[cfg(test)] mod tests { - use zksync_basic_types::{MiniblockNumber, H256}; - - use crate::block::{legacy_miniblock_hash, miniblock_hash, pack_block_info, unpack_block_info}; + use super::*; #[test] fn test_legacy_miniblock_hashes() { @@ -290,7 +324,7 @@ mod tests { .parse() .unwrap(); assert_eq!( - legacy_miniblock_hash(MiniblockNumber(11470850)), + MiniblockHasher::legacy_hash(MiniblockNumber(11470850)), expected_hash ) } @@ -311,12 +345,13 @@ mod tests { .unwrap(); assert_eq!( expected_hash, - miniblock_hash( - MiniblockNumber(1), - 12, + MiniblockHasher { + number: MiniblockNumber(1), + timestamp: 12, prev_miniblock_hash, - txs_rolling_hash - ) + txs_rolling_hash, + } + .finalize(ProtocolVersionId::latest()) ) } From 2796be95f297a12a8ca911f3e1d08bbcae0b7cf9 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Wed, 29 Nov 2023 13:56:47 +0200 Subject: [PATCH 2/7] Update miniblock hashing in libs --- .../system-constants-generator/src/utils.rs | 4 +-- core/lib/dal/src/blocks_web3_dal.rs | 34 ++++++++---------- core/lib/dal/src/tests/mod.rs | 10 +++--- core/lib/dal/src/transactions_web3_dal.rs | 12 +++---- .../src/versions/vm_latest/tests/l2_blocks.rs | 35 ++++++++++--------- .../vm_latest/tests/tester/vm_tester.rs | 6 ++-- .../vm_latest/types/internals/vm_state.rs | 6 ++-- .../types/internals/vm_state.rs | 6 ++-- .../types/internals/vm_state.rs | 6 ++-- .../src/api_server/execution_sandbox/apply.rs | 4 +-- core/lib/zksync_core/src/genesis.rs | 4 +-- .../src/metadata_calculator/tests.rs | 16 ++++----- core/tests/vm-benchmark/harness/src/lib.rs | 4 +-- 13 files changed, 72 insertions(+), 75 deletions(-) diff --git a/core/bin/system-constants-generator/src/utils.rs b/core/bin/system-constants-generator/src/utils.rs index fc576ff44ee..306e0973834 100644 --- a/core/bin/system-constants-generator/src/utils.rs +++ b/core/bin/system-constants-generator/src/utils.rs @@ -17,7 +17,7 @@ use zksync_contracts::{ }; use zksync_state::{InMemoryStorage, StorageView, WriteStorage}; use zksync_types::{ - block::legacy_miniblock_hash, ethabi::Token, fee::Fee, l1::L1Tx, l2::L2Tx, + block::MiniblockHasher, ethabi::Token, fee::Fee, l1::L1Tx, l2::L2Tx, utils::storage_key_for_eth_balance, AccountTreeId, Address, Execute, L1BatchNumber, L1TxCommonData, L2ChainId, MiniblockNumber, Nonce, ProtocolVersionId, StorageKey, Timestamp, Transaction, BOOTLOADER_ADDRESS, H256, SYSTEM_CONTEXT_ADDRESS, @@ -180,7 +180,7 @@ fn default_l1_batch() -> L1BatchEnv { first_l2_block: L2BlockEnv { number: 1, timestamp: 100, - prev_block_hash: legacy_miniblock_hash(MiniblockNumber(0)), + prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), max_virtual_blocks_to_create: 100, }, } diff --git a/core/lib/dal/src/blocks_web3_dal.rs b/core/lib/dal/src/blocks_web3_dal.rs index e42a645966f..70ef4d52aa2 100644 --- a/core/lib/dal/src/blocks_web3_dal.rs +++ b/core/lib/dal/src/blocks_web3_dal.rs @@ -586,7 +586,7 @@ impl BlocksWeb3Dal<'_, '_> { mod tests { use zksync_contracts::BaseSystemContractsHashes; use zksync_types::{ - block::{miniblock_hash, MiniblockHeader}, + block::{MiniblockHasher, MiniblockHeader}, MiniblockNumber, ProtocolVersion, ProtocolVersionId, }; @@ -611,16 +611,13 @@ mod tests { }; conn.blocks_dal().insert_miniblock(&header).await.unwrap(); + let block_hash = MiniblockHasher::new(MiniblockNumber(0), 0, H256::zero()) + .finalize(ProtocolVersionId::latest()); let block_ids = [ api::BlockId::Number(api::BlockNumber::Earliest), api::BlockId::Number(api::BlockNumber::Latest), api::BlockId::Number(api::BlockNumber::Number(0.into())), - api::BlockId::Hash(miniblock_hash( - MiniblockNumber(0), - 0, - H256::zero(), - H256::zero(), - )), + api::BlockId::Hash(block_hash), ]; for block_id in block_ids { let block = conn @@ -630,24 +627,18 @@ mod tests { let block = block.unwrap().unwrap(); assert!(block.transactions.is_empty()); assert_eq!(block.number, U64::zero()); - assert_eq!( - block.hash, - miniblock_hash(MiniblockNumber(0), 0, H256::zero(), H256::zero()) - ); + assert_eq!(block.hash, block_hash); let tx_count = conn.blocks_web3_dal().get_block_tx_count(block_id).await; assert_eq!(tx_count.unwrap(), Some((MiniblockNumber(0), 8.into()))); } + let non_existing_block_hash = MiniblockHasher::new(MiniblockNumber(1), 1, H256::zero()) + .finalize(ProtocolVersionId::latest()); let non_existing_block_ids = [ api::BlockId::Number(api::BlockNumber::Pending), api::BlockId::Number(api::BlockNumber::Number(1.into())), - api::BlockId::Hash(miniblock_hash( - MiniblockNumber(1), - 1, - H256::zero(), - H256::zero(), - )), + api::BlockId::Hash(non_existing_block_hash), ]; for block_id in non_existing_block_ids { let block = conn @@ -749,14 +740,16 @@ mod tests { .await .unwrap(); - let hash = miniblock_hash(MiniblockNumber(0), 0, H256::zero(), H256::zero()); + let hash = MiniblockHasher::new(MiniblockNumber(0), 0, H256::zero()) + .finalize(ProtocolVersionId::latest()); let miniblock_number = conn .blocks_web3_dal() .resolve_block_id(api::BlockId::Hash(hash)) .await; assert_eq!(miniblock_number.unwrap(), Some(MiniblockNumber(0))); - let hash = miniblock_hash(MiniblockNumber(1), 1, H256::zero(), H256::zero()); + let hash = MiniblockHasher::new(MiniblockNumber(1), 1, H256::zero()) + .finalize(ProtocolVersionId::latest()); let miniblock_number = conn .blocks_web3_dal() .resolve_block_id(api::BlockId::Hash(hash)) @@ -776,7 +769,8 @@ mod tests { let mut header = MiniblockHeader { number: MiniblockNumber(0), timestamp: 0, - hash: miniblock_hash(MiniblockNumber(0), 0, H256::zero(), H256::zero()), + hash: MiniblockHasher::new(MiniblockNumber(0), 0, H256::zero()) + .finalize(ProtocolVersionId::latest()), l1_tx_count: 0, l2_tx_count: 0, base_fee_per_gas: 100, diff --git a/core/lib/dal/src/tests/mod.rs b/core/lib/dal/src/tests/mod.rs index c383ea7f944..1607a35666e 100644 --- a/core/lib/dal/src/tests/mod.rs +++ b/core/lib/dal/src/tests/mod.rs @@ -3,7 +3,7 @@ use std::time::Duration; use zksync_contracts::BaseSystemContractsHashes; use zksync_types::{ - block::{miniblock_hash, L1BatchHeader, MiniblockHeader}, + block::{L1BatchHeader, MiniblockHasher, MiniblockHeader}, fee::{Fee, TransactionExecutionMetrics}, helpers::unix_timestamp_ms, l1::{L1Tx, OpProcessingType, PriorityQueueType}, @@ -30,17 +30,19 @@ fn mock_tx_execution_metrics() -> TransactionExecutionMetrics { } pub(crate) fn create_miniblock_header(number: u32) -> MiniblockHeader { + let number = MiniblockNumber(number); + let protocol_version = ProtocolVersionId::default(); MiniblockHeader { - number: MiniblockNumber(number), + number, timestamp: 0, - hash: miniblock_hash(MiniblockNumber(number), 0, H256::zero(), H256::zero()), + hash: MiniblockHasher::new(number, 0, H256::zero()).finalize(protocol_version), l1_tx_count: 0, l2_tx_count: 0, base_fee_per_gas: 100, l1_gas_price: 100, l2_fair_gas_price: 100, base_system_contracts_hashes: BaseSystemContractsHashes::default(), - protocol_version: Some(ProtocolVersionId::default()), + protocol_version: Some(protocol_version), virtual_blocks: 1, } } diff --git a/core/lib/dal/src/transactions_web3_dal.rs b/core/lib/dal/src/transactions_web3_dal.rs index 5e2342d05b7..82798f0c599 100644 --- a/core/lib/dal/src/transactions_web3_dal.rs +++ b/core/lib/dal/src/transactions_web3_dal.rs @@ -354,7 +354,8 @@ impl TransactionsWeb3Dal<'_, '_> { #[cfg(test)] mod tests { use zksync_types::{ - block::miniblock_hash, fee::TransactionExecutionMetrics, l2::L2Tx, ProtocolVersion, + block::MiniblockHasher, fee::TransactionExecutionMetrics, l2::L2Tx, ProtocolVersion, + ProtocolVersionId, }; use super::*; @@ -399,15 +400,12 @@ mod tests { let tx_hash = tx.hash(); prepare_transaction(&mut conn, tx).await; + let block_hash = MiniblockHasher::new(MiniblockNumber(1), 0, H256::zero()) + .finalize(ProtocolVersionId::latest()); let block_ids = [ api::BlockId::Number(api::BlockNumber::Latest), api::BlockId::Number(api::BlockNumber::Number(1.into())), - api::BlockId::Hash(miniblock_hash( - MiniblockNumber(1), - 0, - H256::zero(), - H256::zero(), - )), + api::BlockId::Hash(block_hash), ]; let transaction_ids = block_ids .iter() diff --git a/core/lib/multivm/src/versions/vm_latest/tests/l2_blocks.rs b/core/lib/multivm/src/versions/vm_latest/tests/l2_blocks.rs index 4fd4e0207d4..0a70f756878 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/l2_blocks.rs @@ -19,11 +19,11 @@ use zksync_state::WriteStorage; use zksync_system_constants::REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE; use zksync_types::block::pack_block_info; use zksync_types::{ - block::{legacy_miniblock_hash, miniblock_hash}, - AccountTreeId, Execute, ExecuteTransactionCommon, L1BatchNumber, L1TxCommonData, - MiniblockNumber, StorageKey, Transaction, H160, H256, SYSTEM_CONTEXT_ADDRESS, - SYSTEM_CONTEXT_BLOCK_INFO_POSITION, SYSTEM_CONTEXT_CURRENT_L2_BLOCK_INFO_POSITION, - SYSTEM_CONTEXT_CURRENT_TX_ROLLING_HASH_POSITION, U256, + block::MiniblockHasher, AccountTreeId, Execute, ExecuteTransactionCommon, L1BatchNumber, + L1TxCommonData, MiniblockNumber, ProtocolVersionId, StorageKey, Transaction, H160, H256, + SYSTEM_CONTEXT_ADDRESS, SYSTEM_CONTEXT_BLOCK_INFO_POSITION, + SYSTEM_CONTEXT_CURRENT_L2_BLOCK_INFO_POSITION, SYSTEM_CONTEXT_CURRENT_TX_ROLLING_HASH_POSITION, + U256, }; use zksync_utils::{h256_to_u256, u256_to_h256}; @@ -62,7 +62,7 @@ fn test_l2_block_initialization_timestamp() { vm.vm.bootloader_state.push_l2_block(L2BlockEnv { number: 1, timestamp: 0, - prev_block_hash: legacy_miniblock_hash(MiniblockNumber(0)), + prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), max_virtual_blocks_to_create: 1, }); let l1_tx = get_l1_noop(); @@ -85,7 +85,7 @@ fn test_l2_block_initialization_number_non_zero() { let first_l2_block = L2BlockEnv { number: 0, timestamp: l1_batch.timestamp, - prev_block_hash: legacy_miniblock_hash(MiniblockNumber(0)), + prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), max_virtual_blocks_to_create: 1, }; @@ -244,7 +244,7 @@ fn test_l2_block_new_l2_block() { let correct_first_block = L2BlockEnv { number: 1, timestamp: 1, - prev_block_hash: legacy_miniblock_hash(MiniblockNumber(0)), + prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), max_virtual_blocks_to_create: 1, }; @@ -338,7 +338,7 @@ fn test_first_in_batch( ); storage_ptr.borrow_mut().set_value( prev_block_hash_position, - legacy_miniblock_hash(MiniblockNumber(miniblock_number - 1)), + MiniblockHasher::legacy_hash(MiniblockNumber(miniblock_number - 1)), ); // In order to skip checks from the Rust side of the VM, we firstly use some definitely correct L2 block info. @@ -367,6 +367,9 @@ fn test_first_in_batch( #[test] fn test_l2_block_first_in_batch() { + let prev_block_hash = MiniblockHasher::legacy_hash(MiniblockNumber(0)); + let prev_block_hash = MiniblockHasher::new(MiniblockNumber(1), 1, prev_block_hash) + .finalize(ProtocolVersionId::latest()); test_first_in_batch( 1, 1, @@ -377,17 +380,15 @@ fn test_l2_block_first_in_batch() { L2BlockEnv { number: 2, timestamp: 2, - prev_block_hash: miniblock_hash( - MiniblockNumber(1), - 1, - legacy_miniblock_hash(MiniblockNumber(0)), - H256::zero(), - ), + prev_block_hash, max_virtual_blocks_to_create: 1, }, None, ); + let prev_block_hash = MiniblockHasher::legacy_hash(MiniblockNumber(0)); + let prev_block_hash = MiniblockHasher::new(MiniblockNumber(1), 8, prev_block_hash) + .finalize(ProtocolVersionId::latest()); test_first_in_batch( 8, 1, @@ -398,8 +399,8 @@ fn test_l2_block_first_in_batch() { L2BlockEnv { number: 2, timestamp: 9, - prev_block_hash: miniblock_hash(MiniblockNumber(1), 8, legacy_miniblock_hash(MiniblockNumber(0)), H256::zero()), - max_virtual_blocks_to_create: 1 + prev_block_hash, + max_virtual_blocks_to_create: 1, }, Some(Halt::FailedToSetL2Block("The timestamp of the L2 block must be greater than or equal to the timestamp of the current batch".to_string())), ); diff --git a/core/lib/multivm/src/versions/vm_latest/tests/tester/vm_tester.rs b/core/lib/multivm/src/versions/vm_latest/tests/tester/vm_tester.rs index cbf009d5b02..f4797a26360 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/tester/vm_tester.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/tester/vm_tester.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use zksync_contracts::BaseSystemContracts; use zksync_state::{InMemoryStorage, StoragePtr, StorageView, WriteStorage}; -use zksync_types::block::legacy_miniblock_hash; +use zksync_types::block::MiniblockHasher; use zksync_types::helpers::unix_timestamp_ms; use zksync_types::utils::{deployed_address_create, storage_key_for_eth_balance}; use zksync_types::{ @@ -81,7 +81,7 @@ impl VmTester { let last_l2_block = load_last_l2_block(self.storage.clone()).unwrap_or(L2Block { number: 0, timestamp: 0, - hash: legacy_miniblock_hash(MiniblockNumber(0)), + hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), }); l1_batch.first_l2_block = L2BlockEnv { number: last_l2_block.number + 1, @@ -255,7 +255,7 @@ pub(crate) fn default_l1_batch(number: L1BatchNumber) -> L1BatchEnv { first_l2_block: L2BlockEnv { number: 1, timestamp, - prev_block_hash: legacy_miniblock_hash(MiniblockNumber(0)), + prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), max_virtual_blocks_to_create: 100, }, } 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 0c519a324c0..2d4ab69dd1c 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 @@ -16,7 +16,7 @@ use zk_evm_1_4_0::zkevm_opcode_defs::{ }; use zksync_state::{StoragePtr, WriteStorage}; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::block::legacy_miniblock_hash; +use zksync_types::block::MiniblockHasher; use zksync_types::{zkevm_test_harness::INITIAL_MONOTONIC_CYCLE_COUNTER, Address, MiniblockNumber}; use zksync_utils::h256_to_u256; @@ -67,7 +67,9 @@ pub(crate) fn new_vm_state( L2Block { number: l1_batch_env.first_l2_block.number.saturating_sub(1), timestamp: 0, - hash: legacy_miniblock_hash(MiniblockNumber(l1_batch_env.first_l2_block.number) - 1), + hash: MiniblockHasher::legacy_hash( + MiniblockNumber(l1_batch_env.first_l2_block.number) - 1, + ), } }; 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 b656cd09f9b..44f51bb4bc3 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 @@ -16,7 +16,7 @@ use zk_evm_1_3_3::zkevm_opcode_defs::{ }; use zksync_state::{StoragePtr, WriteStorage}; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::block::legacy_miniblock_hash; +use zksync_types::block::MiniblockHasher; use zksync_types::{zkevm_test_harness::INITIAL_MONOTONIC_CYCLE_COUNTER, Address, MiniblockNumber}; use zksync_utils::h256_to_u256; @@ -67,7 +67,9 @@ pub(crate) fn new_vm_state( L2Block { number: l1_batch_env.first_l2_block.number.saturating_sub(1), timestamp: 0, - hash: legacy_miniblock_hash(MiniblockNumber(l1_batch_env.first_l2_block.number) - 1), + hash: MiniblockHasher::legacy_hash( + MiniblockNumber(l1_batch_env.first_l2_block.number) - 1, + ), } }; 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 8784c754fad..624ff1175eb 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 @@ -16,7 +16,7 @@ use zk_evm_1_3_3::zkevm_opcode_defs::{ }; use zksync_state::{StoragePtr, WriteStorage}; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::block::legacy_miniblock_hash; +use zksync_types::block::MiniblockHasher; use zksync_types::{zkevm_test_harness::INITIAL_MONOTONIC_CYCLE_COUNTER, Address, MiniblockNumber}; use zksync_utils::h256_to_u256; @@ -67,7 +67,9 @@ pub(crate) fn new_vm_state( L2Block { number: l1_batch_env.first_l2_block.number.saturating_sub(1), timestamp: 0, - hash: legacy_miniblock_hash(MiniblockNumber(l1_batch_env.first_l2_block.number) - 1), + hash: MiniblockHasher::legacy_hash( + MiniblockNumber(l1_batch_env.first_l2_block.number) - 1, + ), } }; diff --git a/core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs b/core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs index 36ede77abdb..cc451c86801 100644 --- a/core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs +++ b/core/lib/zksync_core/src/api_server/execution_sandbox/apply.rs @@ -21,7 +21,7 @@ use zksync_system_constants::{ }; use zksync_types::{ api, - block::{legacy_miniblock_hash, pack_block_info, unpack_block_info}, + block::{pack_block_info, unpack_block_info, MiniblockHasher}, get_nonce_key, utils::{decompose_full_nonce, nonces_to_full_nonce, storage_key_for_eth_balance}, AccountTreeId, L1BatchNumber, MiniblockNumber, Nonce, ProtocolVersionId, StorageKey, @@ -107,7 +107,7 @@ pub(super) fn apply_vm_in_sandbox( L2BlockEnv { number: 1, timestamp: 0, - prev_block_hash: legacy_miniblock_hash(MiniblockNumber(0)), + prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), max_virtual_blocks_to_create: 1, } } else { diff --git a/core/lib/zksync_core/src/genesis.rs b/core/lib/zksync_core/src/genesis.rs index 39a8645767d..4f31b924755 100644 --- a/core/lib/zksync_core/src/genesis.rs +++ b/core/lib/zksync_core/src/genesis.rs @@ -10,7 +10,7 @@ use zksync_merkle_tree::domain::ZkSyncTree; use zksync_types::{ block::DeployedContract, - block::{legacy_miniblock_hash, BlockGasCount, L1BatchHeader, MiniblockHeader}, + block::{BlockGasCount, L1BatchHeader, MiniblockHasher, MiniblockHeader}, commitment::{L1BatchCommitment, L1BatchMetadata}, get_code_key, get_system_context_init_logs, protocol_version::{L1VerifierConfig, ProtocolVersion}, @@ -294,7 +294,7 @@ pub(crate) async fn create_genesis_l1_batch( let genesis_miniblock_header = MiniblockHeader { number: MiniblockNumber(0), timestamp: 0, - hash: legacy_miniblock_hash(MiniblockNumber(0)), + hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), l1_tx_count: 0, l2_tx_count: 0, base_fee_per_gas: 0, diff --git a/core/lib/zksync_core/src/metadata_calculator/tests.rs b/core/lib/zksync_core/src/metadata_calculator/tests.rs index 5e86db6087b..4594159b68d 100644 --- a/core/lib/zksync_core/src/metadata_calculator/tests.rs +++ b/core/lib/zksync_core/src/metadata_calculator/tests.rs @@ -12,10 +12,10 @@ use zksync_health_check::{CheckHealth, HealthStatus}; use zksync_merkle_tree::domain::ZkSyncTree; use zksync_object_store::{ObjectStore, ObjectStoreFactory}; use zksync_types::{ - block::{miniblock_hash, BlockGasCount, L1BatchHeader, MiniblockHeader}, + block::{BlockGasCount, L1BatchHeader, MiniblockHasher, MiniblockHeader}, proofs::PrepareBasicCircuitsJob, - AccountTreeId, Address, L1BatchNumber, L2ChainId, MiniblockNumber, StorageKey, StorageLog, - H256, + AccountTreeId, Address, L1BatchNumber, L2ChainId, MiniblockNumber, ProtocolVersionId, + StorageKey, StorageLog, H256, }; use zksync_utils::u32_to_h256; @@ -503,19 +503,15 @@ pub(super) async fn extend_db_state( let miniblock_header = MiniblockHeader { number: miniblock_number, timestamp: header.timestamp, - hash: miniblock_hash( - miniblock_number, - header.timestamp, - H256::zero(), - H256::zero(), - ), + hash: MiniblockHasher::new(miniblock_number, header.timestamp, H256::zero()) + .finalize(ProtocolVersionId::latest()), l1_tx_count: header.l1_tx_count, l2_tx_count: header.l2_tx_count, base_fee_per_gas: header.base_fee_per_gas, l1_gas_price: 0, l2_fair_gas_price: 0, base_system_contracts_hashes: base_system_contracts.hashes(), - protocol_version: Some(Default::default()), + protocol_version: Some(ProtocolVersionId::latest()), virtual_blocks: 0, }; diff --git a/core/tests/vm-benchmark/harness/src/lib.rs b/core/tests/vm-benchmark/harness/src/lib.rs index b7da44aed92..61cecf57ba8 100644 --- a/core/tests/vm-benchmark/harness/src/lib.rs +++ b/core/tests/vm-benchmark/harness/src/lib.rs @@ -8,7 +8,7 @@ use zksync_contracts::{deployer_contract, BaseSystemContracts}; use zksync_state::{InMemoryStorage, StorageView}; use zksync_system_constants::ethereum::MAX_GAS_PER_PUBDATA_BYTE; use zksync_types::{ - block::legacy_miniblock_hash, + block::MiniblockHasher, ethabi::{encode, Token}, fee::Fee, helpers::unix_timestamp_ms, @@ -73,7 +73,7 @@ impl BenchmarkingVm { first_l2_block: L2BlockEnv { number: 1, timestamp, - prev_block_hash: legacy_miniblock_hash(MiniblockNumber(0)), + prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), max_virtual_blocks_to_create: 100, }, }, From 286cb08cfcc42ff29674853d0bd228b099bb509b Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Wed, 29 Nov 2023 13:58:27 +0200 Subject: [PATCH 3/7] Check miniblock hash on EN side --- .../zksync_core/src/state_keeper/tests/mod.rs | 13 +++++---- .../state_keeper/updates/miniblock_updates.rs | 20 ++++++------- .../lib/zksync_core/src/sync_layer/fetcher.rs | 28 +++++++++++++++++-- .../src/sync_layer/gossip/conversions.rs | 1 + core/lib/zksync_core/src/sync_layer/tests.rs | 10 +++++++ 5 files changed, 55 insertions(+), 17 deletions(-) diff --git a/core/lib/zksync_core/src/state_keeper/tests/mod.rs b/core/lib/zksync_core/src/state_keeper/tests/mod.rs index c5841fd8b1b..43799c62615 100644 --- a/core/lib/zksync_core/src/state_keeper/tests/mod.rs +++ b/core/lib/zksync_core/src/state_keeper/tests/mod.rs @@ -18,7 +18,7 @@ use zksync_contracts::{BaseSystemContracts, BaseSystemContractsHashes}; use zksync_system_constants::ZKPORTER_IS_AVAILABLE; use zksync_types::{ aggregated_operations::AggregatedActionType, - block::{legacy_miniblock_hash, miniblock_hash, BlockGasCount, MiniblockExecutionData}, + block::{BlockGasCount, MiniblockExecutionData, MiniblockHasher}, commitment::{L1BatchMetaParameters, L1BatchMetadata}, fee::Fee, l2::L2Tx, @@ -77,7 +77,7 @@ pub(super) fn default_l1_batch_env( first_l2_block: L2BlockEnv { number, timestamp, - prev_block_hash: legacy_miniblock_hash(MiniblockNumber(number - 1)), + prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(number - 1)), max_virtual_blocks_to_create: 1, }, } @@ -444,14 +444,16 @@ async fn pending_batch_is_applied() { MiniblockExecutionData { number: MiniblockNumber(1), timestamp: 1, - prev_block_hash: miniblock_hash(MiniblockNumber(0), 0, H256::zero(), H256::zero()), + prev_block_hash: MiniblockHasher::new(MiniblockNumber(0), 0, H256::zero()) + .finalize(ProtocolVersionId::latest()), virtual_blocks: 1, txs: vec![random_tx(1)], }, MiniblockExecutionData { number: MiniblockNumber(2), timestamp: 2, - prev_block_hash: miniblock_hash(MiniblockNumber(1), 1, H256::zero(), H256::zero()), + prev_block_hash: MiniblockHasher::new(MiniblockNumber(1), 1, H256::zero()) + .finalize(ProtocolVersionId::latest()), virtual_blocks: 1, txs: vec![random_tx(2)], }, @@ -529,7 +531,8 @@ async fn miniblock_timestamp_after_pending_batch() { let pending_batch = pending_batch_data(vec![MiniblockExecutionData { number: MiniblockNumber(1), timestamp: 1, - prev_block_hash: miniblock_hash(MiniblockNumber(0), 0, H256::zero(), H256::zero()), + prev_block_hash: MiniblockHasher::new(MiniblockNumber(0), 0, H256::zero()) + .finalize(ProtocolVersionId::latest()), virtual_blocks: 1, txs: vec![random_tx(1)], }]); diff --git a/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs b/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs index d0a4f035f51..32dc93d981b 100644 --- a/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs +++ b/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use zksync_types::l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}; use zksync_types::{ - block::{legacy_miniblock_hash, miniblock_hash, BlockGasCount}, + block::{BlockGasCount, MiniblockHasher}, event::extract_bytecodes_marked_as_known, tx::tx_execution_info::TxExecutionStatus, tx::{ExecutionMetrics, TransactionExecutionResult}, @@ -31,7 +31,7 @@ pub struct MiniblockUpdates { pub prev_block_hash: H256, pub txs_rolling_hash: H256, pub virtual_blocks: u32, - pub protocol_version: Option, + pub protocol_version: Option, // FIXME: always Some? } impl MiniblockUpdates { @@ -145,15 +145,15 @@ impl MiniblockUpdates { /// Calculates miniblock hash based on the protocol version. pub(crate) fn get_miniblock_hash(&self) -> H256 { - match self.protocol_version { - Some(id) if id >= ProtocolVersionId::Version13 => miniblock_hash( - MiniblockNumber(self.number), - self.timestamp, - self.prev_block_hash, - self.txs_rolling_hash, - ), - _ => legacy_miniblock_hash(MiniblockNumber(self.number)), + let mut digest = MiniblockHasher::new( + MiniblockNumber(self.number), + self.timestamp, + self.prev_block_hash, + ); + for tx in &self.executed_transactions { + digest.push_tx_hash(tx.hash); } + digest.finalize(self.protocol_version.unwrap_or(ProtocolVersionId::Version0)) } pub(crate) fn get_miniblock_env(&self) -> L2BlockEnv { diff --git a/core/lib/zksync_core/src/sync_layer/fetcher.rs b/core/lib/zksync_core/src/sync_layer/fetcher.rs index 9cdd7e64fd1..f97ce4d4c2c 100644 --- a/core/lib/zksync_core/src/sync_layer/fetcher.rs +++ b/core/lib/zksync_core/src/sync_layer/fetcher.rs @@ -5,8 +5,9 @@ use std::time::Duration; use zksync_dal::StorageProcessor; use zksync_types::{ - api::en::SyncBlock, block::ConsensusBlockFields, Address, L1BatchNumber, MiniblockNumber, - ProtocolVersionId, + api::en::SyncBlock, + block::{ConsensusBlockFields, MiniblockHasher}, + Address, L1BatchNumber, MiniblockNumber, ProtocolVersionId, H256, }; use zksync_web3_decl::jsonrpsee::core::Error as RpcError; @@ -29,6 +30,7 @@ pub(super) struct FetchedBlock { pub last_in_batch: bool, pub protocol_version: ProtocolVersionId, pub timestamp: u64, + pub reference_hash: Option, pub l1_gas_price: u64, pub l2_fair_gas_price: u64, pub virtual_blocks: u32, @@ -37,6 +39,16 @@ pub(super) struct FetchedBlock { pub consensus: Option, } +impl FetchedBlock { + fn compute_hash(&self, prev_miniblock_hash: H256) -> H256 { + let mut hasher = MiniblockHasher::new(self.number, self.timestamp, prev_miniblock_hash); + for tx in &self.transactions { + hasher.push_tx_hash(tx.hash()); + } + hasher.finalize(self.protocol_version) + } +} + impl From for FetchedBlock { fn from(block: SyncBlock) -> Self { Self { @@ -45,6 +57,7 @@ impl From for FetchedBlock { last_in_batch: block.last_in_batch, protocol_version: block.protocol_version, timestamp: block.timestamp, + reference_hash: block.hash, l1_gas_price: block.l1_gas_price, l2_fair_gas_price: block.l2_fair_gas_price, virtual_blocks: block.virtual_blocks.unwrap_or(0), @@ -62,6 +75,7 @@ impl From for FetchedBlock { pub struct FetcherCursor { // Fields are public for testing purposes. pub(super) next_miniblock: MiniblockNumber, + pub(super) prev_miniblock_hash: H256, pub(super) l1_batch: L1BatchNumber, } @@ -90,6 +104,7 @@ impl FetcherCursor { // Miniblocks are always fully processed. let next_miniblock = last_miniblock_header.number + 1; + let prev_miniblock_hash = last_miniblock_header.hash; // Decide whether the next batch should be explicitly opened or not. let l1_batch = if was_new_batch_open { // No `OpenBatch` action needed. @@ -101,12 +116,20 @@ impl FetcherCursor { Ok(Self { next_miniblock, + prev_miniblock_hash, l1_batch, }) } pub(super) fn advance(&mut self, block: FetchedBlock) -> Vec { assert_eq!(block.number, self.next_miniblock); + let local_block_hash = block.compute_hash(self.prev_miniblock_hash); + if let Some(reference_hash) = block.reference_hash { + assert_eq!( + local_block_hash, reference_hash, + "Mismatch between the locally computed and received miniblock hash for {block:?}" + ); + } let mut new_actions = Vec::new(); if block.l1_batch_number != self.l1_batch { @@ -162,6 +185,7 @@ impl FetcherCursor { new_actions.push(SyncAction::SealMiniblock(block.consensus)); } self.next_miniblock += 1; + self.prev_miniblock_hash = local_block_hash; new_actions } diff --git a/core/lib/zksync_core/src/sync_layer/gossip/conversions.rs b/core/lib/zksync_core/src/sync_layer/gossip/conversions.rs index 410c2bfe204..e37edf739bf 100644 --- a/core/lib/zksync_core/src/sync_layer/gossip/conversions.rs +++ b/core/lib/zksync_core/src/sync_layer/gossip/conversions.rs @@ -42,6 +42,7 @@ impl FetchedBlock { last_in_batch, protocol_version: ProtocolVersionId::latest(), // FIXME timestamp: payload.timestamp, + reference_hash: Some(payload.hash), l1_gas_price: payload.l1_gas_price, l2_fair_gas_price: payload.l2_fair_gas_price, virtual_blocks: payload.virtual_blocks, diff --git a/core/lib/zksync_core/src/sync_layer/tests.rs b/core/lib/zksync_core/src/sync_layer/tests.rs index 20bafc51cf6..6970bcc9210 100644 --- a/core/lib/zksync_core/src/sync_layer/tests.rs +++ b/core/lib/zksync_core/src/sync_layer/tests.rs @@ -573,6 +573,15 @@ async fn fetcher_with_real_server() { // Fill in transactions grouped in multiple miniblocks in the storage. let tx_hashes = run_state_keeper_with_multiple_miniblocks(pool.clone()).await; let mut tx_hashes = VecDeque::from(tx_hashes); + let mut connection = pool.access_storage().await.unwrap(); + let genesis_miniblock_hash = connection + .blocks_dal() + .get_miniblock_header(MiniblockNumber(0)) + .await + .unwrap() + .expect("No genesis miniblock") + .hash; + drop(connection); // Start the API server. let network_config = NetworkConfig::for_tests(); @@ -588,6 +597,7 @@ async fn fetcher_with_real_server() { let client = ::json_rpc(&format!("http://{server_addr}/")).unwrap(); let fetcher_cursor = FetcherCursor { next_miniblock: MiniblockNumber(1), + prev_miniblock_hash: genesis_miniblock_hash, l1_batch: L1BatchNumber(0), }; let fetcher = fetcher_cursor.into_fetcher( From 2767120e7647b5941757aa39aa05238599251d56 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Wed, 29 Nov 2023 14:00:29 +0200 Subject: [PATCH 4/7] Make `MiniblockUpdates.protocol_version` mandatory --- core/lib/zksync_core/src/state_keeper/io/tests/mod.rs | 6 ++---- .../src/state_keeper/updates/l1_batch_updates.rs | 2 +- .../src/state_keeper/updates/miniblock_updates.rs | 8 ++++---- core/lib/zksync_core/src/state_keeper/updates/mod.rs | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core/lib/zksync_core/src/state_keeper/io/tests/mod.rs b/core/lib/zksync_core/src/state_keeper/io/tests/mod.rs index 0c13a7a614b..6f97f65e10b 100644 --- a/core/lib/zksync_core/src/state_keeper/io/tests/mod.rs +++ b/core/lib/zksync_core/src/state_keeper/io/tests/mod.rs @@ -189,8 +189,7 @@ async fn l1_batch_timestamp_respects_prev_miniblock_with_clock_skew() { #[tokio::test] async fn processing_storage_logs_when_sealing_miniblock() { let connection_pool = ConnectionPool::test_pool().await; - let mut miniblock = - MiniblockUpdates::new(0, 1, H256::zero(), 1, Some(ProtocolVersionId::latest())); + let mut miniblock = MiniblockUpdates::new(0, 1, H256::zero(), 1, ProtocolVersionId::latest()); let tx = create_transaction(10, 100); let storage_logs = [ @@ -285,8 +284,7 @@ async fn processing_storage_logs_when_sealing_miniblock() { async fn processing_events_when_sealing_miniblock() { let pool = ConnectionPool::test_pool().await; let l1_batch_number = L1BatchNumber(2); - let mut miniblock = - MiniblockUpdates::new(0, 1, H256::zero(), 1, Some(ProtocolVersionId::latest())); + let mut miniblock = MiniblockUpdates::new(0, 1, H256::zero(), 1, ProtocolVersionId::latest()); let events = (0_u8..10).map(|i| VmEvent { location: (l1_batch_number, u32::from(i / 4)), diff --git a/core/lib/zksync_core/src/state_keeper/updates/l1_batch_updates.rs b/core/lib/zksync_core/src/state_keeper/updates/l1_batch_updates.rs index fdaa0b036f9..0e99c2b0f2c 100644 --- a/core/lib/zksync_core/src/state_keeper/updates/l1_batch_updates.rs +++ b/core/lib/zksync_core/src/state_keeper/updates/l1_batch_updates.rs @@ -56,7 +56,7 @@ mod tests { #[test] fn apply_miniblock_with_empty_tx() { let mut miniblock_accumulator = - MiniblockUpdates::new(0, 0, H256::zero(), 1, Some(ProtocolVersionId::latest())); + MiniblockUpdates::new(0, 0, H256::zero(), 1, ProtocolVersionId::latest()); let tx = create_transaction(10, 100); let expected_tx_size = tx.bootloader_encoding_size(); diff --git a/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs b/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs index 32dc93d981b..7d9711112f2 100644 --- a/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs +++ b/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs @@ -31,7 +31,7 @@ pub struct MiniblockUpdates { pub prev_block_hash: H256, pub txs_rolling_hash: H256, pub virtual_blocks: u32, - pub protocol_version: Option, // FIXME: always Some? + pub protocol_version: ProtocolVersionId, } impl MiniblockUpdates { @@ -40,7 +40,7 @@ impl MiniblockUpdates { number: u32, prev_block_hash: H256, virtual_blocks: u32, - protocol_version: Option, + protocol_version: ProtocolVersionId, ) -> Self { Self { executed_transactions: vec![], @@ -153,7 +153,7 @@ impl MiniblockUpdates { for tx in &self.executed_transactions { digest.push_tx_hash(tx.hash); } - digest.finalize(self.protocol_version.unwrap_or(ProtocolVersionId::Version0)) + digest.finalize(self.protocol_version) } pub(crate) fn get_miniblock_env(&self) -> L2BlockEnv { @@ -175,7 +175,7 @@ mod tests { #[test] fn apply_empty_l2_tx() { let mut accumulator = - MiniblockUpdates::new(0, 0, H256::random(), 0, Some(ProtocolVersionId::latest())); + MiniblockUpdates::new(0, 0, H256::random(), 0, ProtocolVersionId::latest()); let tx = create_transaction(10, 100); let bootloader_encoding_size = tx.bootloader_encoding_size(); accumulator.extend_from_executed_transaction( diff --git a/core/lib/zksync_core/src/state_keeper/updates/mod.rs b/core/lib/zksync_core/src/state_keeper/updates/mod.rs index dc72893e703..f951e8a7933 100644 --- a/core/lib/zksync_core/src/state_keeper/updates/mod.rs +++ b/core/lib/zksync_core/src/state_keeper/updates/mod.rs @@ -54,7 +54,7 @@ impl UpdatesManager { l1_batch_env.first_l2_block.number, l1_batch_env.first_l2_block.prev_block_hash, l1_batch_env.first_l2_block.max_virtual_blocks_to_create, - Some(protocol_version), + protocol_version, ), storage_writes_deduplicator: StorageWritesDeduplicator::new(), } @@ -135,7 +135,7 @@ impl UpdatesManager { self.miniblock.number + 1, self.miniblock.get_miniblock_hash(), miniblock_params.virtual_blocks, - Some(self.protocol_version), + self.protocol_version, ); let old_miniblock_updates = std::mem::replace(&mut self.miniblock, new_miniblock_updates); self.l1_batch From fc323e9bfe594da3a8aa4dcb5f46f9cfb4e8fccd Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Wed, 29 Nov 2023 14:01:40 +0200 Subject: [PATCH 5/7] Remove `MiniblockUpdates.txs_rolling_hash` --- .../src/state_keeper/updates/miniblock_updates.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs b/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs index 7d9711112f2..cdbefc3f010 100644 --- a/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs +++ b/core/lib/zksync_core/src/state_keeper/updates/miniblock_updates.rs @@ -12,7 +12,6 @@ use zksync_types::{ MiniblockNumber, ProtocolVersionId, StorageLogQuery, Transaction, VmEvent, H256, }; use zksync_utils::bytecode::{hash_bytecode, CompressedBytecodeInfo}; -use zksync_utils::concat_and_hash; #[derive(Debug, Clone, PartialEq)] pub struct MiniblockUpdates { @@ -29,7 +28,6 @@ pub struct MiniblockUpdates { pub timestamp: u64, pub number: u32, pub prev_block_hash: H256, - pub txs_rolling_hash: H256, pub virtual_blocks: u32, pub protocol_version: ProtocolVersionId, } @@ -55,7 +53,6 @@ impl MiniblockUpdates { timestamp, number, prev_block_hash, - txs_rolling_hash: H256::zero(), virtual_blocks, protocol_version, } @@ -124,12 +121,9 @@ impl MiniblockUpdates { self.l1_gas_count += tx_l1_gas_this_tx; self.block_execution_metrics += execution_metrics; self.txs_encoding_size += tx.bootloader_encoding_size(); - self.storage_logs .extend(tx_execution_result.logs.storage_logs); - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx.hash()); - self.executed_transactions.push(TransactionExecutionResult { hash: tx.hash(), transaction: tx, From 685e93f0a178d622c0fd5167596b657382eb6983 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Wed, 29 Nov 2023 14:47:47 +0200 Subject: [PATCH 6/7] Fix `MockMainNodeClient` --- core/lib/zksync_core/src/sync_layer/tests.rs | 21 +++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/core/lib/zksync_core/src/sync_layer/tests.rs b/core/lib/zksync_core/src/sync_layer/tests.rs index 6970bcc9210..f872926282e 100644 --- a/core/lib/zksync_core/src/sync_layer/tests.rs +++ b/core/lib/zksync_core/src/sync_layer/tests.rs @@ -13,7 +13,8 @@ use zksync_config::configs::chain::NetworkConfig; use zksync_contracts::{BaseSystemContractsHashes, SystemContractCode}; use zksync_dal::{ConnectionPool, StorageProcessor}; use zksync_types::{ - api, Address, L1BatchNumber, L2ChainId, MiniblockNumber, ProtocolVersionId, Transaction, H256, + api, block::MiniblockHasher, Address, L1BatchNumber, L2ChainId, MiniblockNumber, + ProtocolVersionId, Transaction, H256, }; use super::{fetcher::FetcherCursor, sync_action::SyncAction, *}; @@ -31,6 +32,7 @@ const POLL_INTERVAL: Duration = Duration::from_millis(50); #[derive(Debug, Default)] struct MockMainNodeClient { + prev_miniblock_hash: H256, l2_blocks: Vec, } @@ -46,14 +48,27 @@ impl MockMainNodeClient { let mut tx_hashes = vec![]; let l2_blocks = (0..=miniblock_count).map(|number| { let is_fictive = number == miniblock_count; + let number = number + number_offset; + let mut hasher = MiniblockHasher::new( + MiniblockNumber(number), + number.into(), + self.prev_miniblock_hash, + ); + let transactions = if is_fictive { vec![] } else { let transaction = create_l2_transaction(10, 100); tx_hashes.push(transaction.hash()); + hasher.push_tx_hash(transaction.hash()); vec![transaction.into()] }; - let number = number + number_offset; + let miniblock_hash = hasher.finalize(if number == 0 { + ProtocolVersionId::Version0 // The genesis block always uses the legacy hashing mode + } else { + ProtocolVersionId::latest() + }); + self.prev_miniblock_hash = miniblock_hash; api::en::SyncBlock { number: MiniblockNumber(number), @@ -67,7 +82,7 @@ impl MockMainNodeClient { operator_address: Address::repeat_byte(2), transactions: Some(transactions), virtual_blocks: Some(!is_fictive as u32), - hash: Some(H256::repeat_byte(1)), + hash: Some(miniblock_hash), protocol_version: ProtocolVersionId::latest(), consensus: None, } From 328a3f710bfc36d98492460a65b47611255f046a Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Fri, 1 Dec 2023 10:31:37 +0200 Subject: [PATCH 7/7] Add "validator" to dictionary --- spellcheck/era.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/spellcheck/era.dic b/spellcheck/era.dic index 214efbcd595..19e5ae92465 100644 --- a/spellcheck/era.dic +++ b/spellcheck/era.dic @@ -261,6 +261,7 @@ blockchains sidechain sidechains tokenomics +validator validator's CHAINID PREVRANDAO