11mod consensus_state;
22
3- use std:: array;
3+ use std:: array:: { self , TryFromSliceError } ;
44
55use ark_ec:: short_weierstrass_jacobian:: GroupAffine ;
66use base64:: prelude:: * ;
@@ -35,33 +35,29 @@ pub extern "C" fn verify_protocol_state_proof_ffi(
3535 public_input_bytes : & [ u8 ; MAX_PUB_INPUT_SIZE ] ,
3636 public_input_len : usize ,
3737) -> bool {
38- let protocol_state_proof = match parse_protocol_state_proof ( & proof_bytes[ ..proof_len] ) {
38+ let protocol_state_proof = match parse_proof ( & proof_bytes[ ..proof_len] ) {
3939 Ok ( protocol_state_proof) => protocol_state_proof,
4040 Err ( err) => {
4141 eprintln ! ( "Failed to parse protocol state proof: {}" , err) ;
4242 return false ;
4343 }
4444 } ;
4545
46- let (
47- candidate_protocol_state_hash,
48- candidate_protocol_state,
49- tip_protocol_state_hash,
50- tip_protocol_state,
51- ) = match parse_protocol_state_pub ( & public_input_bytes[ ..public_input_len] ) {
52- Ok ( protocol_state_pub) => protocol_state_pub,
53- Err ( err) => {
54- eprintln ! ( "Failed to parse protocol state public inputs: {}" , err) ;
55- return false ;
56- }
57- } ;
46+ let ( candidate_hash, tip_hash, candidate_state, tip_state) =
47+ match parse_pub_inputs ( & public_input_bytes[ ..public_input_len] ) {
48+ Ok ( protocol_state_pub) => protocol_state_pub,
49+ Err ( err) => {
50+ eprintln ! ( "Failed to parse protocol state public inputs: {}" , err) ;
51+ return false ;
52+ }
53+ } ;
5854
5955 // TODO(xqft): this can be a batcher's pre-verification check (but don't remove it from here)
60- if MinaHash :: hash ( & tip_protocol_state ) != tip_protocol_state_hash {
56+ if MinaHash :: hash ( & tip_state ) != tip_hash {
6157 eprintln ! ( "The tip's protocol state doesn't match the hash provided as public input" ) ;
6258 return false ;
6359 }
64- if MinaHash :: hash ( & candidate_protocol_state ) != candidate_protocol_state_hash {
60+ if MinaHash :: hash ( & candidate_state ) != candidate_hash {
6561 eprintln ! ( "The candidate's protocol state doesn't match the hash provided as public input" ) ;
6662 return false ;
6763 }
@@ -72,115 +68,104 @@ pub extern "C" fn verify_protocol_state_proof_ffi(
7268 let srs = srs. lock ( ) . unwrap ( ) ;
7369
7470 // Consensus check: Short fork rule
75- let longer_chain = select_longer_chain ( & candidate_protocol_state , & tip_protocol_state ) ;
71+ let longer_chain = select_longer_chain ( & candidate_state , & tip_state ) ;
7672 if longer_chain == LongerChainResult :: Tip {
7773 eprintln ! ( "Consensus check failed" ) ;
7874 return false ;
7975 }
8076
8177 // Pickles verification
82- verify_block (
83- & protocol_state_proof,
84- candidate_protocol_state_hash,
85- & VERIFIER_INDEX ,
86- & srs,
87- )
78+ verify_block ( & protocol_state_proof, candidate_hash, & VERIFIER_INDEX , & srs)
8879}
8980
90- pub fn parse_protocol_state_proof (
91- protocol_state_proof_bytes : & [ u8 ] ,
92- ) -> Result < MinaBaseProofStableV2 , String > {
93- let protocol_state_proof_base64 =
94- std:: str:: from_utf8 ( protocol_state_proof_bytes) . map_err ( |err| err. to_string ( ) ) ?;
95- let protocol_state_proof_binprot = BASE64_URL_SAFE
96- . decode ( protocol_state_proof_base64)
97- . map_err ( |err| err. to_string ( ) ) ?;
98- MinaBaseProofStableV2 :: binprot_read ( & mut protocol_state_proof_binprot. as_slice ( ) )
99- . map_err ( |err| err. to_string ( ) )
81+ pub fn parse_hash ( pub_inputs : & [ u8 ] , offset : & mut usize ) -> Result < Fp , String > {
82+ let hash = pub_inputs
83+ . get ( * offset..* offset + STATE_HASH_SIZE )
84+ . ok_or ( "Failed to slice candidate hash" . to_string ( ) )
85+ . and_then ( |bytes| Fp :: from_bytes ( bytes) . map_err ( |err| err. to_string ( ) ) ) ?;
86+
87+ * offset += STATE_HASH_SIZE ;
88+
89+ Ok ( hash)
90+ }
91+
92+ pub fn parse_state (
93+ pub_inputs : & [ u8 ] ,
94+ offset : & mut usize ,
95+ ) -> Result < MinaStateProtocolStateValueStableV2 , String > {
96+ let state_len: usize = pub_inputs
97+ . get ( * offset..* offset + 4 )
98+ . ok_or ( "Failed to slice state len" . to_string ( ) )
99+ . and_then ( |slice| {
100+ slice
101+ . try_into ( )
102+ . map_err ( |err : TryFromSliceError | err. to_string ( ) )
103+ } )
104+ . map ( u32:: from_be_bytes)
105+ . and_then ( |len| usize:: try_from ( len) . map_err ( |err| err. to_string ( ) ) ) ?;
106+
107+ let state = pub_inputs
108+ . get ( * offset + 4 ..* offset + 4 + state_len)
109+ . ok_or ( "Failed to slice state" . to_string ( ) )
110+ . and_then ( |bytes| std:: str:: from_utf8 ( bytes) . map_err ( |err| err. to_string ( ) ) )
111+ . and_then ( |base64| {
112+ BASE64_STANDARD
113+ . decode ( base64)
114+ . map_err ( |err| err. to_string ( ) )
115+ } )
116+ . and_then ( |binprot| {
117+ MinaStateProtocolStateValueStableV2 :: binprot_read ( & mut binprot. as_slice ( ) )
118+ . map_err ( |err| err. to_string ( ) )
119+ } ) ?;
120+
121+ * offset += 4 + state_len;
122+
123+ Ok ( state)
100124}
101125
102- pub fn parse_protocol_state_pub (
103- protocol_state_pub : & [ u8 ] ,
126+ pub fn parse_pub_inputs (
127+ pub_inputs : & [ u8 ] ,
104128) -> Result <
105129 (
106130 Fp ,
107- MinaStateProtocolStateValueStableV2 ,
108131 Fp ,
109132 MinaStateProtocolStateValueStableV2 ,
133+ MinaStateProtocolStateValueStableV2 ,
110134 ) ,
111135 String ,
112136> {
113- let ( tip_protocol_state_hash, tip_protocol_state, candidate_start) =
114- parse_protocol_state_with_hash ( & protocol_state_pub, 0 ) ?;
115-
116- let ( candidate_protocol_state_hash, candidate_protocol_state, _) =
117- parse_protocol_state_with_hash ( & protocol_state_pub, candidate_start) ?;
118-
119- Ok ( (
120- tip_protocol_state_hash,
121- tip_protocol_state,
122- candidate_protocol_state_hash,
123- candidate_protocol_state,
124- ) )
137+ let mut offset = 0 ;
138+
139+ let candidate_hash = parse_hash ( pub_inputs, & mut offset) ?;
140+ let tip_hash = parse_hash ( pub_inputs, & mut offset) ?;
141+
142+ let candidate_state = parse_state ( pub_inputs, & mut offset) ?;
143+ let tip_state = parse_state ( pub_inputs, & mut offset) ?;
144+
145+ Ok ( ( candidate_hash, tip_hash, candidate_state, tip_state) )
125146}
126147
127- fn parse_protocol_state_with_hash (
128- protocol_state_pub : & [ u8 ] ,
129- start : usize ,
130- ) -> Result <
131- (
132- ark_ff:: Fp256 < mina_curves:: pasta:: fields:: FpParameters > ,
133- MinaStateProtocolStateValueStableV2 ,
134- usize ,
135- ) ,
136- String ,
137- > {
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 ( ) ;
144- let protocol_state_hash =
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 ( ) ;
161- let protocol_state_base64 =
162- std:: str:: from_utf8 ( & protocol_state_bytes) . map_err ( |err| err. to_string ( ) ) ?;
163- let protocol_state_binprot = BASE64_STANDARD
164- . decode ( protocol_state_base64)
165- . map_err ( |err| err. to_string ( ) ) ?;
166- let protocol_state =
167- MinaStateProtocolStateValueStableV2 :: binprot_read ( & mut protocol_state_binprot. as_slice ( ) )
168- . map_err ( |err| err. to_string ( ) ) ?;
169-
170- Ok ( (
171- protocol_state_hash,
172- protocol_state,
173- start + STATE_HASH_SIZE + 4 + protocol_state_len,
174- ) )
148+ pub fn parse_proof ( proof_bytes : & [ u8 ] ) -> Result < MinaBaseProofStableV2 , String > {
149+ std:: str:: from_utf8 ( proof_bytes)
150+ . map_err ( |err| err. to_string ( ) )
151+ . and_then ( |base64| {
152+ BASE64_URL_SAFE
153+ . decode ( base64)
154+ . map_err ( |err| err. to_string ( ) )
155+ } )
156+ . and_then ( |binprot| {
157+ MinaBaseProofStableV2 :: binprot_read ( & mut binprot. as_slice ( ) )
158+ . map_err ( |err| err. to_string ( ) )
159+ } )
175160}
176161
177162#[ cfg( test) ]
178163mod test {
179164 use super :: * ;
180165
181- const PROTOCOL_STATE_PROOF_BYTES : & [ u8 ] =
166+ const PROOF_BYTES : & [ u8 ] =
182167 include_bytes ! ( "../../../../batcher/aligned/test_files/mina/protocol_state.proof" ) ;
183- const PROTOCOL_STATE_PUB_BYTES : & [ u8 ] =
168+ const PUB_INPUT_BYTES : & [ u8 ] =
184169 include_bytes ! ( "../../../../batcher/aligned/test_files/mina/protocol_state.pub" ) ;
185170 const PROTOCOL_STATE_BAD_HASH_PUB_BYTES : & [ u8 ] =
186171 include_bytes ! ( "../../../../batcher/aligned/test_files/mina/protocol_state_bad_hash.pub" ) ;
@@ -190,25 +175,25 @@ mod test {
190175
191176 #[ test]
192177 fn parse_protocol_state_proof_does_not_fail ( ) {
193- parse_protocol_state_proof ( PROTOCOL_STATE_PROOF_BYTES ) . unwrap ( ) ;
178+ parse_proof ( PROOF_BYTES ) . unwrap ( ) ;
194179 }
195180
196181 #[ test]
197182 fn parse_protocol_state_pub_does_not_fail ( ) {
198- parse_protocol_state_pub ( PROTOCOL_STATE_PUB_BYTES ) . unwrap ( ) ;
183+ parse_pub_inputs ( PUB_INPUT_BYTES ) . unwrap ( ) ;
199184 }
200185
201186 #[ test]
202187 fn protocol_state_proof_verifies ( ) {
203188 let mut proof_buffer = [ 0u8 ; super :: MAX_PROOF_SIZE ] ;
204- let proof_size = PROTOCOL_STATE_PROOF_BYTES . len ( ) ;
189+ let proof_size = PROOF_BYTES . len ( ) ;
205190 assert ! ( proof_size <= proof_buffer. len( ) ) ;
206- proof_buffer[ ..proof_size] . clone_from_slice ( PROTOCOL_STATE_PROOF_BYTES ) ;
191+ proof_buffer[ ..proof_size] . clone_from_slice ( PROOF_BYTES ) ;
207192
208193 let mut pub_input_buffer = [ 0u8 ; super :: MAX_PUB_INPUT_SIZE ] ;
209- let pub_input_size = PROTOCOL_STATE_PUB_BYTES . len ( ) ;
194+ let pub_input_size = PUB_INPUT_BYTES . len ( ) ;
210195 assert ! ( pub_input_size <= pub_input_buffer. len( ) ) ;
211- pub_input_buffer[ ..pub_input_size] . clone_from_slice ( PROTOCOL_STATE_PUB_BYTES ) ;
196+ pub_input_buffer[ ..pub_input_size] . clone_from_slice ( PUB_INPUT_BYTES ) ;
212197
213198 let result = verify_protocol_state_proof_ffi (
214199 & proof_buffer,
@@ -222,9 +207,9 @@ mod test {
222207 #[ test]
223208 fn proof_of_protocol_state_with_bad_hash_does_not_verify ( ) {
224209 let mut proof_buffer = [ 0u8 ; super :: MAX_PROOF_SIZE ] ;
225- let proof_size = PROTOCOL_STATE_PROOF_BYTES . len ( ) ;
210+ let proof_size = PROOF_BYTES . len ( ) ;
226211 assert ! ( proof_size <= proof_buffer. len( ) ) ;
227- proof_buffer[ ..proof_size] . clone_from_slice ( PROTOCOL_STATE_PROOF_BYTES ) ;
212+ proof_buffer[ ..proof_size] . clone_from_slice ( PROOF_BYTES ) ;
228213
229214 let mut pub_input_buffer = [ 0u8 ; super :: MAX_PUB_INPUT_SIZE ] ;
230215 let pub_input_size = PROTOCOL_STATE_BAD_HASH_PUB_BYTES . len ( ) ;
@@ -243,9 +228,9 @@ mod test {
243228 #[ test]
244229 fn proof_of_protocol_state_with_bad_consensus_does_not_verify ( ) {
245230 let mut proof_buffer = [ 0u8 ; super :: MAX_PROOF_SIZE ] ;
246- let proof_size = PROTOCOL_STATE_PROOF_BYTES . len ( ) ;
231+ let proof_size = PROOF_BYTES . len ( ) ;
247232 assert ! ( proof_size <= proof_buffer. len( ) ) ;
248- proof_buffer[ ..proof_size] . clone_from_slice ( PROTOCOL_STATE_PROOF_BYTES ) ;
233+ proof_buffer[ ..proof_size] . clone_from_slice ( PROOF_BYTES ) ;
249234
250235 let mut pub_input_buffer = [ 0u8 ; super :: MAX_PUB_INPUT_SIZE ] ;
251236 let pub_input_size = PROTOCOL_STATE_BAD_CONSENSUS_PUB_BYTES . len ( ) ;
0 commit comments