mirror of
https://github.com/mii443/merkle.rs.git
synced 2025-09-01 22:59:16 +00:00
Add serde support.
This adds the `serialization-serde` feature, which implements serde's `Serialize` and `Deserialize` traits for `Proof` and `Lemma`. Fixes #30
This commit is contained in:
committed by
Romain Ruetschi
parent
b20059f773
commit
cc7fccc97c
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
## [Unreleased](https://github.com/SpinResearch/merkle.rs/compare/1.6.0...master)
|
## [Unreleased](https://github.com/SpinResearch/merkle.rs/compare/1.6.0...master)
|
||||||
|
|
||||||
|
- Support serde with the feature flag `serialization-serde`.
|
||||||
|
|
||||||
> Nothing yet.
|
> Nothing yet.
|
||||||
|
|
||||||
## [1.6.0](https://github.com/SpinResearch/merkle.rs/compare/1.5.0...1.6.0) - 2018-05-15
|
## [1.6.0](https://github.com/SpinResearch/merkle.rs/compare/1.5.0...1.6.0) - 2018-05-15
|
||||||
|
@ -20,9 +20,15 @@ categories = ["data-structures", "cryptography"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ring = "^0.12.0"
|
ring = "^0.12.0"
|
||||||
protobuf = { version = "^1.6.0", optional = true }
|
protobuf = { version = "^1.6.0", optional = true }
|
||||||
|
serde = { version = "^1.0.55", optional = true }
|
||||||
|
serde_derive = { version = "^1.0.55", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
serde_json = "1.0.17"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
serialization-protobuf = [ "protobuf" ]
|
serialization-protobuf = [ "protobuf" ]
|
||||||
|
serialization-serde = [ "serde", "serde_derive" ]
|
||||||
|
|
||||||
[package.metadata.release]
|
[package.metadata.release]
|
||||||
sign-commit = true
|
sign-commit = true
|
||||||
|
@ -13,6 +13,12 @@ extern crate ring;
|
|||||||
#[cfg(feature = "serialization-protobuf")]
|
#[cfg(feature = "serialization-protobuf")]
|
||||||
extern crate protobuf;
|
extern crate protobuf;
|
||||||
|
|
||||||
|
#[cfg(feature = "serialization-serde")]
|
||||||
|
extern crate serde;
|
||||||
|
#[cfg(feature = "serialization-serde")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
mod merkletree;
|
mod merkletree;
|
||||||
pub use merkletree::MerkleTree;
|
pub use merkletree::MerkleTree;
|
||||||
|
|
||||||
|
28
src/proof.rs
28
src/proof.rs
@ -9,9 +9,11 @@ use hashutils::HashUtils;
|
|||||||
|
|
||||||
/// An inclusion proof represent the fact that a `value` is a member
|
/// An inclusion proof represent the fact that a `value` is a member
|
||||||
/// of a `MerkleTree` with root hash `root_hash`, and hash function `algorithm`.
|
/// of a `MerkleTree` with root hash `root_hash`, and hash function `algorithm`.
|
||||||
|
#[cfg_attr(feature = "serialization-serde", derive(Serialize, Deserialize))]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Proof<T> {
|
pub struct Proof<T> {
|
||||||
/// The hashing algorithm used in the original `MerkleTree`
|
/// The hashing algorithm used in the original `MerkleTree`
|
||||||
|
#[cfg_attr(feature = "serialization-serde", serde(with = "algorithm_serde"))]
|
||||||
pub algorithm: &'static Algorithm,
|
pub algorithm: &'static Algorithm,
|
||||||
|
|
||||||
/// The hash of the root of the original `MerkleTree`
|
/// The hash of the root of the original `MerkleTree`
|
||||||
@ -24,6 +26,30 @@ pub struct Proof<T> {
|
|||||||
pub value: T,
|
pub value: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serialization-serde")]
|
||||||
|
mod algorithm_serde {
|
||||||
|
use ring::digest::{self, Algorithm};
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use serde::de::Error;
|
||||||
|
|
||||||
|
pub fn serialize<S: Serializer>(algorithm: &&'static Algorithm, se: S)
|
||||||
|
-> Result<S::Ok, S::Error> {
|
||||||
|
// The `Debug` implementation of `Algorithm` prints its ID.
|
||||||
|
format!("{:?}", algorithm).serialize(se)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> Result<&'static Algorithm, D::Error> {
|
||||||
|
match Deserialize::deserialize(de)? {
|
||||||
|
"SHA1" => Ok(&digest::SHA1),
|
||||||
|
"SHA256" => Ok(&digest::SHA256),
|
||||||
|
"SHA384" => Ok(&digest::SHA384),
|
||||||
|
"SHA512" => Ok(&digest::SHA512),
|
||||||
|
"SHA512_256" => Ok(&digest::SHA512_256),
|
||||||
|
_ => Err(D::Error::custom("unknown hash algorithm")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> PartialEq for Proof<T> {
|
impl<T: PartialEq> PartialEq for Proof<T> {
|
||||||
fn eq(&self, other: &Proof<T>) -> bool {
|
fn eq(&self, other: &Proof<T>) -> bool {
|
||||||
self.root_hash == other.root_hash && self.lemma == other.lemma && self.value == other.value
|
self.root_hash == other.root_hash && self.lemma == other.lemma && self.value == other.value
|
||||||
@ -107,6 +133,7 @@ impl<T> Proof<T> {
|
|||||||
/// A `Lemma` holds the hash of a node, the hash of its sibling node,
|
/// A `Lemma` holds the hash of a node, the hash of its sibling node,
|
||||||
/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`
|
/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`
|
||||||
/// must be equal to this `node_hash`.
|
/// must be equal to this `node_hash`.
|
||||||
|
#[cfg_attr(feature = "serialization-serde", derive(Serialize, Deserialize))]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Lemma {
|
pub struct Lemma {
|
||||||
pub node_hash: Vec<u8>,
|
pub node_hash: Vec<u8>,
|
||||||
@ -173,6 +200,7 @@ impl Lemma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Tags a value so that we know from which branch of a `Tree` (if any) it was found.
|
/// Tags a value so that we know from which branch of a `Tree` (if any) it was found.
|
||||||
|
#[cfg_attr(feature = "serialization-serde", derive(Serialize, Deserialize))]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub enum Positioned<T> {
|
pub enum Positioned<T> {
|
||||||
/// The value was found in the left branch
|
/// The value was found in the left branch
|
||||||
|
12
src/tests.rs
12
src/tests.rs
@ -275,3 +275,15 @@ fn test_custom_hashable_impl() {
|
|||||||
assert_eq!(tree.count(), 10);
|
assert_eq!(tree.count(), 10);
|
||||||
assert_eq!(tree.height(), 4);
|
assert_eq!(tree.height(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serialization-serde")]
|
||||||
|
#[test]
|
||||||
|
fn test_serialize_proof_with_serde() {
|
||||||
|
extern crate serde_json;
|
||||||
|
|
||||||
|
let values = (1..10).map(|x| vec![x]).collect::<Vec<_>>();
|
||||||
|
let tree = MerkleTree::from_vec(digest, values);
|
||||||
|
let proof = tree.gen_proof(vec![5]);
|
||||||
|
let serialized = serde_json::to_string(&proof).expect("serialize proof");
|
||||||
|
assert_eq!(proof, serde_json::from_str(&serialized).expect("deserialize proof"));
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user