Skip to content

Commit

Permalink
Converting LeafVersion into an enum
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Dec 30, 2021
1 parent 670e808 commit 1ab9282
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/util/sighash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl<'s> ScriptPath<'s> {
}
/// Create a new ScriptPath structure using default leaf version value
pub fn with_defaults(script: &'s Script) -> Self {
Self::new(script, LeafVersion::default())
Self::new(script, LeafVersion::TapScript)
}
/// Compute the leaf hash
pub fn leaf_hash(&self) -> TapLeafHash {
Expand Down
57 changes: 40 additions & 17 deletions src/util/taproot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//!
//! This module provides support for taproot tagged hashes.
//!

use prelude::*;
use io;
use secp256k1::{self, Secp256k1};
Expand Down Expand Up @@ -142,6 +143,8 @@ pub const TAPROOT_LEAF_MASK: u8 = 0xfe;
/// Tapscript leaf version
// https://github.com/bitcoin/bitcoin/blob/e826b22da252e0599c61d21c98ff89f366b3120f/src/script/interpreter.h#L226
pub const TAPROOT_LEAF_TAPSCRIPT: u8 = 0xc0;
/// Taproot annex prefix
pub const TAPROOT_ANNEX_PREFIX: u8 = 0x50;
/// Tapscript control base size
// https://github.com/bitcoin/bitcoin/blob/e826b22da252e0599c61d21c98ff89f366b3120f/src/script/interpreter.h#L227
pub const TAPROOT_CONTROL_BASE_SIZE: usize = 33;
Expand All @@ -152,6 +155,7 @@ pub const TAPROOT_CONTROL_MAX_SIZE: usize =

// type alias for versioned tap script corresponding merkle proof
type ScriptMerkleProofMap = BTreeMap<(Script, LeafVersion), BTreeSet<TaprootMerkleBranch>>;

/// Data structure for representing Taproot spending information.
/// Taproot output corresponds to a combination of a
/// single public key condition (known the internal key), and zero or more
Expand Down Expand Up @@ -216,7 +220,7 @@ impl TaprootSpendInfo {
{
let mut node_weights = BinaryHeap::<(Reverse<u64>, NodeInfo)>::new();
for (p, leaf) in script_weights {
node_weights.push((Reverse(p as u64), NodeInfo::new_leaf_with_ver(leaf, LeafVersion::default())));
node_weights.push((Reverse(p as u64), NodeInfo::new_leaf_with_ver(leaf, LeafVersion::TapScript)));
}
if node_weights.is_empty() {
return Err(TaprootBuilderError::IncompleteTree);
Expand Down Expand Up @@ -409,7 +413,7 @@ impl TaprootBuilder {
/// See [`TaprootBuilder::add_leaf_with_ver`] for adding a leaf with specific version
/// See [Wikipedia](https://en.wikipedia.org/wiki/Depth-first_search) for more details
pub fn add_leaf(self, depth: usize, script: Script) -> Result<Self, TaprootBuilderError> {
self.add_leaf_with_ver(depth, script, LeafVersion::default())
self.add_leaf_with_ver(depth, script, LeafVersion::TapScript)
}

/// Add a hidden/omitted node at a depth `depth` to the builder.
Expand Down Expand Up @@ -760,12 +764,12 @@ impl ControlBlock {
/// The leaf version for tapleafs
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct LeafVersion(u8);
pub enum LeafVersion {
/// BIP-342 tapscript
TapScript,

impl Default for LeafVersion {
fn default() -> Self {
LeafVersion(TAPROOT_LEAF_TAPSCRIPT)
}
/// Future leaf version
Future(u8)
}

impl LeafVersion {
Expand All @@ -780,23 +784,42 @@ impl LeafVersion {
// or an opcode that is not valid as the first opcode).
// The values that comply to this rule are the 32 even values between
// 0xc0 and 0xfe and also 0x66, 0x7e, 0x80, 0x84, 0x96, 0x98, 0xba, 0xbc, 0xbe
pub fn from_u8(ver: u8) -> Result<Self, TaprootError> {
if ver & TAPROOT_LEAF_MASK == ver && ver != 0x50 {
Ok(LeafVersion(ver))
} else {
Err(TaprootError::InvalidTaprootLeafVersion(ver))
pub fn from_u8(version: u8) -> Result<Self, TaprootError> {
match version {
TAPROOT_LEAF_TAPSCRIPT => Ok(LeafVersion::TapScript),
TAPROOT_ANNEX_PREFIX => Err(TaprootError::InvalidTaprootLeafVersion(TAPROOT_ANNEX_PREFIX)),
even if even & TAPROOT_LEAF_MASK != even => Err(TaprootError::InvalidTaprootLeafVersion(even)),
future => Ok(LeafVersion::Future(future)),
}
}

/// Get the inner version from LeafVersion
pub fn as_u8(&self) -> u8 {
self.0
match self {
LeafVersion::TapScript => TAPROOT_LEAF_TAPSCRIPT,
LeafVersion::Future(version) => *version,
}
}
}

impl Into<u8> for LeafVersion {
fn into(self) -> u8 {
self.0
self.as_u8()
}
}

impl fmt::Display for LeafVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match (self, f.alternate()) {
(LeafVersion::TapScript, false) => f.write_str("tapscript"),
(LeafVersion::TapScript, true) => fmt::Display::fmt(&TAPROOT_LEAF_TAPSCRIPT, f),
(LeafVersion::Future(version), false) => {
f.write_str("future(")?;
fmt::Display::fmt(version, f)?;
f.write_str(")")
},
(LeafVersion::Future(version), true) => fmt::Display::fmt(version, f),
}
}
}

Expand Down Expand Up @@ -1065,7 +1088,7 @@ mod test {
length,
tree_info
.script_map
.get(&(Script::from_hex(script).unwrap(), LeafVersion::default()))
.get(&(Script::from_hex(script).unwrap(), LeafVersion::TapScript))
.expect("Present Key")
.iter()
.next()
Expand All @@ -1080,7 +1103,7 @@ mod test {

// Try to create and verify a control block from each path
for (_weights, script) in script_weights {
let ver_script = (script, LeafVersion::default());
let ver_script = (script, LeafVersion::TapScript);
let ctrl_block = tree_info.control_block(&ver_script).unwrap();
assert!(ctrl_block.verify_taproot_commitment(&secp, &output_key, &ver_script.0))
}
Expand Down Expand Up @@ -1116,7 +1139,7 @@ mod test {
let output_key = tree_info.output_key();

for script in vec![a, b, c, d, e] {
let ver_script = (script, LeafVersion::default());
let ver_script = (script, LeafVersion::TapScript);
let ctrl_block = tree_info.control_block(&ver_script).unwrap();
assert!(ctrl_block.verify_taproot_commitment(&secp, &output_key, &ver_script.0))
}
Expand Down

0 comments on commit 1ab9282

Please sign in to comment.