Skip to content

Commit

Permalink
Merge pull request #138 from LNP-BP/buoy
Browse files Browse the repository at this point in the history
Make MerkleBuoy generic utility
  • Loading branch information
dr-orlovsky authored Oct 9, 2023
2 parents f122107 + d0f97e3 commit b8ae567
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 60 deletions.
58 changes: 58 additions & 0 deletions commit_verify/src/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use core::{iter, slice};
use std::collections::{btree_set, BTreeSet};
use std::io::Write;
use std::ops::SubAssign;

use amplify::confinement::Confined;
use amplify::num::u5;
Expand Down Expand Up @@ -202,3 +203,60 @@ where T: CommitmentId<Id = MerkleNode> + Copy

fn merkle_leaves(&self) -> Self::LeafIter<'_> { self.iter().copied() }
}

/// Helper struct to track depth when working with Merkle blocks.
// TODO: v0.11 Remove default generic from MerkleBuoy
#[derive(Clone, PartialEq, Eq, Debug, Default)]
pub struct MerkleBuoy<D: Copy + Eq + SubAssign<u8> + Default = u5> {
buoy: D,
stack: Option<Box<MerkleBuoy<D>>>,
}

impl<D: Copy + Eq + SubAssign<u8> + Default> MerkleBuoy<D> {
pub fn new(top: D) -> Self {
Self {
buoy: top,
stack: None,
}
}

/// Measure the current buoy level.
pub fn level(&self) -> D {
self.stack
.as_ref()
.map(Box::as_ref)
.map(MerkleBuoy::level)
.unwrap_or(self.buoy)
}

/// Add new item to the buoy.
///
/// Returns whether the buoy have surfaced in a result.
///
/// The buoy surfaces each time the contents it has is reduced to two depth
/// of the same level.
pub fn push(&mut self, depth: D) -> bool {
if depth == D::default() {
return false;
}
match self
.stack
.as_mut()
.map(|stack| (stack.push(depth), stack.level()))
{
None if depth == self.buoy => {
self.buoy -= 1;
true
}
None => {
self.stack = Some(Box::new(MerkleBuoy::new(depth)));
false
}
Some((true, level)) => {
self.stack = None;
self.push(level)
}
Some((false, _)) => false,
}
}
}
55 changes: 0 additions & 55 deletions commit_verify/src/mpc/atoms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,58 +170,3 @@ impl Default for MultiSource {
}
}
}

/// Helper struct to track depth when merging two merkle blocks.
pub struct MerkleBuoy {
buoy: u5,
stack: Option<Box<MerkleBuoy>>,
}

impl MerkleBuoy {
pub fn new(top: u5) -> Self {
Self {
buoy: top,
stack: None,
}
}

/// Measure the current buoy level.
pub fn level(&self) -> u5 {
self.stack
.as_ref()
.map(Box::as_ref)
.map(MerkleBuoy::level)
.unwrap_or(self.buoy)
}

/// Add new item to the buoy.
///
/// Returns whether the buoy have surfaced in a result.
///
/// The buoy surfaces each time the contents it has is reduced to two depth
/// of the same level.
pub fn push(&mut self, depth: u5) -> bool {
if depth == u5::ZERO {
return false;
}
match self
.stack
.as_mut()
.map(|stack| (stack.push(depth), stack.level()))
{
None if depth == self.buoy => {
self.buoy -= 1;
true
}
None => {
self.stack = Some(Box::new(MerkleBuoy::new(depth)));
false
}
Some((true, level)) => {
self.stack = None;
self.push(level)
}
Some((false, _)) => false,
}
}
}
8 changes: 4 additions & 4 deletions commit_verify/src/mpc/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ use amplify::num::u5;
use strict_encoding::StrictEncode;

use crate::id::CommitmentId;
use crate::merkle::MerkleNode;
use crate::merkle::{MerkleBuoy, MerkleNode};
use crate::mpc::atoms::Leaf;
use crate::mpc::tree::protocol_id_pos;
use crate::mpc::{
Commitment, MerkleBuoy, MerkleTree, Message, MessageMap, Proof, ProtocolId, MERKLE_LNPBP4_TAG,
Commitment, MerkleTree, Message, MessageMap, Proof, ProtocolId, MERKLE_LNPBP4_TAG,
};
use crate::{Conceal, LIB_NAME_COMMIT_VERIFY};

Expand Down Expand Up @@ -430,7 +430,7 @@ impl MerkleBlock {
}
Ordering::Less => {
cross_section.push(n2);
let mut buoy = MerkleBuoy::new(n2_depth);
let mut buoy = MerkleBuoy::<u5>::new(n2_depth);
let mut stop = false;
last_b = None;
cross_section.extend(b.by_ref().take_while(|n| {
Expand All @@ -448,7 +448,7 @@ impl MerkleBlock {
}
Ordering::Greater => {
cross_section.push(n1);
let mut buoy = MerkleBuoy::new(n1_depth);
let mut buoy = MerkleBuoy::<u5>::new(n1_depth);
let mut stop = false;
last_a = None;
cross_section.extend(a.by_ref().take_while(|n| {
Expand Down
5 changes: 4 additions & 1 deletion commit_verify/src/mpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ mod atoms;
mod tree;
mod block;

pub use atoms::{Commitment, Leaf, MerkleBuoy, Message, MessageMap, MultiSource, ProtocolId};
pub use atoms::{Commitment, Leaf, Message, MessageMap, MultiSource, ProtocolId};
pub use block::{InvalidProof, LeafNotKnown, MergeError, MerkleBlock, MerkleProof};
#[cfg(feature = "rand")]
pub use tree::Error;
pub use tree::MerkleTree;

#[deprecated(since = "0.10.6", note = "use commit_verify::merkle::MerkleBuoy instead")]
pub use crate::merkle::MerkleBuoy;

pub const MERKLE_LNPBP4_TAG: u128 = u128::from_le_bytes(*b"urn:lnpbp:lnpbp4");

/// Marker trait for variates of LNPBP-4 commitment proofs, which differ by the
Expand Down

0 comments on commit b8ae567

Please sign in to comment.