diff --git a/crates/apollo_storage/src/db/serialization.rs b/crates/apollo_storage/src/db/serialization.rs index 73380a7e28d..7f4ff64d3e1 100644 --- a/crates/apollo_storage/src/db/serialization.rs +++ b/crates/apollo_storage/src/db/serialization.rs @@ -2,7 +2,6 @@ use std::fmt::Debug; use std::io::Write; use std::marker::PhantomData; -#[cfg(test)] use tracing::error; use crate::db::DbError; @@ -106,7 +105,6 @@ impl ValueSerde for VersionZeroWrapper { } /// Trait for migrating values from older versions. -#[cfg(test)] pub(crate) trait Migratable { /// Tries to migrate the value from an older version. fn try_from_older_version( @@ -121,12 +119,10 @@ pub(crate) trait Migratable { /// that is set to the version. When deserializing, the version is checked and the value is migrated /// if the serialization is of an older version. #[derive(Clone, Debug)] -#[cfg(test)] pub(crate) struct VersionWrapper { _value_type: PhantomData, } -#[cfg(test)] impl ValueSerde for VersionWrapper { diff --git a/crates/apollo_storage/src/deprecated/migrations.rs b/crates/apollo_storage/src/deprecated/migrations.rs index 8235098eb34..1111bd319a0 100644 --- a/crates/apollo_storage/src/deprecated/migrations.rs +++ b/crates/apollo_storage/src/deprecated/migrations.rs @@ -1,2 +1,88 @@ -// This file should contain the deprecated structs and the corresponding migration logic. -// Check file history for examples. +use serde::{Deserialize, Serialize}; +use starknet_api::block::{BlockHash, BlockNumber, BlockTimestamp, GasPrice, GasPricePerToken}; +use starknet_api::core::{ + EventCommitment, + GlobalRoot, + ReceiptCommitment, + SequencerContractAddress, + StateDiffCommitment, + TransactionCommitment, +}; +use starknet_api::data_availability::L1DataAvailabilityMode; +use starknet_api::execution_resources::GasAmount; +use tracing::error; + +use crate::db::serialization::{Migratable, StorageSerde, StorageSerdeError}; +use crate::header::StorageBlockHeader; + +impl Migratable for StorageBlockHeader { + fn try_from_older_version( + bytes: &mut impl std::io::Read, + older_version: u8, + ) -> Result { + const CURRENT_VERSION: u8 = 1; + const PREV_VERSION: u8 = CURRENT_VERSION - 1; + + let prev_version_block_header = match older_version { + PREV_VERSION => { + StorageBlockHeaderV0::deserialize_from(bytes).ok_or(StorageSerdeError::Migration) + } + CURRENT_VERSION.. => { + error!("Version {} is >= current version. Can't migrate.", older_version); + Err(StorageSerdeError::Migration) + } + }?; + Ok(prev_version_block_header.into()) + } +} + +/// Pre-SNIP-35 layout of [`StorageBlockHeader`] without `fee_proposal_fri`. +#[derive(Debug, Default, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)] +pub(crate) struct StorageBlockHeaderV0 { + pub block_hash: BlockHash, + pub parent_hash: BlockHash, + pub block_number: BlockNumber, + pub l1_gas_price: GasPricePerToken, + pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, + pub l2_gas_consumed: GasAmount, + pub next_l2_gas_price: GasPrice, + pub state_root: GlobalRoot, + pub sequencer: SequencerContractAddress, + pub timestamp: BlockTimestamp, + pub l1_da_mode: L1DataAvailabilityMode, + pub state_diff_commitment: Option, + pub transaction_commitment: Option, + pub event_commitment: Option, + pub receipt_commitment: Option, + pub state_diff_length: Option, + pub n_transactions: usize, + pub n_events: usize, +} + +impl From for StorageBlockHeader { + fn from(v0_header: StorageBlockHeaderV0) -> Self { + Self { + block_hash: v0_header.block_hash, + parent_hash: v0_header.parent_hash, + block_number: v0_header.block_number, + l1_gas_price: v0_header.l1_gas_price, + l1_data_gas_price: v0_header.l1_data_gas_price, + l2_gas_price: v0_header.l2_gas_price, + l2_gas_consumed: v0_header.l2_gas_consumed, + next_l2_gas_price: v0_header.next_l2_gas_price, + state_root: v0_header.state_root, + sequencer: v0_header.sequencer, + timestamp: v0_header.timestamp, + l1_da_mode: v0_header.l1_da_mode, + state_diff_commitment: v0_header.state_diff_commitment, + transaction_commitment: v0_header.transaction_commitment, + event_commitment: v0_header.event_commitment, + receipt_commitment: v0_header.receipt_commitment, + state_diff_length: v0_header.state_diff_length, + n_transactions: v0_header.n_transactions, + n_events: v0_header.n_events, + fee_proposal_fri: None, + } + } +} diff --git a/crates/apollo_storage/src/deprecated/serializers.rs b/crates/apollo_storage/src/deprecated/serializers.rs index 74655664c25..7821e294ba2 100644 --- a/crates/apollo_storage/src/deprecated/serializers.rs +++ b/crates/apollo_storage/src/deprecated/serializers.rs @@ -1,2 +1,41 @@ -// This file should contain the serialization logic for the deprecated structs. Usually, using the -// auto_storage_serde macro. +use starknet_api::block::{BlockHash, BlockNumber, BlockTimestamp, GasPrice, GasPricePerToken}; +use starknet_api::core::{ + EventCommitment, + GlobalRoot, + ReceiptCommitment, + SequencerContractAddress, + StateDiffCommitment, + TransactionCommitment, +}; +use starknet_api::data_availability::L1DataAvailabilityMode; +use starknet_api::execution_resources::GasAmount; + +use crate::db::serialization::{StorageSerde, StorageSerdeError}; +use crate::deprecated::migrations::StorageBlockHeaderV0; +use crate::serialization::serializers::auto_storage_serde; +#[cfg(test)] +use crate::serialization::serializers_test::{create_storage_serde_test, StorageSerdeTest}; + +auto_storage_serde! { + pub struct StorageBlockHeaderV0 { + pub block_hash: BlockHash, + pub parent_hash: BlockHash, + pub block_number: BlockNumber, + pub l1_gas_price: GasPricePerToken, + pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, + pub l2_gas_consumed: GasAmount, + pub next_l2_gas_price: GasPrice, + pub state_root: GlobalRoot, + pub sequencer: SequencerContractAddress, + pub timestamp: BlockTimestamp, + pub l1_da_mode: L1DataAvailabilityMode, + pub state_diff_commitment: Option, + pub transaction_commitment: Option, + pub event_commitment: Option, + pub receipt_commitment: Option, + pub state_diff_length: Option, + pub n_transactions: usize, + pub n_events: usize, + } +} diff --git a/crates/apollo_storage/src/deprecated/test_instances.rs b/crates/apollo_storage/src/deprecated/test_instances.rs index 7aec292e7e7..40ac31cb375 100644 --- a/crates/apollo_storage/src/deprecated/test_instances.rs +++ b/crates/apollo_storage/src/deprecated/test_instances.rs @@ -1,2 +1,38 @@ -// This file should contain the test instances for the deprecated structs. Usually, using the -// auto_impl_get_test_instance macro. +use apollo_test_utils::{auto_impl_get_test_instance, GetTestInstance}; +use starknet_api::block::{BlockHash, BlockNumber, BlockTimestamp, GasPrice, GasPricePerToken}; +use starknet_api::core::{ + EventCommitment, + GlobalRoot, + ReceiptCommitment, + SequencerContractAddress, + StateDiffCommitment, + TransactionCommitment, +}; +use starknet_api::data_availability::L1DataAvailabilityMode; +use starknet_api::execution_resources::GasAmount; + +use crate::deprecated::migrations::StorageBlockHeaderV0; + +auto_impl_get_test_instance! { + pub struct StorageBlockHeaderV0 { + pub block_hash: BlockHash, + pub parent_hash: BlockHash, + pub block_number: BlockNumber, + pub l1_gas_price: GasPricePerToken, + pub l1_data_gas_price: GasPricePerToken, + pub l2_gas_price: GasPricePerToken, + pub l2_gas_consumed: GasAmount, + pub next_l2_gas_price: GasPrice, + pub state_root: GlobalRoot, + pub sequencer: SequencerContractAddress, + pub timestamp: BlockTimestamp, + pub l1_da_mode: L1DataAvailabilityMode, + pub state_diff_commitment: Option, + pub transaction_commitment: Option, + pub event_commitment: Option, + pub receipt_commitment: Option, + pub state_diff_length: Option, + pub n_transactions: usize, + pub n_events: usize, + } +} diff --git a/crates/apollo_storage/src/lib.rs b/crates/apollo_storage/src/lib.rs index 3d68b8adf09..55bb78a9e46 100644 --- a/crates/apollo_storage/src/lib.rs +++ b/crates/apollo_storage/src/lib.rs @@ -132,7 +132,13 @@ use apollo_proc_macros::{latency_histogram, sequencer_latency_histogram}; use body::events::EventIndex; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use db::db_stats::{DbTableStats, DbWholeStats}; -use db::serialization::{Key, NoVersionValueWrapper, ValueSerde, VersionZeroWrapper}; +use db::serialization::{ + Key, + NoVersionValueWrapper, + ValueSerde, + VersionWrapper, + VersionZeroWrapper, +}; use db::table_types::{CommonPrefix, NoValue, Table, TableType}; use mmap_file::{ open_file, @@ -191,7 +197,7 @@ use crate::version::{VersionStorageReader, VersionStorageWriter}; /// The current version of the storage state code. pub const STORAGE_VERSION_STATE: Version = Version { major: 6, minor: 0 }; /// The current version of the storage blocks code. -pub const STORAGE_VERSION_BLOCKS: Version = Version { major: 6, minor: 0 }; +pub const STORAGE_VERSION_BLOCKS: Version = Version { major: 6, minor: 1 }; /// Opens a storage and returns a [`StorageReader`] and a [`StorageWriter`]. pub fn open_storage( @@ -687,7 +693,7 @@ struct_field_names! { deployed_contracts: TableIdentifier<(ContractAddress, BlockNumber), VersionZeroWrapper, SimpleTable>, contract_address_events_index: TableIdentifier<(ContractAddress, TransactionIndex), NoVersionValueWrapper, CommonPrefix>, // TODO(Shahak): Remove the block hashes from this table and use block hash tables instead. - headers: TableIdentifier, SimpleTable>, + headers: TableIdentifier, SimpleTable>, last_voted_marker: TableIdentifier<(), VersionZeroWrapper, SimpleTable>, markers: TableIdentifier, SimpleTable>, nonces: TableIdentifier<(ContractAddress, BlockNumber), VersionZeroWrapper, CommonPrefix>,