Merge rust-bitcoin/rust-bitcoin#910: Make NodeInfo API public

208eb65f1b Make NodeInfo API public (sanket1729)

Pull request description:

  Reported by @shesek. Users might find it convenient to manually construct the tree using `NodeInfo` API

  ```rust
  let leaf1 = NodeInfo::from_leaf_with_ver();
  let leaf2 = NodeInfo::from_leaf_with_ver();

  let root = NodeInfo::combine(leaf1, leaf2);
  let spend_info = TaprootSpendInfo::from_node_info(&secp, internal_key, root);
  ```

ACKs for top commit:
  dr-orlovsky:
    ACK 208eb65f1b
  apoelstra:
    ACK 208eb65f1b

Tree-SHA512: b5a6b26e0d4a637f7ad6e987976b31b00d3567feca85f1a0bf63aa03603aded0ddae6578b1cabc1056870a596b8cb1a83e4ef3f45802e03da80c3d58d9bab1f1
This commit is contained in:
Andrew Poelstra 2022-03-28 14:02:09 +00:00
commit 10949b7177
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 14 additions and 10 deletions

View File

@ -297,8 +297,10 @@ impl TaprootSpendInfo {
self.output_key_parity self.output_key_parity
} }
// Internal function to compute [`TaprootSpendInfo`] from NodeInfo /// Compute [`TaprootSpendInfo`] from [`NodeInfo`], and internal key.
fn from_node_info<C: secp256k1::Verification>( /// This is useful when you want to manually build a taproot tree wihtout
/// using [`TaprootBuilder`].
pub fn from_node_info<C: secp256k1::Verification>(
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
internal_key: UntweakedPublicKey, internal_key: UntweakedPublicKey,
node: NodeInfo, node: NodeInfo,
@ -498,10 +500,12 @@ impl TaprootBuilder {
} }
} }
// Internally used structure to represent the node information in taproot tree /// Data structure used to represent node information in taproot tree.
/// You can use [`TaprootSpendInfo::from_node_info`] to a get [`TaprootSpendInfo`]
/// from the merkle root [`NodeInfo`].
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub(crate) struct NodeInfo { pub struct NodeInfo {
/// Merkle Hash for this node /// Merkle Hash for this node
pub(crate) hash: sha256::Hash, pub(crate) hash: sha256::Hash,
/// information about leaves inside this node /// information about leaves inside this node
@ -509,16 +513,16 @@ pub(crate) struct NodeInfo {
} }
impl NodeInfo { impl NodeInfo {
// Create a new NodeInfo with omitted/hidden info /// Creates a new [`NodeInfo`] with omitted/hidden info.
fn new_hidden(hash: sha256::Hash) -> Self { pub fn new_hidden(hash: sha256::Hash) -> Self {
Self { Self {
hash: hash, hash: hash,
leaves: vec![], leaves: vec![],
} }
} }
// Create a new leaf with NodeInfo /// Creates a new leaf [`NodeInfo`] with given [`Script`] and [`LeafVersion`].
fn new_leaf_with_ver(script: Script, ver: LeafVersion) -> Self { pub fn new_leaf_with_ver(script: Script, ver: LeafVersion) -> Self {
let leaf = LeafInfo::new(script, ver); let leaf = LeafInfo::new(script, ver);
Self { Self {
hash: leaf.hash(), hash: leaf.hash(),
@ -526,8 +530,8 @@ impl NodeInfo {
} }
} }
// Combine two NodeInfo's to create a new parent /// Combines two [`NodeInfo`] to create a new parent.
fn combine(a: Self, b: Self) -> Result<Self, TaprootBuilderError> { pub fn combine(a: Self, b: Self) -> Result<Self, TaprootBuilderError> {
let mut all_leaves = Vec::with_capacity(a.leaves.len() + b.leaves.len()); let mut all_leaves = Vec::with_capacity(a.leaves.len() + b.leaves.len());
for mut a_leaf in a.leaves { for mut a_leaf in a.leaves {
a_leaf.merkle_branch.push(b.hash)?; // add hashing partner a_leaf.merkle_branch.push(b.hash)?; // add hashing partner