Skip to content

Commit bf6d8ae

Browse files
authored
Re-implement serialization (#201)
* Serialization tests now pass again * Tidy up and test more edge-cases * Use attributes rather than custom serializer for arrays * Add JSON Schema support * Tests for JSON Schema generation and validation * Add comments * Support custom predicates * Clippy fixes * Make deserialization/constructor functions pub(crate)
1 parent 26a6b2d commit bf6d8ae

File tree

17 files changed

+551
-252
lines changed

17 files changed

+551
-252
lines changed

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,17 @@ plonky2 = { git = "https://github.com/0xPolygonZero/plonky2", optional = true }
2222
serde = "1.0.219"
2323
serde_json = "1.0.140"
2424
base64 = "0.22.1"
25-
schemars = "1.0.0-alpha.17"
25+
schemars = "0.8.22"
2626

2727
# Uncomment for debugging with https://github.com/ed255/plonky2/ at branch `feat/debug`. The repo directory needs to be checked out next to the pod2 repo directory.
2828
# [patch."https://github.com/0xPolygonZero/plonky2"]
2929
# plonky2 = { path = "../plonky2/plonky2" }
3030

31+
[dev-dependencies]
32+
pretty_assertions = "1.4.1"
33+
# Used only for testing JSON Schema generation and validation.
34+
jsonschema = "0.30.0"
35+
3136
[features]
3237
default = ["backend_plonky2"]
3338
backend_plonky2 = ["plonky2"]

src/backends/plonky2/mainpod/operation.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ use std::fmt;
22

33
use anyhow::{anyhow, Result};
44
use plonky2::field::types::Field;
5+
use serde::{Deserialize, Serialize};
56

6-
// use serde::{Deserialize, Serialize};
77
use crate::{
88
backends::plonky2::{mainpod::Statement, primitives::merkletree::MerkleClaimAndProof},
99
middleware::{self, OperationType, Params, ToFields, F},
1010
};
1111

12-
#[derive(Clone, Debug, PartialEq)]
12+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1313
pub enum OperationArg {
1414
None,
1515
Index(usize),
@@ -31,7 +31,7 @@ impl OperationArg {
3131
}
3232
}
3333

34-
#[derive(Clone, Debug, PartialEq)]
34+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
3535
pub enum OperationAux {
3636
None,
3737
MerkleProofIndex(usize),
@@ -47,7 +47,7 @@ impl ToFields for OperationAux {
4747
}
4848
}
4949

50-
#[derive(Clone, Debug, PartialEq)]
50+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
5151
pub struct Operation(pub OperationType, pub Vec<OperationArg>, pub OperationAux);
5252

5353
impl Operation {

src/backends/plonky2/mainpod/statement.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::fmt;
22

33
use anyhow::{anyhow, Result};
4+
use serde::{Deserialize, Serialize};
45

5-
// use serde::{Deserialize, Serialize};
66
use crate::middleware::{
77
self, NativePredicate, Params, Predicate, StatementArg, ToFields, WildcardValue,
88
};
99

10-
#[derive(Clone, Debug, PartialEq)]
10+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1111
pub struct Statement(pub Predicate, pub Vec<StatementArg>);
1212

1313
impl Statement {

src/backends/plonky2/mock/mainpod.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
use std::{any::Any, fmt};
66

77
use anyhow::{anyhow, Result};
8+
use base64::{prelude::BASE64_STANDARD, Engine};
9+
use serde::{Deserialize, Serialize};
810

9-
// use base64::prelude::*;
10-
// use serde::{Deserialize, Serialize};
11-
use crate::backends::plonky2::mainpod::process_private_statements_operations;
1211
use crate::{
1312
backends::plonky2::{
1413
mainpod::{
1514
extract_merkle_proofs, hash_statements, layout_statements, normalize_statement,
16-
process_public_statements_operations, Operation, Statement,
15+
process_private_statements_operations, process_public_statements_operations, Operation,
16+
Statement,
1717
},
1818
primitives::merkletree::MerkleClaimAndProof,
1919
},
@@ -31,7 +31,7 @@ impl PodProver for MockProver {
3131
}
3232
}
3333

34-
#[derive(Clone, Debug)]
34+
#[derive(Clone, Debug, Serialize, Deserialize)]
3535
pub struct MockMainPod {
3636
params: Params,
3737
id: PodId,
@@ -166,14 +166,17 @@ impl MockMainPod {
166166
})
167167
}
168168

169-
// pub fn deserialize(serialized: String) -> Result<Self> {
170-
// let proof = String::from_utf8(BASE64_STANDARD.decode(&serialized)?)
171-
// .map_err(|e| anyhow::anyhow!("Invalid base64 encoding: {}", e))?;
172-
// let pod: MockMainPod = serde_json::from_str(&proof)
173-
// .map_err(|e| anyhow::anyhow!("Failed to parse proof: {}", e))?;
169+
// MockMainPods include some internal private state which is necessary
170+
// for verification. In non-mock Pods, this state will not be necessary,
171+
// as the public statements can be verified using a ZK proof.
172+
pub(crate) fn deserialize(serialized: String) -> Result<Self> {
173+
let proof = String::from_utf8(BASE64_STANDARD.decode(&serialized)?)
174+
.map_err(|e| anyhow::anyhow!("Invalid base64 encoding: {}", e))?;
175+
let pod: MockMainPod = serde_json::from_str(&proof)
176+
.map_err(|e| anyhow::anyhow!("Failed to parse proof: {}", e))?;
174177

175-
// Ok(pod)
176-
// }
178+
Ok(pod)
179+
}
177180
}
178181

179182
impl Pod for MockMainPod {
@@ -282,8 +285,7 @@ impl Pod for MockMainPod {
282285
}
283286

284287
fn serialized_proof(&self) -> String {
285-
todo!()
286-
// BASE64_STANDARD.encode(serde_json::to_string(self).unwrap())
288+
BASE64_STANDARD.encode(serde_json::to_string(self).unwrap())
287289
}
288290
}
289291

src/backends/plonky2/mock/signedpod.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,11 @@ pub struct MockSignedPod {
4343
kvs: HashMap<Key, Value>,
4444
}
4545

46-
// impl MockSignedPod {
47-
// pub fn deserialize(id: PodId, signature: String, dict: Dictionary) -> Self {
48-
// Self {
49-
// id,
50-
// signature,
51-
// dict,
52-
// }
53-
// }
54-
// }
46+
impl MockSignedPod {
47+
pub(crate) fn new(id: PodId, signature: String, kvs: HashMap<Key, Value>) -> Self {
48+
Self { id, signature, kvs }
49+
}
50+
}
5551

5652
impl Pod for MockSignedPod {
5753
fn verify(&self) -> Result<()> {

src/backends/plonky2/primitives/merkletree.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::{collections::HashMap, fmt, iter::IntoIterator};
44

55
use anyhow::{anyhow, Result};
66
use plonky2::field::types::Field;
7+
use serde::{Deserialize, Serialize};
78

8-
// use serde::{Deserialize, Serialize};
99
pub use super::merkletree_circuit::*;
1010
use crate::middleware::{hash_fields, Hash, RawValue, EMPTY_HASH, EMPTY_VALUE, F};
1111

@@ -208,7 +208,7 @@ impl fmt::Display for MerkleTree {
208208
}
209209
}
210210

211-
#[derive(Clone, Debug, PartialEq)]
211+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
212212
pub struct MerkleProof {
213213
// note: currently we don't use the `_existence` field, we would use if we merge the methods
214214
// `verify` and `verify_nonexistence` into a single one
@@ -260,7 +260,7 @@ impl MerkleProof {
260260
}
261261
}
262262

263-
#[derive(Clone, Debug, PartialEq)]
263+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
264264
pub struct MerkleClaimAndProof {
265265
pub root: Hash,
266266
pub key: RawValue,

src/frontend/custom.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::{collections::HashMap, fmt, hash as h, iter, iter::zip, sync::Arc};
44
use anyhow::{anyhow, Result};
55
use schemars::JsonSchema;
66

7-
// use serde::{Deserialize, Serialize};
87
use crate::{
98
frontend::{AnchoredKey, Statement, StatementArg},
109
middleware::{

src/frontend/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ use std::{collections::HashMap, convert::From, fmt};
55

66
use anyhow::{anyhow, Result};
77
use itertools::Itertools;
8+
use serde::{Deserialize, Serialize};
89

9-
// use schemars::JsonSchema;
10-
11-
// use serde::{Deserialize, Serialize};
1210
use crate::middleware::{
1311
self, check_st_tmpl, hash_str, AnchoredKey, Key, MainPodInputs, NativeOperation,
1412
NativePredicate, OperationAux, OperationType, Params, PodId, PodProver, PodSigner, Predicate,
@@ -17,8 +15,10 @@ use crate::middleware::{
1715

1816
mod custom;
1917
mod operation;
18+
mod serialization;
2019
pub use custom::*;
2120
pub use operation::*;
21+
use serialization::*;
2222

2323
/// This type is just for presentation purposes.
2424
#[derive(Clone, Debug, Default, PartialEq, Eq)]
@@ -66,8 +66,8 @@ impl SignedPodBuilder {
6666

6767
/// SignedPod is a wrapper on top of backend::SignedPod, which additionally stores the
6868
/// string<-->hash relation of the keys.
69-
#[derive(Debug, Clone)]
70-
// #[serde(try_from = "SignedPodHelper", into = "SignedPodHelper")]
69+
#[derive(Debug, Clone, Serialize, Deserialize)]
70+
#[serde(try_from = "SignedPodHelper", into = "SignedPodHelper")]
7171
pub struct SignedPod {
7272
pub pod: Box<dyn middleware::Pod>,
7373
// We store a copy of the key values for quick access
@@ -591,8 +591,8 @@ impl MainPodBuilder {
591591
}
592592
}
593593

594-
#[derive(Debug, Clone)]
595-
// #[serde(try_from = "MainPodHelper", into = "MainPodHelper")]
594+
#[derive(Debug, Clone, Serialize, Deserialize)]
595+
#[serde(try_from = "MainPodHelper", into = "MainPodHelper")]
596596
pub struct MainPod {
597597
pub pod: Box<dyn middleware::Pod>,
598598
pub public_statements: Vec<Statement>,

src/frontend/operation.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::fmt;
22

3-
// use serde::{Deserialize, Serialize};
43
use crate::{
54
frontend::SignedPod,
65
middleware::{AnchoredKey, OperationAux, OperationType, Statement, Value},

0 commit comments

Comments
 (0)