mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-10 12:11:59 +00:00
Remove tree hashing from ssz crate
This commit is contained in:
@@ -8,7 +8,7 @@ pub const MERKLE_HASH_CHUNCK: usize = 2 * BYTES_PER_CHUNK;
|
||||
|
||||
pub use cached_tree_hash::{BTreeOverlay, CachedTreeHashSubTree, Error, TreeHashCache};
|
||||
pub use signed_root::SignedRoot;
|
||||
pub use standard_tree_hash::{efficient_merkleize, TreeHash};
|
||||
pub use standard_tree_hash::{merkle_root, TreeHash};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum TreeHashType {
|
||||
@@ -25,3 +25,26 @@ fn num_sanitized_leaves(num_bytes: usize) -> usize {
|
||||
fn num_nodes(num_leaves: usize) -> usize {
|
||||
2 * num_leaves - 1
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_tree_hash_for_ssz_bytes {
|
||||
($type: ident) => {
|
||||
impl tree_hash::TreeHash for $type {
|
||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||
tree_hash::TreeHashType::List
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
panic!("bytesN should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
panic!("bytesN should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
tree_hash::merkle_root(&ssz::ssz_encode(self))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ use hashing::hash;
|
||||
use int_to_bytes::int_to_bytes32;
|
||||
use ssz::ssz_encode;
|
||||
|
||||
mod impls;
|
||||
|
||||
pub trait TreeHash {
|
||||
fn tree_hash_type() -> TreeHashType;
|
||||
|
||||
@@ -13,70 +15,9 @@ pub trait TreeHash {
|
||||
fn tree_hash_root(&self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
impl TreeHash for u64 {
|
||||
fn tree_hash_type() -> TreeHashType {
|
||||
TreeHashType::Basic
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
ssz_encode(self)
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
HASHSIZE / 8
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
int_to_bytes32(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TreeHash for Vec<T>
|
||||
where
|
||||
T: TreeHash,
|
||||
{
|
||||
fn tree_hash_type() -> TreeHashType {
|
||||
TreeHashType::List
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
unreachable!("List should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
unreachable!("List should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
let leaves = match T::tree_hash_type() {
|
||||
TreeHashType::Basic => {
|
||||
let mut leaves =
|
||||
Vec::with_capacity((HASHSIZE / T::tree_hash_packing_factor()) * self.len());
|
||||
|
||||
for item in self {
|
||||
leaves.append(&mut item.tree_hash_packed_encoding());
|
||||
}
|
||||
|
||||
leaves
|
||||
}
|
||||
TreeHashType::Composite | TreeHashType::List => {
|
||||
let mut leaves = Vec::with_capacity(self.len() * HASHSIZE);
|
||||
|
||||
for item in self {
|
||||
leaves.append(&mut item.tree_hash_root())
|
||||
}
|
||||
|
||||
leaves
|
||||
}
|
||||
};
|
||||
|
||||
// Mix in the length
|
||||
let mut root_and_len = Vec::with_capacity(HASHSIZE * 2);
|
||||
root_and_len.append(&mut efficient_merkleize(&leaves)[0..32].to_vec());
|
||||
root_and_len.append(&mut int_to_bytes32(self.len() as u64));
|
||||
|
||||
hash(&root_and_len)
|
||||
}
|
||||
pub fn merkle_root(bytes: &[u8]) -> Vec<u8> {
|
||||
// TODO: replace this with a _more_ efficient fn which is more memory efficient.
|
||||
efficient_merkleize(&bytes)[0..32].to_vec()
|
||||
}
|
||||
|
||||
pub fn efficient_merkleize(bytes: &[u8]) -> Vec<u8> {
|
||||
|
||||
97
eth2/utils/tree_hash/src/standard_tree_hash/impls.rs
Normal file
97
eth2/utils/tree_hash/src/standard_tree_hash/impls.rs
Normal file
@@ -0,0 +1,97 @@
|
||||
use super::*;
|
||||
use ethereum_types::H256;
|
||||
|
||||
macro_rules! impl_for_bitsize {
|
||||
($type: ident, $bit_size: expr) => {
|
||||
impl TreeHash for $type {
|
||||
fn tree_hash_type() -> TreeHashType {
|
||||
TreeHashType::Basic
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
ssz_encode(self)
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
HASHSIZE / ($bit_size / 8)
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
int_to_bytes32(*self as u64)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_for_bitsize!(u8, 8);
|
||||
impl_for_bitsize!(u16, 16);
|
||||
impl_for_bitsize!(u32, 32);
|
||||
impl_for_bitsize!(u64, 64);
|
||||
impl_for_bitsize!(usize, 64);
|
||||
impl_for_bitsize!(bool, 8);
|
||||
|
||||
impl TreeHash for H256 {
|
||||
fn tree_hash_type() -> TreeHashType {
|
||||
TreeHashType::Basic
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
ssz_encode(self)
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
ssz_encode(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TreeHash for Vec<T>
|
||||
where
|
||||
T: TreeHash,
|
||||
{
|
||||
fn tree_hash_type() -> TreeHashType {
|
||||
TreeHashType::List
|
||||
}
|
||||
|
||||
fn tree_hash_packed_encoding(&self) -> Vec<u8> {
|
||||
unreachable!("List should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_packing_factor() -> usize {
|
||||
unreachable!("List should never be packed.")
|
||||
}
|
||||
|
||||
fn tree_hash_root(&self) -> Vec<u8> {
|
||||
let leaves = match T::tree_hash_type() {
|
||||
TreeHashType::Basic => {
|
||||
let mut leaves =
|
||||
Vec::with_capacity((HASHSIZE / T::tree_hash_packing_factor()) * self.len());
|
||||
|
||||
for item in self {
|
||||
leaves.append(&mut item.tree_hash_packed_encoding());
|
||||
}
|
||||
|
||||
leaves
|
||||
}
|
||||
TreeHashType::Composite | TreeHashType::List => {
|
||||
let mut leaves = Vec::with_capacity(self.len() * HASHSIZE);
|
||||
|
||||
for item in self {
|
||||
leaves.append(&mut item.tree_hash_root())
|
||||
}
|
||||
|
||||
leaves
|
||||
}
|
||||
};
|
||||
|
||||
// Mix in the length
|
||||
let mut root_and_len = Vec::with_capacity(HASHSIZE * 2);
|
||||
root_and_len.append(&mut merkle_root(&leaves));
|
||||
root_and_len.append(&mut int_to_bytes32(self.len() as u64));
|
||||
|
||||
hash(&root_and_len)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user