11mod consensus_state;
22
3+ use std:: array;
4+
35use ark_ec:: short_weierstrass_jacobian:: GroupAffine ;
46use base64:: prelude:: * ;
57use consensus_state:: { select_longer_chain, LongerChainResult } ;
@@ -24,9 +26,7 @@ lazy_static! {
2426// TODO(xqft): check proof size
2527const MAX_PROOF_SIZE : usize = 16 * 1024 ;
2628const MAX_PUB_INPUT_SIZE : usize = 6 * 1024 ;
27- const PROTOCOL_STATE_HASH_SIZE : usize = 32 ;
28- // TODO(gabrielbosio): check that this length is always the same for every block
29- const PROTOCOL_STATE_SIZE : usize = 2056 ;
29+ const STATE_HASH_SIZE : usize = 32 ;
3030
3131#[ no_mangle]
3232pub extern "C" fn verify_protocol_state_proof_ffi (
@@ -110,14 +110,11 @@ pub fn parse_protocol_state_pub(
110110 ) ,
111111 String ,
112112> {
113- let ( tip_protocol_state_hash, tip_protocol_state) = parse_protocol_state_with_hash (
114- & protocol_state_pub[ ..( PROTOCOL_STATE_HASH_SIZE + PROTOCOL_STATE_SIZE ) ] ,
115- ) ?;
113+ let ( tip_protocol_state_hash, tip_protocol_state, candidate_start) =
114+ parse_protocol_state_with_hash ( & protocol_state_pub, 0 ) ?;
116115
117- let ( candidate_protocol_state_hash, candidate_protocol_state) = parse_protocol_state_with_hash (
118- & protocol_state_pub[ ( PROTOCOL_STATE_HASH_SIZE + PROTOCOL_STATE_SIZE )
119- ..( ( PROTOCOL_STATE_HASH_SIZE + PROTOCOL_STATE_SIZE ) * 2 ) ] ,
120- ) ?;
116+ let ( candidate_protocol_state_hash, candidate_protocol_state, _) =
117+ parse_protocol_state_with_hash ( & protocol_state_pub, candidate_start) ?;
121118
122119 Ok ( (
123120 tip_protocol_state_hash,
@@ -129,25 +126,52 @@ pub fn parse_protocol_state_pub(
129126
130127fn parse_protocol_state_with_hash (
131128 protocol_state_pub : & [ u8 ] ,
129+ start : usize ,
132130) -> Result <
133131 (
134132 ark_ff:: Fp256 < mina_curves:: pasta:: fields:: FpParameters > ,
135133 MinaStateProtocolStateValueStableV2 ,
134+ usize ,
136135 ) ,
137136 String ,
138137> {
138+ let protocol_state_hash_bytes: Vec < _ > = protocol_state_pub
139+ . iter ( )
140+ . skip ( start)
141+ . take ( STATE_HASH_SIZE )
142+ . map ( |byte| byte. clone ( ) )
143+ . collect ( ) ;
139144 let protocol_state_hash =
140- Fp :: from_bytes ( & protocol_state_pub[ ..32 ] ) . map_err ( |err| err. to_string ( ) ) ?;
145+ Fp :: from_bytes ( & protocol_state_hash_bytes) . map_err ( |err| err. to_string ( ) ) ?;
146+
147+ let protocol_state_len_vec: Vec < _ > = protocol_state_pub
148+ . iter ( )
149+ . skip ( start + STATE_HASH_SIZE )
150+ . take ( 8 )
151+ . collect ( ) ;
152+ let protocol_state_len_bytes: [ u8 ; 4 ] = array:: from_fn ( |i| protocol_state_len_vec[ i] . clone ( ) ) ;
153+ let protocol_state_len = u32:: from_be_bytes ( protocol_state_len_bytes) as usize ;
154+
155+ let protocol_state_bytes: Vec < _ > = protocol_state_pub
156+ . iter ( )
157+ . skip ( start + STATE_HASH_SIZE + 4 )
158+ . take ( protocol_state_len)
159+ . map ( |byte| byte. clone ( ) )
160+ . collect ( ) ;
141161 let protocol_state_base64 =
142- std:: str:: from_utf8 ( & protocol_state_pub [ 32 .. ] ) . map_err ( |err| err. to_string ( ) ) ?;
162+ std:: str:: from_utf8 ( & protocol_state_bytes ) . map_err ( |err| err. to_string ( ) ) ?;
143163 let protocol_state_binprot = BASE64_STANDARD
144164 . decode ( protocol_state_base64)
145165 . map_err ( |err| err. to_string ( ) ) ?;
146166 let protocol_state =
147167 MinaStateProtocolStateValueStableV2 :: binprot_read ( & mut protocol_state_binprot. as_slice ( ) )
148168 . map_err ( |err| err. to_string ( ) ) ?;
149169
150- Ok ( ( protocol_state_hash, protocol_state) )
170+ Ok ( (
171+ protocol_state_hash,
172+ protocol_state,
173+ start + STATE_HASH_SIZE + 4 + protocol_state_len,
174+ ) )
151175}
152176
153177#[ cfg( test) ]
@@ -158,9 +182,11 @@ mod test {
158182 include_bytes ! ( "../../../../batcher/aligned/test_files/mina/protocol_state.proof" ) ;
159183 const PROTOCOL_STATE_PUB_BYTES : & [ u8 ] =
160184 include_bytes ! ( "../../../../batcher/aligned/test_files/mina/protocol_state.pub" ) ;
161- const BAD_PROTOCOL_STATE_PUB_BYTES : & [ u8 ] =
162- include_bytes ! ( "../../../../batcher/aligned/test_files/mina/bad_protocol_state.pub" ) ;
163- // BAD_PROTOCOL_STATE_PUB_BYTES has an invalid hash.
185+ const PROTOCOL_STATE_BAD_HASH_PUB_BYTES : & [ u8 ] =
186+ include_bytes ! ( "../../../../batcher/aligned/test_files/mina/protocol_state_bad_hash.pub" ) ;
187+ const PROTOCOL_STATE_BAD_CONSENSUS_PUB_BYTES : & [ u8 ] = include_bytes ! (
188+ "../../../../batcher/aligned/test_files/mina/protocol_state_bad_consensus.pub"
189+ ) ;
164190
165191 #[ test]
166192 fn parse_protocol_state_proof_does_not_fail ( ) {
@@ -194,16 +220,37 @@ mod test {
194220 }
195221
196222 #[ test]
197- fn bad_protocol_state_proof_does_not_verify ( ) {
223+ fn proof_of_protocol_state_with_bad_hash_does_not_verify ( ) {
224+ let mut proof_buffer = [ 0u8 ; super :: MAX_PROOF_SIZE ] ;
225+ let proof_size = PROTOCOL_STATE_PROOF_BYTES . len ( ) ;
226+ assert ! ( proof_size <= proof_buffer. len( ) ) ;
227+ proof_buffer[ ..proof_size] . clone_from_slice ( PROTOCOL_STATE_PROOF_BYTES ) ;
228+
229+ let mut pub_input_buffer = [ 0u8 ; super :: MAX_PUB_INPUT_SIZE ] ;
230+ let pub_input_size = PROTOCOL_STATE_BAD_HASH_PUB_BYTES . len ( ) ;
231+ assert ! ( pub_input_size <= pub_input_buffer. len( ) ) ;
232+ pub_input_buffer[ ..pub_input_size] . clone_from_slice ( PROTOCOL_STATE_BAD_HASH_PUB_BYTES ) ;
233+
234+ let result = verify_protocol_state_proof_ffi (
235+ & proof_buffer,
236+ proof_size,
237+ & pub_input_buffer,
238+ pub_input_size,
239+ ) ;
240+ assert ! ( !result) ;
241+ }
242+
243+ #[ test]
244+ fn proof_of_protocol_state_with_bad_consensus_does_not_verify ( ) {
198245 let mut proof_buffer = [ 0u8 ; super :: MAX_PROOF_SIZE ] ;
199246 let proof_size = PROTOCOL_STATE_PROOF_BYTES . len ( ) ;
200247 assert ! ( proof_size <= proof_buffer. len( ) ) ;
201248 proof_buffer[ ..proof_size] . clone_from_slice ( PROTOCOL_STATE_PROOF_BYTES ) ;
202249
203250 let mut pub_input_buffer = [ 0u8 ; super :: MAX_PUB_INPUT_SIZE ] ;
204- let pub_input_size = BAD_PROTOCOL_STATE_PUB_BYTES . len ( ) ;
251+ let pub_input_size = PROTOCOL_STATE_BAD_CONSENSUS_PUB_BYTES . len ( ) ;
205252 assert ! ( pub_input_size <= pub_input_buffer. len( ) ) ;
206- pub_input_buffer[ ..pub_input_size] . clone_from_slice ( BAD_PROTOCOL_STATE_PUB_BYTES ) ;
253+ pub_input_buffer[ ..pub_input_size] . clone_from_slice ( PROTOCOL_STATE_BAD_CONSENSUS_PUB_BYTES ) ;
207254
208255 let result = verify_protocol_state_proof_ffi (
209256 & proof_buffer,
0 commit comments