Skip to content

Commit ef8a3a8

Browse files
committed
Introduce FutureLeafVersion
1 parent b028385 commit ef8a3a8

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

src/util/taproot.rs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -760,14 +760,45 @@ impl ControlBlock {
760760
}
761761
}
762762

763+
/// Inner type representing future (non-tapscript) leaf versions. See [`LeafVersion::Future`].
764+
///
765+
/// NB: NO PUBLIC CONSTRUCTOR!
766+
/// The only way to construct this is by converting u8 to LeafVersion and then extracting it.
767+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
768+
pub struct FutureLeafVersion(u8);
769+
770+
impl FutureLeafVersion {
771+
pub(self) fn from_consensus(version: u8) -> Result<FutureLeafVersion, TaprootError> {
772+
match version {
773+
TAPROOT_LEAF_TAPSCRIPT => unreachable!("FutureLeafVersion::from_consensus should be never called for 0xC0 value"),
774+
TAPROOT_ANNEX_PREFIX => Err(TaprootError::InvalidTaprootLeafVersion(TAPROOT_ANNEX_PREFIX)),
775+
odd if odd & 0xFE != odd => Err(TaprootError::InvalidTaprootLeafVersion(odd)),
776+
even => Ok(FutureLeafVersion(even))
777+
}
778+
}
779+
780+
/// Get consensus representation of the future leaf version.
781+
#[inline]
782+
pub fn into_consensus(self) -> u8 {
783+
self.0
784+
}
785+
}
786+
787+
impl fmt::Display for FutureLeafVersion {
788+
#[inline]
789+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
790+
fmt::Display::fmt(&self.0, f)
791+
}
792+
}
793+
763794
/// The leaf version for tapleafs
764795
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
765796
pub enum LeafVersion {
766797
/// BIP-342 tapscript
767798
TapScript,
768799

769800
/// Future leaf version
770-
Future(u8)
801+
Future(FutureLeafVersion)
771802
}
772803

773804
impl LeafVersion {
@@ -790,16 +821,15 @@ impl LeafVersion {
790821
match version {
791822
TAPROOT_LEAF_TAPSCRIPT => Ok(LeafVersion::TapScript),
792823
TAPROOT_ANNEX_PREFIX => Err(TaprootError::InvalidTaprootLeafVersion(TAPROOT_ANNEX_PREFIX)),
793-
odd if odd & TAPROOT_LEAF_MASK != odd => Err(TaprootError::InvalidTaprootLeafVersion(odd)),
794-
future => Ok(LeafVersion::Future(future)),
824+
future => FutureLeafVersion::from_consensus(future).map(LeafVersion::Future),
795825
}
796826
}
797827

798828
/// Get consensus representation of the [`LeafVersion`].
799829
pub fn into_consensus(self) -> u8 {
800830
match self {
801831
LeafVersion::TapScript => TAPROOT_LEAF_TAPSCRIPT,
802-
LeafVersion::Future(version) => version,
832+
LeafVersion::Future(version) => version.into_consensus(),
803833
}
804834
}
805835
}
@@ -809,7 +839,7 @@ impl fmt::Display for LeafVersion {
809839
match (self, f.alternate()) {
810840
(LeafVersion::TapScript, false) => f.write_str("tapscript"),
811841
(LeafVersion::TapScript, true) => fmt::Display::fmt(&TAPROOT_LEAF_TAPSCRIPT, f),
812-
(LeafVersion::Future(version), false) => write!(f, "future_script_{:#02x}", version),
842+
(LeafVersion::Future(version), false) => write!(f, "future_script_{:#02x}", version.0),
813843
(LeafVersion::Future(version), true) => fmt::Display::fmt(version, f),
814844
}
815845
}

0 commit comments

Comments
 (0)