Skip to content

Commit c99e66c

Browse files
committed
Change order of pub inputs, simplify fns and names
1 parent e0e42d2 commit c99e66c

1 file changed

Lines changed: 93 additions & 108 deletions

File tree

operator/mina/lib/src/lib.rs

Lines changed: 93 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
mod consensus_state;
22

3-
use std::array;
3+
use std::array::{self, TryFromSliceError};
44

55
use ark_ec::short_weierstrass_jacobian::GroupAffine;
66
use 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)]
178163
mod 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

Comments
 (0)