Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions tree_hash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ keywords.workspace = true
categories.workspace = true

[dependencies]
alloy-primitives = "1"
alloy-primitives = { version = "1", default-features = false }
ethereum_hashing = { version = "0.8", default-features = false, features = ["zero_hash_cache"] }
ethereum_ssz = "0.10"
smallvec = "1"
typenum = "1"
ethereum_ssz = { version = "0.10", default-features = false }
smallvec = { version = "1", default-features = false }
typenum = { version = "1", default-features = false }

[dev-dependencies]
proptest = "1"
Expand All @@ -25,6 +25,8 @@ ethereum_ssz_derive = "0.10"
trybuild = "1"

[features]
default = ["ring"]
default = ["std", "ring"]
std = ["alloy-primitives/std", "ethereum_ssz/std", "ethereum_hashing/std"]
arbitrary = ["alloy-primitives/arbitrary"]
ring = ["ethereum_hashing/ring"]
sha2 = ["ethereum_hashing/sha2"]
4 changes: 2 additions & 2 deletions tree_hash/src/impls.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::*;
use alloc::sync::Arc;
use alloy_primitives::{Address, FixedBytes, U128, U256};
use ssz::{Bitfield, Fixed, Progressive, Variable};
use std::sync::Arc;
use typenum::Unsigned;

fn int_to_hash256(int: u64) -> Hash256 {
Expand Down Expand Up @@ -267,8 +267,8 @@ impl<N: Unsigned + Clone> TreeHash for Bitfield<Fixed<N>> {
#[cfg(test)]
mod test {
use super::*;
use core::str::FromStr;
use ssz::{BitList, BitVector};
use std::str::FromStr;
use typenum::{U32, U8};

#[test]
Expand Down
8 changes: 6 additions & 2 deletions tree_hash/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

pub mod impls;
mod merkle_hasher;
mod merkleize_padded;
Expand Down Expand Up @@ -27,7 +31,7 @@ pub type PackedEncoding = SmallVec<[u8; SMALLVEC_SIZE]>;
///
/// `minimum_leaf_count` will only be used if it is greater than or equal to the minimum number of leaves that can be created from `bytes`.
pub fn merkle_root(bytes: &[u8], minimum_leaf_count: usize) -> Hash256 {
let leaves = std::cmp::max(bytes.len().div_ceil(HASHSIZE), minimum_leaf_count);
let leaves = core::cmp::max(bytes.len().div_ceil(HASHSIZE), minimum_leaf_count);

if leaves == 0 {
// If there are no bytes then the hash is always zero.
Expand Down Expand Up @@ -60,7 +64,7 @@ pub fn merkle_root(bytes: &[u8], minimum_leaf_count: usize) -> Hash256 {
///
/// Used in `TreeHash` for inserting the length of a list above it's root.
pub fn mix_in_length(root: &Hash256, length: usize) -> Hash256 {
let usize_len = std::mem::size_of::<usize>();
let usize_len = core::mem::size_of::<usize>();

let mut length_bytes = [0; BYTES_PER_CHUNK];
length_bytes[0..usize_len].copy_from_slice(&length.to_le_bytes());
Expand Down
9 changes: 5 additions & 4 deletions tree_hash/src/merkle_hasher.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{get_zero_hash, Hash256, HASHSIZE};
use core::mem;
use ethereum_hashing::{Context, Sha256Context, HASH_LEN};
use smallvec::{smallvec, SmallVec};
use std::mem;

type SmallVec8<T> = SmallVec<[T; 8]>;

Expand All @@ -11,8 +11,8 @@ pub enum Error {
MaximumLeavesExceeded { max_leaves: usize },
}

impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Error::MaximumLeavesExceeded { max_leaves } => write!(
f,
Expand All @@ -22,6 +22,7 @@ impl std::fmt::Display for Error {
}
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}

/// Helper struct to store either a hash digest or a slice.
Expand Down Expand Up @@ -215,7 +216,7 @@ impl MerkleHasher {
pub fn write(&mut self, bytes: &[u8]) -> Result<(), Error> {
let mut ptr = 0;
while ptr <= bytes.len() {
let slice = &bytes[ptr..std::cmp::min(bytes.len(), ptr + HASHSIZE)];
let slice = &bytes[ptr..core::cmp::min(bytes.len(), ptr + HASHSIZE)];

if self.buffer.is_empty() && slice.len() == HASHSIZE {
self.process_leaf(slice)?;
Expand Down
7 changes: 4 additions & 3 deletions tree_hash/src/merkleize_padded.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{get_zero_hash, Hash256, BYTES_PER_CHUNK};
use alloc::{vec, vec::Vec};
use ethereum_hashing::{hash32_concat, hash_fixed};

/// Merkleize `bytes` and return the root, optionally padding the tree out to `min_leaves` number of
Expand Down Expand Up @@ -52,10 +53,10 @@ pub fn merkleize_padded(bytes: &[u8], min_leaves: usize) -> Hash256 {
//
// Since there is more than one node in this tree (see prior assertion), there should always be
// one or more initial parent nodes.
let initial_parents_with_values = std::cmp::max(1, next_even_number(leaves_with_values) / 2);
let initial_parents_with_values = core::cmp::max(1, next_even_number(leaves_with_values) / 2);

// The number of leaves in the full tree (including padding nodes).
let num_leaves = std::cmp::max(leaves_with_values, min_leaves).next_power_of_two();
let num_leaves = core::cmp::max(leaves_with_values, min_leaves).next_power_of_two();

// The number of levels in the tree.
//
Expand Down Expand Up @@ -313,7 +314,7 @@ mod test {
fn test_against_reference(input: &[u8], min_nodes: usize) {
let mut reference_input = input.to_vec();
reference_input.resize(
std::cmp::max(
core::cmp::max(
reference_input.len(),
min_nodes.next_power_of_two() * BYTES_PER_CHUNK,
),
Expand Down
3 changes: 2 additions & 1 deletion tree_hash/src/merkleize_standard.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
use alloc::{vec, vec::Vec};
use ethereum_hashing::hash;

/// Merkleizes bytes and returns the root, using a simple algorithm that does not optimize to avoid
Expand Down Expand Up @@ -30,7 +31,7 @@ pub fn merkleize_standard(bytes: &[u8]) -> Hash256 {
let nodes = num_nodes(leaves);
let internal_nodes = nodes - leaves;

let num_bytes = std::cmp::max(internal_nodes, 1) * HASHSIZE + bytes.len();
let num_bytes = core::cmp::max(internal_nodes, 1) * HASHSIZE + bytes.len();

let mut o: Vec<u8> = vec![0; internal_nodes * HASHSIZE];

Expand Down
8 changes: 5 additions & 3 deletions tree_hash/src/progressive_merkle_hasher.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{Hash256, MerkleHasher, BYTES_PER_CHUNK};
use alloc::vec::Vec;
use ethereum_hashing::hash32_concat;
use smallvec::SmallVec;

Expand All @@ -7,14 +8,15 @@ pub enum Error {
MerkleHasher(crate::merkle_hasher::Error),
}

impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Error::MerkleHasher(e) => write!(f, "{e}"),
}
}
}

#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Expand Down Expand Up @@ -108,7 +110,7 @@ impl ProgressiveMerkleHasher {
return Ok(());
}

let chunk = std::mem::take(&mut self.buffer);
let chunk = core::mem::take(&mut self.buffer);
self.process_chunk(&chunk)?;
}

Expand Down