From 56f4eff4be5c79f82b2aa71e2f67eda24c6b0fb7 Mon Sep 17 00:00:00 2001 From: yoavGrs <97383386+yoavGrs@users.noreply.github.com> Date: Thu, 28 Sep 2023 17:27:30 +0300 Subject: [PATCH] feat(common): calculate block body commitments (#1203) --- Cargo.lock | 54 +++----- Cargo.toml | 3 + .../papyrus_common/resources/block_hash.json | 8 +- .../resources/deprecated_block_hash_v0.json | 10 +- .../resources/deprecated_block_hash_v1.json | 10 +- .../deprecated_block_hash_v1_no_events.json | 10 +- .../resources/deprecated_block_hash_v2.json | 10 +- crates/papyrus_common/src/block_hash.rs | 126 ++++++++++-------- crates/papyrus_common/src/block_hash_test.rs | 12 +- crates/papyrus_rpc/src/v0_3_0/api/test.rs | 2 + crates/papyrus_rpc/src/v0_4_0/api/test.rs | 2 + crates/papyrus_storage/src/serializers.rs | 2 + .../src/sources/central_sync_test.rs | 10 +- crates/starknet_client/Cargo.toml | 1 + .../src/reader/objects/block.rs | 10 +- crates/test_utils/src/lib.rs | 4 + 16 files changed, 171 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c9178505a..b582c19721 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] @@ -1596,16 +1596,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -3164,9 +3154,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.31.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0770b0a3d4c70567f0d58331f3088b0e4c4f56c9b8d764efe654b4a5d46de3a" +checksum = "a3e02c584f4595792d09509a94cdb92a3cef7592b1eb2d9877ee6f527062d0ea" dependencies = [ "console", "lazy_static", @@ -3215,7 +3205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.13", + "rustix 0.38.14", "windows-sys 0.48.0", ] @@ -5094,9 +5084,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -5104,14 +5094,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -5347,9 +5335,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.13" +version = "0.38.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" dependencies = [ "bitflags 2.4.0", "errno 0.3.3", @@ -5830,9 +5818,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smol_str" @@ -5993,8 +5981,7 @@ dependencies = [ [[package]] name = "starknet_api" version = "0.5.0-rc1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f70f6673391b3f3624651e8692f4e76aab9194abb3d3feeb3a07a6b0546639ee" +source = "git+https://github.com/starkware-libs/starknet-api?rev=1526a40921762641a39872643c53305c3e959ab2#1526a40921762641a39872643c53305c3e959ab2" dependencies = [ "cairo-lang-starknet", "derive_more", @@ -6022,6 +6009,7 @@ dependencies = [ "mockall", "mockito", "os_info", + "papyrus_common", "papyrus_config", "pretty_assertions", "rand", @@ -6184,7 +6172,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.13", + "rustix 0.38.14", "windows-sys 0.48.0", ] @@ -6478,9 +6466,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -6944,7 +6932,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.13", + "rustix 0.38.14", ] [[package]] @@ -6965,9 +6953,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] diff --git a/Cargo.toml b/Cargo.toml index 66a4154b9d..6958e11d7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -101,3 +101,6 @@ tracing-subscriber = "0.3.16" tower = "0.4" url = "2.2.2" validator = "0.12" + +[patch.crates-io] +starknet_api = { git = "https://github.com/starkware-libs/starknet-api", rev = "1526a40921762641a39872643c53305c3e959ab2" } diff --git a/crates/papyrus_common/resources/block_hash.json b/crates/papyrus_common/resources/block_hash.json index e5c6df4edd..2b69ea1a55 100644 --- a/crates/papyrus_common/resources/block_hash.json +++ b/crates/papyrus_common/resources/block_hash.json @@ -6,7 +6,9 @@ "gas_price": "0x41ab3fdb5", "state_root": "0x6c4171ece740d153a40106b18545f147d62c513a9cb67eb7b06f83a2508b3a4", "sequencer": "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", - "timestamp": 1693484880 + "timestamp": 1693484880, + "n_transactions": 332, + "n_events": 1561 }, "body": { "transactions": [ @@ -31910,5 +31912,9 @@ "0x3d441f44150eb5cdc78f15403c9b9e30f967897112f896da00c84bffe3b26c0", "0x600f222f797801af5de701de7e240790c6b0bac312ec2d6c3f298381299fe38" ] + }, + "commitments": { + "transactions_commitment": "0x0", + "events_commitment": "0x0" } } diff --git a/crates/papyrus_common/resources/deprecated_block_hash_v0.json b/crates/papyrus_common/resources/deprecated_block_hash_v0.json index e3dee65826..f6010cd32d 100644 --- a/crates/papyrus_common/resources/deprecated_block_hash_v0.json +++ b/crates/papyrus_common/resources/deprecated_block_hash_v0.json @@ -6,7 +6,9 @@ "gas_price": "0x0", "state_root": "0x3810b7805897aff09b3bba1d41fe2eb21a3853d98553794928684d1089f25cf", "sequencer": "0x0", - "timestamp": 1643150436 + "timestamp": 1643150436, + "n_transactions": 31, + "n_events": 0 }, "body": { "transactions": [ @@ -777,5 +779,9 @@ "0x23dea100ac41500d28bb9426a08385c0af0f4546ff9abe8187c9446c5c23539", "0x2cf9ed8ec288e35a2939ffc60be5edef318251a74af6f8ed85fb44aa2ec218f" ] + }, + "commitments": { + "transactions_commitment": "0x0", + "events_commitment": "0x0" } -} \ No newline at end of file +} diff --git a/crates/papyrus_common/resources/deprecated_block_hash_v1.json b/crates/papyrus_common/resources/deprecated_block_hash_v1.json index 5d0ddfa966..7bee5afc0f 100644 --- a/crates/papyrus_common/resources/deprecated_block_hash_v1.json +++ b/crates/papyrus_common/resources/deprecated_block_hash_v1.json @@ -6,7 +6,9 @@ "gas_price": "0x0", "state_root": "0x46a99896768700c5848dbc53a6048e554884ea6b0e881ba2f9a3d4e3096feb6", "sequencer": "0x0", - "timestamp": 1643463800 + "timestamp": 1643463800, + "n_transactions": 44, + "n_events": 1 }, "body": { "transactions": [ @@ -1259,5 +1261,9 @@ "0x6b0559b7931b5e47492c6a9df64559fb34b4117c7e26a5e12875fa49f9eded", "0x405d74766b46c3509843514f59a2b0fddd9c3ab193e0accd1f3168be36a2f0f" ] + }, + "commitments": { + "transactions_commitment": "0x0", + "events_commitment": "0x0" } -} \ No newline at end of file +} diff --git a/crates/papyrus_common/resources/deprecated_block_hash_v1_no_events.json b/crates/papyrus_common/resources/deprecated_block_hash_v1_no_events.json index 297c906ea0..39617f928b 100644 --- a/crates/papyrus_common/resources/deprecated_block_hash_v1_no_events.json +++ b/crates/papyrus_common/resources/deprecated_block_hash_v1_no_events.json @@ -6,7 +6,9 @@ "gas_price": "0x0", "state_root": "0x5a5f26ce761d20ac9dfdc3a009b6adeaabac74b97de38c7633af690efd9b175", "sequencer": "0x0", - "timestamp": 1643609156 + "timestamp": 1643609156, + "n_transactions": 111, + "n_events": 0 }, "body": { "transactions": [ @@ -3169,5 +3171,9 @@ "0x912170b6c5b0454e66fb8dab8da03f8cd9a32acfe9df6690d05dcdca19e52", "0x4822394e8699126997fbdc7d4427926e01876e19970fadbfa0307653ec53e47" ] + }, + "commitments": { + "transactions_commitment": "0x0", + "events_commitment": "0x0" } -} \ No newline at end of file +} diff --git a/crates/papyrus_common/resources/deprecated_block_hash_v2.json b/crates/papyrus_common/resources/deprecated_block_hash_v2.json index fdce6f8fd2..041c2cd2fa 100644 --- a/crates/papyrus_common/resources/deprecated_block_hash_v2.json +++ b/crates/papyrus_common/resources/deprecated_block_hash_v2.json @@ -6,7 +6,9 @@ "gas_price": "0x38ae2e27b", "state_root": "0x67d06ffd8b41a4a4d4bbe0b6f991760e365aa499add0180b7ee52c0d6b67843", "sequencer": "0x0", - "timestamp": 1652680274 + "timestamp": 1652680274, + "n_transactions": 171, + "n_events": 36 }, "body": { "transactions": [ @@ -4377,5 +4379,9 @@ "0x445cbfe77407c2092e2906b1e0319dac9cde3a27d7b4b1108cbeb8ba5bfd4a", "0x521761e9ed44deb91b85e46f2f93b35fca588784424fecda7d44d14b70a2939" ] + }, + "commitments": { + "transactions_commitment": "0x0", + "events_commitment": "0x0" } -} \ No newline at end of file +} diff --git a/crates/papyrus_common/src/block_hash.rs b/crates/papyrus_common/src/block_hash.rs index 82f849275c..42cc60121e 100644 --- a/crates/papyrus_common/src/block_hash.rs +++ b/crates/papyrus_common/src/block_hash.rs @@ -4,7 +4,7 @@ mod block_hash_test; use std::iter::zip; -use starknet_api::block::{Block, BlockBody}; +use starknet_api::block::{Block, BlockBody, BlockBodyCommitments, BlockHeader}; use starknet_api::core::ChainId; use starknet_api::hash::{pedersen_hash, StarkFelt, StarkHash}; use starknet_api::transaction::{ @@ -19,7 +19,7 @@ use starknet_api::StarknetApiError; use crate::patricia_hash_tree::calculate_root; use crate::transaction_hash::{ascii_as_felt, PedersenHashChain, ZERO}; -#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] enum BlockHashVersion { V0, V1, @@ -27,75 +27,107 @@ enum BlockHashVersion { V3, } -/// Validates hash of a starknet block. +/// Validate hash of a starknet block. /// A hash is valid if it is the result of one of the hash functions that were ever used in /// Starknet. pub fn validate_block_hash(block: &Block, chain_id: &ChainId) -> Result { for version in [BlockHashVersion::V3, BlockHashVersion::V2, BlockHashVersion::V1, BlockHashVersion::V0] { - if calculate_block_hash_by_version(block, version, chain_id)? == block.header.block_hash.0 { + if calculate_block_hash_by_version(&block.header, &block.commitments, version, chain_id)? + == block.header.block_hash.0 + { return Ok(true); } } Ok(false) } -// Calculates hash of a starknet block by version, ignoring the block hash field in the given block. +// Calculate hash of a starknet block by version, ignoring the block hash field in the given block +// header. fn calculate_block_hash_by_version( - block: &Block, + block_header: &BlockHeader, + block_commitments: &BlockBodyCommitments, version: BlockHashVersion, chain_id: &ChainId, ) -> Result { - let (n_transactions, transactions_patricia_root) = - get_transactions_hash_data(&block.body, &version)?; - - let (n_events, events_patricia_root) = - get_events_hash_data(&block.body.transaction_outputs, &version); + let sequencer = if version == BlockHashVersion::V2 { + get_chain_sequencer_address(chain_id) + } else { + block_header.sequencer.0.key().to_owned() + }; Ok(PedersenHashChain::new() - .chain(&block.header.block_number.0.into()) - .chain(&block.header.state_root.0) - .chain_if_else( - &get_chain_sequencer_address(chain_id), - block.header.sequencer.0.key(), - version == BlockHashVersion::V2, - ) - .chain_if_else(&block.header.timestamp.0.into(), &ZERO, version >= BlockHashVersion::V1) - .chain(&n_transactions) - .chain(&transactions_patricia_root) - .chain(&n_events) - .chain(&events_patricia_root) - .chain(&ZERO) // Not implemented Element. - .chain(&ZERO) // Not implemented Element. + .chain(&block_header.block_number.0.into()) + .chain(&block_header.state_root.0) + .chain(&sequencer) + .chain_if_else(&block_header.timestamp.0.into(), &ZERO, version >= BlockHashVersion::V1) + .chain(&block_header.n_transactions.into()) + .chain(&block_commitments.transactions_commitment) + .chain_if_else(&block_header.n_events.into(), &ZERO, version >= BlockHashVersion::V1) + .chain_if_else(&block_commitments.events_commitment, &ZERO, version >= BlockHashVersion::V1) + .chain(&ZERO) // Not implemented element. + .chain(&ZERO) // Not implemented element. .chain_if(&ascii_as_felt(chain_id.0.as_str())?, version == BlockHashVersion::V0) - .chain(&block.header.parent_hash.0) + .chain(&block_header.parent_hash.0) .get_hash()) } -// Returns the number of the transactions, and the Patricia root of the transactions. -fn get_transactions_hash_data( +/// Calculate the commitments according to the fittest block hash version. However, the result does +/// not guarantee that the block hash is valid. +pub fn calculate_block_commitments( + block_header: &BlockHeader, + block_body: &BlockBody, +) -> Result { + let events_commitment = get_events_commitment(&block_body.transaction_outputs); + + // Try to reach the given block hash by v3 transactions commitment. + let v3_transactions_commitment = get_transactions_commitment(block_body, true)?; + let v3_block_commitments = BlockBodyCommitments { + transactions_commitment: v3_transactions_commitment, + events_commitment, + }; + let v3_block_hash = calculate_block_hash_by_version( + block_header, + &v3_block_commitments, + BlockHashVersion::V3, + // The chain id is not used for version 3. + &ChainId("".to_owned()), + )?; + if v3_block_hash == block_header.block_hash.0 { + return Ok(v3_block_commitments); + } + + // Assume we can reach the given block hash by deprecated transactions commitment with some + // deprecated block hash versions. + let deprecated_transactions_commitment = get_transactions_commitment(block_body, false)?; + Ok(BlockBodyCommitments { + transactions_commitment: deprecated_transactions_commitment, + events_commitment, + }) +} + +// Return the Patricia root of the transactions. +fn get_transactions_commitment( block_body: &BlockBody, - version: &BlockHashVersion, -) -> Result<(StarkFelt, StarkFelt), StarknetApiError> { - let n_transactions = usize_into_felt(block_body.transactions.len()); + is_version_3_and_up: bool, +) -> Result { let transaction_patricia_leaves = zip(block_body.transactions.iter(), block_body.transaction_hashes.iter()) .map(|(transaction, transaction_hash)| { - get_transaction_leaf(transaction, transaction_hash, version) + get_transaction_leaf(transaction, transaction_hash, is_version_3_and_up) }) .collect::, _>>()?; - let transactions_patricia_root = calculate_root(transaction_patricia_leaves); - Ok((n_transactions, transactions_patricia_root)) + Ok(calculate_root(transaction_patricia_leaves)) } -// Returns a Patricia leaf value for a transaction. +// Return a Patricia leaf value for a transaction. fn get_transaction_leaf( transaction: &Transaction, transaction_hash: &TransactionHash, - version: &BlockHashVersion, + is_version_3_and_up: bool, ) -> Result { - let signature = if version >= &BlockHashVersion::V3 { + let signature = if is_version_3_and_up { get_transaction_signature(transaction) } else { get_signature_only_from_invoke(transaction) @@ -125,20 +157,14 @@ fn get_signature_only_from_invoke(transaction: &Transaction) -> Vec { if let Transaction::Invoke(invoke) = transaction { invoke.signature().0 } else { vec![] } } -// Returns the number of the events, and the Patricia root of the events. -fn get_events_hash_data( - transaction_outputs: &[TransactionOutput], - version: &BlockHashVersion, -) -> (StarkFelt, StarkFelt) { - if version < &BlockHashVersion::V1 { - return (*ZERO, *ZERO); - } +// Return the Patricia root of the events. +fn get_events_commitment(transaction_outputs: &[TransactionOutput]) -> StarkFelt { let event_patricia_leaves: Vec<_> = transaction_outputs.iter().flat_map(|output| output.events()).map(get_event_leaf).collect(); - (usize_into_felt(event_patricia_leaves.len()), calculate_root(event_patricia_leaves)) + calculate_root(event_patricia_leaves) } -// Returns a Patricia leaf value for an event. +// Return a Patricia leaf value for an event. fn get_event_leaf(event: &Event) -> StarkHash { let event_keys: Vec<_> = event.content.keys.iter().map(|key| key.0).collect(); PedersenHashChain::new() @@ -150,7 +176,7 @@ fn get_event_leaf(event: &Event) -> StarkHash { // The fixed sequencer addresses of the chains that have historic blocks with block hash version 2. fn get_chain_sequencer_address(chain_id: &ChainId) -> StarkHash { - match chain_id.to_string().as_str() { + match chain_id.0.as_str() { "SN_MAIN" => StarkHash::try_from( "0x021f4b90b0377c82bf330b7b5295820769e72d79d8acd0effa0ebde6e9988bc5", ) @@ -160,7 +186,3 @@ fn get_chain_sequencer_address(chain_id: &ChainId) -> StarkHash { _ => unimplemented!("Sequencer address for chain"), } } - -fn usize_into_felt(u: usize) -> StarkFelt { - u128::try_from(u).expect("Expect at most 128 bits").into() -} diff --git a/crates/papyrus_common/src/block_hash_test.rs b/crates/papyrus_common/src/block_hash_test.rs index a475bfabe5..10fba9769b 100644 --- a/crates/papyrus_common/src/block_hash_test.rs +++ b/crates/papyrus_common/src/block_hash_test.rs @@ -3,12 +3,18 @@ use starknet_api::core::ChainId; use test_utils::read_json_file; use super::calculate_block_hash_by_version; -use crate::block_hash::BlockHashVersion; +use crate::block_hash::{calculate_block_commitments, BlockHashVersion}; fn validate_block_hash_util(file_name: &str, version: BlockHashVersion) -> bool { let chain_id = ChainId("SN_MAIN".to_owned()); - let block: Block = serde_json::from_value(read_json_file(file_name)).unwrap(); - let calculated_hash = calculate_block_hash_by_version(&block, version, &chain_id).unwrap(); + // The commitments are calculated according the content of the block, ignoring the declared + // commitments in the input file. + let mut block: Block = serde_json::from_value(read_json_file(file_name)).unwrap(); + block.commitments = calculate_block_commitments(&block.header, &block.body).unwrap(); + + let calculated_hash = + calculate_block_hash_by_version(&block.header, &block.commitments, version, &chain_id) + .unwrap(); calculated_hash == block.header.block_hash.0 } diff --git a/crates/papyrus_rpc/src/v0_3_0/api/test.rs b/crates/papyrus_rpc/src/v0_3_0/api/test.rs index 7895cecf53..1606315dbe 100644 --- a/crates/papyrus_rpc/src/v0_3_0/api/test.rs +++ b/crates/papyrus_rpc/src/v0_3_0/api/test.rs @@ -1693,6 +1693,7 @@ async fn get_events_no_blocks_in_filter() { ..BlockHeader::default() }, body: get_test_body(1, None, None, None), + ..Default::default() }; storage_writer .begin_rw_txn() @@ -1780,6 +1781,7 @@ async fn serialize_returns_valid_json() { ..BlockHeader::default() }, body: get_test_body(5, Some(5), None, None), + ..Default::default() }; let mut state_diff = StateDiff::get_test_instance(&mut rng); // In the test instance both declared_classes and deprecated_declared_classes have an entry diff --git a/crates/papyrus_rpc/src/v0_4_0/api/test.rs b/crates/papyrus_rpc/src/v0_4_0/api/test.rs index 7ff57c1e9e..58d6280d85 100644 --- a/crates/papyrus_rpc/src/v0_4_0/api/test.rs +++ b/crates/papyrus_rpc/src/v0_4_0/api/test.rs @@ -1604,6 +1604,7 @@ async fn get_events_no_blocks_in_filter() { ..BlockHeader::default() }, body: get_test_body(1, None, None, None), + ..Default::default() }; storage_writer .begin_rw_txn() @@ -1687,6 +1688,7 @@ async fn serialize_returns_valid_json() { ..BlockHeader::default() }, body: get_test_body(5, Some(5), None, None), + ..Default::default() }; let mut state_diff = StateDiff::get_test_instance(&mut rng); // In the test instance both declared_classes and deprecated_declared_classes have an entry diff --git a/crates/papyrus_storage/src/serializers.rs b/crates/papyrus_storage/src/serializers.rs index 4577757f12..1a72b0d20f 100644 --- a/crates/papyrus_storage/src/serializers.rs +++ b/crates/papyrus_storage/src/serializers.rs @@ -138,6 +138,8 @@ auto_storage_serde! { pub state_root: GlobalRoot, pub sequencer: ContractAddress, pub timestamp: BlockTimestamp, + pub n_transactions: u64, + pub n_events: u64, } pub struct BlockNumber(pub u64); pub enum BlockStatus { diff --git a/crates/papyrus_sync/src/sources/central_sync_test.rs b/crates/papyrus_sync/src/sources/central_sync_test.rs index ef6e9599b8..c6f69ca467 100644 --- a/crates/papyrus_sync/src/sources/central_sync_test.rs +++ b/crates/papyrus_sync/src/sources/central_sync_test.rs @@ -12,7 +12,7 @@ use papyrus_storage::header::{HeaderStorageReader, StarknetVersion}; use papyrus_storage::state::StateStorageReader; use papyrus_storage::test_utils::get_test_storage; use papyrus_storage::{StorageError, StorageReader, StorageWriter}; -use starknet_api::block::{Block, BlockBody, BlockHash, BlockHeader, BlockNumber}; +use starknet_api::block::{Block, BlockHash, BlockHeader, BlockNumber}; use starknet_api::hash::StarkFelt; use starknet_api::stark_felt; use starknet_api::state::StateDiff; @@ -166,7 +166,7 @@ async fn sync_happy_flow() { parent_hash: create_block_hash(block_number.prev().unwrap_or_default(), false), ..BlockHeader::default() }; - yield Ok((block_number, Block { header, body: BlockBody::default() }, StarknetVersion(STARKNET_VERSION.to_string()))); + yield Ok((block_number, Block { header, ..Default::default() }, StarknetVersion(STARKNET_VERSION.to_string()))); } } .boxed(); @@ -447,7 +447,7 @@ async fn sync_with_revert() { block_hash: create_block_hash(i, false), parent_hash: create_block_hash(i.prev().unwrap_or_default(), false), ..BlockHeader::default()}; - yield Ok((i,Block{header, body: BlockBody::default()}, StarknetVersion(STARKNET_VERSION.to_string()))); + yield Ok((i,Block{header, ..Default::default()}, StarknetVersion(STARKNET_VERSION.to_string()))); } } .boxed(), @@ -461,7 +461,7 @@ async fn sync_with_revert() { block_hash: create_block_hash(i, i.0 >= CHAIN_FORK_BLOCK_NUMBER), parent_hash: create_block_hash(i.prev().unwrap_or_default(), i.0 > CHAIN_FORK_BLOCK_NUMBER), ..BlockHeader::default()}; - yield Ok((i, Block{header, body: BlockBody::default()}, StarknetVersion(STARKNET_VERSION.to_string()))); + yield Ok((i, Block{header, ..Default::default()}, StarknetVersion(STARKNET_VERSION.to_string()))); } } .boxed(), @@ -544,7 +544,7 @@ async fn test_unrecoverable_sync_error_flow() { }; yield Ok(( BLOCK_NUMBER, - Block { header, body: BlockBody::default()}, + Block { header, ..Default::default()}, StarknetVersion(STARKNET_VERSION.to_string()), )); } diff --git a/crates/starknet_client/Cargo.toml b/crates/starknet_client/Cargo.toml index 807c84ddf8..0c914f3b47 100644 --- a/crates/starknet_client/Cargo.toml +++ b/crates/starknet_client/Cargo.toml @@ -23,6 +23,7 @@ http.workspace = true indexmap = { workspace = true, features = ["serde"] } mockall = { workspace = true, optional = true } os_info.workspace = true +papyrus_common = { path = "../papyrus_common", version = "0.0.5" } papyrus_config = { path = "../papyrus_config", version = "0.0.5" } rand = { workspace = true, optional = true } rand_chacha = { workspace = true, optional = true } diff --git a/crates/starknet_client/src/reader/objects/block.rs b/crates/starknet_client/src/reader/objects/block.rs index 47c5045e8a..46cd7255d6 100644 --- a/crates/starknet_client/src/reader/objects/block.rs +++ b/crates/starknet_client/src/reader/objects/block.rs @@ -4,6 +4,7 @@ mod block_test; use std::ops::Index; +use papyrus_common::block_hash::calculate_block_commitments; use serde::{Deserialize, Serialize}; use starknet_api::block::{ Block as starknet_api_block, @@ -184,6 +185,8 @@ impl Block { .map(starknet_api::transaction::Transaction::try_from) .collect::>()?; + let n_events = transaction_outputs.iter().flat_map(|output| output.events()).count(); + // Get the header. let header = starknet_api::block::BlockHeader { block_hash: self.block_hash, @@ -193,6 +196,9 @@ impl Block { state_root: self.state_root, sequencer: self.sequencer_address, timestamp: self.timestamp, + n_transactions: u64::try_from(transactions.len()) + .expect("usize to u64 conversion shouldn't fail"), + n_events: u64::try_from(n_events).expect("usize to u64 conversion shouldn't fail"), }; let body = starknet_api::block::BlockBody { @@ -201,7 +207,9 @@ impl Block { transaction_hashes, }; - Ok((starknet_api_block { header, body }, self.starknet_version)) + let commitments = calculate_block_commitments(&header, &body)?; + + Ok((starknet_api_block { header, body, commitments }, self.starknet_version)) } } diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index f103fe5768..90c9908a4a 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs @@ -38,6 +38,7 @@ use serde::{Deserialize, Serialize}; use starknet_api::block::{ Block, BlockBody, + BlockBodyCommitments, BlockHash, BlockHeader, BlockNumber, @@ -231,6 +232,7 @@ fn get_rand_test_block_with_events( from_addresses, keys, ), + commitments: BlockBodyCommitments::default(), } } @@ -388,6 +390,8 @@ auto_impl_get_test_instance! { pub state_root: GlobalRoot, pub sequencer: ContractAddress, pub timestamp: BlockTimestamp, + pub n_transactions: u64, + pub n_events: u64, } pub struct BlockNumber(pub u64); pub enum BlockStatus {