Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[step1] implementing serialization of types via Serde #160

Merged
merged 22 commits into from
Oct 11, 2021

Conversation

mimoo
Copy link
Contributor

@mimoo mimoo commented Oct 4, 2021

We currently use serialization of our types by hand: https://github.com/MinaProtocol/mina/blob/develop/src/lib/marlin_plonk_bindings/stubs/src/index_serialization.rs

This is error-prone, and hard to maintain. As types and structs change, we need to make sure to change the serialization logic. The Rust-way is to use Serde, which offers a set of macros that we can use to implement serialization and deserialization traits for all of our types.

One of the problem we have is that arkworks, for some yet-unknown reason, doesn't implement Serde::{Serialize, Deserialize} on its types, but instead its own set of ark-serialize traits. This means that we need to tell serde how to use these arkworks-specific traits to serialize and deserialize.

No biggy, the serde_with crate comes to the rescue. We just need to annotate fields like this now:

#[serde_as]
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct EvaluationDomains<F: FftField> {
    #[serde_as(as = "o1_utils::serialization::SerdeAs")]
    pub d1: Domain<F>, // size n

The nice part is that it works with containers too:

    #[serde_as(as = "[o1_utils::serialization::SerdeAs; PERMUTS]")]
    pub shift: [Fr<G>; PERMUTS],

@mimoo mimoo requested review from imeckler, jspada and mrmr1993 October 4, 2021 17:38
@mimoo mimoo mentioned this pull request Oct 4, 2021
9 tasks
@@ -1,5 +1,12 @@
//! This adds a few utility functions for the [DensePolynomial] arkworks type.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

squeezing in this commit, it's a no-op

@@ -13,7 +13,7 @@ use serde_with::serde_as;
use std::io::{Error, ErrorKind, Read, Result as IoResult, Write};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

squeezing this commit as well, just adding some ocaml types that I need

@@ -139,7 +139,7 @@ pub fn derive_ocaml_enum(item: TokenStream) -> TokenStream {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

squeezing this one as well. This is to get better errors when using ocaml-gen

pub endo: F,

/// random oracle argument parameters
#[serde(skip)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created an issue about skipping fields: #161

Base automatically changed from mimoo/15-wire-plonk-fixes-3 to master October 7, 2021 17:38
@mimoo mimoo changed the title implementing serialization of types via Serde [step1] implementing serialization of types via Serde Oct 11, 2021
Copy link
Member

@mrmr1993 mrmr1993 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with nits. Can you add comments for the `TODO-someday's?


/// You can use this to serialize an arkworks type with serde and the "serialize_with" attribute.
/// See https://serde.rs/field-attrs.html
pub fn serialize<S>(val: impl CanonicalSerialize, serializer: S) -> Result<S::Ok, S::Error>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Efficiency nit: using a generic <T: CanonicalSerialize>(val: T, ...) gets compile-time specialised instead of using a vtable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these two are the same :o

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the only difference is when the impl is on the return value, IIUC

Copy link
Member

@mrmr1993 mrmr1993 Oct 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it does seem to just be syntactic sugar. I'd confused it with dyn 🤦‍♂️ Sorry for the noise!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nw!

T2: From<T1>,
{
(
a[0].clone().into(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO-someday: It would be better to use ocaml::Value::alloc_tuple and then store_field for each value, to avoid cloning

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, I think we can do this:

let (a0, a1, a2) = (a[0], a[1], a[2])

which might move the value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created issue #178

T2: From<T1>,
{
[
a.0.into(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO-someday: it would be better to use ocaml::Value::field to avoid copying in rust here.

@@ -61,7 +60,15 @@ fn test_generic_gate() {
// add a zero gate, just because
let wires = Wire::new(abs_row);
gates.push(CircuitGate::<Fp>::zero(abs_row, wires));
abs_row += 1;
//abs_row += 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left there in case someone wants to continue the test with more gates :o

@mimoo mimoo force-pushed the mimoo/serialization3 branch from c2f59a4 to aff4fd3 Compare October 11, 2021 18:58
@mimoo
Copy link
Contributor Author

mimoo commented Oct 11, 2021

rebase

@mimoo mimoo merged commit 34e0c85 into master Oct 11, 2021
@mimoo mimoo deleted the mimoo/serialization3 branch October 11, 2021 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants