-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
230 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
use crate::{Error, Hasher, MerkleProof, MerkleProofSerializer}; | ||
use std::convert::TryFrom; | ||
|
||
/// Serializes proof data to bytes with a direct hash order - hashes are concatenated from | ||
/// left to right, bottom to top. | ||
pub struct DirectHashesOrder {} | ||
|
||
impl MerkleProofSerializer for DirectHashesOrder { | ||
fn serialize<T: Hasher>(proof: &MerkleProof<T>) -> Vec<u8> { | ||
let mut vectors: Vec<Vec<u8>> = proof | ||
.proof_hashes() | ||
.iter() | ||
.cloned() | ||
.map(|hash| hash.into()) | ||
.collect(); | ||
vectors.drain(..).flatten().collect() | ||
} | ||
|
||
fn deserialize<T: Hasher>(bytes: &[u8]) -> Result<MerkleProof<T>, Error> { | ||
let hash_size = T::hash_size(); | ||
|
||
if bytes.len() % hash_size != 0 { | ||
return Err(Error::wrong_proof_size(bytes.len(), hash_size)); | ||
} | ||
|
||
let hashes_count = bytes.len() / hash_size; | ||
let mut proof_hashes_slices = Vec::<T::Hash>::with_capacity(hashes_count); | ||
|
||
for i in 0..hashes_count { | ||
let slice_start = i * hash_size; | ||
let slice_end = (i + 1) * hash_size; | ||
let slice = bytes | ||
.get(slice_start..slice_end) | ||
.ok_or_else(Error::vec_to_hash_conversion_error)?; | ||
let vec = | ||
Vec::<u8>::try_from(slice).map_err(|_| Error::vec_to_hash_conversion_error())?; | ||
match T::Hash::try_from(vec) { | ||
Ok(val) => proof_hashes_slices.push(val), | ||
Err(_) => return Err(Error::vec_to_hash_conversion_error()), | ||
} | ||
} | ||
|
||
Ok(MerkleProof::new(proof_hashes_slices)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use crate::{Error, Hasher, MerkleProof}; | ||
|
||
/// Trait representing a Merkle proof serializer. Used in [`MerkleProof::serialize`] and | ||
/// [`MerkleProof::deserialize`]. | ||
/// | ||
/// The library provides some built-in implementations of this trait - check | ||
/// [`proof_serializers`] module. | ||
/// | ||
/// [`proof_serializers`]: crate::proof_serializers | ||
pub trait MerkleProofSerializer { | ||
/// Serialize data from [`MerkleProof`] into a binary | ||
fn serialize<T: Hasher>(proof: &MerkleProof<T>) -> Vec<u8>; | ||
|
||
/// Deserialize data produced by [`MerkleProofSerializer::serialize`] back into [`MerkleProof`] | ||
fn deserialize<T: Hasher>(bytes: &[u8]) -> Result<MerkleProof<T>, Error>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
//! This module contains built-in implementations of the [`MerkleProofSerializer`] trait. | ||
//! Serializers are used in [`MerkleProof::serialize`] and [`MerkleProof::deserialize`] | ||
//! | ||
//! [`MerkleProofSerializer`]: crate::MerkleProofSerializer | ||
//! [`MerkleProof::serialize`]: crate::MerkleProof::serialize | ||
//! [`MerkleProof::deserialize`]: crate::MerkleProof::deserialize | ||
mod direct_hashes_order; | ||
mod merkle_proof_serializer; | ||
mod reverse_hashes_order; | ||
|
||
pub use direct_hashes_order::DirectHashesOrder; | ||
pub use merkle_proof_serializer::MerkleProofSerializer; | ||
pub use reverse_hashes_order::ReverseHashesOrder; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use crate::{Error, Hasher, MerkleProof, MerkleProofSerializer}; | ||
use std::convert::TryFrom; | ||
|
||
/// Serializes proof data to bytes with a reverse hash order - hashes are concatenated from | ||
/// top to bottom, right to left. | ||
pub struct ReverseHashesOrder {} | ||
|
||
impl MerkleProofSerializer for ReverseHashesOrder { | ||
fn serialize<T: Hasher>(proof: &MerkleProof<T>) -> Vec<u8> { | ||
let mut hashes: Vec<Vec<u8>> = proof | ||
.proof_hashes() | ||
.iter() | ||
.cloned() | ||
.map(|hash| hash.into()) | ||
.collect(); | ||
|
||
hashes.reverse(); | ||
hashes.drain(..).flatten().collect() | ||
} | ||
|
||
fn deserialize<T: Hasher>(bytes: &[u8]) -> Result<MerkleProof<T>, Error> { | ||
let hash_size = T::hash_size(); | ||
|
||
if bytes.len() % hash_size != 0 { | ||
return Err(Error::wrong_proof_size(bytes.len(), hash_size)); | ||
} | ||
|
||
let hashes_count = bytes.len() / hash_size; | ||
let mut proof_hashes_slices = Vec::<T::Hash>::with_capacity(hashes_count); | ||
|
||
for i in 0..hashes_count { | ||
let slice_start = i * hash_size; | ||
let slice_end = (i + 1) * hash_size; | ||
let slice = bytes | ||
.get(slice_start..slice_end) | ||
.ok_or_else(Error::vec_to_hash_conversion_error)?; | ||
let vec = | ||
Vec::<u8>::try_from(slice).map_err(|_| Error::vec_to_hash_conversion_error())?; | ||
match T::Hash::try_from(vec) { | ||
Ok(val) => proof_hashes_slices.push(val), | ||
Err(_) => return Err(Error::vec_to_hash_conversion_error()), | ||
} | ||
} | ||
|
||
proof_hashes_slices.reverse(); | ||
|
||
Ok(MerkleProof::new(proof_hashes_slices)) | ||
} | ||
} |