Skip to content

Commit

Permalink
chore: add state_diff_length, receipt_commitment to BlockHeader from …
Browse files Browse the repository at this point in the history
…SN API (#1811)

chore: bring new BlockHeader from SN API
  • Loading branch information
ShahakShama authored Mar 14, 2024
1 parent 35e85b3 commit a74c8d2
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,4 @@ url = "2.2.2"
validator = "0.12"

[patch.crates-io]
starknet_api = { git = "https://github.com/starkware-libs/starknet-api", rev = "1fc73f22a4e4bcc453eb25bea898256bba3bdf27" }
starknet_api = { git = "https://github.com/starkware-libs/starknet-api", rev = "fa2cf6d6da46c43efe141e9ffc044ae9ebbf4541" }
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,14 @@ impl TryFrom<protobuf::SignedBlockHeader> for SignedBlockHeader {
sequencer,
timestamp,
l1_da_mode,
// TODO(shahak): fill this.
state_diff_commitment: None,
transaction_commitment,
event_commitment,
// TODO(shahak): fill this.
state_diff_length: None,
// TODO(shahak): fill this.
receipt_commitment: None,
n_transactions,
n_events,
starknet_version,
Expand Down
75 changes: 74 additions & 1 deletion crates/papyrus_storage/src/deprecated/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use starknet_api::core::{
EventCommitment,
GlobalRoot,
SequencerContractAddress,
StateDiffCommitment,
TransactionCommitment,
};
use starknet_api::data_availability::L1DataAvailabilityMode;
Expand All @@ -13,6 +14,37 @@ 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<Self, StorageSerdeError> {
// TODO: Once we have version 3, extract the code below to a function.
const CURRENT_VERSION: u8 = 2;
// match doesn't allow any calculations in patterns
const PREV_VERSION: u8 = CURRENT_VERSION - 1;
// match doesn't allow exclusive ranges in patterns
const BEFORE_PREV_VERSION: u8 = PREV_VERSION - 1;

let prev_version_block_header = match older_version {
0..=BEFORE_PREV_VERSION => {
StorageBlockHeaderV1::try_from_older_version(bytes, older_version)
}
PREV_VERSION => {
StorageBlockHeaderV1::deserialize_from(bytes).ok_or(StorageSerdeError::Migration)
}
CURRENT_VERSION.. => {
error!(
"Unable to migrate stored header from version {} to current version.",
older_version
);
Err(StorageSerdeError::Migration)
}
}?;
Ok(prev_version_block_header.into())
}
}

impl Migratable for StorageBlockHeaderV1 {
fn try_from_older_version(
bytes: &mut impl std::io::Read,
older_version: u8,
Expand All @@ -30,6 +62,24 @@ impl Migratable for StorageBlockHeader {
}
}

#[derive(Debug, Default, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)]
pub(crate) struct StorageBlockHeaderV1 {
pub block_hash: BlockHash,
pub parent_hash: BlockHash,
pub block_number: BlockNumber,
pub l1_gas_price: GasPricePerToken,
pub l1_data_gas_price: GasPricePerToken,
pub state_root: GlobalRoot,
pub sequencer: SequencerContractAddress,
pub timestamp: BlockTimestamp,
pub l1_da_mode: L1DataAvailabilityMode,
pub state_diff_commitment: Option<StateDiffCommitment>,
pub transaction_commitment: Option<TransactionCommitment>,
pub event_commitment: Option<EventCommitment>,
pub n_transactions: Option<usize>,
pub n_events: Option<usize>,
}

// Storage headers until starknet version 0.13.1.
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord)]
pub(crate) struct StorageBlockHeaderV0 {
Expand All @@ -48,7 +98,30 @@ pub(crate) struct StorageBlockHeaderV0 {
pub n_events: usize,
}

impl From<StorageBlockHeaderV0> for StorageBlockHeader {
impl From<StorageBlockHeaderV1> for StorageBlockHeader {
fn from(v1_header: StorageBlockHeaderV1) -> Self {
Self {
block_hash: v1_header.block_hash,
parent_hash: v1_header.parent_hash,
block_number: v1_header.block_number,
l1_gas_price: v1_header.l1_gas_price,
l1_data_gas_price: v1_header.l1_data_gas_price,
state_root: v1_header.state_root,
sequencer: v1_header.sequencer,
timestamp: v1_header.timestamp,
l1_da_mode: v1_header.l1_da_mode,
state_diff_commitment: v1_header.state_diff_commitment,
state_diff_length: None,
receipt_commitment: None,
transaction_commitment: v1_header.transaction_commitment,
event_commitment: v1_header.event_commitment,
n_transactions: v1_header.n_transactions,
n_events: v1_header.n_events,
}
}
}

impl From<StorageBlockHeaderV0> for StorageBlockHeaderV1 {
fn from(v0_header: StorageBlockHeaderV0) -> Self {
// In older versions, the transaction_commitment and event_commitment are 0 instead of None.
let missing_commitments_data = v0_header.transaction_commitment
Expand Down
124 changes: 89 additions & 35 deletions crates/papyrus_storage/src/deprecated/migrations_test.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
use std::fmt::Debug;

use starknet_api::block::{BlockNumber, StarknetVersion};
use starknet_api::core::{EventCommitment, TransactionCommitment};
use starknet_api::hash::StarkFelt;
use starknet_api::stark_felt;
use test_log::test;
use test_utils::{get_rng, GetTestInstance};

use crate::db::serialization::VersionZeroWrapper;
use crate::db::table_types::Table;
use crate::deprecated::migrations::StorageBlockHeaderV0;
use crate::deprecated::migrations::{StorageBlockHeaderV0, StorageBlockHeaderV1};
use crate::header::{HeaderStorageReader, HeaderStorageWriter};
use crate::test_utils::get_test_storage;
use crate::MarkerKind;
use crate::{MarkerKind, StorageReader, StorageWriter, ValueSerde, VersionWrapper};

fn write_old_headers<TVersionWrapper: ValueSerde + Debug>(
writer: &mut StorageWriter,
reader: &StorageReader,
headers: &[&TVersionWrapper::Value],
) {
// No easy way to insert a deprecated version into the db.
let table_id = writer
.db_writer
.create_simple_table::<BlockNumber, TVersionWrapper>(reader.tables.headers.name)
.unwrap();
let txn = writer.begin_rw_txn().unwrap();
let table = txn.open_table(&table_id).unwrap();
for (i, header) in headers.iter().enumerate() {
table.insert(&txn.txn, &BlockNumber(i.try_into().unwrap()), header).unwrap();
}
txn.open_table(&txn.tables.markers)
.unwrap()
.upsert(&txn.txn, &MarkerKind::Header, &BlockNumber(headers.len().try_into().unwrap()))
.unwrap();
txn.commit().unwrap();
}

#[test]
fn header_v0_to_v1() {
fn header_v0_to_current() {
let ((reader, mut writer), _dir) = get_test_storage();
// Insert a headers V0 to the db.
let header_without_commitments = StorageBlockHeaderV0::default();
Expand All @@ -31,47 +56,76 @@ fn header_v0_to_v1() {
.commit()
.unwrap();

// No easy way to insert a deprecated version into the db.
let v0_table_id = writer
.db_writer
.create_simple_table::<BlockNumber, VersionZeroWrapper<StorageBlockHeaderV0>>(
reader.tables.headers.name,
)
.unwrap();
let txn = writer.begin_rw_txn().unwrap();
let v0_table = txn.open_table(&v0_table_id).unwrap();
v0_table.insert(&txn.txn, &BlockNumber(0), &header_without_commitments).unwrap();
v0_table.insert(&txn.txn, &BlockNumber(1), &header_with_commitments).unwrap();
txn.open_table(&txn.tables.markers)
.unwrap()
.upsert(&txn.txn, &MarkerKind::Header, &BlockNumber(2))
.unwrap();
txn.commit().unwrap();
write_old_headers::<VersionZeroWrapper<StorageBlockHeaderV0>>(
&mut writer,
&reader,
&[&header_without_commitments, &header_with_commitments],
);

// Read the headers, expecting to get the V1 version via the migration.
let header_v1_no_commitments =
// Read the headers, expecting to get the latest version via the migration.
let header_current_no_commitments =
reader.begin_ro_txn().unwrap().get_block_header(BlockNumber(0)).unwrap();
assert!(header_v1_no_commitments.is_some());
let header_v1_no_commitments = header_v1_no_commitments.unwrap();
assert!(header_v1_no_commitments.state_diff_commitment.is_none());
assert!(header_v1_no_commitments.event_commitment.is_none());
assert!(header_v1_no_commitments.n_transactions.is_none());
assert!(header_v1_no_commitments.n_events.is_none());
assert!(header_current_no_commitments.is_some());
let header_current_no_commitments = header_current_no_commitments.unwrap();
assert!(header_current_no_commitments.state_diff_commitment.is_none());
assert!(header_current_no_commitments.event_commitment.is_none());
assert!(header_current_no_commitments.n_transactions.is_none());
assert!(header_current_no_commitments.n_events.is_none());

let header_v1_with_commitments =
let header_current_with_commitments =
reader.begin_ro_txn().unwrap().get_block_header(BlockNumber(1)).unwrap();
assert!(header_v1_with_commitments.is_some());
let header_v1_with_commitments = header_v1_with_commitments.unwrap();
assert!(header_current_with_commitments.is_some());
let header_current_with_commitments = header_current_with_commitments.unwrap();
// In V0 there is no state_diff_commitment.
assert!(header_v1_with_commitments.state_diff_commitment.is_none());
assert!(header_current_with_commitments.state_diff_commitment.is_none());
assert_eq!(
header_v1_with_commitments.transaction_commitment,
header_current_with_commitments.transaction_commitment,
Some(TransactionCommitment(stark_felt!("0x1")))
);
assert_eq!(
header_v1_with_commitments.event_commitment,
header_current_with_commitments.event_commitment,
Some(EventCommitment(stark_felt!("0x2")))
);
assert_eq!(header_v1_with_commitments.n_transactions, Some(3));
assert_eq!(header_v1_with_commitments.n_events, Some(4));
assert_eq!(header_current_with_commitments.n_transactions, Some(3));
assert_eq!(header_current_with_commitments.n_events, Some(4));
}

#[test]
fn header_v1_to_current() {
let ((reader, mut writer), _dir) = get_test_storage();
// Insert a headers V1 to the db.
let header_v1 = StorageBlockHeaderV1::get_test_instance(&mut get_rng());
writer
.begin_rw_txn()
.unwrap()
.update_starknet_version(&BlockNumber(0), &StarknetVersion::default())
.unwrap()
.commit()
.unwrap();

write_old_headers::<VersionWrapper<StorageBlockHeaderV1, 1>>(
&mut writer,
&reader,
&[&header_v1],
);

// Read the headers, expecting to get the V1 version via the migration.
let header_current = reader.begin_ro_txn().unwrap().get_block_header(BlockNumber(0)).unwrap();
let header_current = header_current.unwrap();
assert!(header_current.receipt_commitment.is_none());
assert!(header_current.state_diff_length.is_none());
assert_eq!(header_current.block_hash, header_v1.block_hash);
assert_eq!(header_current.parent_hash, header_v1.parent_hash);
assert_eq!(header_current.block_number, header_v1.block_number);
assert_eq!(header_current.l1_gas_price, header_v1.l1_gas_price);
assert_eq!(header_current.l1_data_gas_price, header_v1.l1_data_gas_price);
assert_eq!(header_current.state_root, header_v1.state_root);
assert_eq!(header_current.sequencer, header_v1.sequencer);
assert_eq!(header_current.timestamp, header_v1.timestamp);
assert_eq!(header_current.l1_da_mode, header_v1.l1_da_mode);
assert_eq!(header_current.state_diff_commitment, header_v1.state_diff_commitment);
assert_eq!(header_current.transaction_commitment, header_v1.transaction_commitment);
assert_eq!(header_current.event_commitment, header_v1.event_commitment);
assert_eq!(header_current.n_transactions, header_v1.n_transactions);
assert_eq!(header_current.n_events, header_v1.n_events);
}
21 changes: 19 additions & 2 deletions crates/papyrus_storage/src/deprecated/serializers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ use starknet_api::core::{
EventCommitment,
GlobalRoot,
SequencerContractAddress,
StateDiffCommitment,
TransactionCommitment,
};
use starknet_api::data_availability::L1DataAvailabilityMode;

use crate::db::serialization::{StorageSerde, StorageSerdeError};
use crate::deprecated::migrations::StorageBlockHeaderV0;
use crate::deprecated::migrations::{StorageBlockHeaderV0, StorageBlockHeaderV1};
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 struct StorageBlockHeaderV0 {
pub block_hash: BlockHash,
pub parent_hash: BlockHash,
pub block_number: BlockNumber,
Expand All @@ -29,4 +30,20 @@ auto_storage_serde! {
pub n_transactions: usize,
pub n_events: usize,
}
pub struct StorageBlockHeaderV1 {
pub block_hash: BlockHash,
pub parent_hash: BlockHash,
pub block_number: BlockNumber,
pub l1_gas_price: GasPricePerToken,
pub l1_data_gas_price: GasPricePerToken,
pub state_root: GlobalRoot,
pub sequencer: SequencerContractAddress,
pub timestamp: BlockTimestamp,
pub l1_da_mode: L1DataAvailabilityMode,
pub state_diff_commitment: Option<StateDiffCommitment>,
pub transaction_commitment: Option<TransactionCommitment>,
pub event_commitment: Option<EventCommitment>,
pub n_transactions: Option<usize>,
pub n_events: Option<usize>,
}
}
19 changes: 18 additions & 1 deletion crates/papyrus_storage/src/deprecated/test_instances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use starknet_api::core::{
EventCommitment,
GlobalRoot,
SequencerContractAddress,
StateDiffCommitment,
TransactionCommitment,
};
use starknet_api::data_availability::L1DataAvailabilityMode;
use test_utils::{auto_impl_get_test_instance, GetTestInstance};

use crate::deprecated::migrations::StorageBlockHeaderV0;
use crate::deprecated::migrations::{StorageBlockHeaderV0, StorageBlockHeaderV1};

auto_impl_get_test_instance! {
pub struct StorageBlockHeaderV0 {
Expand All @@ -26,4 +27,20 @@ auto_impl_get_test_instance! {
pub n_transactions: usize,
pub n_events: usize,
}
pub struct StorageBlockHeaderV1 {
pub block_hash: BlockHash,
pub parent_hash: BlockHash,
pub block_number: BlockNumber,
pub l1_gas_price: GasPricePerToken,
pub l1_data_gas_price: GasPricePerToken,
pub state_root: GlobalRoot,
pub sequencer: SequencerContractAddress,
pub timestamp: BlockTimestamp,
pub l1_da_mode: L1DataAvailabilityMode,
pub state_diff_commitment: Option<StateDiffCommitment>,
pub transaction_commitment: Option<TransactionCommitment>,
pub event_commitment: Option<EventCommitment>,
pub n_transactions: Option<usize>,
pub n_events: Option<usize>,
}
}
Loading

0 comments on commit a74c8d2

Please sign in to comment.