use crate::EvaluationFrame;
use math::FieldElement;
use utils::{
collections::Vec, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
SliceReader,
};
type ParsedOodFrame<E> = (EvaluationFrame<E>, Option<EvaluationFrame<E>>, Vec<E>);
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct OodFrame {
trace_states: Vec<u8>,
evaluations: Vec<u8>,
}
impl OodFrame {
pub fn set_trace_states<E: FieldElement>(&mut self, trace_states: &[Vec<E>]) {
assert!(
self.trace_states.is_empty(),
"trace sates have already been set"
);
for trace_state in trace_states {
trace_state.write_into(&mut self.trace_states);
}
}
pub fn set_constraint_evaluations<E: FieldElement>(&mut self, evaluations: &[E]) {
assert!(
self.evaluations.is_empty(),
"constraint evaluations have already been set"
);
assert!(
!evaluations.is_empty(),
"cannot set to empty constraint evaluations"
);
evaluations.write_into(&mut self.evaluations)
}
pub fn parse<E: FieldElement>(
self,
main_trace_width: usize,
aux_trace_width: usize,
num_evaluations: usize,
) -> Result<ParsedOodFrame<E>, DeserializationError> {
assert!(main_trace_width > 0, "trace width cannot be zero");
assert!(num_evaluations > 0, "number of evaluations cannot be zero");
let mut reader = SliceReader::new(&self.trace_states);
let current = E::read_batch_from(&mut reader, main_trace_width)?;
let current_aux = E::read_batch_from(&mut reader, aux_trace_width)?;
let next = E::read_batch_from(&mut reader, main_trace_width)?;
let next_aux = E::read_batch_from(&mut reader, aux_trace_width)?;
if reader.has_more_bytes() {
return Err(DeserializationError::UnconsumedBytes);
}
let main_frame = EvaluationFrame::from_rows(current, next);
let aux_frame = if aux_trace_width > 0 {
Some(EvaluationFrame::from_rows(current_aux, next_aux))
} else {
None
};
let mut reader = SliceReader::new(&self.evaluations);
let evaluations = E::read_batch_from(&mut reader, num_evaluations)?;
if reader.has_more_bytes() {
return Err(DeserializationError::UnconsumedBytes);
}
Ok((main_frame, aux_frame, evaluations))
}
}
impl Serializable for OodFrame {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
target.write_u16(self.trace_states.len() as u16);
target.write_u8_slice(&self.trace_states);
target.write_u16(self.evaluations.len() as u16);
target.write_u8_slice(&self.evaluations)
}
}
impl Deserializable for OodFrame {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let num_trace_state_bytes = source.read_u16()? as usize;
let trace_states = source.read_u8_vec(num_trace_state_bytes)?;
let num_constraint_evaluation_bytes = source.read_u16()? as usize;
let evaluations = source.read_u8_vec(num_constraint_evaluation_bytes)?;
Ok(OodFrame {
trace_states,
evaluations,
})
}
}