|
| 1 | +use std::array; |
| 2 | + |
1 | 3 | use base64::prelude::*; |
2 | 4 | use log::{debug, warn}; |
3 | 5 |
|
4 | 6 | const STATE_HASH_SIZE: usize = 32; |
5 | | -// TODO(gabrielbosio): check that this length is always the same for every block |
6 | | -const PROTOCOL_STATE_SIZE: usize = 2056; |
7 | 7 |
|
8 | 8 | pub fn verify_protocol_state_proof_integrity(proof: &[u8], public_input: &[u8]) -> bool { |
9 | | - if public_input.len() != (STATE_HASH_SIZE + PROTOCOL_STATE_SIZE) * 2 { |
10 | | - return false; |
11 | | - } |
12 | | - |
13 | 9 | debug!("Checking Mina protocol state proof"); |
14 | 10 | if let Err(err) = check_protocol_state_proof(proof) { |
15 | 11 | warn!("Protocol state proof check failed: {}", err); |
@@ -38,24 +34,35 @@ pub fn check_protocol_state_proof(protocol_state_proof_bytes: &[u8]) -> Result<( |
38 | 34 |
|
39 | 35 | pub fn check_protocol_state_pub(protocol_state_pub: &[u8]) -> Result<(), String> { |
40 | 36 | // TODO(xqft): check hash and binprot deserialization |
41 | | - let candidate_protocol_state_base64 = std::str::from_utf8( |
42 | | - &protocol_state_pub[STATE_HASH_SIZE..(STATE_HASH_SIZE + PROTOCOL_STATE_SIZE)], |
43 | | - ) |
44 | | - .map_err(|err| err.to_string())?; |
45 | | - BASE64_STANDARD |
46 | | - .decode(candidate_protocol_state_base64) |
47 | | - .map_err(|err| err.to_string())?; |
| 37 | + let candidate_protocol_state_len = |
| 38 | + check_protocol_state_and_hash(protocol_state_pub, STATE_HASH_SIZE)?; |
48 | 39 |
|
49 | | - let tip_protocol_state_base64 = std::str::from_utf8( |
50 | | - &protocol_state_pub[(STATE_HASH_SIZE + PROTOCOL_STATE_SIZE) + STATE_HASH_SIZE |
51 | | - ..((STATE_HASH_SIZE + PROTOCOL_STATE_SIZE) * 2)], |
52 | | - ) |
53 | | - .map_err(|err| err.to_string())?; |
| 40 | + let _tip_protocol_state_len = check_protocol_state_and_hash( |
| 41 | + protocol_state_pub, |
| 42 | + STATE_HASH_SIZE + 4 + candidate_protocol_state_len + STATE_HASH_SIZE, |
| 43 | + )?; |
| 44 | + |
| 45 | + Ok(()) |
| 46 | +} |
| 47 | + |
| 48 | +fn check_protocol_state_and_hash(protocol_state_pub: &[u8], start: usize) -> Result<usize, String> { |
| 49 | + let protocol_state_len_vec: Vec<_> = protocol_state_pub.iter().skip(start).take(4).collect(); |
| 50 | + let protocol_state_len_bytes: [u8; 4] = array::from_fn(|i| protocol_state_len_vec[i].clone()); |
| 51 | + let protocol_state_len = u32::from_be_bytes(protocol_state_len_bytes) as usize; |
| 52 | + |
| 53 | + let protocol_state_bytes: Vec<_> = protocol_state_pub |
| 54 | + .iter() |
| 55 | + .skip(start + 4) |
| 56 | + .take(protocol_state_len) |
| 57 | + .map(|byte| byte.clone()) |
| 58 | + .collect(); |
| 59 | + let protocol_state_base64 = |
| 60 | + std::str::from_utf8(protocol_state_bytes.as_slice()).map_err(|err| err.to_string())?; |
54 | 61 | BASE64_STANDARD |
55 | | - .decode(tip_protocol_state_base64) |
| 62 | + .decode(protocol_state_base64) |
56 | 63 | .map_err(|err| err.to_string())?; |
57 | 64 |
|
58 | | - Ok(()) |
| 65 | + Ok(protocol_state_len) |
59 | 66 | } |
60 | 67 |
|
61 | 68 | #[cfg(test)] |
|
0 commit comments