From d98a921928b35f12185453693f9798130294766b Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Mon, 22 Apr 2024 21:29:15 -0400 Subject: [PATCH 1/7] tendermint_hash --- src/tendermint_hash.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/tendermint_hash.rs diff --git a/src/tendermint_hash.rs b/src/tendermint_hash.rs new file mode 100644 index 0000000..6a6a08e --- /dev/null +++ b/src/tendermint_hash.rs @@ -0,0 +1,40 @@ +use sha2::{Sha256, Digest}; + +fn hash(bytes: &[u8]) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.update(bytes); + let result: [u8; 32] = hasher.finalize().into(); + result +} + +const LEAF_PREFIX: &[u8] = &[0]; +const INNER_PREFIX: &[u8] = &[1]; + +fn leaf_hash(bytes: &[u8]) -> [u8; 32] { + hash([LEAF_PREFIX, bytes].concat().as_slice()) +} + +fn inner_hash(left: &[u8], right: &[u8]) -> [u8; 32] { + hash([INNER_PREFIX, left, right].concat().as_slice()) +} + +pub struct TmSha2Hasher; + +impl TmSha2Hasher { + pub fn new() -> Self { + TmSha2Hasher + } +} + +impl MerkleHash for TmSha2Hasher { + type Output = [u8; 32]; + + const EMPTY_ROOT : Self::Output = [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]; + + fn hash_leaf(&self, data: &[u8]) -> Self::Output { + leaf_hash(data) + } + fn hash_nodes(&self, left: &Self::Output, right: &Self::Output) -> Self::Output { + inner_hash(left, right) + } +} \ No newline at end of file From d5e7a6c3ae2fea7ef2ef5bc0d63c61b08e058278 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Tue, 23 Apr 2024 11:10:26 -0400 Subject: [PATCH 2/7] document and link to tree --- src/lib.rs | 3 +++ src/tendermint_hash.rs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 052ace6..bde298a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,9 @@ use simple_merkle::{ mod namespaced_hash; pub use namespaced_hash::*; +mod tendermint_hash; +pub use tendermint_hash::*; + // pub mod db; pub mod nmt_proof; pub mod simple_merkle; diff --git a/src/tendermint_hash.rs b/src/tendermint_hash.rs index 6a6a08e..fec4f53 100644 --- a/src/tendermint_hash.rs +++ b/src/tendermint_hash.rs @@ -1,5 +1,7 @@ use sha2::{Sha256, Digest}; +use crate::simple_merkle::tree::MerkleHash; + fn hash(bytes: &[u8]) -> [u8; 32] { let mut hasher = Sha256::new(); hasher.update(bytes); @@ -18,9 +20,11 @@ fn inner_hash(left: &[u8], right: &[u8]) -> [u8; 32] { hash([INNER_PREFIX, left, right].concat().as_slice()) } +/// A sha256 hasher, compatible with [Tendermint merkle hash](https://github.com/informalsystems/tendermint-rs/blob/979456c9f33463944f97f7ea3900640e59f7ea6d/tendermint/src/merkle.rs) pub struct TmSha2Hasher; impl TmSha2Hasher { + /// Create a new instance of the hasher pub fn new() -> Self { TmSha2Hasher } From 1c76d890e368955e5b9094471570cb7c34efebd3 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Tue, 23 Apr 2024 11:21:17 -0400 Subject: [PATCH 3/7] update to use less copy --- src/tendermint_hash.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/tendermint_hash.rs b/src/tendermint_hash.rs index fec4f53..5dc70a4 100644 --- a/src/tendermint_hash.rs +++ b/src/tendermint_hash.rs @@ -2,22 +2,25 @@ use sha2::{Sha256, Digest}; use crate::simple_merkle::tree::MerkleHash; -fn hash(bytes: &[u8]) -> [u8; 32] { - let mut hasher = Sha256::new(); - hasher.update(bytes); - let result: [u8; 32] = hasher.finalize().into(); - result -} - const LEAF_PREFIX: &[u8] = &[0]; const INNER_PREFIX: &[u8] = &[1]; fn leaf_hash(bytes: &[u8]) -> [u8; 32] { - hash([LEAF_PREFIX, bytes].concat().as_slice()) + //hash([LEAF_PREFIX, bytes].concat().as_slice()) + let mut hasher = Sha256::new(); + hasher.update(LEAF_PREFIX); + hasher.update(bytes); + let result: [u8; 32] = hasher.finalize().into(); + result } fn inner_hash(left: &[u8], right: &[u8]) -> [u8; 32] { - hash([INNER_PREFIX, left, right].concat().as_slice()) + let mut hasher = Sha256::new(); + hasher.update(INNER_PREFIX); + hasher.update(left); + hasher.update(right); + let result: [u8; 32] = hasher.finalize().into(); + result } /// A sha256 hasher, compatible with [Tendermint merkle hash](https://github.com/informalsystems/tendermint-rs/blob/979456c9f33463944f97f7ea3900640e59f7ea6d/tendermint/src/merkle.rs) From 19f3e166df727445f09d756789a71e31ecabc746 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Tue, 23 Apr 2024 16:14:07 -0400 Subject: [PATCH 4/7] removed let binding and added a test --- Cargo.toml | 1 + src/tendermint_hash.rs | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index def0d03..55d7d59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ borsh = { version = "0.10.0", optional = true } borsh = { version = "0.10.0" } serde_json = "1.0.96" postcard = { version = "1.0.4" } +tendermint = {version = "0.35.0"} [features] default = ["std"] diff --git a/src/tendermint_hash.rs b/src/tendermint_hash.rs index 5dc70a4..46f3461 100644 --- a/src/tendermint_hash.rs +++ b/src/tendermint_hash.rs @@ -10,8 +10,7 @@ fn leaf_hash(bytes: &[u8]) -> [u8; 32] { let mut hasher = Sha256::new(); hasher.update(LEAF_PREFIX); hasher.update(bytes); - let result: [u8; 32] = hasher.finalize().into(); - result + hasher.finalize().into() } fn inner_hash(left: &[u8], right: &[u8]) -> [u8; 32] { @@ -19,8 +18,7 @@ fn inner_hash(left: &[u8], right: &[u8]) -> [u8; 32] { hasher.update(INNER_PREFIX); hasher.update(left); hasher.update(right); - let result: [u8; 32] = hasher.finalize().into(); - result + hasher.finalize().into() } /// A sha256 hasher, compatible with [Tendermint merkle hash](https://github.com/informalsystems/tendermint-rs/blob/979456c9f33463944f97f7ea3900640e59f7ea6d/tendermint/src/merkle.rs) @@ -44,4 +42,22 @@ impl MerkleHash for TmSha2Hasher { fn hash_nodes(&self, left: &Self::Output, right: &Self::Output) -> Self::Output { inner_hash(left, right) } +} + +#[cfg(test)] +mod tests { + use super::*; + use tendermint::merkle::simple_hash_from_byte_vectors; + use crate::{MerkleTree, MemDb}; + #[test] + fn test_tm_hash_matches_upstream() { + let leaves: Vec<&[u8]> = vec![b"leaf_1", b"leaf_2", b"leaf_3", b"leaf_4"]; + let hasher = TmSha2Hasher{}; + let mut tree: MerkleTree, TmSha2Hasher> = MerkleTree::with_hasher(hasher); + leaves.iter().for_each(|leaf| { + tree.push_raw_leaf(leaf); + }); + let hash_from_byte_slices = simple_hash_from_byte_vectors::(leaves.as_slice()); + assert_eq!(tree.root().as_ref(), &hash_from_byte_slices); + } } \ No newline at end of file From ca8e7767739a144cc5a960df990915efa58d9ca7 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Thu, 25 Apr 2024 08:52:52 -0500 Subject: [PATCH 5/7] Fix warnings --- src/lib.rs | 4 ++-- src/tendermint_hash.rs | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index bde298a..3810495 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,7 @@ mod maybestd { #[cfg(not(feature = "std"))] pub use core::{cmp, fmt, hash, marker, mem, ops}; #[cfg(feature = "std")] - pub use std::{boxed, cmp, collections, fmt, format, hash, marker, mem, ops, string, vec}; + pub use std::{boxed, cmp, fmt, hash, marker, mem, ops, vec}; pub mod hash_or_btree_map { #[cfg(not(feature = "std"))] @@ -417,7 +417,7 @@ pub enum RangeProofType { #[cfg(test)] mod tests { - use crate::maybestd::{format, vec::Vec}; + use crate::maybestd::vec::Vec; use crate::NamespaceMerkleHasher; use crate::{ namespaced_hash::{NamespaceId, NamespacedSha2Hasher}, diff --git a/src/tendermint_hash.rs b/src/tendermint_hash.rs index 46f3461..0e877b1 100644 --- a/src/tendermint_hash.rs +++ b/src/tendermint_hash.rs @@ -24,6 +24,12 @@ fn inner_hash(left: &[u8], right: &[u8]) -> [u8; 32] { /// A sha256 hasher, compatible with [Tendermint merkle hash](https://github.com/informalsystems/tendermint-rs/blob/979456c9f33463944f97f7ea3900640e59f7ea6d/tendermint/src/merkle.rs) pub struct TmSha2Hasher; +impl Default for TmSha2Hasher { + fn default() -> Self { + Self::new() + } +} + impl TmSha2Hasher { /// Create a new instance of the hasher pub fn new() -> Self { From 2b5e18b78716eef1adabe61b888521bc34cd47a7 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Thu, 25 Apr 2024 09:01:28 -0500 Subject: [PATCH 6/7] Improve feature granularity in maybestd to fix warns --- src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3810495..fbca929 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,11 +18,15 @@ extern crate alloc; mod maybestd { #[cfg(not(feature = "std"))] - pub use alloc::{boxed, collections, format, string, vec}; + pub use alloc::{boxed, vec}; + #[cfg(all(not(feature = "std"), feature = "serde"))] + pub use alloc::{format, string}; #[cfg(not(feature = "std"))] pub use core::{cmp, fmt, hash, marker, mem, ops}; #[cfg(feature = "std")] pub use std::{boxed, cmp, fmt, hash, marker, mem, ops, vec}; + #[cfg(all(feature = "std", feature = "serde"))] + pub use std::{format, string}; pub mod hash_or_btree_map { #[cfg(not(feature = "std"))] From d10e85958504da328ca6d9f939be6e3a2853ebd7 Mon Sep 17 00:00:00 2001 From: Preston Evans Date: Thu, 25 Apr 2024 09:41:17 -0500 Subject: [PATCH 7/7] fmt --- src/tendermint_hash.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tendermint_hash.rs b/src/tendermint_hash.rs index 0e877b1..9657080 100644 --- a/src/tendermint_hash.rs +++ b/src/tendermint_hash.rs @@ -1,4 +1,4 @@ -use sha2::{Sha256, Digest}; +use sha2::{Digest, Sha256}; use crate::simple_merkle::tree::MerkleHash; @@ -40,7 +40,10 @@ impl TmSha2Hasher { impl MerkleHash for TmSha2Hasher { type Output = [u8; 32]; - const EMPTY_ROOT : Self::Output = [227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]; + const EMPTY_ROOT: Self::Output = [ + 227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, + 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85, + ]; fn hash_leaf(&self, data: &[u8]) -> Self::Output { leaf_hash(data) @@ -53,12 +56,12 @@ impl MerkleHash for TmSha2Hasher { #[cfg(test)] mod tests { use super::*; + use crate::{MemDb, MerkleTree}; use tendermint::merkle::simple_hash_from_byte_vectors; - use crate::{MerkleTree, MemDb}; #[test] fn test_tm_hash_matches_upstream() { let leaves: Vec<&[u8]> = vec![b"leaf_1", b"leaf_2", b"leaf_3", b"leaf_4"]; - let hasher = TmSha2Hasher{}; + let hasher = TmSha2Hasher {}; let mut tree: MerkleTree, TmSha2Hasher> = MerkleTree::with_hasher(hasher); leaves.iter().for_each(|leaf| { tree.push_raw_leaf(leaf); @@ -66,4 +69,4 @@ mod tests { let hash_from_byte_slices = simple_hash_from_byte_vectors::(leaves.as_slice()); assert_eq!(tree.root().as_ref(), &hash_from_byte_slices); } -} \ No newline at end of file +}