Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
pallet-mmr: get hash for block that added node
Browse files Browse the repository at this point in the history
  • Loading branch information
acatangiu committed Jun 4, 2022
1 parent 1e43a41 commit 2cee03f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
2 changes: 1 addition & 1 deletion frame/merkle-mountain-range/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// all the leaves to be present.
/// It may return an error or panic if used incorrectly.
pub fn generate_batch_proof(
leaf_indices: Vec<NodeIndex>,
leaf_indices: Vec<LeafIndex>,
) -> Result<
(Vec<LeafOf<T, I>>, primitives::BatchProof<<T as Config<I>>::Hash>),
primitives::Error,
Expand Down
15 changes: 11 additions & 4 deletions frame/merkle-mountain-range/src/mmr/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,18 @@ impl<StorageType, T, I, L> Default for Storage<StorageType, T, I, L> {
}

fn parent_hash_of_ancestor_that_added_node<T: frame_system::Config>(
_pos: NodeIndex,
pos: NodeIndex,
) -> <T as frame_system::Config>::Hash {
// TODO: implement
let block_num_from_pos: <T as frame_system::Config>::BlockNumber = 42_u32.into();
<frame_system::Pallet<T>>::block_hash(block_num_from_pos)
// TODO: turn this in a pallet storage item recording block-num when pallet was activated.
let block_offset = 0;

let leaf_idx = NodesUtils::leaf_index_that_added_node(pos);
let block_num: <T as frame_system::Config>::BlockNumber =
u32::try_from(leaf_idx + block_offset)
.expect("leaf-idx < block-num; qed")
.into();
// TODO: I think this only holds recent history, so old block hashes might not be here.
<frame_system::Pallet<T>>::block_hash(block_num)
}

impl<T, I, L> mmr_lib::MMRStore<NodeOf<T, I, L>> for Storage<OffchainStorage, T, I, L>
Expand Down
48 changes: 48 additions & 0 deletions frame/merkle-mountain-range/src/mmr/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,60 @@ impl NodesUtils {

64 - self.no_of_leaves.next_power_of_two().leading_zeros()
}

/// Calculate `LeafIndex` for the leaf that added `node_index` to the MMR.
pub fn leaf_index_that_added_node(node_index: NodeIndex) -> LeafIndex {
let rightmost_leaf_pos = Self::rightmost_leaf_node_index_from_pos(node_index);
Self::leaf_node_index_to_leaf_index(rightmost_leaf_pos)
}

// Translate a _leaf_ `NodeIndex` to its `LeafIndex`.
fn leaf_node_index_to_leaf_index(pos: NodeIndex) -> LeafIndex {
if pos == 0 {
return 0
}
let (leaf_count, _) =
mmr_lib::helper::get_peaks(pos)
.iter()
.fold((0, 0), |(mut acc, last_peak), peak| {
let leaves = (peak - last_peak) >> 1;
acc += leaves + 1;
// last_peak, leaves, acc);
(acc, peak.clone())
});
leaf_count
}

// Starting from any node position get position of rightmost leaf; this is the leaf
// responsible for the addition of node `pos`.
fn rightmost_leaf_node_index_from_pos(mut pos: NodeIndex) -> NodeIndex {
use mmr_lib::helper::pos_height_in_tree;
if pos > 0 {
let mut current_height = pos_height_in_tree(pos);
let mut right_child_height = pos_height_in_tree(pos - 1);
while right_child_height < current_height {
pos = pos - 1;
current_height = right_child_height;
right_child_height = pos_height_in_tree(pos - 1);
}
}
pos
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_leaf_node_index_to_leaf_index() {
use mmr_lib::helper::leaf_index_to_pos;
for index in 0..100000 {
let pos = leaf_index_to_pos(index);
assert_eq!(NodesUtils::leaf_node_index_to_leaf_index(pos), index);
}
}

#[test]
fn should_calculate_number_of_leaves_correctly() {
assert_eq!(
Expand Down

0 comments on commit 2cee03f

Please sign in to comment.