Skip to content

Commit 849fe29

Browse files
yoavGrsclaude
andcommitted
apollo_storage: add helper to build declared class component hashes for a block
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 54ab075 commit 849fe29

1 file changed

Lines changed: 50 additions & 2 deletions

File tree

crates/apollo_storage/src/class.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,23 @@
6868
#[path = "class_test.rs"]
6969
mod class_test;
7070

71+
use std::collections::HashMap;
72+
7173
use apollo_proc_macros::latency_histogram;
7274
use starknet_api::block::BlockNumber;
7375
use starknet_api::core::ClassHash;
7476
use starknet_api::deprecated_contract_class::ContractClass as DeprecatedContractClass;
75-
use starknet_api::state::SierraContractClass;
77+
use starknet_api::state::{ContractClassComponentHashes, SierraContractClass};
7678

7779
use crate::db::table_types::Table;
7880
use crate::db::RW;
7981
use crate::mmap_file::LocationInFile;
80-
use crate::state::{DeclaredClassesTable, DeprecatedDeclaredClassesTable, FileOffsetTable};
82+
use crate::state::{
83+
DeclaredClassesTable,
84+
DeprecatedDeclaredClassesTable,
85+
FileOffsetTable,
86+
StateStorageReader,
87+
};
8188
use crate::{
8289
DbTransaction,
8390
FileHandlers,
@@ -87,6 +94,8 @@ use crate::{
8794
StorageError,
8895
StorageResult,
8996
StorageTransaction,
97+
StorageTxn,
98+
TransactionKind,
9099
};
91100

92101
/// Interface for reading data related to classes or deprecated classes.
@@ -205,6 +214,45 @@ impl<T: StorageTransaction> ClassStorageReader for T {
205214
}
206215
}
207216

217+
/// Builds the map from each Cairo 1 class hash declared in `block_number` to its contract class
218+
/// component hashes, matching the `declared_class_hash_to_component_hashes` field of the OS block
219+
/// input. This excludes classes whose compiled class hash was merely migrated in `block_number`.
220+
pub fn get_declared_class_hash_to_component_hashes<Mode: TransactionKind>(
221+
txn: &StorageTxn<'_, Mode>,
222+
block_number: BlockNumber,
223+
) -> StorageResult<HashMap<ClassHash, ContractClassComponentHashes>> {
224+
let state_diff = txn.get_state_diff(block_number)?.ok_or(StorageError::MissingObject {
225+
object_name: "state diff".to_string(),
226+
height: block_number,
227+
})?;
228+
let state_reader = txn.get_state_reader()?;
229+
230+
let mut declared_sierra_classes = Vec::new();
231+
// Read all Sierra classes declared in this block from storage.
232+
for class_hash in state_diff.class_hash_to_compiled_class_hash.keys() {
233+
// `class_hash_to_compiled_class_hash` merges fresh declarations with migrated classes,
234+
// while `declared_classes_block` records each class's original declaration block.
235+
// Only classes first declared in this block contribute component hashes.
236+
if state_reader.get_class_definition_block_number(class_hash)? != Some(block_number) {
237+
// A migrated class that was declared in an earlier block.
238+
continue;
239+
}
240+
let sierra_class = txn.get_class(class_hash)?.ok_or(StorageError::DBInconsistency {
241+
msg: format!(
242+
"Class {class_hash} is declared in block {} but its Sierra class is missing from \
243+
storage.",
244+
block_number.0
245+
),
246+
})?;
247+
declared_sierra_classes.push((*class_hash, sierra_class));
248+
}
249+
250+
Ok(declared_sierra_classes
251+
.into_iter()
252+
.map(|(class_hash, sierra_class)| (class_hash, sierra_class.get_component_hashes()))
253+
.collect())
254+
}
255+
208256
impl<T: StorageTransaction<Mode = RW>> ClassStorageWriter for T {
209257
#[latency_histogram("storage_append_classes_latency_seconds", false)]
210258
fn append_classes(

0 commit comments

Comments
 (0)