From 103fe4e0f50fc7afcb687db612a772a442b47ed7 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 6 Oct 2023 12:45:08 +0200 Subject: [PATCH 1/4] mpc: make MerkleBuoy generic over the depth --- commit_verify/src/mpc/atoms.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/commit_verify/src/mpc/atoms.rs b/commit_verify/src/mpc/atoms.rs index d8291fe1..f59dafbc 100644 --- a/commit_verify/src/mpc/atoms.rs +++ b/commit_verify/src/mpc/atoms.rs @@ -20,6 +20,7 @@ // limitations under the License. use std::io::Write; +use std::ops::SubAssign; use amplify::confinement::MediumOrdMap; use amplify::num::u5; @@ -171,14 +172,15 @@ impl Default for MultiSource { } } -/// Helper struct to track depth when merging two merkle blocks. -pub struct MerkleBuoy { - buoy: u5, - stack: Option>, +/// Helper struct to track depth when working with Merkle blocks. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct MerkleBuoy + Default = u5> { + buoy: D, + stack: Option>>, } -impl MerkleBuoy { - pub fn new(top: u5) -> Self { +impl + Default> MerkleBuoy { + pub fn new(top: D) -> Self { Self { buoy: top, stack: None, @@ -186,7 +188,7 @@ impl MerkleBuoy { } /// Measure the current buoy level. - pub fn level(&self) -> u5 { + pub fn level(&self) -> D { self.stack .as_ref() .map(Box::as_ref) @@ -200,8 +202,8 @@ impl MerkleBuoy { /// /// 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 { + pub fn push(&mut self, depth: D) -> bool { + if depth == D::default() { return false; } match self From 270ac2c743fd84e94d1e5e5e2c9e964ef5f65949 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 6 Oct 2023 12:45:31 +0200 Subject: [PATCH 2/4] mpc: move MerkleBuoy to merkle module --- commit_verify/src/merkle.rs | 57 ++++++++++++++++++++++++++++++++++ commit_verify/src/mpc/atoms.rs | 57 ---------------------------------- commit_verify/src/mpc/block.rs | 4 +-- commit_verify/src/mpc/mod.rs | 5 ++- 4 files changed, 63 insertions(+), 60 deletions(-) diff --git a/commit_verify/src/merkle.rs b/commit_verify/src/merkle.rs index 39ca6a7d..aa90ca2c 100644 --- a/commit_verify/src/merkle.rs +++ b/commit_verify/src/merkle.rs @@ -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; @@ -202,3 +203,59 @@ where T: CommitmentId + Copy fn merkle_leaves(&self) -> Self::LeafIter<'_> { self.iter().copied() } } + +/// Helper struct to track depth when working with Merkle blocks. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct MerkleBuoy + Default = u5> { + buoy: D, + stack: Option>>, +} + +impl + Default> MerkleBuoy { + 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, + } + } +} diff --git a/commit_verify/src/mpc/atoms.rs b/commit_verify/src/mpc/atoms.rs index f59dafbc..c6aae141 100644 --- a/commit_verify/src/mpc/atoms.rs +++ b/commit_verify/src/mpc/atoms.rs @@ -20,7 +20,6 @@ // limitations under the License. use std::io::Write; -use std::ops::SubAssign; use amplify::confinement::MediumOrdMap; use amplify::num::u5; @@ -171,59 +170,3 @@ impl Default for MultiSource { } } } - -/// Helper struct to track depth when working with Merkle blocks. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct MerkleBuoy + Default = u5> { - buoy: D, - stack: Option>>, -} - -impl + Default> MerkleBuoy { - 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, - } - } -} diff --git a/commit_verify/src/mpc/block.rs b/commit_verify/src/mpc/block.rs index 991d46fb..d598bea4 100644 --- a/commit_verify/src/mpc/block.rs +++ b/commit_verify/src/mpc/block.rs @@ -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}; diff --git a/commit_verify/src/mpc/mod.rs b/commit_verify/src/mpc/mod.rs index 8df462f8..3ccd157b 100644 --- a/commit_verify/src/mpc/mod.rs +++ b/commit_verify/src/mpc/mod.rs @@ -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 From 247db25f5ac380814d5676cb54a7dc1dba7faf13 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 6 Oct 2023 12:47:43 +0200 Subject: [PATCH 3/4] merkle: plan for MerkleBuoy generic default to be removed in v0.11 --- commit_verify/src/merkle.rs | 1 + commit_verify/src/mpc/block.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/commit_verify/src/merkle.rs b/commit_verify/src/merkle.rs index aa90ca2c..d15cf7ce 100644 --- a/commit_verify/src/merkle.rs +++ b/commit_verify/src/merkle.rs @@ -205,6 +205,7 @@ where T: CommitmentId + Copy } /// Helper struct to track depth when working with Merkle blocks. +// TODO: v0.11 Remove default generic from MerkleBuoy #[derive(Clone, PartialEq, Eq, Debug)] pub struct MerkleBuoy + Default = u5> { buoy: D, diff --git a/commit_verify/src/mpc/block.rs b/commit_verify/src/mpc/block.rs index d598bea4..887dee6c 100644 --- a/commit_verify/src/mpc/block.rs +++ b/commit_verify/src/mpc/block.rs @@ -430,7 +430,7 @@ impl MerkleBlock { } Ordering::Less => { cross_section.push(n2); - let mut buoy = MerkleBuoy::new(n2_depth); + let mut buoy = MerkleBuoy::::new(n2_depth); let mut stop = false; last_b = None; cross_section.extend(b.by_ref().take_while(|n| { @@ -448,7 +448,7 @@ impl MerkleBlock { } Ordering::Greater => { cross_section.push(n1); - let mut buoy = MerkleBuoy::new(n1_depth); + let mut buoy = MerkleBuoy::::new(n1_depth); let mut stop = false; last_a = None; cross_section.extend(a.by_ref().take_while(|n| { From d0f97e3e99fb9164949d841e09b8394bd0374f17 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 6 Oct 2023 12:55:29 +0200 Subject: [PATCH 4/4] merkle: impl Default for MerkleBuoy --- commit_verify/src/merkle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commit_verify/src/merkle.rs b/commit_verify/src/merkle.rs index d15cf7ce..c187e9e1 100644 --- a/commit_verify/src/merkle.rs +++ b/commit_verify/src/merkle.rs @@ -206,7 +206,7 @@ where T: CommitmentId + Copy /// Helper struct to track depth when working with Merkle blocks. // TODO: v0.11 Remove default generic from MerkleBuoy -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Default)] pub struct MerkleBuoy + Default = u5> { buoy: D, stack: Option>>,