Skip to content

Commit

Permalink
Update TaprootBuilder::finalize
Browse files Browse the repository at this point in the history
This commit does two things:
1) BUG FIX: We should have checked that the length of the branch is 1
before computing the spend_info on it. This was introduced in rust-bitcoin#936, but
slipped past my review :(
2) Update the return type to return the consumed `self` value. This
function can only error when there the tree building is not complete.
Returning TaprootBuilderError causes issues in downstream projects that
need to deal with error cases which cannot happen in this function
  • Loading branch information
sanket1729 committed Jul 29, 2022
1 parent 5813ec7 commit 5cadbd5
Showing 1 changed file with 9 additions and 14 deletions.
23 changes: 9 additions & 14 deletions src/util/taproot.rs
Expand Up @@ -199,7 +199,8 @@ impl TaprootSpendInfo {
I: IntoIterator<Item=(u32, Script)>,
C: secp256k1::Verification,
{
TaprootBuilder::with_huffman_tree(script_weights)?.finalize(secp, internal_key)
let builder = TaprootBuilder::with_huffman_tree(script_weights)?;
Ok(builder.finalize(secp, internal_key).expect("Huffman Tree is always complete"))
}

/// Creates a new key spend with `internal_key` and `merkle_root`. Provide [`None`] for
Expand Down Expand Up @@ -451,19 +452,19 @@ impl TaprootBuilder {

/// Creates a [`TaprootSpendInfo`] with the given internal key.
///
// TODO: in a future breaking API change, this no longer needs to return result
/// Returns the builder as Err if the builder is not finalized.
/// See also [`TaprootBuilder::is_finalized`]
pub fn finalize<C: secp256k1::Verification>(
mut self,
secp: &Secp256k1<C>,
internal_key: UntweakedPublicKey,
) -> Result<TaprootSpendInfo, TaprootBuilderError> {
match self.branch.pop() {
None => Ok(TaprootSpendInfo::new_key_spend(secp, internal_key, None)),
Some(Some(node)) => {
) -> Result<TaprootSpendInfo, TaprootBuilder> {
match (self.branch.len(), self.branch.pop()) {
(0, None) => Ok(TaprootSpendInfo::new_key_spend(secp, internal_key, None)),
(1, Some(Some(node))) => {
Ok(TaprootSpendInfo::from_node_info(secp, internal_key, node))
}
_ => Err(TaprootBuilderError::IncompleteTree),

_ => Err(self),
}
}

Expand Down Expand Up @@ -1013,8 +1014,6 @@ pub enum TaprootBuilderError {
OverCompleteTree,
/// Invalid taproot internal key.
InvalidInternalKey(secp256k1::Error),
/// Called finalize on an incomplete tree.
IncompleteTree,
/// Called finalize on a empty tree.
EmptyTree,
}
Expand All @@ -1036,9 +1035,6 @@ impl fmt::Display for TaprootBuilderError {
TaprootBuilderError::InvalidInternalKey(ref e) => {
write_err!(f, "invalid internal x-only key"; e)
}
TaprootBuilderError::IncompleteTree => {
write!(f, "Called finalize on an incomplete tree")
}
TaprootBuilderError::EmptyTree => {
write!(f, "Called finalize on an empty tree")
}
Expand All @@ -1057,7 +1053,6 @@ impl std::error::Error for TaprootBuilderError {
InvalidMerkleTreeDepth(_)
| NodeNotInDfsOrder
| OverCompleteTree
| IncompleteTree
| EmptyTree => None
}
}
Expand Down

0 comments on commit 5cadbd5

Please sign in to comment.