@@ -43,7 +43,7 @@ pub extern "C" fn verify_protocol_state_proof_ffi(
4343 }
4444 } ;
4545
46- let ( candidate_hash, tip_hash, candidate_state, tip_state) =
46+ let ( candidate_ledger_hash , candidate_hash, tip_hash, candidate_state, tip_state) =
4747 match parse_pub_inputs ( & public_input_bytes[ ..public_input_len] ) {
4848 Ok ( protocol_state_pub) => protocol_state_pub,
4949 Err ( err) => {
@@ -52,11 +52,33 @@ pub extern "C" fn verify_protocol_state_proof_ffi(
5252 }
5353 } ;
5454
55+ let expected_candidate_ledger_hash = match candidate_state
56+ . body
57+ . blockchain_state
58+ . staged_ledger_hash
59+ . non_snark
60+ . ledger_hash
61+ . to_fp ( )
62+ {
63+ Ok ( hash) => hash,
64+ Err ( err) => {
65+ eprintln ! ( "Failed to parse candidate ledger hash: {}" , err) ;
66+ return false ;
67+ }
68+ } ;
69+
70+ // TODO(xqft): this can be a batcher's pre-verification check (but don't remove it from here)
71+ if candidate_ledger_hash != expected_candidate_ledger_hash {
72+ eprintln ! ( "Candidate ledger hash on public inputs doesn't match the encoded state's one" ) ;
73+ return false ;
74+ }
75+
5576 // TODO(xqft): this can be a batcher's pre-verification check (but don't remove it from here)
5677 if MinaHash :: hash ( & tip_state) != tip_hash {
5778 eprintln ! ( "The tip's protocol state doesn't match the hash provided as public input" ) ;
5879 return false ;
5980 }
81+ // TODO(xqft): this can be a batcher's pre-verification check (but don't remove it from here)
6082 if MinaHash :: hash ( & candidate_state) != candidate_hash {
6183 eprintln ! ( "The candidate's protocol state doesn't match the hash provided as public input" ) ;
6284 return false ;
@@ -127,6 +149,7 @@ pub fn parse_pub_inputs(
127149 pub_inputs : & [ u8 ] ,
128150) -> Result <
129151 (
152+ Fp ,
130153 Fp ,
131154 Fp ,
132155 MinaStateProtocolStateValueStableV2 ,
@@ -136,13 +159,21 @@ pub fn parse_pub_inputs(
136159> {
137160 let mut offset = 0 ;
138161
162+ let candidate_ledger_hash = parse_hash ( pub_inputs, & mut offset) ?;
163+
139164 let candidate_hash = parse_hash ( pub_inputs, & mut offset) ?;
140165 let tip_hash = parse_hash ( pub_inputs, & mut offset) ?;
141166
142167 let candidate_state = parse_state ( pub_inputs, & mut offset) ?;
143168 let tip_state = parse_state ( pub_inputs, & mut offset) ?;
144169
145- Ok ( ( candidate_hash, tip_hash, candidate_state, tip_state) )
170+ Ok ( (
171+ candidate_ledger_hash,
172+ candidate_hash,
173+ tip_hash,
174+ candidate_state,
175+ tip_state,
176+ ) )
146177}
147178
148179pub fn parse_proof ( proof_bytes : & [ u8 ] ) -> Result < MinaBaseProofStableV2 , String > {
0 commit comments