Repository: mintlayer/mintlayer-core
Pull request #795 (2023-03-29 21:55:13)

Enable scale code as a feature in merkletree crate
Another step to move the crate outside of mintlayer-core


Patch:
diff --git a/.github/scripts/codecheck.py b/.github/scripts/codecheck.py
index c2f38f2f6..85a8e944e 100755
--- a/.github/scripts/codecheck.py
+++ b/.github/scripts/codecheck.py
@@ -149,7 +149,7 @@ def check_todos():
 
 def run_checks():
     return all([
-            disallow(SCALECODEC_RE, exclude = ['serialization/core']),
+            disallow(SCALECODEC_RE, exclude = ['serialization/core', 'merkletree']),
             disallow(JSONRPSEE_RE, exclude = ['rpc']),
             check_local_licenses(),
             check_crate_versions(),
diff --git a/Cargo.lock b/Cargo.lock
index a18e64cd8..841ea7aef 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2095,6 +2095,7 @@ dependencies = [
  "blake2",
  "fixed-hash",
  "itertools",
+ "parity-scale-codec",
  "rand 0.8.5",
  "rand_chacha 0.3.1",
  "rstest",
diff --git a/common/Cargo.toml b/common/Cargo.toml
index 197c344cb..b6f0a46ca 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -9,7 +9,7 @@ rust-version.workspace = true
 
 [dependencies]
 crypto = { path = '../crypto'}
-merkletree = { path = "../merkletree" }
+merkletree = { path = "../merkletree", features = ["scale-codec"] }
 serialization = { path = "../serialization" }
 logging = { path = "../logging/" }
 script = { path = '../script'}
diff --git a/merkletree/Cargo.toml b/merkletree/Cargo.toml
index 40e3b19d4..2a57939a7 100644
--- a/merkletree/Cargo.toml
+++ b/merkletree/Cargo.toml
@@ -5,9 +5,13 @@ version.workspace = true
 edition.workspace = true
 rust-version.workspace = true
 
+[features]
+scale-codec = ["dep:parity-scale-codec"]
+
 [dependencies]
 itertools = "0.10"
 thiserror = "1.0"
+parity-scale-codec = { version = "3.1", optional = true }
 
 [dev-dependencies]
 blake2 = "0.10"
diff --git a/merkletree/src/merkle/mod.rs b/merkletree/src/merkle/mod.rs
index bd28e9774..896559c08 100644
--- a/merkletree/src/merkle/mod.rs
+++ b/merkletree/src/merkle/mod.rs
@@ -28,12 +28,12 @@ pub enum MerkleTreeFormError {
 pub enum MerkleTreeProofExtractionError {
     #[error("No leaves were provided to create a proof")]
     NoLeavesToCreateProof,
-    #[error("One or more indexes are larger than the number of leaves in the tree: {0:?} vs leaves count {1}")]
-    IndexOutOfRange(Vec<usize>, usize),
+    #[error("One or more indexes are larger than the number of leaves in the tree: {0:?} vs leaf-count {1}")]
+    IndexOutOfRange(Vec<u32>, u32),
     #[error("Leaf index out of range: {0} vs leaves count {1}")]
-    LeafIndexOutOfRange(usize, usize),
+    LeafIndexOutOfRange(u32, u32),
     #[error("Leaves indices must be sorted in ascending: {0:?}")]
-    UnsortedOrUniqueLeavesIndices(Vec<usize>),
+    UnsortedOrUniqueLeavesIndices(Vec<u32>),
     #[error("Access error: {0}")]
     AccessError(#[from] MerkleTreeAccessError),
 }
@@ -43,9 +43,9 @@ pub enum MerkleTreeAccessError {
     #[error("Invalid tree size provided is invalid: {0}")]
     InvalidTreeSize(usize),
     #[error("Invalid initial index for leaf in iterator. Provided {0} vs tree size {1}")]
-    AbsIndexOutOfRange(usize, usize),
+    AbsIndexOutOfRange(u32, u32),
     #[error("Invalid initial index for leaf in iterator. Provided {0} vs size {1}")]
-    IterStartIndexOutOfRange(usize, usize),
+    IterStartIndexOutOfRange(u32, u32),
 }
 
 #[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
@@ -53,11 +53,13 @@ pub enum MerkleProofVerificationError {
     #[error("No leaves provided")]
     LeavesContainerProvidedIsEmpty,
     #[error("Invalid tree size")]
-    InvalidTreeLeavesCount(usize),
+    InvalidTreeLeavesCount(u32),
     #[error("One or more leaves have indices out of range: {0:?} vs leaves count {1}")]
-    LeavesIndicesOutOfRange(Vec<usize>, usize),
+    LeavesIndicesOutOfRange(Vec<u32>, u32),
     #[error("One or more nodes have indices out of range: {0:?} vs tree size {1}")]
-    NodesIndicesOutOfRange(Vec<usize>, usize),
+    NodesIndicesOutOfRange(Vec<u32>, u32),
     #[error("A required node is missing. Index of node: {0}")]
-    RequiredNodeMissing(usize),
+    RequiredNodeMissing(u32),
+    #[error("Tree size arithmetic error: {0}")]
+    TreeSizeArithmeticError(u32),
 }
diff --git a/merkletree/src/merkle/pos/mod.rs b/merkletree/src/merkle/pos/mod.rs
index 582c31bb1..7e583ff93 100644
--- a/merkletree/src/merkle/pos/mod.rs
+++ b/merkletree/src/merkle/pos/mod.rs
@@ -15,7 +15,7 @@
 
 pub mod node_kind;
 
-use std::num::NonZeroUsize;
+use std::num::NonZeroU32;
 
 use self::node_kind::NodeKind;
 
@@ -27,11 +27,11 @@ use super::tree::tree_size::TreeSize;
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub struct NodePosition {
     tree_size: TreeSize,
-    absolute_index: usize,
+    absolute_index: u32,
 }
 
 impl NodePosition {
-    pub fn from_abs_index(tree_size: TreeSize, absolute_index: usize) -> Option<Self> {
+    pub fn from_abs_index(tree_size: TreeSize, absolute_index: u32) -> Option<Self> {
         if absolute_index >= tree_size.get() {
             return None;
         }
@@ -44,8 +44,8 @@ impl NodePosition {
 
     pub fn from_position(
         tree_size: TreeSize,
-        level_from_bottom: usize,
-        index_in_level: usize,
+        level_from_bottom: u32,
+        index_in_level: u32,
     ) -> Option<Self> {
         let level_count = tree_size.level_count().get();
         if level_from_bottom >= level_count {
@@ -73,13 +73,13 @@ impl NodePosition {
         self.tree_size
     }
 
-    pub fn abs_index(&self) -> usize {
+    pub fn abs_index(&self) -> u32 {
         self.absolute_index
     }
 
     /// Returns the level and index in the level of the node, as in (level, index).
     /// Notice that the index value is capped by the number of nodes in the level.
-    pub fn position(&self) -> (usize, usize) {
+    pub fn position(&self) -> (u32, u32) {
         assert!(
             self.abs_index() < self.tree_size.get(),
             "Index must be within the tree size"
@@ -87,7 +87,7 @@ impl NodePosition {
 
         let level_from_top = (self.tree_size.get() - self.abs_index() + 1)
             .next_power_of_two()
-            .trailing_zeros() as usize;
+            .trailing_zeros();
 
         let level = self.tree_size.level_count().get() - level_from_top;
         let level_start = self.tree_size.level_start(level).expect("Abs index is valid");
@@ -107,8 +107,10 @@ impl NodePosition {
         }
     }
 
-    pub fn tree_level_count(&self) -> NonZeroUsize {
-        (self.tree_size.get().trailing_ones() as usize)
+    pub fn tree_level_count(&self) -> NonZeroU32 {
+        self.tree_size
+            .get()
+            .trailing_ones()
             .try_into()
             .expect("Cannot be zero if tree_size is not zero")
     }
diff --git a/merkletree/src/merkle/proof/multi/mod.rs b/merkletree/src/merkle/proof/multi/mod.rs
index c38335a91..87f444948 100644
--- a/merkletree/src/merkle/proof/multi/mod.rs
+++ b/merkletree/src/merkle/proof/multi/mod.rs
@@ -18,7 +18,6 @@ mod ordered_node;
 use std::{
     collections::{BTreeMap, BTreeSet},
     fmt::Debug,
-    num::NonZeroUsize,
 };
 
 use itertools::Itertools;
@@ -48,7 +47,7 @@ pub struct MultiProofNodes<'a, T, H> {
     /// The minimal set of nodes needed to recreate the root hash (in addition to the leaves)
     nodes: Vec<Node<'a, T, H>>,
     /// The number of leaves in the tree, from which this proof was extracted
-    tree_leaf_count: NonZeroUsize,
+    tree_leaf_count: u32,
 }
 
 impl<T: Debug, H> Debug for MultiProofNodes<'_, T, H> {
@@ -62,8 +61,8 @@ impl<T: Debug, H> Debug for MultiProofNodes<'_, T, H> {
 }
 
 /// Ensure the leaves indices are sorted and unique
-fn is_sorted_and_unique(leaves_indices: &[usize]) -> bool {
-    leaves_indices.iter().tuple_windows::<(&usize, &usize)>().all(|(i, j)| i < j)
+fn is_sorted_and_unique(leaves_indices: &[u32]) -> bool {
+    leaves_indices.iter().tuple_windows::<(&u32, &u32)>().all(|(i, j)| i < j)
 }
 
 fn transpose<T>(v: Vec<Vec<T>>) -> Vec<Vec<T>> {
@@ -91,7 +90,7 @@ impl<'a, T, H> MultiProofNodes<'a, T, H> {
         &self.proof_leaves
     }
 
-    pub fn tree_leaf_count(&self) -> NonZeroUsize {
+    pub fn tree_leaf_count(&self) -> u32 {
         self.tree_leaf_count
     }
 }
@@ -99,7 +98,7 @@ impl<'a, T, H> MultiProofNodes<'a, T, H> {
 impl<'a, T: Clone, H: PairHasher<Type = T>> MultiProofNodes<'a, T, H> {
     pub fn from_tree_leaves(
         tree: &'a MerkleTree<T, H>,
-        leaves_indices: &[usize],
+        leaves_indices: &[u32],
     ) -> Result<Self, MerkleTreeProofExtractionError> {
         if leaves_indices.is_empty() {
             return Err(MerkleTreeProofExtractionError::NoLeavesToCreateProof);
@@ -157,7 +156,7 @@ impl<'a, T: Clone, H: PairHasher<Type = T>> MultiProofNodes<'a, T, H> {
             let siblings = nodes_of_level
                 .iter()
                 .map(|node| node.sibling().expect(sibling_err).abs_index())
-                .collect::<BTreeSet<usize>>();
+                .collect::<BTreeSet<u32>>();
 
             // We remove leaves that are already in siblings because they will come from the verification input.
             // This happens when the leaves, for which a proof is requested, are used together to build a parent node
@@ -190,14 +189,14 @@ impl<'a, T: Clone, H: PairHasher<Type = T>> MultiProofNodes<'a, T, H> {
                 .map(|i| tree.node_from_bottom(0, *i).expect("Leaves already checked"))
                 .collect(),
             nodes: proof,
-            tree_leaf_count: tree.leaf_count(),
+            tree_leaf_count: tree.leaf_count().get(),
         })
     }
 
     pub fn into_values(self) -> MultiProofHashes<T, H> {
         MultiProofHashes {
             nodes: self.nodes.into_iter().map(|n| (n.abs_index(), n.hash().clone())).collect(),
-            tree_leaf_count: self.proof_leaves[0].tree().leaf_count(),
+            tree_leaf_count: self.proof_leaves[0].tree().leaf_count().get(),
             _phantom: std::marker::PhantomData,
         }
     }
@@ -207,32 +206,33 @@ impl<'a, T: Clone, H: PairHasher<Type = T>> MultiProofNodes<'a, T, H> {
 /// This struct is supposed to be serialized and stored to be used later, unlike `MultiProofNodes`.
 #[must_use]
 #[derive(Debug, Clone)]
+#[cfg_attr(
+    feature = "scale-codec",
+    derive(parity_scale_codec::Encode, parity_scale_codec::Decode)
+)]
 pub struct MultiProofHashes<T, H> {
     /// The minimal set of nodes needed to recreate the root hash (in addition to the leaves)
-    nodes: BTreeMap<usize, T>,
+    nodes: BTreeMap<u32, T>,
     /// The number of leaves in the tree, from which this proof was extracted
-    tree_leaf_count: NonZeroUsize,
+    tree_leaf_count: u32,
     _phantom: std::marker::PhantomData<H>,
 }
 
 impl<T, H> MultiProofHashes<T, H> {
-    pub fn nodes(&self) -> &BTreeMap<usize, T> {
+    pub fn nodes(&self) -> &BTreeMap<u32, T> {
         &self.nodes
     }
 
-    pub fn tree_leaf_count(&self) -> NonZeroUsize {
+    pub fn tree_leaf_count(&self) -> u32 {
         self.tree_leaf_count
     }
 }
 
 impl<T: Eq + Clone, H: PairHasher<Type = T>> MultiProofHashes<T, H> {
     /// While verifying the multi-proof, we need to precalculate all the possible nodes that are required to build the root hash.
-    fn calculate_missing_nodes(
-        tree_size: TreeSize,
-        input: BTreeMap<&usize, &T>,
-    ) -> BTreeMap<usize, T> {
+    fn calculate_missing_nodes(tree_size: TreeSize, input: BTreeMap<&u32, &T>) -> BTreeMap<u32, T> {
         let mut result =
-            input.into_iter().map(|(a, b)| (*a, b.clone())).collect::<BTreeMap<usize, T>>();
+            input.into_iter().map(|(a, b)| (*a, b.clone())).collect::<BTreeMap<u32, T>>();
         for (index_l, index_r) in tree_size.iter_pairs_indices() {
             if !result.contains_key(&index_l) || !result.contains_key(&(index_r)) {
                 continue;
@@ -265,7 +265,7 @@ impl<T: Eq + Clone, H: PairHasher<Type = T>> MultiProofHashes<T, H> {
     /// circumventing verification by providing a proof of a single node.
     pub fn verify(
         &self,
-        leaves: BTreeMap<usize, T>,
+        leaves: BTreeMap<u32, T>,
         root: T,
     ) -> Result<ProofVerifyResult, MerkleProofVerificationError> {
         // in case it's a single-node tree, we don't need to verify or hash anything
@@ -274,21 +274,21 @@ impl<T: Eq + Clone, H: PairHasher<Type = T>> MultiProofHashes<T, H> {
             return Err(MerkleProofVerificationError::LeavesContainerProvidedIsEmpty);
         }
 
-        if !self.tree_leaf_count.get().is_power_of_two() {
+        if !self.tree_leaf_count.is_power_of_two() {
             return Err(MerkleProofVerificationError::InvalidTreeLeavesCount(
-                self.tree_leaf_count().get(),
+                self.tree_leaf_count(),
             ));
         }
 
-        if leaves.iter().any(|(index, _hash)| *index >= self.tree_leaf_count.get()) {
+        if leaves.iter().any(|(index, _hash)| *index >= self.tree_leaf_count) {
             return Err(MerkleProofVerificationError::LeavesIndicesOutOfRange(
                 leaves.keys().cloned().collect(),
-                self.tree_leaf_count.get(),
+                self.tree_leaf_count,
             ));
         }
 
-        let tree_size = TreeSize::from_value(self.tree_leaf_count.get() * 2 - 1)
-            .expect("Already proven from source");
+        let tree_size =
+            TreeSize::from_u32(self.tree_leaf_count * 2 - 1).expect("Already proven from source");
 
         if self.nodes.iter().any(|(index, _hash)| *index >= tree_size.get()) {
             return Err(MerkleProofVerificationError::NodesIndicesOutOfRange(
diff --git a/merkletree/src/merkle/proof/single/mod.rs b/merkletree/src/merkle/proof/single/mod.rs
index 3a0e762b9..36b86f00f 100644
--- a/merkletree/src/merkle/proof/single/mod.rs
+++ b/merkletree/src/merkle/proof/single/mod.rs
@@ -61,7 +61,7 @@ impl<'a, T: Clone, H: PairHasher<Type = T>> SingleProofNodes<'a, T, H> {
     /// A proof doesn't contain the root.
     pub fn from_tree_leaf(
         tree: &'a MerkleTree<T, H>,
-        leaf_index: usize,
+        leaf_index: u32,
     ) -> Result<Self, MerkleTreeProofExtractionError> {
         let leaf_count = tree.leaf_count().get();
         if leaf_index > leaf_count {
@@ -82,8 +82,8 @@ impl<'a, T: Clone, H: PairHasher<Type = T>> SingleProofNodes<'a, T, H> {
         let proof: Vec<_> = leaf.into_iter_parents().map_while(|n| n.sibling()).collect();
 
         assert_eq!(
-            proof.len(),
-            tree.level_count().get() - 1,
+            proof.len() as u32,
+            tree.level_count().get()  - 1,
             "This happens only if the we fail to find a sibling, which is only for root. In the loop, this cannot happen, so siblings must exist"
         );
 
@@ -97,7 +97,7 @@ impl<'a, T: Clone, H: PairHasher<Type = T>> SingleProofNodes<'a, T, H> {
 
     pub fn into_values(self) -> SingleProofHashes<T, H> {
         let proof = self.branch.into_iter().map(|node| node.hash().clone()).collect::<Vec<_>>();
-        let leaf_abs_index = self.leaf.into_position().position().1 as u32;
+        let leaf_abs_index = self.leaf.into_position().position().1;
         SingleProofHashes {
             leaf_index_in_level: leaf_abs_index,
             branch: proof,
@@ -111,6 +111,10 @@ impl<'a, T: Clone, H: PairHasher<Type = T>> SingleProofNodes<'a, T, H> {
 /// This struct is supposed to be serialized, unlike `SingleProofNodes`.
 #[must_use]
 #[derive(Debug, Clone, PartialEq, Eq)]
+#[cfg_attr(
+    feature = "scale-codec",
+    derive(parity_scale_codec::Encode, parity_scale_codec::Decode)
+)]
 pub struct SingleProofHashes<T, H> {
     leaf_index_in_level: u32,
     branch: Vec<T>,
diff --git a/merkletree/src/merkle/tree/mod.rs b/merkletree/src/merkle/tree/mod.rs
index a39e0d73d..b8aadf371 100644
--- a/merkletree/src/merkle/tree/mod.rs
+++ b/merkletree/src/merkle/tree/mod.rs
@@ -19,7 +19,7 @@ pub mod tree_size;
 use self::{padding::IncrementalPaddingIterator, tree_size::TreeSize};
 use std::fmt::Debug;
 
-use std::num::NonZeroUsize;
+use std::num::NonZeroU32;
 
 use super::{hasher::PairHasher, pos::NodePosition, MerkleTreeAccessError, MerkleTreeFormError};
 
@@ -70,21 +70,17 @@ impl<T: Clone, H> MerkleTree<T, H> {
             .expect("(total_node_count) By design, tree_size is always > 0")
     }
 
-    pub fn leaf_count(&self) -> NonZeroUsize {
+    pub fn leaf_count(&self) -> NonZeroU32 {
         let tree_size = self.total_node_count();
         tree_size.leaf_count()
     }
 
-    pub fn level_count(&self) -> NonZeroUsize {
+    pub fn level_count(&self) -> NonZeroU32 {
         let tree_size = self.total_node_count();
         tree_size.level_count()
     }
 
-    pub fn node_value_from_bottom(
-        &self,
-        level_from_bottom: usize,
-        index_in_level: usize,
-    ) -> Option<T> {
+    pub fn node_value_from_bottom(&self, level_from_bottom: u32, index_in_level: u32) -> Option<T> {
         let index_in_tree = NodePosition::from_position(
             self.tree.len().try_into().expect("Tree size is by design > 0"),
             level_from_bottom,
@@ -92,13 +88,13 @@ impl<T: Clone, H> MerkleTree<T, H> {
         )?
         .abs_index();
 
-        Some(self.tree[index_in_tree].clone())
+        Some(self.tree[index_in_tree as usize].clone())
     }
 
     pub fn node_from_bottom(
         &self,
-        level_from_bottom: usize,
-        index_in_level: usize,
+        level_from_bottom: u32,
+        index_in_level: u32,
     ) -> Option<Node<T, H>> {
         let absolute_index = NodePosition::from_position(
             self.tree.len().try_into().expect("Tree size is by design > 0"),
@@ -142,7 +138,7 @@ impl<T: Clone, H: PairHasher<Type = T>> MerkleTree<T, H> {
 
         let tree = Self::create_tree_from_padded_leaves(padded_leaves_iter)?;
 
-        TreeSize::from_value(tree.len()).expect("Invalid tree size. Invariant broken.");
+        TreeSize::try_from(tree.len()).expect("Invalid tree size. Invariant broken.");
         let res = Self {
             tree,
             _hasher: std::marker::PhantomData,
@@ -152,7 +148,7 @@ impl<T: Clone, H: PairHasher<Type = T>> MerkleTree<T, H> {
 
     pub fn iter_from_leaf_to_root(
         &self,
-        leaf_index: usize,
+        leaf_index: u32,
     ) -> Result<MerkleTreeNodeParentIterator<T, H>, MerkleTreeAccessError> {
         let leaf_count = self.leaf_count().get();
 
@@ -175,7 +171,7 @@ impl<T: Clone, H: PairHasher<Type = T>> MerkleTree<T, H> {
 
 pub struct Node<'a, T, H> {
     tree_ref: &'a MerkleTree<T, H>,
-    absolute_index: usize,
+    absolute_index: u32,
 }
 
 impl<T: Debug, H> Debug for Node<'_, T, H> {
@@ -208,14 +204,14 @@ impl<T, H> Copy for Node<'_, T, H> {}
 
 impl<'a, T, H> Node<'a, T, H> {
     pub fn hash(&self) -> &T {
-        &self.tree_ref.tree[self.absolute_index]
+        &self.tree_ref.tree[self.absolute_index as usize]
     }
 
     pub fn tree(&self) -> &'a MerkleTree<T, H> {
         self.tree_ref
     }
 
-    pub fn abs_index(&self) -> usize {
+    pub fn abs_index(&self) -> u32 {
         self.absolute_index
     }
 }
@@ -248,7 +244,7 @@ impl<'a, T: Clone, H: PairHasher<Type = T>> Node<'a, T, H> {
     }
 
     pub fn is_root(&self) -> bool {
-        self.absolute_index == self.tree().tree.len() - 1
+        self.absolute_index == self.tree().tree.len() as u32 - 1
     }
 
     pub fn into_iter_parents(self) -> MerkleTreeNodeParentIterator<'a, T, H> {
diff --git a/merkletree/src/merkle/tree/tree_size.rs b/merkletree/src/merkle/tree/tree_size.rs
index 00eda8100..76fc947d9 100644
--- a/merkletree/src/merkle/tree/tree_size.rs
+++ b/merkletree/src/merkle/tree/tree_size.rs
@@ -15,44 +15,48 @@
 
 use std::{
     fmt::{Display, Formatter},
-    num::NonZeroUsize,
+    num::NonZeroU32,
 };
 
 use itertools::Itertools;
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct TreeSize(usize);
+pub struct TreeSize(u32);
 
-const MAX_TREE_SIZE: usize = 1 << 31;
+const MAX_TREE_SIZE: u32 = 1 << 31;
 
 #[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
 pub enum TreeSizeError {
     #[error("Zero is invalid size for tree")]
     ZeroSize,
     #[error("Tree size must be power of two minus one; this value was found: {0}")]
-    InvalidSize(usize),
+    InvalidSize(u32),
     #[error("Tree with this huge size is not supported: {0}")]
-    HugeTreeUnsupported(usize),
+    HugeTreeUnsupported(u64),
 }
 
 impl TreeSize {
-    pub fn get(&self) -> usize {
+    pub fn get(&self) -> u32 {
         self.0
     }
 
-    pub fn leaf_count(&self) -> NonZeroUsize {
+    pub fn leaf_count(&self) -> NonZeroU32 {
         ((self.0 + 1) / 2).try_into().expect("Guaranteed by construction")
     }
 
-    pub fn level_count(&self) -> NonZeroUsize {
-        (self.0.count_ones() as usize).try_into().expect("Guaranteed by construction")
+    pub fn level_count(&self) -> NonZeroU32 {
+        self.0.count_ones().try_into().expect("Guaranteed by construction")
     }
 
-    pub fn from_value(value: usize) -> Result<Self, TreeSizeError> {
+    pub fn from_u32(value: u32) -> Result<Self, TreeSizeError> {
         Self::try_from(value)
     }
 
-    pub fn from_leaf_count(leaf_count: usize) -> Result<Self, TreeSizeError> {
+    pub fn from_usize(value: usize) -> Result<Self, TreeSizeError> {
+        Self::try_from(value)
+    }
+
+    pub fn from_leaf_count(leaf_count: u32) -> Result<Self, TreeSizeError> {
         if leaf_count == 0 {
             return Err(TreeSizeError::ZeroSize);
         }
@@ -60,7 +64,7 @@ impl TreeSize {
     }
 
     /// The absolute index, at which the first node at level `level_from_bottom` starts.
-    pub fn level_start(&self, level_from_bottom: usize) -> Option<usize> {
+    pub fn level_start(&self, level_from_bottom: u32) -> Option<u32> {
         let level_count = self.level_count().get();
         if level_from_bottom >= level_count {
             return None;
@@ -82,35 +86,47 @@ impl TreeSize {
 
     /// Creates an iterator that returns the indices of the nodes of the tree, from left to right, as pairs.
     /// Root isn't included in this iterator
-    pub fn iter_pairs_indices(&self) -> impl Iterator<Item = (usize, usize)> {
-        (0..self.get() - 1).tuple_windows::<(usize, usize)>().step_by(2)
+    pub fn iter_pairs_indices(&self) -> impl Iterator<Item = (u32, u32)> {
+        (0..self.get() - 1).tuple_windows::<(u32, u32)>().step_by(2)
     }
 }
 
-impl TryFrom<usize> for TreeSize {
+impl TryFrom<u32> for TreeSize {
     type Error = TreeSizeError;
 
-    fn try_from(value: usize) -> Result<Self, Self::Error> {
+    fn try_from(value: u32) -> Result<Self, Self::Error> {
         if value == 0 {
             Err(TreeSizeError::ZeroSize)
         } else if !(value + 1).is_power_of_two() {
             Err(TreeSizeError::InvalidSize(value))
         } else if value > MAX_TREE_SIZE {
-            Err(TreeSizeError::HugeTreeUnsupported(value))
+            Err(TreeSizeError::HugeTreeUnsupported(value as u64))
         } else {
             Ok(Self(value))
         }
     }
 }
 
-impl From<TreeSize> for usize {
+impl TryFrom<usize> for TreeSize {
+    type Error = TreeSizeError;
+
+    fn try_from(value: usize) -> Result<Self, Self::Error> {
+        if value > MAX_TREE_SIZE as usize {
+            return Err(TreeSizeError::HugeTreeUnsupported(value as u64));
+        }
+        let size: u32 = value.try_into().expect("Must fit because of last MAX_TREE_SIZE check");
+        Self::try_from(size)
+    }
+}
+
+impl From<TreeSize> for u32 {
     fn from(tree_size: TreeSize) -> Self {
         tree_size.0
     }
 }
 
-impl AsRef<usize> for TreeSize {
-    fn as_ref(&self) -> &usize {
+impl AsRef<u32> for TreeSize {
+    fn as_ref(&self) -> &u32 {
         &self.0
     }
 }
@@ -136,42 +152,39 @@ mod tests {
         let mut rng = make_seedable_rng(seed);
 
         // select simple values
-        assert_eq!(TreeSize::try_from(0), Err(TreeSizeError::ZeroSize));
-        assert_eq!(TreeSize::try_from(1), Ok(TreeSize(1)));
-        assert_eq!(TreeSize::try_from(2), Err(TreeSizeError::InvalidSize(2)));
-        assert_eq!(TreeSize::try_from(3), Ok(TreeSize(3)));
-        assert_eq!(TreeSize::try_from(4), Err(TreeSizeError::InvalidSize(4)));
-        assert_eq!(TreeSize::try_from(5), Err(TreeSizeError::InvalidSize(5)));
-        assert_eq!(TreeSize::try_from(6), Err(TreeSizeError::InvalidSize(6)));
-        assert_eq!(TreeSize::try_from(7), Ok(TreeSize(7)));
-        assert_eq!(TreeSize::try_from(8), Err(TreeSizeError::InvalidSize(8)));
-        assert_eq!(TreeSize::try_from(9), Err(TreeSizeError::InvalidSize(9)));
-        assert_eq!(TreeSize::try_from(10), Err(TreeSizeError::InvalidSize(10)));
-        assert_eq!(TreeSize::try_from(11), Err(TreeSizeError::InvalidSize(11)));
-        assert_eq!(TreeSize::try_from(12), Err(TreeSizeError::InvalidSize(12)));
-        assert_eq!(TreeSize::try_from(13), Err(TreeSizeError::InvalidSize(13)));
-        assert_eq!(TreeSize::try_from(14), Err(TreeSizeError::InvalidSize(14)));
-        assert_eq!(TreeSize::try_from(15), Ok(TreeSize(15)));
-        assert_eq!(TreeSize::try_from(16), Err(TreeSizeError::InvalidSize(16)));
+        assert_eq!(TreeSize::from_u32(0), Err(TreeSizeError::ZeroSize));
+        assert_eq!(TreeSize::from_u32(1), Ok(TreeSize(1)));
+        assert_eq!(TreeSize::from_u32(2), Err(TreeSizeError::InvalidSize(2)));
+        assert_eq!(TreeSize::from_u32(3), Ok(TreeSize(3)));
+        assert_eq!(TreeSize::from_u32(4), Err(TreeSizeError::InvalidSize(4)));
+        assert_eq!(TreeSize::from_u32(5), Err(TreeSizeError::InvalidSize(5)));
+        assert_eq!(TreeSize::from_u32(6), Err(TreeSizeError::InvalidSize(6)));
+        assert_eq!(TreeSize::from_u32(7), Ok(TreeSize(7)));
+        assert_eq!(TreeSize::from_u32(8), Err(TreeSizeError::InvalidSize(8)));
+        assert_eq!(TreeSize::from_u32(9), Err(TreeSizeError::InvalidSize(9)));
+        assert_eq!(TreeSize::from_u32(10), Err(TreeSizeError::InvalidSize(10)));
+        assert_eq!(TreeSize::from_u32(11), Err(TreeSizeError::InvalidSize(11)));
+        assert_eq!(TreeSize::from_u32(12), Err(TreeSizeError::InvalidSize(12)));
+        assert_eq!(TreeSize::from_u32(13), Err(TreeSizeError::InvalidSize(13)));
+        assert_eq!(TreeSize::from_u32(14), Err(TreeSizeError::InvalidSize(14)));
+        assert_eq!(TreeSize::from_u32(15), Ok(TreeSize(15)));
+        assert_eq!(TreeSize::from_u32(16), Err(TreeSizeError::InvalidSize(16)));
 
         // exhaustive valid
-        for i in 1..MAX_TREE_SIZE.ilog2() as usize {
-            assert_eq!(TreeSize::try_from((1 << i) - 1), Ok(TreeSize((1 << i) - 1)));
+        for i in 1..MAX_TREE_SIZE.ilog2() {
+            assert_eq!(TreeSize::from_u32((1 << i) - 1), Ok(TreeSize((1 << i) - 1)));
         }
 
         // random invalid
-        let attempts_count: usize = 1000;
+        let attempts_count: u32 = 1000;
         for _ in 0..attempts_count {
             let sz = rng.gen_range(1..MAX_TREE_SIZE);
             if (sz + 1).is_power_of_two() {
                 assert_eq!(TreeSize::try_from(sz), Ok(TreeSize(sz)));
-                assert_eq!(TreeSize::from_value(sz), Ok(TreeSize(sz)));
+                assert_eq!(TreeSize::from_u32(sz), Ok(TreeSize(sz)));
             } else {
                 assert_eq!(TreeSize::try_from(sz), Err(TreeSizeError::InvalidSize(sz)));
-                assert_eq!(
-                    TreeSize::from_value(sz),
-                    Err(TreeSizeError::InvalidSize(sz))
-                );
+                assert_eq!(TreeSize::from_u32(sz), Err(TreeSizeError::InvalidSize(sz)));
             }
         }
     }
@@ -236,35 +249,35 @@ mod tests {
 
     #[test]
     fn calculations() {
-        let t1 = TreeSize::try_from(1).unwrap();
+        let t1 = TreeSize::from_u32(1).unwrap();
         assert_eq!(t1.get(), 1);
         assert_eq!(t1.leaf_count().get(), 1);
         assert_eq!(t1.level_count().get(), 1);
         assert_eq!(t1.level_start(0).unwrap(), 0);
-        for i in 1..1000usize {
+        for i in 1..1000u32 {
             assert_eq!(t1.level_start(i), None);
         }
 
-        let t3 = TreeSize::try_from(3).unwrap();
+        let t3 = TreeSize::from_u32(3).unwrap();
         assert_eq!(t3.get(), 3);
         assert_eq!(t3.leaf_count().get(), 2);
         assert_eq!(t3.level_count().get(), 2);
-        for i in 2..1000usize {
+        for i in 2..1000u32 {
             assert_eq!(t3.level_start(i), None);
         }
 
-        let t7 = TreeSize::try_from(7).unwrap();
+        let t7 = TreeSize::from_u32(7).unwrap();
         assert_eq!(t7.get(), 7);
         assert_eq!(t7.leaf_count().get(), 4);
         assert_eq!(t7.level_count().get(), 3);
         assert_eq!(t7.level_start(0).unwrap(), 0);
         assert_eq!(t7.level_start(1).unwrap(), 4);
         assert_eq!(t7.level_start(2).unwrap(), 6);
-        for i in 3..1000usize {
+        for i in 3..1000u32 {
             assert_eq!(t7.level_start(i), None);
         }
 
-        let t15 = TreeSize::try_from(15).unwrap();
+        let t15 = TreeSize::from_u32(15).unwrap();
         assert_eq!(t15.get(), 15);
         assert_eq!(t15.leaf_count().get(), 8);
         assert_eq!(t15.level_count().get(), 4);
@@ -272,11 +285,11 @@ mod tests {
         assert_eq!(t15.level_start(1).unwrap(), 8);
         assert_eq!(t15.level_start(2).unwrap(), 12);
         assert_eq!(t15.level_start(3).unwrap(), 14);
-        for i in 4..1000usize {
+        for i in 4..1000u32 {
             assert_eq!(t15.level_start(i), None);
         }
 
-        let t31 = TreeSize::try_from(31).unwrap();
+        let t31 = TreeSize::from_u32(31).unwrap();
         assert_eq!(t31.get(), 31);
         assert_eq!(t31.leaf_count().get(), 16);
         assert_eq!(t31.level_count().get(), 5);
@@ -285,11 +298,11 @@ mod tests {
         assert_eq!(t31.level_start(2).unwrap(), 24);
         assert_eq!(t31.level_start(3).unwrap(), 28);
         assert_eq!(t31.level_start(4).unwrap(), 30);
-        for i in 5..1000usize {
+        for i in 5..1000u32 {
             assert_eq!(t31.level_start(i), None);
         }
 
-        let t63 = TreeSize::try_from(63).unwrap();
+        let t63 = TreeSize::from_u32(63).unwrap();
         assert_eq!(t63.get(), 63);
         assert_eq!(t63.leaf_count().get(), 32);
         assert_eq!(t63.level_count().get(), 6);
@@ -299,11 +312,11 @@ mod tests {
         assert_eq!(t63.level_start(3).unwrap(), 56);
         assert_eq!(t63.level_start(4).unwrap(), 60);
         assert_eq!(t63.level_start(5).unwrap(), 62);
-        for i in 6..1000usize {
+        for i in 6..1000u32 {
             assert_eq!(t63.level_start(i), None);
         }
 
-        let t127 = TreeSize::try_from(127).unwrap();
+        let t127 = TreeSize::from_u32(127).unwrap();
         assert_eq!(t127.get(), 127);
         assert_eq!(t127.leaf_count().get(), 64);
         assert_eq!(t127.level_count().get(), 7);
@@ -314,11 +327,11 @@ mod tests {
         assert_eq!(t127.level_start(4).unwrap(), 120);
         assert_eq!(t127.level_start(5).unwrap(), 124);
         assert_eq!(t127.level_start(6).unwrap(), 126);
-        for i in 7..1000usize {
+        for i in 7..1000u32 {
             assert_eq!(t127.level_start(i), None);
         }
 
-        let t255 = TreeSize::try_from(255).unwrap();
+        let t255 = TreeSize::from_u32(255).unwrap();
         assert_eq!(t255.get(), 255);
         assert_eq!(t255.leaf_count().get(), 128);
         assert_eq!(t255.level_count().get(), 8);
@@ -330,7 +343,7 @@ mod tests {
         assert_eq!(t255.level_start(5).unwrap(), 248);
         assert_eq!(t255.level_start(6).unwrap(), 252);
         assert_eq!(t255.level_start(7).unwrap(), 254);
-        for i in 8..1000usize {
+        for i in 8..1000u32 {
             assert_eq!(t255.level_start(i), None);
         }
     }
@@ -342,31 +355,31 @@ mod tests {
         let huge_tree_size = (((MAX_TREE_SIZE as u64) << 1) - 1) as usize;
         assert_eq!(
             TreeSize::try_from(huge_tree_size).unwrap_err(),
-            TreeSizeError::HugeTreeUnsupported(huge_tree_size)
+            TreeSizeError::HugeTreeUnsupported(huge_tree_size as u64)
         );
     }
 
     #[test]
     fn iter_non_root_indices() {
-        let t1 = TreeSize::try_from(1).unwrap();
+        let t1 = TreeSize::from_u32(1).unwrap();
         assert_eq!(t1.iter_pairs_indices().count(), 0);
 
-        let t3 = TreeSize::try_from(3).unwrap();
+        let t3 = TreeSize::from_u32(3).unwrap();
         assert_eq!(t3.iter_pairs_indices().collect::<Vec<_>>(), vec![(0, 1)]);
 
-        let t7 = TreeSize::try_from(7).unwrap();
+        let t7 = TreeSize::from_u32(7).unwrap();
         assert_eq!(
             t7.iter_pairs_indices().collect::<Vec<_>>(),
             vec![(0, 1), (2, 3), (4, 5)]
         );
 
-        let t15 = TreeSize::try_from(15).unwrap();
+        let t15 = TreeSize::from_u32(15).unwrap();
         assert_eq!(
             t15.iter_pairs_indices().collect::<Vec<_>>(),
             vec![(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 11), (12, 13)]
         );
 
-        let t31 = TreeSize::try_from(31).unwrap();
+        let t31 = TreeSize::from_u32(31).unwrap();
         assert_eq!(
             t31.iter_pairs_indices().collect::<Vec<_>>(),
             vec![
@@ -389,10 +402,13 @@ mod tests {
         );
 
         // Exhaustive... without this taking way too long
-        for i in 1..10_usize {
-            let tree_size = TreeSize::try_from((1 << i) - 1).unwrap();
-            assert_eq!(TreeSize::try_from((1 << i) - 1), Ok(TreeSize((1 << i) - 1)));
-            assert_eq!(tree_size.iter_pairs_indices().count(), tree_size.get() / 2);
+        for i in 1..10_u32 {
+            let tree_size = TreeSize::from_u32((1 << i) - 1).unwrap();
+            assert_eq!(TreeSize::from_u32((1 << i) - 1), Ok(TreeSize((1 << i) - 1)));
+            assert_eq!(
+                tree_size.iter_pairs_indices().count() as u32,
+                tree_size.get() / 2
+            );
             assert_eq!(
                 tree_size.iter_pairs_indices().collect::<Vec<_>>(),
                 (0..tree_size.get() / 2).map(|i| (i * 2, i * 2 + 1)).collect::<Vec<_>>()


Test patch:
diff --git a/merkletree/src/merkle/pos/tests.rs b/merkletree/src/merkle/pos/tests.rs
index e084cba54..fcc22e16b 100644
--- a/merkletree/src/merkle/pos/tests.rs
+++ b/merkletree/src/merkle/pos/tests.rs
@@ -20,7 +20,7 @@ use super::*;
 
 #[test]
 fn construction_from_abs_index() {
-    for tree_size_in in 1..16 {
+    for tree_size_in in 1..16u32 {
         let tree_size: Result<TreeSize, _> = tree_size_in.try_into();
         let tree_size = match tree_size {
             Ok(t) => {
@@ -52,7 +52,7 @@ fn construction_from_abs_index() {
     }
 }
 
-const BIG_VAL: usize = 1000;
+const BIG_VAL: u32 = 1000;
 
 #[rstest]
 #[case(1,  0..1, &[0..1], true)]
@@ -68,15 +68,15 @@ const BIG_VAL: usize = 1000;
 #[case(31, 0..2, &[16..BIG_VAL, 8..BIG_VAL,  4..BIG_VAL, 2..BIG_VAL, 1..BIG_VAL], false)]
 #[case(63, 0..2, &[32..BIG_VAL, 16..BIG_VAL, 8..BIG_VAL, 4..BIG_VAL, 2..BIG_VAL, 1..BIG_VAL], false)]
 fn construction_from_position(
-    #[case] tree_size: usize,
-    #[case] levels: Range<usize>,
-    #[case] indices_in_levels: &[Range<usize>],
+    #[case] tree_size: u32,
+    #[case] levels: Range<u32>,
+    #[case] indices_in_levels: &[Range<u32>],
     #[case] success: bool,
 ) {
     let tree_size: TreeSize = tree_size.try_into().unwrap();
 
     for level in levels {
-        for index in indices_in_levels[level].clone() {
+        for index in indices_in_levels[level as usize].clone() {
             let pos = NodePosition::from_position(tree_size, level, index);
             assert_eq!(
                 pos.is_some(),
@@ -99,8 +99,8 @@ fn construction_from_position(
 #[test]
 fn abs_index_to_and_from_pos() {
     // Exhaustive to a limit to avoid making the test take too long
-    for tree_log_size in 1..10 {
-        let tree_size: TreeSize = ((1 << tree_log_size) - 1).try_into().unwrap();
+    for tree_log_size in 1..10u32 {
+        let tree_size: TreeSize = ((1 << tree_log_size) - 1u32).try_into().unwrap();
         for abs_pos in 0..tree_size.get() {
             let pos_from_abs = NodePosition::from_abs_index(tree_size, abs_pos).unwrap();
             let (level, index) = pos_from_abs.position();
@@ -112,7 +112,7 @@ fn abs_index_to_and_from_pos() {
 
 #[test]
 fn parent_iter_one_leaf() {
-    let t_size = 1.try_into().unwrap();
+    let t_size = 1u32.try_into().unwrap();
 
     let n = NodePosition::from_abs_index(t_size, 0).unwrap();
     let mut leaf0iter = n.into_iter_parents();
@@ -122,7 +122,7 @@ fn parent_iter_one_leaf() {
 
 #[test]
 fn parent_iter_two_leaves() {
-    let t_size = 3.try_into().unwrap();
+    let t_size = 3u32.try_into().unwrap();
 
     let n = NodePosition::from_abs_index(t_size, 0).unwrap();
     let mut leaf0iter = n.into_iter_parents();
@@ -139,7 +139,7 @@ fn parent_iter_two_leaves() {
 
 #[test]
 fn parent_iter_four_leaves() {
-    let t_size = 7.try_into().unwrap();
+    let t_size = 7u32.try_into().unwrap();
 
     let n = NodePosition::from_abs_index(t_size, 0).unwrap();
     let mut leaf0iter = n.into_iter_parents();
@@ -172,7 +172,7 @@ fn parent_iter_four_leaves() {
 
 #[test]
 fn parent_iter_eight_leaves() {
-    let t_size = 15.try_into().unwrap();
+    let t_size = 15u32.try_into().unwrap();
 
     let n = NodePosition::from_abs_index(t_size, 0).unwrap();
     let mut leaf0iter = n.into_iter_parents();
@@ -241,7 +241,7 @@ fn parent_iter_eight_leaves() {
 
 #[test]
 fn node_and_siblings_one_leaf() {
-    let t_size = 1.try_into().unwrap();
+    let t_size = 1u32.try_into().unwrap();
     let node = NodePosition::from_abs_index(t_size, 0).unwrap();
 
     assert_eq!(node.abs_index(), 0);
@@ -250,7 +250,7 @@ fn node_and_siblings_one_leaf() {
 
 #[test]
 fn node_and_siblings_two_leaves() {
-    let t_size = 3.try_into().unwrap();
+    let t_size = 3u32.try_into().unwrap();
 
     // To get the sibling, we use this simple function
     let flip_even_odd = |i| if i % 2 == 0 { i + 1 } else { i - 1 };
@@ -270,7 +270,7 @@ fn node_and_siblings_two_leaves() {
 
 #[test]
 fn node_and_siblings_four_leaves() {
-    let t_size = 7.try_into().unwrap();
+    let t_size = 7u32.try_into().unwrap();
 
     // To get the sibling, we use this simple function
     let flip_even_odd = |i| if i % 2 == 0 { i + 1 } else { i - 1 };
@@ -296,7 +296,7 @@ fn node_and_siblings_four_leaves() {
 
 #[test]
 fn node_and_siblings_eight_leaves() {
-    let t_size = 15.try_into().unwrap();
+    let t_size = 15u32.try_into().unwrap();
 
     // To get the sibling, we use this simple function
     let flip_even_odd = |i| if i % 2 == 0 { i + 1 } else { i - 1 };
@@ -329,7 +329,7 @@ fn node_and_siblings_eight_leaves() {
 #[test]
 fn from_abs_index_construction_boundaries() {
     for p in 1..10 {
-        let t_size: TreeSize = ((1 << p) - 1).try_into().unwrap();
+        let t_size: TreeSize = ((1 << p) - 1u32).try_into().unwrap();
 
         for i in 0..t_size.get() {
             assert!(NodePosition::from_abs_index(t_size, i).is_some());
@@ -343,18 +343,18 @@ fn from_abs_index_construction_boundaries() {
 #[test]
 fn absolute_index_from_bottom() {
     // Tree size: 1
-    let s: TreeSize = 1.try_into().expect("is not zero");
+    let s: TreeSize = 1u32.try_into().expect("is not zero");
     assert_eq!(NodePosition::from_position(s, 0, 0).unwrap().abs_index(), 0);
 
     // Tree size: 3
-    let s: TreeSize = 3.try_into().expect("is not zero");
+    let s: TreeSize = 3u32.try_into().expect("is not zero");
     assert_eq!(NodePosition::from_position(s, 0, 0).unwrap().abs_index(), 0);
     assert_eq!(NodePosition::from_position(s, 0, 1).unwrap().abs_index(), 1);
 
     assert_eq!(NodePosition::from_position(s, 1, 0).unwrap().abs_index(), 2);
 
     // Tree size: 7
-    let s: TreeSize = 7.try_into().expect("is not zero");
+    let s: TreeSize = 7u32.try_into().expect("is not zero");
     assert_eq!(NodePosition::from_position(s, 0, 0).unwrap().abs_index(), 0);
     assert_eq!(NodePosition::from_position(s, 0, 1).unwrap().abs_index(), 1);
     assert_eq!(NodePosition::from_position(s, 0, 2).unwrap().abs_index(), 2);
@@ -366,7 +366,7 @@ fn absolute_index_from_bottom() {
     assert_eq!(NodePosition::from_position(s, 2, 0).unwrap().abs_index(), 6);
 
     // Tree size: 15
-    let s: TreeSize = 15.try_into().expect("is not zero");
+    let s: TreeSize = 15u32.try_into().expect("is not zero");
     assert_eq!(NodePosition::from_position(s, 0, 0).unwrap().abs_index(), 0);
     assert_eq!(NodePosition::from_position(s, 0, 1).unwrap().abs_index(), 1);
     assert_eq!(NodePosition::from_position(s, 0, 2).unwrap().abs_index(), 2);
diff --git a/merkletree/src/merkle/proof/multi/tests.rs b/merkletree/src/merkle/proof/multi/tests.rs
index e6d63e522..7f5416f71 100644
--- a/merkletree/src/merkle/proof/multi/tests.rs
+++ b/merkletree/src/merkle/proof/multi/tests.rs
@@ -24,10 +24,17 @@ use crate::internal::{hash_data, HashAlgo, HashedData};
 
 use super::*;
 
-fn gen_leaves(n: usize) -> Vec<HashedData> {
+fn gen_leaves(n: u32) -> Vec<HashedData> {
     (0..n).map(|i| hash_data(HashedData::from_low_u64_be(i as u64))).collect()
 }
 
+fn indices_to_map(leaves_indices: &[u32], leaves: &[HashedData]) -> BTreeMap<u32, HashedData> {
+    leaves_indices
+        .iter()
+        .map(|i| (*i, leaves[*i as usize]))
+        .collect::<BTreeMap<_, _>>()
+}
+
 #[test]
 fn sorted_and_unique() {
     assert!(is_sorted_and_unique(&[]));
@@ -67,7 +74,7 @@ fn multi_proof_one_leaf_with_multiproof_as_single_proof() {
     assert_eq!(multi_proof.nodes(), single_proof.branch());
     assert_eq!(multi_proof.proof_leaves().len(), 1);
     assert_eq!(multi_proof.proof_leaves()[0], single_proof.leaf());
-    assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count());
+    assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count().get());
 }
 
 /// Proof of one leaf must be equivalent to single proof
@@ -83,7 +90,7 @@ fn multi_proof_two_leaves_with_multiproof_as_single_proof() {
         assert_eq!(multi_proof.nodes(), single_proof.branch());
         assert_eq!(multi_proof.proof_leaves().len(), 1);
         assert_eq!(multi_proof.proof_leaves()[0], single_proof.leaf());
-        assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count());
+        assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count().get());
     }
 }
 
@@ -100,7 +107,7 @@ fn multi_proof_four_leaves_with_multiproof_as_single_proof() {
         assert_eq!(multi_proof.nodes(), single_proof.branch());
         assert_eq!(multi_proof.proof_leaves().len(), 1);
         assert_eq!(multi_proof.proof_leaves()[0], single_proof.leaf());
-        assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count());
+        assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count().get());
     }
 }
 
@@ -109,7 +116,7 @@ fn multi_proof_four_leaves_with_multiproof_as_single_proof() {
 #[case(&[0], vec![1])]
 #[case(&[1], vec![0])]
 #[case(&[0,1], vec![])]
-fn multi_proof_two_leaves_with_proof_leaves(#[case] input: &[usize], #[case] nodes: Vec<usize>) {
+fn multi_proof_two_leaves_with_proof_leaves(#[case] input: &[u32], #[case] nodes: Vec<u32>) {
     let leaves = gen_leaves(2);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves).unwrap();
 
@@ -126,7 +133,7 @@ fn multi_proof_two_leaves_with_proof_leaves(#[case] input: &[usize], #[case] nod
             .collect::<Vec<_>>(),
         input
     );
-    assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count());
+    assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count().get());
 }
 
 /// The number of tests is the 2^n-1, where n = 4 for 4 leaves, yielding 15 tests (we exclude the empty input case).
@@ -146,7 +153,7 @@ fn multi_proof_two_leaves_with_proof_leaves(#[case] input: &[usize], #[case] nod
 #[case(&[0,2,3], vec![1])]
 #[case(&[1,2,3], vec![0])]
 #[case(&[0,1,2,3], vec![])]
-fn multi_proof_four_leaves_with_proof_leaves(#[case] input: &[usize], #[case] nodes: Vec<usize>) {
+fn multi_proof_four_leaves_with_proof_leaves(#[case] input: &[u32], #[case] nodes: Vec<u32>) {
     let leaves = gen_leaves(4);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves).unwrap();
 
@@ -163,7 +170,7 @@ fn multi_proof_four_leaves_with_proof_leaves(#[case] input: &[usize], #[case] no
             .collect::<Vec<_>>(),
         input
     );
-    assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count());
+    assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count().get());
 }
 
 /// Proof of one leaf must be equivalent to single proof
@@ -179,7 +186,7 @@ fn multi_proof_eight_leaves_with_multiproof_as_single_proof() {
         assert_eq!(multi_proof.nodes(), single_proof.branch());
         assert_eq!(multi_proof.proof_leaves().len(), 1);
         assert_eq!(multi_proof.proof_leaves()[0], single_proof.leaf());
-        assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count());
+        assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count().get());
     }
 }
 
@@ -441,7 +448,7 @@ fn multi_proof_eight_leaves_with_multiproof_as_single_proof() {
 #[case(&[0,2,3,4,5,6,7], vec![1])]
 #[case(&[1,2,3,4,5,6,7], vec![0])]
 #[case(&[0,1,2,3,4,5,6,7], vec![])]
-fn multi_proof_eight_leaves_with_proof_leaves(#[case] input: &[usize], #[case] nodes: Vec<usize>) {
+fn multi_proof_eight_leaves_with_proof_leaves(#[case] input: &[u32], #[case] nodes: Vec<u32>) {
     let leaves = gen_leaves(8);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves).unwrap();
 
@@ -458,10 +465,10 @@ fn multi_proof_eight_leaves_with_proof_leaves(#[case] input: &[usize], #[case] n
             .collect::<Vec<_>>(),
         input
     );
-    assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count());
+    assert_eq!(multi_proof.tree_leaf_count(), t.leaf_count().get());
 }
 
-fn gen_leaves_indices_combinations(leaf_count: usize) -> impl Iterator<Item = Vec<usize>> {
+fn gen_leaves_indices_combinations(leaf_count: u32) -> impl Iterator<Item = Vec<u32>> {
     assert!(
         leaf_count.is_power_of_two(),
         "leaf_count must be a power of 2"
@@ -470,14 +477,15 @@ fn gen_leaves_indices_combinations(leaf_count: usize) -> impl Iterator<Item = Ve
     for i in 0..leaf_count {
         leaves_indices.push(i);
     }
-    (0..leaf_count + 1).flat_map(move |n| leaves_indices.clone().into_iter().combinations(n))
+    (0..leaf_count + 1)
+        .flat_map(move |n| leaves_indices.clone().into_iter().combinations(n as usize))
 }
 
 #[rstest]
 #[case(2)]
 #[case(4)]
 #[case(8)]
-fn leaf_count_combinations_generator(#[case] leaf_count: usize) {
+fn leaf_count_combinations_generator(#[case] leaf_count: u32) {
     assert_eq!(
         gen_leaves_indices_combinations(leaf_count).count(),
         1 << leaf_count
@@ -493,14 +501,10 @@ fn leaf_count_combinations_generator(#[case] leaf_count: usize) {
 #[case(32)]
 #[case(64)]
 #[case(128)]
-fn multi_proof_verification_leaves_empty(#[case] leaf_count: usize) {
+fn multi_proof_verification_leaves_empty(#[case] leaf_count: u32) {
     let leaves = gen_leaves(leaf_count);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
 
-    let indices_to_map = |leaves_indices: &[usize]| {
-        leaves_indices.iter().map(|i| (*i, leaves[*i])).collect::<BTreeMap<_, _>>()
-    };
-
     // So creating the proof won't work anyway without leaves... but this can still be manipulated
     assert_eq!(
         MultiProofNodes::from_tree_leaves(&t, &[]).unwrap_err(),
@@ -510,7 +514,10 @@ fn multi_proof_verification_leaves_empty(#[case] leaf_count: usize) {
     // we provide something  in the creation because it doesn't work with empty leaves, yet we test verification with it
     let multi_proof = MultiProofNodes::from_tree_leaves(&t, &[0]).unwrap();
     assert_eq!(
-        multi_proof.into_values().verify(indices_to_map(&[]), t.root()).unwrap_err(),
+        multi_proof
+            .into_values()
+            .verify(indices_to_map(&[], &leaves), t.root())
+            .unwrap_err(),
         MerkleProofVerificationError::LeavesContainerProvidedIsEmpty,
         "Failed for indices: {:?}",
         &[0]
@@ -534,7 +541,7 @@ fn multi_proof_verification_leaves_empty(#[case] leaf_count: usize) {
 #[case(Seed::from_entropy(), 128, Some(500))]
 fn multi_proof_verification(
     #[case] seed: Seed,
-    #[case] leaf_count: usize,
+    #[case] leaf_count: u32,
     #[case] max_test_cases: Option<usize>,
 ) {
     let mut rng = make_seedable_rng(seed);
@@ -542,10 +549,6 @@ fn multi_proof_verification(
     let leaves = gen_leaves(leaf_count);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
 
-    let indices_to_map = |leaves_indices: &[usize]| {
-        leaves_indices.iter().map(|i| (*i, leaves[*i])).collect::<BTreeMap<_, _>>()
-    };
-
     let mut cases = gen_leaves_indices_combinations(leaf_count)
         .take(max_test_cases.unwrap_or(usize::MAX))
         .collect::<Vec<_>>();
@@ -563,7 +566,7 @@ fn multi_proof_verification(
             continue;
         }
         let multi_proof = MultiProofNodes::from_tree_leaves(&t, &leaves_indices).unwrap();
-        let leaves_hashes_map = indices_to_map(&leaves_indices);
+        let leaves_hashes_map = indices_to_map(&leaves_indices, &leaves);
         assert!(
             multi_proof
                 .into_values()
@@ -581,14 +584,10 @@ fn multi_proof_verification_one_leaf() {
     let leaves = gen_leaves(1);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
 
-    let indices_to_map = |leaves_indices: &[usize]| {
-        leaves_indices.iter().map(|i| (*i, leaves[*i])).collect::<BTreeMap<_, _>>()
-    };
-
     let leaves_indices = vec![0];
 
     let multi_proof = MultiProofNodes::from_tree_leaves(&t, &leaves_indices).unwrap();
-    let leaves_hashes_map = indices_to_map(&leaves_indices);
+    let leaves_hashes_map = indices_to_map(&leaves_indices, &leaves);
 
     assert!(
         multi_proof
@@ -618,7 +617,7 @@ fn multi_proof_verification_one_leaf() {
 #[case(Seed::from_entropy(), 128, Some(50))]
 fn multi_proof_verification_tampered_nodes(
     #[case] seed: Seed,
-    #[case] leaf_count: usize,
+    #[case] leaf_count: u32,
     #[case] max_test_cases: Option<usize>,
 ) {
     let mut rng = make_seedable_rng(seed);
@@ -626,10 +625,6 @@ fn multi_proof_verification_tampered_nodes(
     let leaves = gen_leaves(leaf_count);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
 
-    let indices_to_map = |leaves_indices: &[usize]| {
-        leaves_indices.iter().map(|i| (*i, leaves[*i])).collect::<BTreeMap<_, _>>()
-    };
-
     let mut cases = gen_leaves_indices_combinations(leaf_count)
         .take(max_test_cases.unwrap_or(usize::MAX))
         .collect::<Vec<_>>();
@@ -656,7 +651,7 @@ fn multi_proof_verification_tampered_nodes(
             let mut multi_proof = multi_proof.clone();
             multi_proof.nodes.insert(*node_idx, HashedData::random_using(&mut rng));
 
-            let leaves_hashes_map = indices_to_map(&leaves_indices);
+            let leaves_hashes_map = indices_to_map(&leaves_indices, &leaves);
             assert!(
                 multi_proof.verify(leaves_hashes_map, t.root()).unwrap().failed(),
                 "Failed for indices: {:?}",
@@ -683,7 +678,7 @@ fn multi_proof_verification_tampered_nodes(
 #[case(Seed::from_entropy(), 128, Some(50))]
 fn multi_proof_verification_tampered_leaves(
     #[case] seed: Seed,
-    #[case] leaf_count: usize,
+    #[case] leaf_count: u32,
     #[case] max_test_cases: Option<usize>,
 ) {
     let mut rng = make_seedable_rng(seed);
@@ -691,10 +686,6 @@ fn multi_proof_verification_tampered_leaves(
     let leaves = gen_leaves(leaf_count);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
 
-    let indices_to_map = |leaves_indices: &[usize]| {
-        leaves_indices.iter().map(|i| (*i, leaves[*i])).collect::<BTreeMap<_, _>>()
-    };
-
     let mut cases = gen_leaves_indices_combinations(leaf_count)
         .take(max_test_cases.unwrap_or(usize::MAX))
         .collect::<Vec<_>>();
@@ -713,7 +704,7 @@ fn multi_proof_verification_tampered_leaves(
         }
         let multi_proof =
             MultiProofNodes::from_tree_leaves(&t, &leaves_indices).unwrap().into_values();
-        let leaves_hashes_map = indices_to_map(&leaves_indices);
+        let leaves_hashes_map = indices_to_map(&leaves_indices, &leaves);
 
         for leaf_idx in leaves_hashes_map.keys() {
             //assert that the leaf we'll mess with is part of the input list
@@ -748,7 +739,7 @@ fn multi_proof_verification_tampered_leaves(
 #[case(Seed::from_entropy(), 128, Some(50))]
 fn multi_proof_verification_tampered_tree_size_into_invalid_value(
     #[case] seed: Seed,
-    #[case] leaf_count: usize,
+    #[case] leaf_count: u32,
     #[case] max_test_cases: Option<usize>,
 ) {
     let mut rng = make_seedable_rng(seed);
@@ -756,8 +747,11 @@ fn multi_proof_verification_tampered_tree_size_into_invalid_value(
     let leaves = gen_leaves(leaf_count);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
 
-    let indices_to_map = |leaves_indices: &[usize]| {
-        leaves_indices.iter().map(|i| (*i, leaves[*i])).collect::<BTreeMap<_, _>>()
+    let indices_to_map = |leaves_indices: &[u32]| {
+        leaves_indices
+            .iter()
+            .map(|i| (*i, leaves[*i as usize]))
+            .collect::<BTreeMap<_, _>>()
     };
 
     let mut cases = gen_leaves_indices_combinations(leaf_count)
@@ -781,12 +775,11 @@ fn multi_proof_verification_tampered_tree_size_into_invalid_value(
         let leaves_hashes_map = indices_to_map(&leaves_indices);
 
         // Tamper with tree size
-        multi_proof.tree_leaf_count =
-            NonZeroUsize::new(multi_proof.tree_leaf_count.get() + 1).unwrap();
+        multi_proof.tree_leaf_count += 1;
 
         assert_eq!(
             multi_proof.verify(leaves_hashes_map, t.root()).unwrap_err(),
-            MerkleProofVerificationError::InvalidTreeLeavesCount(multi_proof.tree_leaf_count.get()),
+            MerkleProofVerificationError::InvalidTreeLeavesCount(multi_proof.tree_leaf_count),
             "Failed for indices: {:?}",
             leaves_indices
         );
@@ -810,7 +803,7 @@ fn multi_proof_verification_tampered_tree_size_into_invalid_value(
 #[case(Seed::from_entropy(), 128, Some(50))]
 fn multi_proof_verification_tampered_tree_size_into_wrong_value(
     #[case] seed: Seed,
-    #[case] leaf_count: usize,
+    #[case] leaf_count: u32,
     #[case] max_test_cases: Option<usize>,
 ) {
     let mut rng = make_seedable_rng(seed);
@@ -818,8 +811,11 @@ fn multi_proof_verification_tampered_tree_size_into_wrong_value(
     let leaves = gen_leaves(leaf_count);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
 
-    let indices_to_map = |leaves_indices: &[usize]| {
-        leaves_indices.iter().map(|i| (*i, leaves[*i])).collect::<BTreeMap<_, _>>()
+    let indices_to_map = |leaves_indices: &[u32]| {
+        leaves_indices
+            .iter()
+            .map(|i| (*i, leaves[*i as usize]))
+            .collect::<BTreeMap<_, _>>()
     };
 
     let mut cases = gen_leaves_indices_combinations(leaf_count)
@@ -843,8 +839,7 @@ fn multi_proof_verification_tampered_tree_size_into_wrong_value(
         let leaves_hashes_map = indices_to_map(&leaves_indices);
 
         // Tamper with tree size. By multiplying by 2, the size is valid, but the nodes are not for that tree
-        multi_proof.tree_leaf_count =
-            NonZeroUsize::new(multi_proof.tree_leaf_count.get() * 2).unwrap();
+        multi_proof.tree_leaf_count *= multi_proof.tree_leaf_count;
 
         let verify_result = multi_proof.verify(leaves_hashes_map, t.root());
 
diff --git a/merkletree/src/merkle/proof/single/tests.rs b/merkletree/src/merkle/proof/single/tests.rs
index 89db76f45..8a100b004 100644
--- a/merkletree/src/merkle/proof/single/tests.rs
+++ b/merkletree/src/merkle/proof/single/tests.rs
@@ -22,7 +22,7 @@ use crate::{
     tree::MerkleTree,
 };
 
-fn gen_leaves(n: usize) -> Vec<HashedData> {
+fn gen_leaves(n: u32) -> Vec<HashedData> {
     (0..n).map(|i| hash_data(HashedData::from_low_u64_be(i as u64))).collect()
 }
 
@@ -37,7 +37,10 @@ fn single_proof_one_leaf() {
     let p0 = SingleProofNodes::from_tree_leaf(&t, leaf_index).unwrap();
     assert_eq!(p0.branch().len(), 0);
 
-    assert!(p0.into_values().verify(leaves[leaf_index], t.root()).passed_trivially());
+    assert!(p0
+        .into_values()
+        .verify(leaves[leaf_index as usize], t.root())
+        .passed_trivially());
 }
 
 #[rstest]
@@ -73,9 +76,9 @@ fn single_proof_one_leaf() {
 #[case(16, 14, &[15,22,26,28])]
 #[case(16, 15, &[14,22,26,28])]
 fn single_proof_eight_leaves(
-    #[case] leaf_count: usize,
-    #[case] leaf_index: usize,
-    #[case] branch: &[usize],
+    #[case] leaf_count: u32,
+    #[case] leaf_index: u32,
+    #[case] branch: &[u32],
 ) {
     let leaves = gen_leaves(leaf_count);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
@@ -86,7 +89,10 @@ fn single_proof_eight_leaves(
         branch
     );
 
-    assert!(p.into_values().verify(leaves[leaf_index], t.root()).passed_decisively());
+    assert!(p
+        .into_values()
+        .verify(leaves[leaf_index as usize], t.root())
+        .passed_decisively());
 }
 
 #[rstest]
@@ -102,20 +108,21 @@ fn single_proof_eight_leaves(
 #[case(Seed::from_entropy(), 32)]
 #[trace]
 #[case(Seed::from_entropy(), 64)]
-fn single_proof_eight_leaves_tamper_with_nodes(#[case] seed: Seed, #[case] leaf_count: usize) {
+fn single_proof_eight_leaves_tamper_with_nodes(#[case] seed: Seed, #[case] leaf_count: u32) {
     let mut rng = make_seedable_rng(seed);
 
     let leaves = gen_leaves(leaf_count);
     let t = MerkleTree::<HashedData, HashAlgo>::from_leaves(leaves.clone()).unwrap();
 
     for (leaf_index, _) in leaves.iter().enumerate() {
+        let leaf_index = leaf_index as u32;
         let proof = SingleProofNodes::from_tree_leaf(&t, leaf_index).unwrap().into_values();
 
         // Tamper with the proof
         for node_index in 0..proof.branch.len() {
             let mut p = proof.clone();
             p.branch[node_index] = HashedData::random_using(&mut rng);
-            assert!(p.verify(leaves[leaf_index], t.root()).failed());
+            assert!(p.verify(leaves[leaf_index as usize], t.root()).failed());
         }
     }
 }
@@ -133,7 +140,7 @@ fn single_proof_eight_leaves_tamper_with_nodes(#[case] seed: Seed, #[case] leaf_
 #[case(Seed::from_entropy(), 32)]
 #[trace]
 #[case(Seed::from_entropy(), 64)]
-fn single_proof_eight_leaves_tamper_with_leaf(#[case] seed: Seed, #[case] leaf_count: usize) {
+fn single_proof_eight_leaves_tamper_with_leaf(#[case] seed: Seed, #[case] leaf_count: u32) {
     let mut rng = make_seedable_rng(seed);
 
     let leaves = gen_leaves(leaf_count);
diff --git a/merkletree/src/merkle/tree/tests.rs b/merkletree/src/merkle/tree/tests.rs
index 9f83b3cc6..92acc85ed 100644
--- a/merkletree/src/merkle/tree/tests.rs
+++ b/merkletree/src/merkle/tree/tests.rs
@@ -224,11 +224,11 @@ fn merkletree_with_arbitrary_length_5() {
 fn leaf_count_from_tree_size() {
     for i in 1..30 {
         let leaf_count = 1 << (i - 1);
-        let tree_size = (1 << i) - 1;
+        let tree_size: u32 = (1 << i) - 1;
         let tree_size: TreeSize = tree_size.try_into().unwrap();
         assert_eq!(
             tree_size.leaf_count(),
-            NonZeroUsize::new(leaf_count).unwrap(),
+            NonZeroU32::new(leaf_count).unwrap(),
             "Check failed for i = {}",
             i
         );
@@ -410,11 +410,11 @@ fn bottom_access_eight_leaves() {
 
 #[test]
 fn position_from_index_1_tree_element() {
-    let tree_size: TreeSize = 1.try_into().unwrap();
+    let tree_size: TreeSize = 1u32.try_into().unwrap();
     {
         let level = 0;
         let level_start = 0;
-        let level_end: usize = 1;
+        let level_end: u32 = 1;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i).unwrap(),
@@ -426,11 +426,11 @@ fn position_from_index_1_tree_element() {
 
 #[test]
 fn position_from_index_3_tree_elements() {
-    let tree_size: TreeSize = 3.try_into().unwrap();
+    let tree_size: TreeSize = 3u32.try_into().unwrap();
     {
         let level = 0;
         let level_start = 0;
-        let level_end: usize = 2;
+        let level_end: u32 = 2;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),
@@ -441,7 +441,7 @@ fn position_from_index_3_tree_elements() {
     {
         let level = 1;
         let level_start = 2;
-        let level_end: usize = 3;
+        let level_end: u32 = 3;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),
@@ -453,11 +453,11 @@ fn position_from_index_3_tree_elements() {
 
 #[test]
 fn position_from_index_7_tree_elements() {
-    let tree_size: TreeSize = 7.try_into().unwrap();
+    let tree_size: TreeSize = 7u32.try_into().unwrap();
     {
         let level = 0;
         let level_start = 0;
-        let level_end: usize = 4;
+        let level_end: u32 = 4;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),
@@ -468,7 +468,7 @@ fn position_from_index_7_tree_elements() {
     {
         let level = 1;
         let level_start = 4;
-        let level_end: usize = 6;
+        let level_end: u32 = 6;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),
@@ -479,7 +479,7 @@ fn position_from_index_7_tree_elements() {
     {
         let level = 2;
         let level_start = 6;
-        let level_end: usize = 7;
+        let level_end: u32 = 7;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),
@@ -491,11 +491,11 @@ fn position_from_index_7_tree_elements() {
 
 #[test]
 fn position_from_index_15_tree_elements() {
-    let tree_size: TreeSize = 15.try_into().unwrap();
+    let tree_size: TreeSize = 15u32.try_into().unwrap();
     {
         let level = 0;
         let level_start = 0;
-        let level_end: usize = 8;
+        let level_end: u32 = 8;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),
@@ -506,7 +506,7 @@ fn position_from_index_15_tree_elements() {
     {
         let level = 1;
         let level_start = 8;
-        let level_end: usize = 12;
+        let level_end: u32 = 12;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),
@@ -517,7 +517,7 @@ fn position_from_index_15_tree_elements() {
     {
         let level = 2;
         let level_start = 12;
-        let level_end: usize = 14;
+        let level_end: u32 = 14;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),
@@ -528,7 +528,7 @@ fn position_from_index_15_tree_elements() {
     {
         let level = 3;
         let level_start = 14;
-        let level_end: usize = 15;
+        let level_end: u32 = 15;
         for i in level_start..level_end {
             assert_eq!(
                 NodePosition::from_abs_index(tree_size, i),