@@ -20,7 +20,7 @@ use soroban_sdk::{
2020} ;
2121
2222use crate :: types:: errors:: Error ;
23- use crate :: types:: state:: { Proof , PublicInputs , VerifyingKey } ;
23+ use crate :: types:: state:: { Proof , PublicInputs , SchemaVersion , VerifyingKey } ;
2424
2525// ──────────────────────────────────────────────────────────────
2626// Public Input Linear Combination
@@ -35,9 +35,9 @@ fn compute_vk_x(
3535 vk : & VerifyingKey ,
3636 pub_inputs : & PublicInputs ,
3737) -> Result < Bn254G1Affine , Error > {
38- // The VK must have exactly 9 IC points: IC[0] + 8 public inputs
39- // [pool_id, root, nullifier_hash, recipient, amount, relayer, fee, denomination ]
40- if vk. gamma_abc_g1 . len ( ) != 9 {
38+ // The VK must have exactly 7 IC points: IC[0] + 6 public inputs
39+ // [root, nullifier_hash, recipient, amount, relayer, fee]
40+ if vk. gamma_abc_g1 . len ( ) != 7 {
4141 return Err ( Error :: MalformedVerifyingKey ) ;
4242 }
4343
@@ -48,15 +48,13 @@ fn compute_vk_x(
4848 let mut acc = Bn254G1Affine :: from_bytes ( ic0_bytes) ;
4949
5050 // Public inputs as 32-byte field elements → Fr scalars
51- let inputs: [ & BytesN < 32 > ; 8 ] = [
52- & pub_inputs. pool_id ,
51+ let inputs: [ & BytesN < 32 > ; 6 ] = [
5352 & pub_inputs. root ,
5453 & pub_inputs. nullifier_hash ,
5554 & pub_inputs. recipient ,
5655 & pub_inputs. amount ,
5756 & pub_inputs. relayer ,
5857 & pub_inputs. fee ,
59- & pub_inputs. denomination ,
6058 ] ;
6159
6260 for ( i, input_bytes) in inputs. iter ( ) . enumerate ( ) {
@@ -140,52 +138,40 @@ pub fn verify_proof(
140138}
141139
142140// ──────────────────────────────────────────────────────────────
143- // Tests
141+ // Schema Version Validation
144142// ──────────────────────────────────────────────────────────────
145143
146- #[ cfg( test) ]
147- mod tests {
148- use super :: * ;
149-
150- #[ test]
151- fn test_verifier_schema_parity ( ) {
152- // ZK-087: Ensure the contract verifier's expectations match the
153- // authoritative machine-readable schema artifact.
154- let schema_json = include_str ! ( "../../../../artifacts/zk/v1/verifier_schema.json" ) ;
155-
156- // Count public input names in schema
157- let input_count = schema_json. matches ( "\" name\" :" ) . count ( ) ;
158-
159- // Verifier expects IC[0] + all public inputs
160- let expected_ic_total = input_count + 1 ;
161-
162- // This pins the verifier to the schema
163- assert_eq ! ( expected_ic_total, 9 , "Schema must define exactly 8 public inputs (plus IC[0])" ) ;
164- }
165-
166- #[ test]
167- fn test_public_input_order ( ) {
168- let schema_json = include_str ! ( "../../../../artifacts/zk/v1/verifier_schema.json" ) ;
169-
170- // Names must appear in this order in the JSON
171- let expected_order = [
172- "pool_id" ,
173- "root" ,
174- "nullifier_hash" ,
175- "recipient" ,
176- "amount" ,
177- "relayer" ,
178- "fee" ,
179- "denomination"
180- ] ;
181-
182- let mut last_pos = 0 ;
183- for name in expected_order {
184- let search_str = concat ! ( "\" name\" : \" " , stringify!( name) , "\" " ) ;
185- let pos = schema_json. find ( search_str)
186- . expect ( concat ! ( "Field " , stringify!( name) , " missing from schema" ) ) ;
187- assert ! ( pos > last_pos, concat!( "Field " , stringify!( name) , " out of order in schema" ) ) ;
188- last_pos = pos;
189- }
144+ /// Validates that the proof schema version matches the expected version.
145+ ///
146+ /// This function ensures that proofs are generated with a compatible schema version,
147+ /// preventing runtime errors from schema mismatches at the verifier boundary.
148+ ///
149+ /// # Arguments
150+ /// * `proof_schema` - The schema version from the proof
151+ /// * `expected_version_str` - The expected schema version string (e.g., "1.0.0")
152+ ///
153+ /// # Returns
154+ /// * `Ok(())` if the schema versions are compatible
155+ /// * `Err(Error::InvalidSchemaVersion)` if the expected version string is malformed
156+ /// * `Err(Error::SchemaVersionMismatch)` if the versions are incompatible
157+ ///
158+ /// # Compatibility Rules
159+ /// Schema versions are compatible if:
160+ /// - Major versions match exactly
161+ /// - Minor versions match exactly
162+ /// - Patch versions can differ (backward compatible bug fixes)
163+ pub fn validate_schema_version (
164+ proof_schema : & SchemaVersion ,
165+ expected_version_str : & str ,
166+ ) -> Result < ( ) , Error > {
167+ // Parse the expected version string
168+ let expected = SchemaVersion :: from_string ( expected_version_str)
169+ . map_err ( |_| Error :: InvalidSchemaVersion ) ?;
170+
171+ // Check compatibility using semantic versioning rules
172+ if !proof_schema. is_compatible_with ( & expected) {
173+ return Err ( Error :: SchemaVersionMismatch ) ;
190174 }
175+
176+ Ok ( ( ) )
191177}
0 commit comments