Skip to content

Commit 348ca25

Browse files
Merge pull request #13021 from starkware-libs/yonatan/merge-main-v0.14.1-committer-into-main-v0.14.2-1772610549
Merge main-v0.14.1-committer into main-v0.14.2
2 parents 7abbcbc + 40d5be0 commit 348ca25

107 files changed

Lines changed: 4873 additions & 1036 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/apollo_batcher/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ cairo-vm.workspace = true
3838
chrono.workspace = true
3939
futures.workspace = true
4040
indexmap.workspace = true
41+
lru.workspace = true
4142
reqwest = { workspace = true, features = ["json"] }
4243
serde.workspace = true
4344
starknet_api.workspace = true

crates/apollo_batcher/src/batcher.rs

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ use indexmap::{IndexMap, IndexSet};
7171
#[cfg(test)]
7272
use mockall::automock;
7373
use starknet_api::block::{BlockHash, BlockNumber, UnixTimestamp};
74-
use starknet_api::block_hash::block_hash_calculator::PartialBlockHashComponents;
75-
use starknet_api::block_hash::state_diff_hash::calculate_state_diff_hash;
74+
use starknet_api::block_hash::block_hash_calculator::{
75+
PartialBlockHash,
76+
PartialBlockHashComponents,
77+
};
7678
use starknet_api::consensus_transaction::InternalConsensusTransaction;
7779
use starknet_api::core::{ContractAddress, GlobalRoot, Nonce, StateDiffCommitment};
7880
use starknet_api::state::{StateNumber, ThinStateDiff};
@@ -849,7 +851,25 @@ impl Batcher {
849851
);
850852
trace!("Rejected transactions: {:#?}, State diff: {:#?}.", rejected_tx_hashes, state_diff);
851853

852-
let state_diff_commitment = calculate_state_diff_hash(&state_diff);
854+
// Proposal commitment is the the partial block hash when it's available, and None
855+
// otherwise. The commitment is computed here to set the prev_proposal_commitment cache. As
856+
// this cache is only used for blocks obtained through the decision_reached flow, it can
857+
// be None for old (pre 0.13.2) blocks.
858+
let proposal_commitment = match &storage_commitment_block_hash {
859+
StorageCommitmentBlockHash::Partial(components) => Some((
860+
height,
861+
ProposalCommitment {
862+
partial_block_hash: PartialBlockHash::from_partial_block_hash_components(
863+
components,
864+
)
865+
.map_err(|e| {
866+
error!("Failed to compute partial block hash: {}", e);
867+
BatcherError::InternalError
868+
})?,
869+
},
870+
)),
871+
StorageCommitmentBlockHash::ParentHash(_) => None,
872+
};
853873

854874
// Commit the proposal to the storage.
855875
self.storage_writer
@@ -859,8 +879,8 @@ impl Batcher {
859879
BatcherError::InternalError
860880
})?;
861881
info!("Successfully committed proposal for block {} to storage.", height);
862-
self.prev_proposal_commitment =
863-
Some((height, ProposalCommitment { state_diff_commitment }));
882+
883+
self.prev_proposal_commitment = proposal_commitment;
864884

865885
// Notify the L1 provider of the new block.
866886
let rejected_l1_handler_tx_hashes = rejected_tx_hashes
@@ -1160,21 +1180,30 @@ impl Batcher {
11601180
Ok(Some(commitment))
11611181
}
11621182
None => {
1163-
// Parent proposal commitment is not cached. Compute it from the stored state diff.
1164-
let state_diff = self
1183+
// Parent proposal commitment is not cached. Read partial block hash
1184+
// components from storage and compute the partial block hash.
1185+
let (_, components) = self
11651186
.storage_reader
1166-
.get_state_diff(prev_height)
1187+
.get_parent_hash_and_partial_block_hash_components(prev_height)
11671188
.map_err(|err| {
11681189
error!(
1169-
"Failed to read state diff for previous height {prev_height}: {}",
1190+
"Failed to read partial block hash components for previous height \
1191+
{prev_height}: {}",
11701192
err
11711193
);
11721194
BatcherError::InternalError
1173-
})?
1174-
.expect("Missing state diff for previous height.");
1195+
})?;
1196+
let components =
1197+
components.expect("Missing partial block hash components for previous height.");
11751198

11761199
Ok(Some(ProposalCommitment {
1177-
state_diff_commitment: calculate_state_diff_hash(&state_diff),
1200+
partial_block_hash: PartialBlockHash::from_partial_block_hash_components(
1201+
&components,
1202+
)
1203+
.map_err(|e| {
1204+
error!("Failed to compute partial block hash: {}", e);
1205+
BatcherError::InternalError
1206+
})?,
11781207
}))
11791208
}
11801209
}
@@ -1249,13 +1278,26 @@ impl Batcher {
12491278

12501279
pub fn get_block_hash(&mut self, block_number: BlockNumber) -> BatcherResult<BlockHash> {
12511280
self.get_commitment_results_and_write_to_storage()?;
1252-
self.storage_reader
1281+
let cache = &mut self.commitment_manager.recent_block_hashes_cache;
1282+
1283+
// Try to get the block hash from the cache.
1284+
if let Some(block_hash) = cache.get(&block_number) {
1285+
return Ok(*block_hash);
1286+
}
1287+
1288+
// If the block hash is not in the cache, fetch it from storage.
1289+
info!("Block hash of block {block_number} not found in cache, fetching from storage.");
1290+
// TODO(Nimrod): Consider adding block-hashes cache misses metric.
1291+
let block_hash = self
1292+
.storage_reader
12531293
.get_block_hash(block_number)
12541294
.map_err(|err| {
12551295
error!("Failed to get block hash from storage: {err}");
12561296
BatcherError::InternalError
12571297
})?
1258-
.ok_or(BatcherError::BlockHashNotFound(block_number))
1298+
.ok_or(BatcherError::BlockHashNotFound(block_number))?;
1299+
cache.put(block_number, block_hash);
1300+
Ok(block_hash)
12591301
}
12601302

12611303
fn get_commitment_results_and_write_to_storage(&mut self) -> BatcherResult<()> {

crates/apollo_batcher/src/batcher_test.rs

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ use starknet_api::block::{
5252
BlockNumber,
5353
StarknetVersion,
5454
};
55-
use starknet_api::block_hash::block_hash_calculator::PartialBlockHashComponents;
56-
use starknet_api::block_hash::state_diff_hash::calculate_state_diff_hash;
55+
use starknet_api::block_hash::block_hash_calculator::{
56+
calculate_block_hash,
57+
PartialBlockHash,
58+
PartialBlockHashComponents,
59+
};
5760
use starknet_api::consensus_transaction::InternalConsensusTransaction;
5861
use starknet_api::core::{ClassHash, CompiledClassHash, GlobalRoot, Nonce};
5962
use starknet_api::state::ThinStateDiff;
@@ -180,7 +183,12 @@ async fn finished_proposal_info() -> FinishedProposalInfo {
180183
}
181184

182185
fn parent_proposal_commitment() -> ProposalCommitment {
183-
ProposalCommitment { state_diff_commitment: calculate_state_diff_hash(&test_state_diff()) }
186+
ProposalCommitment {
187+
partial_block_hash: PartialBlockHash::from_partial_block_hash_components(
188+
&PartialBlockHashComponents::default(),
189+
)
190+
.expect("default partial block hash components are valid"),
191+
}
184192
}
185193

186194
fn validate_block_input(proposal_id: ProposalId) -> ValidateBlockInput {
@@ -1419,6 +1427,14 @@ async fn decision_reached() {
14191427
)
14201428
.returning(|_, _, _| Ok(()));
14211429

1430+
mock_dependencies
1431+
.storage_reader
1432+
.expect_get_parent_hash_and_partial_block_hash_components()
1433+
.with(eq(INITIAL_HEIGHT.prev().unwrap()))
1434+
.returning(|_| {
1435+
Ok((Some(BlockHash::default()), Some(PartialBlockHashComponents::default())))
1436+
});
1437+
14221438
mock_create_builder_for_propose_block(
14231439
&mut mock_dependencies.clients.block_builder_factory,
14241440
vec![],
@@ -1491,6 +1507,14 @@ async fn test_execution_info_order_is_kept() {
14911507
.collect();
14921508
verify_indexed_execution_infos(&execution_infos);
14931509

1510+
mock_dependencies
1511+
.storage_reader
1512+
.expect_get_parent_hash_and_partial_block_hash_components()
1513+
.with(eq(INITIAL_HEIGHT.prev().unwrap()))
1514+
.returning(|_| {
1515+
Ok((Some(BlockHash::default()), Some(PartialBlockHashComponents::default())))
1516+
});
1517+
14941518
mock_create_builder_for_propose_block(
14951519
&mut mock_dependencies.clients.block_builder_factory,
14961520
vec![],
@@ -1576,6 +1600,14 @@ async fn decision_reached_return_success_when_l1_commit_block_fails(
15761600

15771601
mock_dependencies.clients.mempool_client.expect_commit_block().returning(|_| Ok(()));
15781602

1603+
mock_dependencies
1604+
.storage_reader
1605+
.expect_get_parent_hash_and_partial_block_hash_components()
1606+
.with(eq(INITIAL_HEIGHT.prev().unwrap()))
1607+
.returning(|_| {
1608+
Ok((Some(BlockHash::default()), Some(PartialBlockHashComponents::default())))
1609+
});
1610+
15791611
mock_create_builder_for_propose_block(
15801612
&mut mock_dependencies.clients.block_builder_factory,
15811613
vec![],
@@ -1640,32 +1672,27 @@ async fn get_block_hash_not_found() {
16401672
#[tokio::test]
16411673
async fn get_block_hash_after_reading_commitment_results() {
16421674
let mut mock_dependencies = MockDependencies::default();
1643-
let block_hash = BlockHash::default();
1675+
let global_root = GlobalRoot::default();
1676+
let partial_components =
1677+
PartialBlockHashComponents { block_number: INITIAL_HEIGHT, ..Default::default() };
1678+
let parent_hash = BlockHash::default();
1679+
let expected_block_hash =
1680+
calculate_block_hash(&partial_components, global_root, parent_hash).unwrap();
16441681

16451682
// Should be called by the commitment manager when finalizing results and writing them to
16461683
// storage.
16471684
mock_dependencies
16481685
.storage_reader
16491686
.expect_get_parent_hash_and_partial_block_hash_components()
16501687
.with(eq(INITIAL_HEIGHT))
1651-
.returning(|height| {
1652-
let partial = PartialBlockHashComponents { block_number: height, ..Default::default() };
1653-
Ok((Some(BlockHash::default()), Some(partial)))
1654-
});
1688+
.returning(move |_| Ok((Some(parent_hash), Some(partial_components.clone()))));
16551689
mock_dependencies
16561690
.storage_writer
16571691
.expect_set_global_root_and_block_hash()
16581692
.times(1)
1659-
.with(eq(INITIAL_HEIGHT), eq(GlobalRoot::default()), always())
1693+
.with(eq(INITIAL_HEIGHT), eq(global_root), always())
16601694
.returning(|_, _, _| Ok(()));
16611695

1662-
mock_dependencies
1663-
.storage_reader
1664-
.expect_get_block_hash()
1665-
.times(1)
1666-
.with(eq(INITIAL_HEIGHT))
1667-
.returning(move |_| Ok(Some(block_hash)));
1668-
16691696
let mut batcher = create_batcher(mock_dependencies).await;
16701697

16711698
// Send a commitment task directly to the state committer so a result will be available.
@@ -1678,7 +1705,7 @@ async fn get_block_hash_after_reading_commitment_results() {
16781705
wait_for_n_items(&mut batcher.commitment_manager.results_receiver, 1).await;
16791706

16801707
let result = batcher.get_block_hash(INITIAL_HEIGHT);
1681-
assert_eq!(result, Ok(block_hash));
1708+
assert_eq!(result, Ok(expected_block_hash));
16821709
assert_eq!(
16831710
get_number_of_items_in_channel_from_receiver(&batcher.commitment_manager.results_receiver),
16841711
0

0 commit comments

Comments
 (0)