Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ prost = "0.13"
prost-build = "0.13"
protoc-prebuilt = "0.3"

# MessagePack
rmp = "0.8.14"
rmp-serde = "1.3.0"

cfg-if = "1.0.0"
dirs = "4"
serde = { version = "1.0.136", features = ["derive"] }
Expand Down
1 change: 1 addition & 0 deletions acvm-repo/acir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ flate2.workspace = true
bincode.workspace = true
base64.workspace = true
prost.workspace = true
rmp-serde.workspace = true
serde-big-array = "0.5.1"
strum = { workspace = true }
strum_macros = { workspace = true }
Expand Down
90 changes: 48 additions & 42 deletions acvm-repo/acir/src/circuit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ pub mod opcodes;

use crate::{
native_types::{Expression, Witness},
proto::convert::ProtoSchema,
serialization::{bincode_deserialize, bincode_serialize},
};
use acir_field::AcirField;
use noir_protobuf::ProtoCodec as _;
pub use opcodes::Opcode;
use thiserror::Error;

Expand Down Expand Up @@ -248,8 +247,9 @@ impl<F: AcirField> Circuit<F> {
}

impl<F: Serialize + AcirField> Program<F> {
/// Serialize and compress the [Program] into bytes.
fn write<W: Write>(&self, writer: W) -> std::io::Result<()> {
let buf = self.bincode_serialize()?;
let buf = bincode_serialize(self)?;
let mut encoder = flate2::write::GzEncoder::new(writer, Compression::default());
encoder.write_all(&buf)?;
encoder.finish()?;
Expand All @@ -273,38 +273,13 @@ impl<F: Serialize + AcirField> Program<F> {
}
}

impl<F: Serialize + AcirField> Program<F> {
/// Serialize the program using `bincode`, which is what we have to use until Barretenberg can read another format.
pub(crate) fn bincode_serialize(&self) -> std::io::Result<Vec<u8>> {
bincode::serialize(self).map_err(std::io::Error::other)
}
}

impl<F: AcirField + for<'a> Deserialize<'a>> Program<F> {
pub(crate) fn bincode_deserialize(buf: &[u8]) -> std::io::Result<Self> {
bincode::deserialize(buf)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))
}
}

#[allow(dead_code)] // TODO: Remove once we switch to protobuf
impl<F: AcirField> Program<F> {
/// Serialize the program using `protobuf`, which is what we try to replace `bincode` with.
pub(crate) fn proto_serialize(&self) -> Vec<u8> {
ProtoSchema::<F>::serialize_to_vec(self)
}
pub(crate) fn proto_deserialize(buf: &[u8]) -> std::io::Result<Self> {
ProtoSchema::<F>::deserialize_from_vec(buf)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))
}
}

impl<F: AcirField + for<'a> Deserialize<'a>> Program<F> {
/// Decompress and deserialize bytes into a [Program].
fn read<R: Read>(reader: R) -> std::io::Result<Self> {
let mut gz_decoder = flate2::read::GzDecoder::new(reader);
let mut buf = Vec::new();
gz_decoder.read_to_end(&mut buf)?;
let program = Self::bincode_deserialize(&buf)?;
let program = bincode_deserialize(&buf)?;
Ok(program)
}

Expand Down Expand Up @@ -523,6 +498,7 @@ mod tests {

use crate::circuit::Program;
use crate::native_types::{WitnessMap, WitnessStack};
use crate::serialization::*;

// It's not possible to set the maximum size of collections via `ProptestConfig`, only an env var,
// because e.g. the `VecStrategy` uses `Config::default().max_default_size_range`. On top of that,
Expand Down Expand Up @@ -576,8 +552,8 @@ mod tests {
#[test]
fn prop_program_proto_roundtrip() {
run_with_max_size_range(100, |program: Program<TestField>| {
let bz = Program::proto_serialize(&program);
let de = Program::proto_deserialize(&bz)?;
let bz = proto_serialize(&program);
let de = proto_deserialize(&bz)?;
prop_assert_eq!(program, de);
Ok(())
});
Expand All @@ -586,8 +562,18 @@ mod tests {
#[test]
fn prop_program_bincode_roundtrip() {
run_with_max_size_range(100, |program: Program<TestField>| {
let bz = Program::bincode_serialize(&program)?;
let de = Program::bincode_deserialize(&bz)?;
let bz = bincode_serialize(&program)?;
let de = bincode_deserialize(&bz)?;
prop_assert_eq!(program, de);
Ok(())
});
}

#[test]
fn prop_program_msgpack_roundtrip() {
run_with_max_size_range(100, |(program, compact): (Program<TestField>, bool)| {
let bz = msgpack_serialize(&program, compact)?;
let de = msgpack_deserialize(&bz)?;
prop_assert_eq!(program, de);
Ok(())
});
Expand All @@ -606,8 +592,8 @@ mod tests {
#[test]
fn prop_witness_stack_proto_roundtrip() {
run_with_max_size_range(10, |witness: WitnessStack<TestField>| {
let bz = WitnessStack::proto_serialize(&witness);
let de = WitnessStack::proto_deserialize(&bz)?;
let bz = proto_serialize(&witness);
let de = proto_deserialize(&bz)?;
prop_assert_eq!(witness, de);
Ok(())
});
Expand All @@ -616,8 +602,18 @@ mod tests {
#[test]
fn prop_witness_stack_bincode_roundtrip() {
run_with_max_size_range(10, |witness: WitnessStack<TestField>| {
let bz = WitnessStack::bincode_serialize(&witness)?;
let de = WitnessStack::bincode_deserialize(&bz)?;
let bz = bincode_serialize(&witness)?;
let de = bincode_deserialize(&bz)?;
prop_assert_eq!(witness, de);
Ok(())
});
}

#[test]
fn prop_witness_stack_msgpack_roundtrip() {
run_with_max_size_range(10, |(witness, compact): (WitnessStack<TestField>, bool)| {
let bz = msgpack_serialize(&witness, compact)?;
let de = msgpack_deserialize(&bz)?;
prop_assert_eq!(witness, de);
Ok(())
});
Expand All @@ -636,8 +632,8 @@ mod tests {
#[test]
fn prop_witness_map_proto_roundtrip() {
run_with_max_size_range(10, |witness: WitnessMap<TestField>| {
let bz = WitnessMap::proto_serialize(&witness);
let de = WitnessMap::proto_deserialize(&bz)?;
let bz = proto_serialize(&witness);
let de = proto_deserialize(&bz)?;
prop_assert_eq!(witness, de);
Ok(())
});
Expand All @@ -646,8 +642,18 @@ mod tests {
#[test]
fn prop_witness_map_bincode_roundtrip() {
run_with_max_size_range(10, |witness: WitnessMap<TestField>| {
let bz = WitnessMap::bincode_serialize(&witness)?;
let de = WitnessMap::bincode_deserialize(&bz)?;
let bz = bincode_serialize(&witness)?;
let de = bincode_deserialize(&bz)?;
prop_assert_eq!(witness, de);
Ok(())
});
}

#[test]
fn prop_witness_map_msgpack_roundtrip() {
run_with_max_size_range(10, |(witness, compact): (WitnessMap<TestField>, bool)| {
let bz = msgpack_serialize(&witness, compact)?;
let de = msgpack_deserialize(&bz)?;
prop_assert_eq!(witness, de);
Ok(())
});
Expand Down
1 change: 1 addition & 0 deletions acvm-repo/acir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
pub mod circuit;
pub mod native_types;
mod proto;
mod serialization;

pub use acir_field;
pub use acir_field::{AcirField, FieldElement};
Expand All @@ -19,7 +20,7 @@
mod reflection {
//! Getting test failures? You've probably changed the ACIR serialization format.
//!
//! These tests generate C++ deserializers for [`ACIR bytecode`][super::circuit::Circuit]

Check warning on line 23 in acvm-repo/acir/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (deserializers)
//! and the [`WitnessMap`] structs. These get checked against the C++ files committed to the `codegen` folder
//! to see if changes have been to the serialization format. These are almost always a breaking change!
//!
Expand Down
15 changes: 1 addition & 14 deletions acvm-repo/acir/src/native_types/witness_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@

use acir_field::AcirField;
use flate2::Compression;
use flate2::bufread::GzDecoder;

Check warning on line 9 in acvm-repo/acir/src/native_types/witness_map.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (bufread)
use flate2::bufread::GzEncoder;

Check warning on line 10 in acvm-repo/acir/src/native_types/witness_map.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (bufread)
use noir_protobuf::ProtoCodec as _;
use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::{native_types::Witness, proto::convert::ProtoSchema};
use crate::native_types::Witness;

#[derive(Debug, Error)]
enum SerializationError {
Expand Down Expand Up @@ -96,18 +95,6 @@
}
}

#[allow(dead_code)]
impl<F: AcirField> WitnessMap<F> {
pub(crate) fn proto_serialize(&self) -> Vec<u8> {
ProtoSchema::<F>::serialize_to_vec(self)
}

pub(crate) fn proto_deserialize(buf: &[u8]) -> Result<Self, WitnessMapError> {
ProtoSchema::<F>::deserialize_from_vec(buf)
.map_err(|e| SerializationError::Deserialize(e.to_string()).into())
}
}

impl<F: Serialize + AcirField> TryFrom<WitnessMap<F>> for Vec<u8> {
type Error = WitnessMapError;

Expand Down
15 changes: 0 additions & 15 deletions acvm-repo/acir/src/native_types/witness_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@

use acir_field::AcirField;
use flate2::Compression;
use flate2::bufread::GzDecoder;

Check warning on line 5 in acvm-repo/acir/src/native_types/witness_stack.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (bufread)
use flate2::bufread::GzEncoder;

Check warning on line 6 in acvm-repo/acir/src/native_types/witness_stack.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (bufread)
use noir_protobuf::ProtoCodec as _;
use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::proto::convert::ProtoSchema;

use super::WitnessMap;

#[derive(Debug, Error)]
Expand Down Expand Up @@ -82,18 +79,6 @@
}
}

#[allow(dead_code)]
impl<F: AcirField> WitnessStack<F> {
pub(crate) fn proto_serialize(&self) -> Vec<u8> {
ProtoSchema::<F>::serialize_to_vec(self)
}

pub(crate) fn proto_deserialize(buf: &[u8]) -> Result<Self, WitnessStackError> {
ProtoSchema::<F>::deserialize_from_vec(buf)
.map_err(|e| SerializationError::Deserialize(e.to_string()).into())
}
}

impl<F: Serialize + AcirField> TryFrom<&WitnessStack<F>> for Vec<u8> {
type Error = WitnessStackError;

Expand Down
Loading
Loading