From 705193c84b1bb7da037bad00f48d5b1aac1d32a9 Mon Sep 17 00:00:00 2001 From: Vaclav Barta Date: Wed, 20 Mar 2024 10:46:21 +0100 Subject: [PATCH] unified parse_total_l2_to_l1_pubdata with parse_resolved_pubdata --- state-reconstruct-fetcher/src/constants.rs | 2 + state-reconstruct-fetcher/src/types/common.rs | 34 +++++++++++- state-reconstruct-fetcher/src/types/v2.rs | 36 +------------ state-reconstruct-fetcher/src/types/v3.rs | 53 ++++--------------- 4 files changed, 48 insertions(+), 77 deletions(-) diff --git a/state-reconstruct-fetcher/src/constants.rs b/state-reconstruct-fetcher/src/constants.rs index b12c09e..9d987e4 100644 --- a/state-reconstruct-fetcher/src/constants.rs +++ b/state-reconstruct-fetcher/src/constants.rs @@ -38,4 +38,6 @@ pub mod zksync { pub const LENGTH_BITS_OFFSET: u8 = 3; // Size of `CommitBatchInfo.pubdataCommitments` item. pub const PUBDATA_COMMITMENT_SIZE: usize = 144; + // Size of the unparsed end of `CommitBatchInfo.pubdataCommitments`. + pub const CALLDATA_SOURCE_TAIL_SIZE: usize = 32; } diff --git a/state-reconstruct-fetcher/src/types/common.rs b/state-reconstruct-fetcher/src/types/common.rs index ba61658..7a0d77a 100644 --- a/state-reconstruct-fetcher/src/types/common.rs +++ b/state-reconstruct-fetcher/src/types/common.rs @@ -2,7 +2,9 @@ use ethers::{abi, types::U256}; use super::{L2ToL1Pubdata, PackingType, ParseError}; -use crate::constants::zksync::{LENGTH_BITS_OFFSET, OPERATION_BITMASK}; +use crate::constants::zksync::{ + L2_TO_L1_LOG_SERIALIZE_SIZE, LENGTH_BITS_OFFSET, OPERATION_BITMASK, +}; pub struct ExtractedToken { pub new_l2_block_number: U256, @@ -85,6 +87,36 @@ impl TryFrom<&abi::Token> for ExtractedToken { } // TODO: Move these to a dedicated parser struct. +pub fn parse_resolved_pubdata(bytes: &[u8]) -> Result, ParseError> { + let mut l2_to_l1_pubdata = Vec::new(); + + let mut pointer = 0; + // Skip over logs and messages. + let num_of_l1_to_l2_logs = u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)); + pointer += L2_TO_L1_LOG_SERIALIZE_SIZE * num_of_l1_to_l2_logs as usize; + + let num_of_messages = u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)); + for _ in 0..num_of_messages { + let current_message_len = u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)); + pointer += current_message_len as usize; + } + + // Parse published bytecodes. + let num_of_bytecodes = u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)); + for _ in 0..num_of_bytecodes { + let current_bytecode_len = + u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)) as usize; + let bytecode = bytes[pointer..pointer + current_bytecode_len].to_vec(); + pointer += current_bytecode_len; + l2_to_l1_pubdata.push(L2ToL1Pubdata::PublishedBytecode(bytecode)) + } + + let mut state_diffs = parse_compressed_state_diffs(bytes, &mut pointer)?; + l2_to_l1_pubdata.append(&mut state_diffs); + + Ok(l2_to_l1_pubdata) +} + pub fn parse_compressed_state_diffs( bytes: &[u8], pointer: &mut usize, diff --git a/state-reconstruct-fetcher/src/types/v2.rs b/state-reconstruct-fetcher/src/types/v2.rs index 1d7e98a..cc98f2f 100644 --- a/state-reconstruct-fetcher/src/types/v2.rs +++ b/state-reconstruct-fetcher/src/types/v2.rs @@ -2,10 +2,9 @@ use ethers::{abi, types::U256}; use serde::{Deserialize, Serialize}; use super::{ - common::{parse_compressed_state_diffs, read_next_n_bytes, ExtractedToken}, + common::{parse_resolved_pubdata, ExtractedToken}, CommitBlockFormat, CommitBlockInfo, L2ToL1Pubdata, ParseError, }; -use crate::constants::zksync::L2_TO_L1_LOG_SERIALIZE_SIZE; /// Data needed to commit new block #[derive(Debug, Serialize, Deserialize)] @@ -53,7 +52,7 @@ impl TryFrom<&abi::Token> for V2 { } = token.try_into()?; let new_enumeration_index = new_enumeration_index.as_u64(); - let total_l2_to_l1_pubdata = parse_total_l2_to_l1_pubdata(total_l2_to_l1_pubdata)?; + let total_l2_to_l1_pubdata = parse_resolved_pubdata(&total_l2_to_l1_pubdata[..])?; let blk = V2 { block_number: new_l2_block_number.as_u64(), timestamp: timestamp.as_u64(), @@ -68,34 +67,3 @@ impl TryFrom<&abi::Token> for V2 { Ok(blk) } } - -fn parse_total_l2_to_l1_pubdata(bytes: Vec) -> Result, ParseError> { - let mut l2_to_l1_pubdata = Vec::new(); - let mut pointer = 0; - - // Skip over logs and messages. - let num_of_l1_to_l2_logs = u32::from_be_bytes(read_next_n_bytes(&bytes, &mut pointer)); - pointer += L2_TO_L1_LOG_SERIALIZE_SIZE * num_of_l1_to_l2_logs as usize; - - let num_of_messages = u32::from_be_bytes(read_next_n_bytes(&bytes, &mut pointer)); - for _ in 0..num_of_messages { - let current_message_len = u32::from_be_bytes(read_next_n_bytes(&bytes, &mut pointer)); - pointer += current_message_len as usize; - } - - // Parse published bytecodes. - let num_of_bytecodes = u32::from_be_bytes(read_next_n_bytes(&bytes, &mut pointer)); - for _ in 0..num_of_bytecodes { - let current_bytecode_len = - u32::from_be_bytes(read_next_n_bytes(&bytes, &mut pointer)) as usize; - let bytecode = bytes[pointer..pointer + current_bytecode_len].to_vec(); - pointer += current_bytecode_len; - l2_to_l1_pubdata.push(L2ToL1Pubdata::PublishedBytecode(bytecode)) - } - - // Parse compressed state diffs. - let mut state_diffs = parse_compressed_state_diffs(&bytes, &mut pointer)?; - l2_to_l1_pubdata.append(&mut state_diffs); - - Ok(l2_to_l1_pubdata) -} diff --git a/state-reconstruct-fetcher/src/types/v3.rs b/state-reconstruct-fetcher/src/types/v3.rs index c26c246..655a917 100644 --- a/state-reconstruct-fetcher/src/types/v3.rs +++ b/state-reconstruct-fetcher/src/types/v3.rs @@ -8,12 +8,12 @@ use tokio::time::{sleep, Duration}; use zkevm_circuits::eip_4844::ethereum_4844_data_into_zksync_pubdata; use super::{ - common::{parse_compressed_state_diffs, read_next_n_bytes, ExtractedToken}, + common::{parse_resolved_pubdata, read_next_n_bytes, ExtractedToken}, L2ToL1Pubdata, ParseError, }; use crate::{ blob_http_client::BlobHttpClient, - constants::zksync::{L2_TO_L1_LOG_SERIALIZE_SIZE, PUBDATA_COMMITMENT_SIZE}, + constants::zksync::{CALLDATA_SOURCE_TAIL_SIZE, PUBDATA_COMMITMENT_SIZE}, }; /// `MAX_RETRIES` is the maximum number of retries on failed blob retrieval. @@ -109,7 +109,14 @@ impl V3 { ) -> Result, ParseError> { let bytes = &self.pubdata_commitments[..]; match self.pubdata_source { - PubdataSource::Calldata => parse_resolved_pubdata(bytes, true), + PubdataSource::Calldata => { + let l = bytes.len(); + if l < CALLDATA_SOURCE_TAIL_SIZE { + Err(ParseError::InvalidCalldata("too short".to_string())) + } else { + parse_resolved_pubdata(&bytes[..l - CALLDATA_SOURCE_TAIL_SIZE]) + } + } PubdataSource::Blob => parse_pubdata_from_blobs(bytes, client).await, } } @@ -121,44 +128,6 @@ fn parse_pubdata_source(bytes: &[u8], pointer: &mut usize) -> Result Result, ParseError> { - let mut l2_to_l1_pubdata = Vec::new(); - - let mut pointer = 0; - // Skip over logs and messages. - let num_of_l1_to_l2_logs = u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)); - pointer += L2_TO_L1_LOG_SERIALIZE_SIZE * num_of_l1_to_l2_logs as usize; - - let num_of_messages = u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)); - for _ in 0..num_of_messages { - let current_message_len = u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)); - pointer += current_message_len as usize; - } - - // Parse published bytecodes. - let num_of_bytecodes = u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)); - for _ in 0..num_of_bytecodes { - let current_bytecode_len = - u32::from_be_bytes(read_next_n_bytes(bytes, &mut pointer)) as usize; - let bytecode = bytes[pointer..pointer + current_bytecode_len].to_vec(); - pointer += current_bytecode_len; - l2_to_l1_pubdata.push(L2ToL1Pubdata::PublishedBytecode(bytecode)) - } - - // Parse compressed state diffs. - // NOTE: Is this correct? Ignoring the last 32 bytes? - let diff_bytes = if shorten { - let end_point = bytes.len() - 32; - &bytes[..end_point] - } else { - bytes - }; - let mut state_diffs = parse_compressed_state_diffs(diff_bytes, &mut pointer)?; - l2_to_l1_pubdata.append(&mut state_diffs); - - Ok(l2_to_l1_pubdata) -} - async fn parse_pubdata_from_blobs( bytes: &[u8], client: &BlobHttpClient, @@ -180,7 +149,7 @@ async fn parse_pubdata_from_blobs( } let blobs_view = &blobs[..l]; - parse_resolved_pubdata(blobs_view, false) + parse_resolved_pubdata(blobs_view) } async fn get_blob(kzg_commitment: &[u8], client: &BlobHttpClient) -> Result, ParseError> {