Merge rust-bitcoin/rust-bitcoin#956: Improve docs in `sighash` and `psbt/mod.rs`

9896f27eae psbt: Improve documentation (Tobin C. Harding)
33a50831ce sighash: Improve documentation (Tobin Harding)

Pull request description:

  Done while working on sighash and PSBT signing. Just the usual docs fixes. Note, does not do the whole `psbt` module just the file mentioned.

ACKs for top commit:
  apoelstra:
    ACK 9896f27eae

Tree-SHA512: 5fbfa258cdb216189922a49a42b7ab9fb78faeee72d82f8cb99a1b3d930d170074013e317b0e7af259a404ac4db93841b4d2b525e933c5e145da71e7522800fd
This commit is contained in:
sanket1729 2022-05-19 18:58:58 -07:00
commit fcb035fb4f
No known key found for this signature in database
GPG Key ID: 648FFB183E0870A2
2 changed files with 83 additions and 83 deletions

View File

@ -53,13 +53,12 @@ pub type Psbt = PartiallySignedTransaction;
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PartiallySignedTransaction { pub struct PartiallySignedTransaction {
/// The unsigned transaction, scriptSigs and witnesses for each input must be /// The unsigned transaction, scriptSigs and witnesses for each input must be empty.
/// empty.
pub unsigned_tx: Transaction, pub unsigned_tx: Transaction,
/// The version number of this PSBT. If omitted, the version number is 0. /// The version number of this PSBT. If omitted, the version number is 0.
pub version: u32, pub version: u32,
/// A global map from extended public keys to the used key fingerprint and /// A global map from extended public keys to the used key fingerprint and
/// derivation path as defined by BIP 32 /// derivation path as defined by BIP 32.
pub xpub: BTreeMap<ExtendedPubKey, KeySource>, pub xpub: BTreeMap<ExtendedPubKey, KeySource>,
/// Global proprietary key-value pairs. /// Global proprietary key-value pairs.
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
@ -68,11 +67,9 @@ pub struct PartiallySignedTransaction {
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
pub unknown: BTreeMap<raw::Key, Vec<u8>>, pub unknown: BTreeMap<raw::Key, Vec<u8>>,
/// The corresponding key-value map for each input in the unsigned /// The corresponding key-value map for each input in the unsigned transaction.
/// transaction.
pub inputs: Vec<Input>, pub inputs: Vec<Input>,
/// The corresponding key-value map for each output in the unsigned /// The corresponding key-value map for each output in the unsigned transaction.
/// transaction.
pub outputs: Vec<Output>, pub outputs: Vec<Output>,
} }
@ -103,8 +100,7 @@ impl PartiallySignedTransaction {
}) })
} }
/// Checks that unsigned transaction does not have scriptSig's or witness /// Checks that unsigned transaction does not have scriptSig's or witness data.
/// data
fn unsigned_tx_checks(&self) -> Result<(), Error> { fn unsigned_tx_checks(&self) -> Result<(), Error> {
for txin in &self.unsigned_tx.input { for txin in &self.unsigned_tx.input {
if !txin.script_sig.is_empty() { if !txin.script_sig.is_empty() {
@ -119,8 +115,11 @@ impl PartiallySignedTransaction {
Ok(()) Ok(())
} }
/// Create a PartiallySignedTransaction from an unsigned transaction, error /// Creates a PSBT from an unsigned transaction.
/// if not unsigned ///
/// # Errors
///
/// If transactions is not unsigned.
pub fn from_unsigned_tx(tx: Transaction) -> Result<Self, Error> { pub fn from_unsigned_tx(tx: Transaction) -> Result<Self, Error> {
let psbt = PartiallySignedTransaction { let psbt = PartiallySignedTransaction {
inputs: vec![Default::default(); tx.input.len()], inputs: vec![Default::default(); tx.input.len()],
@ -136,8 +135,7 @@ impl PartiallySignedTransaction {
Ok(psbt) Ok(psbt)
} }
/// Extract the Transaction from a PartiallySignedTransaction by filling in /// Extracts the `Transaction` from a PSBT by filling in the available signature information.
/// the available signature information in place.
pub fn extract_tx(self) -> Transaction { pub fn extract_tx(self) -> Transaction {
let mut tx: Transaction = self.unsigned_tx; let mut tx: Transaction = self.unsigned_tx;
@ -222,13 +220,13 @@ mod display_from_str {
use crate::consensus::encode::{Error, self}; use crate::consensus::encode::{Error, self};
use base64::display::Base64Display; use base64::display::Base64Display;
/// Error happening during PSBT decoding from Base64 string /// Error encountered during PSBT decoding from Base64 string.
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))] #[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
pub enum PsbtParseError { pub enum PsbtParseError {
/// Error in internal PSBT data structure /// Error in internal PSBT data structure.
PsbtEncoding(Error), PsbtEncoding(Error),
/// Error in PSBT Base64 encoding /// Error in PSBT Base64 encoding.
Base64Encoding(::base64::DecodeError) Base64Encoding(::base64::DecodeError)
} }

View File

@ -39,33 +39,33 @@ use super::taproot::LeafVersion;
/// Efficiently calculates signature hash message for legacy, segwit and taproot inputs. /// Efficiently calculates signature hash message for legacy, segwit and taproot inputs.
#[derive(Debug)] #[derive(Debug)]
pub struct SighashCache<T: Deref<Target=Transaction>> { pub struct SighashCache<T: Deref<Target=Transaction>> {
/// Access to transaction required for various introspection, moreover type /// Access to transaction required for transaction introspection. Moreover, type
/// `T: Deref<Target=Transaction>` allows to accept borrow and mutable borrow, the /// `T: Deref<Target=Transaction>` allows us to use borrowed and mutable borrowed types,
/// latter in particular is necessary for [`SighashCache::witness_mut`] /// the latter in particular is necessary for [`SighashCache::witness_mut`].
tx: T, tx: T,
/// Common cache for taproot and segwit inputs. It's an option because it's not needed for legacy inputs /// Common cache for taproot and segwit inputs, `None` for legacy inputs.
common_cache: Option<CommonCache>, common_cache: Option<CommonCache>,
/// Cache for segwit v0 inputs, it's the result of another round of sha256 on `common_cache` /// Cache for segwit v0 inputs (the result of another round of sha256 on `common_cache`).
segwit_cache: Option<SegwitCache>, segwit_cache: Option<SegwitCache>,
/// Cache for taproot v1 inputs /// Cache for taproot v1 inputs.
taproot_cache: Option<TaprootCache>, taproot_cache: Option<TaprootCache>,
} }
/// Values cached common between segwit and taproot inputs /// Common values cached between segwit and taproot inputs.
#[derive(Debug)] #[derive(Debug)]
struct CommonCache { struct CommonCache {
prevouts: sha256::Hash, prevouts: sha256::Hash,
sequences: sha256::Hash, sequences: sha256::Hash,
/// in theory, `outputs` could be `Option` since `NONE` and `SINGLE` doesn't need it, but since /// In theory `outputs` could be an `Option` since `SIGHASH_NONE` and `SIGHASH_SINGLE` do not
/// `ALL` is the mostly used variant by large, we don't bother /// need it, but since `SIGHASH_ALL` is by far the most used variant we don't bother.
outputs: sha256::Hash, outputs: sha256::Hash,
} }
/// Values cached for segwit inputs, it's equal to [`CommonCache`] plus another round of `sha256` /// Values cached for segwit inputs, equivalent to [`CommonCache`] plus another round of `sha256`.
#[derive(Debug)] #[derive(Debug)]
struct SegwitCache { struct SegwitCache {
prevouts: sha256d::Hash, prevouts: sha256d::Hash,
@ -73,29 +73,29 @@ struct SegwitCache {
outputs: sha256d::Hash, outputs: sha256d::Hash,
} }
/// Values cached for taproot inputs /// Values cached for taproot inputs.
#[derive(Debug)] #[derive(Debug)]
struct TaprootCache { struct TaprootCache {
amounts: sha256::Hash, amounts: sha256::Hash,
script_pubkeys: sha256::Hash, script_pubkeys: sha256::Hash,
} }
/// Contains outputs of previous transactions. /// Contains outputs of previous transactions. In the case [`SchnorrSighashType`] variant is
/// In the case [`SchnorrSighashType`] variant is `ANYONECANPAY`, [`Prevouts::One`] may be provided /// `SIGHASH_ANYONECANPAY`, [`Prevouts::One`] may be used.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Prevouts<'u, T> where T: 'u + Borrow<TxOut> { pub enum Prevouts<'u, T> where T: 'u + Borrow<TxOut> {
/// `One` variant allows to provide the single Prevout needed. It's useful for example /// `One` variant allows provision of the single prevout needed. It's useful, for example, when
/// when modifier `ANYONECANPAY` is provided, only prevout of the current input is needed. /// modifier `SIGHASH_ANYONECANPAY` is provided, only prevout of the current input is needed.
/// The first `usize` argument is the input index this [`TxOut`] is referring to. /// The first `usize` argument is the input index this [`TxOut`] is referring to.
One(usize, T), One(usize, T),
/// When `ANYONECANPAY` is not provided, or the caller is handy giving all prevouts so the same /// When `SIGHASH_ANYONECANPAY` is not provided, or when the caller is giving all prevouts so
/// variable can be used for multiple inputs. /// the same variable can be used for multiple inputs.
All(&'u [T]), All(&'u [T]),
} }
const KEY_VERSION_0: u8 = 0u8; const KEY_VERSION_0: u8 = 0u8;
/// Information related to the script path spending /// Information related to the script path spending.
/// ///
/// This can be hashed into a [`TapLeafHash`]. /// This can be hashed into a [`TapLeafHash`].
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
@ -104,29 +104,29 @@ pub struct ScriptPath<'s> {
leaf_version: LeafVersion, leaf_version: LeafVersion,
} }
/// Hashtype of an input's signature, encoded in the last byte of the signature /// Hashtype of an input's signature, encoded in the last byte of the signature.
/// Fixed values so they can be casted as integer types for encoding /// Fixed values so they can be cast as integer types for encoding.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum SchnorrSighashType { pub enum SchnorrSighashType {
/// 0x0: Used when not explicitly specified, defaulting to [`SchnorrSighashType::All`] /// 0x0: Used when not explicitly specified, defaults to [`SchnorrSighashType::All`]
Default = 0x00, Default = 0x00,
/// 0x1: Sign all outputs /// 0x1: Sign all outputs.
All = 0x01, All = 0x01,
/// 0x2: Sign no outputs --- anyone can choose the destination /// 0x2: Sign no outputs --- anyone can choose the destination.
None = 0x02, None = 0x02,
/// 0x3: Sign the output whose index matches this input's index. If none exists, /// 0x3: Sign the output whose index matches this input's index. If none exists,
/// sign the hash `0000000000000000000000000000000000000000000000000000000000000001`. /// sign the hash `0000000000000000000000000000000000000000000000000000000000000001`.
/// (This rule is probably an unintentional C++ism, but it's consensus so we have /// (This rule is probably an unintentional C++ism, but it's consensus so we have
/// to follow it.) /// to follow it.)
Single = 0x03, Single = 0x03,
/// 0x81: Sign all outputs but only this input /// 0x81: Sign all outputs but only this input.
AllPlusAnyoneCanPay = 0x81, AllPlusAnyoneCanPay = 0x81,
/// 0x82: Sign no outputs and only this input /// 0x82: Sign no outputs and only this input.
NonePlusAnyoneCanPay = 0x82, NonePlusAnyoneCanPay = 0x82,
/// 0x83: Sign one output and only this input (see `Single` for what "one output" means) /// 0x83: Sign one output and only this input (see `Single` for what "one output" means).
SinglePlusAnyoneCanPay = 0x83, SinglePlusAnyoneCanPay = 0x83,
/// Reserved for future use, `#[non_exhaustive]` is not available with current MSRV /// Reserved for future use, `#[non_exhaustive]` is not available with MSRV 1.29.0
Reserved = 0xFF, Reserved = 0xFF,
} }
serde_string_impl!(SchnorrSighashType, "a SchnorrSighashType data"); serde_string_impl!(SchnorrSighashType, "a SchnorrSighashType data");
@ -165,45 +165,46 @@ impl str::FromStr for SchnorrSighashType {
} }
} }
/// Possible errors in computing the signature message /// Possible errors in computing the signature message.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Error { pub enum Error {
/// Could happen only by using `*_encode_signing_*` methods with custom writers, engines writers /// Could happen only by using `*_encode_signing_*` methods with custom writers, engines writers
/// like the ones used in methods `*_signature_hash` don't error /// like the ones used in methods `*_signature_hash` do not error.
Io(io::ErrorKind), Io(io::ErrorKind),
/// Requested index is greater or equal than the number of inputs in the transaction /// Requested index is greater or equal than the number of inputs in the transaction.
IndexOutOfInputsBounds { IndexOutOfInputsBounds {
/// Requested index /// Requested index.
index: usize, index: usize,
/// Number of transaction inputs /// Number of transaction inputs.
inputs_size: usize, inputs_size: usize,
}, },
/// Using SIGHASH_SINGLE without a "corresponding output" (an output with the same index as the /// Using `SIGHASH_SINGLE` without a "corresponding output" (an output with the same index as
/// input being verified) is a validation failure /// the input being verified) is a validation failure.
SingleWithoutCorrespondingOutput { SingleWithoutCorrespondingOutput {
/// Requested index /// Requested index.
index: usize, index: usize,
/// Number of transaction outputs /// Number of transaction outputs.
outputs_size: usize, outputs_size: usize,
}, },
/// There are mismatches in the number of prevouts provided compared with the number of /// There are mismatches in the number of prevouts provided compared to the number of inputs in
/// inputs in the transaction /// the transaction.
PrevoutsSize, PrevoutsSize,
/// Requested a prevout index which is greater than the number of prevouts provided or a /// Requested a prevout index which is greater than the number of prevouts provided or a
/// [`Prevouts::One`] with different index /// [`Prevouts::One`] with different index.
PrevoutIndex, PrevoutIndex,
/// A single prevout has been provided but all prevouts are needed without `ANYONECANPAY` /// A single prevout has been provided but all prevouts are needed unless using
/// `SIGHASH_ANYONECANPAY`.
PrevoutKind, PrevoutKind,
/// Annex must be at least one byte long and the first bytes must be `0x50` /// Annex must be at least one byte long and the first bytes must be `0x50`.
WrongAnnex, WrongAnnex,
/// Invalid Sighash type /// Invalid Sighash type.
InvalidSighashType(u32), InvalidSighashType(u32),
} }
@ -260,18 +261,18 @@ impl<'u, T> Prevouts<'u, T> where T: Borrow<TxOut> {
} }
impl<'s> ScriptPath<'s> { impl<'s> ScriptPath<'s> {
/// Create a new ScriptPath structure /// Creates a new `ScriptPath` structure.
pub fn new(script: &'s Script, leaf_version: LeafVersion) -> Self { pub fn new(script: &'s Script, leaf_version: LeafVersion) -> Self {
ScriptPath { ScriptPath {
script, script,
leaf_version, leaf_version,
} }
} }
/// Create a new ScriptPath structure using default leaf version value /// Creates a new `ScriptPath` structure using default leaf version value.
pub fn with_defaults(script: &'s Script) -> Self { pub fn with_defaults(script: &'s Script) -> Self {
Self::new(script, LeafVersion::TapScript) Self::new(script, LeafVersion::TapScript)
} }
/// Compute the leaf hash /// Computes the leaf hash for this `ScriptPath`.
pub fn leaf_hash(&self) -> TapLeafHash { pub fn leaf_hash(&self) -> TapLeafHash {
let mut enc = TapLeafHash::engine(); let mut enc = TapLeafHash::engine();
@ -302,7 +303,7 @@ impl From<EcdsaSighashType> for SchnorrSighashType {
} }
impl SchnorrSighashType { impl SchnorrSighashType {
/// Break the sighash flag into the "real" sighash flag and the ANYONECANPAY boolean /// Breaks the sighash flag into the "real" sighash flag and the `SIGHASH_ANYONECANPAY` boolean.
pub(crate) fn split_anyonecanpay_flag(self) -> (SchnorrSighashType, bool) { pub(crate) fn split_anyonecanpay_flag(self) -> (SchnorrSighashType, bool) {
match self { match self {
SchnorrSighashType::Default => (SchnorrSighashType::Default, false), SchnorrSighashType::Default => (SchnorrSighashType::Default, false),
@ -316,7 +317,7 @@ impl SchnorrSighashType {
} }
} }
/// Create a [`SchnorrSighashType`] from raw `u8` /// Creates a [`SchnorrSighashType`] from raw `u8`.
pub fn from_u8(hash_ty: u8) -> Result<Self, Error> { pub fn from_u8(hash_ty: u8) -> Result<Self, Error> {
match hash_ty { match hash_ty {
0x00 => Ok(SchnorrSighashType::Default), 0x00 => Ok(SchnorrSighashType::Default),
@ -333,10 +334,11 @@ impl SchnorrSighashType {
} }
impl<R: Deref<Target = Transaction>> SighashCache<R> { impl<R: Deref<Target = Transaction>> SighashCache<R> {
/// Compute the sighash components from an unsigned transaction and auxiliary /// Constructs a new `SighashCache` from an unsigned transaction.
/// in a lazy manner when required. ///
/// For the generated sighashes to be valid, no fields in the transaction may change except for /// The sighash components are computed in a lazy manner when required. For the generated
/// script_sig and witnesses. /// sighashes to be valid, no fields in the transaction may change except for script_sig and
/// witness.
pub fn new(tx: R) -> Self { pub fn new(tx: R) -> Self {
SighashCache { SighashCache {
tx, tx,
@ -346,8 +348,8 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
} }
} }
/// Encode the BIP341 signing data for any flag type into a given object implementing a /// Encodes the BIP341 signing data for any flag type into a given object implementing a
/// io::Write trait. /// [`io::Write`] trait.
pub fn taproot_encode_signing_data_to<Write: io::Write, T: Borrow<TxOut>>( pub fn taproot_encode_signing_data_to<Write: io::Write, T: Borrow<TxOut>>(
&mut self, &mut self,
mut writer: Write, mut writer: Write,
@ -477,7 +479,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
Ok(()) Ok(())
} }
/// Compute the BIP341 sighash for any flag type. /// Computes the BIP341 sighash for any flag type.
pub fn taproot_signature_hash<T: Borrow<TxOut>>( pub fn taproot_signature_hash<T: Borrow<TxOut>>(
&mut self, &mut self,
input_index: usize, input_index: usize,
@ -498,7 +500,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
Ok(TapSighashHash::from_engine(enc)) Ok(TapSighashHash::from_engine(enc))
} }
/// Compute the BIP341 sighash for a key spend /// Computes the BIP341 sighash for a key spend.
pub fn taproot_key_spend_signature_hash<T: Borrow<TxOut>>( pub fn taproot_key_spend_signature_hash<T: Borrow<TxOut>>(
&mut self, &mut self,
input_index: usize, input_index: usize,
@ -517,7 +519,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
Ok(TapSighashHash::from_engine(enc)) Ok(TapSighashHash::from_engine(enc))
} }
/// Compute the BIP341 sighash for a script spend /// Computes the BIP341 sighash for a script spend.
/// ///
/// Assumes the default `OP_CODESEPARATOR` position of `0xFFFFFFFF`. Custom values can be /// Assumes the default `OP_CODESEPARATOR` position of `0xFFFFFFFF`. Custom values can be
/// provided through the more fine-grained API of [`SighashCache::taproot_encode_signing_data_to`]. /// provided through the more fine-grained API of [`SighashCache::taproot_encode_signing_data_to`].
@ -540,7 +542,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
Ok(TapSighashHash::from_engine(enc)) Ok(TapSighashHash::from_engine(enc))
} }
/// Encode the BIP143 signing data for any flag type into a given object implementing a /// Encodes the BIP143 signing data for any flag type into a given object implementing a
/// [`std::io::Write`] trait. /// [`std::io::Write`] trait.
pub fn segwit_encode_signing_data_to<Write: io::Write>( pub fn segwit_encode_signing_data_to<Write: io::Write>(
&mut self, &mut self,
@ -605,7 +607,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
Ok(()) Ok(())
} }
/// Compute the BIP143 sighash for any flag type. /// Computes the BIP143 sighash for any flag type.
pub fn segwit_signature_hash( pub fn segwit_signature_hash(
&mut self, &mut self,
input_index: usize, input_index: usize,
@ -624,8 +626,8 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
Ok(Sighash::from_engine(enc)) Ok(Sighash::from_engine(enc))
} }
/// Encode the legacy signing data for any flag type into a given object implementing a /// Encodes the legacy signing data for any flag type into a given object implementing a
/// [`std::io::Write`] trait. Internally calls [`Transaction::encode_signing_data_to`] /// [`std::io::Write`] trait. Internally calls [`Transaction::encode_signing_data_to`].
pub fn legacy_encode_signing_data_to<Write: io::Write, U: Into<u32>>( pub fn legacy_encode_signing_data_to<Write: io::Write, U: Into<u32>>(
&self, &self,
mut writer: Write, mut writer: Write,
@ -645,7 +647,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
Ok(()) Ok(())
} }
/// Computes the legacy sighash for any sighash type. /// Computes the legacy sighash for any `sighash_type`.
pub fn legacy_signature_hash( pub fn legacy_signature_hash(
&self, &self,
input_index: usize, input_index: usize,
@ -730,8 +732,8 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
} }
impl<R: DerefMut<Target=Transaction>> SighashCache<R> { impl<R: DerefMut<Target=Transaction>> SighashCache<R> {
/// When the SighashCache is initialized with a mutable reference to a transaction instead of a /// When the `SighashCache` is initialized with a mutable reference to a transaction instead of
/// regular reference, this method is available to allow modification to the witnesses. /// a regular reference, this method is available to allow modification to the witnesses.
/// ///
/// This allows in-line signing such as /// This allows in-line signing such as
/// ``` /// ```
@ -761,12 +763,12 @@ impl From<io::Error> for Error {
} }
} }
/// The `Annex` struct is a slice wrapper enforcing first byte to be `0x50`. /// The `Annex` struct is a slice wrapper enforcing first byte is `0x50`.
#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Annex<'a>(&'a [u8]); pub struct Annex<'a>(&'a [u8]);
impl<'a> Annex<'a> { impl<'a> Annex<'a> {
/// Creates a new `Annex` struct checking the first byte is `0x50` /// Creates a new `Annex` struct checking the first byte is `0x50`.
pub fn new(annex_bytes: &'a [u8]) -> Result<Self, Error> { pub fn new(annex_bytes: &'a [u8]) -> Result<Self, Error> {
if annex_bytes.first() == Some(&TAPROOT_ANNEX_PREFIX) { if annex_bytes.first() == Some(&TAPROOT_ANNEX_PREFIX) {
Ok(Annex(annex_bytes)) Ok(Annex(annex_bytes))
@ -775,7 +777,7 @@ impl<'a> Annex<'a> {
} }
} }
/// Returns the Annex bytes data (including first byte `0x50`) /// Returns the Annex bytes data (including first byte `0x50`).
pub fn as_bytes(&self) -> &[u8] { pub fn as_bytes(&self) -> &[u8] {
&*self.0 &*self.0
} }