Skip to content

Commit eae40db

Browse files
apollo_gateway: add compute_big_storage_key + cross-language fixture. (#14117)
Renames and relocates the GCS-naming helper per review feedback: * The helper moves from `ProofFacts::big_storage_key` (in `starknet_api`) to a free function `compute_big_storage_key` alongside `GcsProofArchiveWriter` in `apollo_gateway::proof_archive_writer`. The storage-naming contract was coupling a public API type to the GCS layer; the new home keeps it next to the only producer of those keys. * Renames `big_storage_key` → `compute_big_storage_key` since the function does Poseidon work — `compute_` signals derivation, not a property read. * As a free function (not a trait method), the helper stays callable from any consumer side without requiring a `ProofArchiveWriter` instance + GCS config. Also moves the JSON fixture under `apollo_gateway/resources/` and the expect-test under `apollo_gateway/src/proof_archive_writer_test.rs`. Drops the redundant `starts_with("proofs/")` rstest — the fixture pins exact strings, of which the prefix is a strict subset. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7b48e6c commit eae40db

6 files changed

Lines changed: 82 additions & 2 deletions

File tree

Cargo.lock

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

crates/apollo_gateway/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ tracing.workspace = true
5454
[dev-dependencies]
5555
apollo_class_manager_types = { workspace = true, features = ["testing"] }
5656
apollo_gateway_config = { workspace = true, features = ["testing"] }
57+
apollo_infra_utils.workspace = true
5758
apollo_mempool.workspace = true
5859
apollo_mempool_types = { workspace = true, features = ["testing"] }
5960
apollo_metrics = { workspace = true, features = ["testing"] }
@@ -67,6 +68,7 @@ blockifier = { workspace = true, features = ["mocks", "testing"] }
6768
blockifier_test_utils.workspace = true
6869
cairo-lang-sierra-to-casm.workspace = true
6970
criterion = { workspace = true, features = ["async_tokio"] }
71+
expect-test.workspace = true
7072
metrics.workspace = true
7173
metrics-exporter-prometheus.workspace = true
7274
mockall.workspace = true
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[
2+
{
3+
"big_storage_key": "proofs/1330163329880897963929329415144033128916878238201091319571200413658610585730",
4+
"proof_facts": [
5+
"0x1",
6+
"0x2",
7+
"0x3"
8+
]
9+
},
10+
{
11+
"big_storage_key": "proofs/2384960345383653703825803024708982182127528589318022519244349682493582074337",
12+
"proof_facts": [
13+
"0x0"
14+
]
15+
},
16+
{
17+
"big_storage_key": "proofs/2423937516222001646661741181647152765517884388953635986164148712285196226589",
18+
"proof_facts": [
19+
"0x50524f4f4630",
20+
"0x5649525455414c5f534e4f53",
21+
"0x1",
22+
"0x5649525455414c5f534e4f5330",
23+
"0x7a0",
24+
"0x2fa80",
25+
"0x4d82f98134d9b03a412bd54c25aa1e92ca0261a745737ba52fd46dd25f537c0",
26+
"0x0"
27+
]
28+
}
29+
]

crates/apollo_gateway/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ pub mod gateway;
44
pub mod gateway_fixed_block_state_reader;
55
pub mod metrics;
66
pub mod proof_archive_writer;
7+
#[cfg(test)]
8+
mod proof_archive_writer_test;
79
mod state_reader;
810
#[cfg(any(feature = "testing", test))]
911
mod state_reader_test_utils;

crates/apollo_gateway/src/proof_archive_writer.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ use tokio::sync::OnceCell;
1212
// The expected error code for precondition failed errors when using `if_generation_match` in GCS.
1313
const GCS_ERROR_CODE_PRECONDITION_FAILED: u16 = 412;
1414

15+
/// GCS object name where the Stwo proof for these facts is archived.
16+
pub fn compute_big_storage_key(proof_facts: &ProofFacts) -> String {
17+
format!("proofs/{}", proof_facts.hash())
18+
}
19+
1520
/// Trait for writing proof facts and proofs to large storage systems.
1621
/// Implementations should be thread-safe (Send + Sync).
1722
#[cfg_attr(any(feature = "testing", test), automock)]
@@ -65,9 +70,8 @@ impl ProofArchiveWriterTrait for GcsProofArchiveWriter {
6570
proof: Proof,
6671
) -> Result<(), ProofArchiveError> {
6772
let client = self.client.get().expect("GCS client not connected. Call connect() first.");
68-
let facts_hash = proof_facts.hash();
6973
let proof_bytes: Vec<u8> = proof.0.iter().flat_map(|&val| val.to_be_bytes()).collect();
70-
let object_name = format!("proofs/{}", facts_hash);
74+
let object_name = compute_big_storage_key(&proof_facts);
7175

7276
let result = client
7377
.upload_object(
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use std::path::PathBuf;
2+
use std::sync::LazyLock;
3+
4+
use apollo_infra_utils::compile_time_cargo_manifest_dir;
5+
use expect_test::expect_file;
6+
use starknet_api::proof_facts;
7+
use starknet_api::transaction::fields::ProofFacts;
8+
use starknet_types_core::felt::Felt;
9+
10+
use crate::proof_archive_writer::compute_big_storage_key;
11+
12+
static PROOF_FACTS_BIG_STORAGE_KEYS_FIXTURE_PATH: LazyLock<PathBuf> = LazyLock::new(|| {
13+
PathBuf::from(compile_time_cargo_manifest_dir!())
14+
.join("resources/proof_facts_big_storage_keys.json")
15+
});
16+
17+
/// Returns the cases pinned by the cross-language fixture.
18+
fn big_storage_key_cases() -> Vec<ProofFacts> {
19+
vec![
20+
proof_facts![Felt::from(1u64), Felt::from(2u64), Felt::from(3u64)],
21+
proof_facts![Felt::ZERO],
22+
ProofFacts::snos_proof_facts_for_testing(),
23+
]
24+
}
25+
26+
/// Cross-language fixture for services that need to derive the proof archive key — regenerate with
27+
/// UPDATE_EXPECT=1.
28+
#[test]
29+
fn proof_facts_big_storage_keys_fixture() {
30+
let fixture: Vec<serde_json::Value> = big_storage_key_cases()
31+
.iter()
32+
.map(|facts| {
33+
serde_json::json!({
34+
"proof_facts": facts.0.iter().map(|f| f.to_hex_string()).collect::<Vec<_>>(),
35+
"big_storage_key": compute_big_storage_key(facts),
36+
})
37+
})
38+
.collect();
39+
let json = serde_json::to_string_pretty(&fixture).unwrap() + "\n";
40+
expect_file![PROOF_FACTS_BIG_STORAGE_KEYS_FIXTURE_PATH.as_path()].assert_eq(&json);
41+
}

0 commit comments

Comments
 (0)