Skip to content

Commit

Permalink
Merge #175: Add witness_version functions to CheckedHrpstring
Browse files Browse the repository at this point in the history
2d7832a Add witness_version functions to CheckedHrpstring (Tobin C. Harding)
3ce7225 Improve docs on `UncheckedHrpstring::witness_version` (Tobin C. Harding)

Pull request description:

  As we did for `UncheckedHrpstring` add functions to the `CheckedHrpstring` struct to allow checking the initial byte of the data part and removing it if required.

  Add an initial patch that improves the docs on the `UncheckedHrpstring::remove_witness_version` function (this is then copied in patch 2).

ACKs for top commit:
  apoelstra:
    ACK 2d7832a tested with rust-elements and it works!

Tree-SHA512: e380f524c06f8bfa6efe952e835fef66c3620367ed94d6716c6b5070479188ea95d719958292258938c0a3d709810c2da46af35b910e63e0a630776ce0691fbc
  • Loading branch information
apoelstra committed Jan 30, 2024
2 parents 50d59d6 + 2d7832a commit 92146d7
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/primitives/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ impl<'s> UncheckedHrpstring<'s> {
/// Attempts to convert the first character of the data part to a witness version. If this
/// succeeds, and it is a valid version (0..16 inclusive) we return it, otherwise `None`.
///
/// Future calls to [`Self::data_part_ascii`] will still include the witness version, use
/// [`Self::remove_witness_version`] to remove it.
///
/// This function makes no guarantees on the validity of the checksum.
///
/// # Examples
Expand Down Expand Up @@ -373,6 +376,68 @@ impl<'s> CheckedHrpstring<'s> {
#[inline]
pub fn data_part_ascii_no_checksum(&self) -> &'s [u8] { self.ascii }

/// Attempts to remove the first byte of the data part, treating it as a witness version.
///
/// If [`Self::witness_version`] succeeds this function removes the first character (witness
/// version byte) from the internal ASCII data part buffer. Future calls to
/// [`Self::data_part_ascii_no_checksum`] will no longer include it.
///
/// # Examples
///
/// ```
/// use bech32::{primitives::decode::CheckedHrpstring, Bech32, Fe32};
///
/// let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
/// let ascii = "ar0srrr7xfkvy5l643lydnw9re59gtzz";
///
/// let mut checked = CheckedHrpstring::new::<Bech32>(&addr).unwrap();
/// let witness_version = checked.remove_witness_version().unwrap();
/// assert_eq!(witness_version, Fe32::Q);
/// assert!(checked.data_part_ascii_no_checksum().iter().eq(ascii.as_bytes().iter()))
/// ```
#[inline]
pub fn remove_witness_version(&mut self) -> Option<Fe32> {
self.witness_version().map(|witver| {
self.ascii = &self.ascii[1..]; // Remove the witness version byte.
witver
})
}

/// Returns the segwit witness version if there is one.
///
/// Attempts to convert the first character of the data part to a witness version. If this
/// succeeds, and it is a valid version (0..16 inclusive) we return it, otherwise `None`.
///
/// Future calls to [`Self::data_part_ascii_no_checksum`] will still include the witness
/// version, use [`Self::remove_witness_version`] to remove it.
///
/// This function makes no guarantees on the validity of the checksum.
///
/// # Examples
///
/// ```
/// use bech32::{primitives::decode::CheckedHrpstring, Bech32, Fe32};
///
/// let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
///
/// let checked = CheckedHrpstring::new::<Bech32>(&addr).unwrap();
/// assert_eq!(checked.witness_version(), Some(Fe32::Q));
/// ```
#[inline]
pub fn witness_version(&self) -> Option<Fe32> {
let data_part = self.data_part_ascii_no_checksum();
if data_part.is_empty() {
return None;
}

// unwrap ok because we know we gave valid bech32 characters.
let witness_version = Fe32::from_char(data_part[0].into()).unwrap();
if witness_version.to_u8() > 16 {
return None;
}
Some(witness_version)
}

/// Returns an iterator that yields the data part of the parsed bech32 encoded string as [`Fe32`]s.
///
/// Converts the ASCII bytes representing field elements to the respective field elements.
Expand Down

0 comments on commit 92146d7

Please sign in to comment.