mirror of
https://github.com/mii443/merkle.rs.git
synced 2025-08-22 16:05:30 +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)
|
||||
|
||||
- Support serde with the feature flag `serialization-serde`.
|
||||
|
||||
> Nothing yet.
|
||||
|
||||
## [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]
|
||||
ring = "^0.12.0"
|
||||
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]
|
||||
serialization-protobuf = [ "protobuf" ]
|
||||
serialization-serde = [ "serde", "serde_derive" ]
|
||||
|
||||
[package.metadata.release]
|
||||
sign-commit = true
|
||||
|
@ -13,6 +13,12 @@ extern crate ring;
|
||||
#[cfg(feature = "serialization-protobuf")]
|
||||
extern crate protobuf;
|
||||
|
||||
#[cfg(feature = "serialization-serde")]
|
||||
extern crate serde;
|
||||
#[cfg(feature = "serialization-serde")]
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
mod 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
|
||||
/// of a `MerkleTree` with root hash `root_hash`, and hash function `algorithm`.
|
||||
#[cfg_attr(feature = "serialization-serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Proof<T> {
|
||||
/// The hashing algorithm used in the original `MerkleTree`
|
||||
#[cfg_attr(feature = "serialization-serde", serde(with = "algorithm_serde"))]
|
||||
pub algorithm: &'static Algorithm,
|
||||
|
||||
/// The hash of the root of the original `MerkleTree`
|
||||
@ -24,6 +26,30 @@ pub struct Proof<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> {
|
||||
fn eq(&self, other: &Proof<T>) -> bool {
|
||||
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,
|
||||
/// and a sub lemma, whose `node_hash`, when combined with this `sibling_hash`
|
||||
/// must be equal to this `node_hash`.
|
||||
#[cfg_attr(feature = "serialization-serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Lemma {
|
||||
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.
|
||||
#[cfg_attr(feature = "serialization-serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum Positioned<T> {
|
||||
/// 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.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