Capitalize Taproot
Taproot is a proper noun and should be capitalized in docs and strings. Make all occurrences of Taproot in comments or strings capitalized.
This commit is contained in:
parent
2dd79639b0
commit
c8e6c13608
|
@ -1,4 +1,4 @@
|
||||||
//! Example of taproot PSBT workflow
|
//! Example of Taproot PSBT workflow
|
||||||
|
|
||||||
// We use the alias `alias bt='bitcoin-cli -regtest'` for brevity.
|
// We use the alias `alias bt='bitcoin-cli -regtest'` for brevity.
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
// At some point we may want to extend the locktime further into the future for the beneficiary.
|
// At some point we may want to extend the locktime further into the future for the beneficiary.
|
||||||
// We can do this by "refreshing" the inheritance transaction as the benefactor. This effectively
|
// We can do this by "refreshing" the inheritance transaction as the benefactor. This effectively
|
||||||
// spends the inheritance transaction via the key path of the taproot output, and is not encumbered
|
// spends the inheritance transaction via the key path of the Taproot output, and is not encumbered
|
||||||
// by the timelock so we can spend it immediately. We set up a new output similar to the first with
|
// by the timelock so we can spend it immediately. We set up a new output similar to the first with
|
||||||
// a locktime that is 'locktime_delta' blocks greater.
|
// a locktime that is 'locktime_delta' blocks greater.
|
||||||
let (tx, _) = benefactor.refresh_tx(1000)?;
|
let (tx, _) = benefactor.refresh_tx(1000)?;
|
||||||
|
@ -294,7 +294,7 @@ fn generate_bip86_key_spend_tx(
|
||||||
let (_, (_, derivation_path)) = input
|
let (_, (_, derivation_path)) = input
|
||||||
.tap_key_origins
|
.tap_key_origins
|
||||||
.get(&input.tap_internal_key.ok_or("Internal key missing in PSBT")?)
|
.get(&input.tap_internal_key.ok_or("Internal key missing in PSBT")?)
|
||||||
.ok_or("Missing taproot key origin")?;
|
.ok_or("Missing Taproot key origin")?;
|
||||||
|
|
||||||
let secret_key = master_xpriv.derive_priv(secp, &derivation_path).to_priv().inner;
|
let secret_key = master_xpriv.derive_priv(secp, &derivation_path).to_priv().inner;
|
||||||
sign_psbt_taproot(
|
sign_psbt_taproot(
|
||||||
|
@ -395,7 +395,7 @@ impl BenefactorWallet {
|
||||||
let beneficiary_key =
|
let beneficiary_key =
|
||||||
self.beneficiary_xpub.derive_pub(&self.secp, &derivation_path)?.to_x_only_pub();
|
self.beneficiary_xpub.derive_pub(&self.secp, &derivation_path)?.to_x_only_pub();
|
||||||
|
|
||||||
// Build up the leaf script and combine with internal key into a taproot commitment
|
// Build up the leaf script and combine with internal key into a Taproot commitment
|
||||||
let script = Self::time_lock_script(lock_time, beneficiary_key);
|
let script = Self::time_lock_script(lock_time, beneficiary_key);
|
||||||
let leaf_hash = script.tapscript_leaf_hash();
|
let leaf_hash = script.tapscript_leaf_hash();
|
||||||
|
|
||||||
|
@ -486,7 +486,7 @@ impl BenefactorWallet {
|
||||||
let beneficiary_key =
|
let beneficiary_key =
|
||||||
self.beneficiary_xpub.derive_pub(&self.secp, &new_derivation_path)?.to_x_only_pub();
|
self.beneficiary_xpub.derive_pub(&self.secp, &new_derivation_path)?.to_x_only_pub();
|
||||||
|
|
||||||
// Build up the leaf script and combine with internal key into a taproot commitment
|
// Build up the leaf script and combine with internal key into a Taproot commitment
|
||||||
let lock_time = absolute::LockTime::from_height(
|
let lock_time = absolute::LockTime::from_height(
|
||||||
psbt.unsigned_tx.lock_time.to_consensus_u32() + lock_time_delta,
|
psbt.unsigned_tx.lock_time.to_consensus_u32() + lock_time_delta,
|
||||||
)
|
)
|
||||||
|
@ -528,7 +528,7 @@ impl BenefactorWallet {
|
||||||
let (_, (_, derivation_path)) = input
|
let (_, (_, derivation_path)) = input
|
||||||
.tap_key_origins
|
.tap_key_origins
|
||||||
.get(&input.tap_internal_key.ok_or("Internal key missing in PSBT")?)
|
.get(&input.tap_internal_key.ok_or("Internal key missing in PSBT")?)
|
||||||
.ok_or("Missing taproot key origin")?;
|
.ok_or("Missing Taproot key origin")?;
|
||||||
let secret_key =
|
let secret_key =
|
||||||
self.master_xpriv.derive_priv(&self.secp, &derivation_path).to_priv().inner;
|
self.master_xpriv.derive_priv(&self.secp, &derivation_path).to_priv().inner;
|
||||||
sign_psbt_taproot(
|
sign_psbt_taproot(
|
||||||
|
|
|
@ -465,7 +465,7 @@ impl Address {
|
||||||
Ok(Address::p2sh_from_hash(script_hash, network))
|
Ok(Address::p2sh_from_hash(script_hash, network))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to taproot address from an untweaked key.
|
/// Creates a pay to Taproot address from an untweaked key.
|
||||||
pub fn p2tr<C: Verification>(
|
pub fn p2tr<C: Verification>(
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
internal_key: UntweakedPublicKey,
|
internal_key: UntweakedPublicKey,
|
||||||
|
@ -476,7 +476,7 @@ impl Address {
|
||||||
Address::from_witness_program(program, hrp)
|
Address::from_witness_program(program, hrp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to taproot address from a pre-tweaked output key.
|
/// Creates a pay to Taproot address from a pre-tweaked output key.
|
||||||
pub fn p2tr_tweaked(output_key: TweakedPublicKey, hrp: impl Into<KnownHrp>) -> Address {
|
pub fn p2tr_tweaked(output_key: TweakedPublicKey, hrp: impl Into<KnownHrp>) -> Address {
|
||||||
let program = WitnessProgram::p2tr_tweaked(output_key);
|
let program = WitnessProgram::p2tr_tweaked(output_key);
|
||||||
Address::from_witness_program(program, hrp)
|
Address::from_witness_program(program, hrp)
|
||||||
|
@ -642,7 +642,7 @@ impl Address {
|
||||||
///
|
///
|
||||||
/// This is determined by directly comparing the address payload with either the
|
/// This is determined by directly comparing the address payload with either the
|
||||||
/// hash of the given public key or the segwit redeem hash generated from the
|
/// hash of the given public key or the segwit redeem hash generated from the
|
||||||
/// given key. For taproot addresses, the supplied key is assumed to be tweaked
|
/// given key. For Taproot addresses, the supplied key is assumed to be tweaked
|
||||||
pub fn is_related_to_pubkey(&self, pubkey: PublicKey) -> bool {
|
pub fn is_related_to_pubkey(&self, pubkey: PublicKey) -> bool {
|
||||||
let pubkey_hash = pubkey.pubkey_hash();
|
let pubkey_hash = pubkey.pubkey_hash();
|
||||||
let payload = self.payload_as_bytes();
|
let payload = self.payload_as_bytes();
|
||||||
|
|
|
@ -468,9 +468,9 @@ impl Script {
|
||||||
/// Bitcoin Core uses accurate counting for sigops contained within redeemScripts (P2SH)
|
/// Bitcoin Core uses accurate counting for sigops contained within redeemScripts (P2SH)
|
||||||
/// and witnessScripts (P2WSH) only. It uses legacy for sigops in scriptSigs and scriptPubkeys.
|
/// and witnessScripts (P2WSH) only. It uses legacy for sigops in scriptSigs and scriptPubkeys.
|
||||||
///
|
///
|
||||||
/// (Note: taproot scripts don't count toward the sigop count of the block,
|
/// (Note: Taproot scripts don't count toward the sigop count of the block,
|
||||||
/// nor do they have CHECKMULTISIG operations. This function does not count OP_CHECKSIGADD,
|
/// nor do they have CHECKMULTISIG operations. This function does not count OP_CHECKSIGADD,
|
||||||
/// so do not use this to try and estimate if a taproot script goes over the sigop budget.)
|
/// so do not use this to try and estimate if a Taproot script goes over the sigop budget.)
|
||||||
pub fn count_sigops(&self) -> usize { self.count_sigops_internal(true) }
|
pub fn count_sigops(&self) -> usize { self.count_sigops_internal(true) }
|
||||||
|
|
||||||
/// Counts the sigops for this Script using legacy counting.
|
/// Counts the sigops for this Script using legacy counting.
|
||||||
|
@ -482,9 +482,9 @@ impl Script {
|
||||||
/// Bitcoin Core uses legacy counting for sigops contained within scriptSigs and
|
/// Bitcoin Core uses legacy counting for sigops contained within scriptSigs and
|
||||||
/// scriptPubkeys. It uses accurate for redeemScripts (P2SH) and witnessScripts (P2WSH).
|
/// scriptPubkeys. It uses accurate for redeemScripts (P2SH) and witnessScripts (P2WSH).
|
||||||
///
|
///
|
||||||
/// (Note: taproot scripts don't count toward the sigop count of the block,
|
/// (Note: Taproot scripts don't count toward the sigop count of the block,
|
||||||
/// nor do they have CHECKMULTISIG operations. This function does not count OP_CHECKSIGADD,
|
/// nor do they have CHECKMULTISIG operations. This function does not count OP_CHECKSIGADD,
|
||||||
/// so do not use this to try and estimate if a taproot script goes over the sigop budget.)
|
/// so do not use this to try and estimate if a Taproot script goes over the sigop budget.)
|
||||||
pub fn count_sigops_legacy(&self) -> usize { self.count_sigops_internal(false) }
|
pub fn count_sigops_legacy(&self) -> usize { self.count_sigops_internal(false) }
|
||||||
|
|
||||||
fn count_sigops_internal(&self, accurate: bool) -> usize {
|
fn count_sigops_internal(&self, accurate: bool) -> usize {
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl WitnessProgram {
|
||||||
WitnessProgram { version: WitnessVersion::V0, program: ArrayVec::from_slice(&program) }
|
WitnessProgram { version: WitnessVersion::V0, program: ArrayVec::from_slice(&program) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [`WitnessProgram`] from a 32 byte serialize taproot xonly pubkey.
|
/// Creates a [`WitnessProgram`] from a 32 byte serialize Taproot xonly pubkey.
|
||||||
fn new_p2tr(program: [u8; 32]) -> Self {
|
fn new_p2tr(program: [u8; 32]) -> Self {
|
||||||
WitnessProgram { version: WitnessVersion::V1, program: ArrayVec::from_slice(&program) }
|
WitnessProgram { version: WitnessVersion::V1, program: ArrayVec::from_slice(&program) }
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ impl WitnessProgram {
|
||||||
WitnessProgram::new_p2wsh(hash.to_byte_array())
|
WitnessProgram::new_p2wsh(hash.to_byte_array())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to taproot address from an untweaked key.
|
/// Creates a pay to Taproot address from an untweaked key.
|
||||||
pub fn p2tr<C: Verification>(
|
pub fn p2tr<C: Verification>(
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
internal_key: UntweakedPublicKey,
|
internal_key: UntweakedPublicKey,
|
||||||
|
@ -97,7 +97,7 @@ impl WitnessProgram {
|
||||||
WitnessProgram::new_p2tr(pubkey)
|
WitnessProgram::new_p2tr(pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pay to taproot address from a pre-tweaked output key.
|
/// Creates a pay to Taproot address from a pre-tweaked output key.
|
||||||
pub fn p2tr_tweaked(output_key: TweakedPublicKey) -> Self {
|
pub fn p2tr_tweaked(output_key: TweakedPublicKey) -> Self {
|
||||||
let pubkey = output_key.to_inner().serialize();
|
let pubkey = output_key.to_inner().serialize();
|
||||||
WitnessProgram::new_p2tr(pubkey)
|
WitnessProgram::new_p2tr(pubkey)
|
||||||
|
|
|
@ -920,9 +920,9 @@ impl Transaction {
|
||||||
|
|
||||||
/// Counts the total number of sigops.
|
/// Counts the total number of sigops.
|
||||||
///
|
///
|
||||||
/// This value is for pre-taproot transactions only.
|
/// This value is for pre-Taproot transactions only.
|
||||||
///
|
///
|
||||||
/// > In taproot, a different mechanism is used. Instead of having a global per-block limit,
|
/// > In Taproot, a different mechanism is used. Instead of having a global per-block limit,
|
||||||
/// > there is a per-transaction-input limit, proportional to the size of that input.
|
/// > there is a per-transaction-input limit, proportional to the size of that input.
|
||||||
/// > ref: <https://bitcoin.stackexchange.com/questions/117356/what-is-sigop-signature-operation#117359>
|
/// > ref: <https://bitcoin.stackexchange.com/questions/117356/what-is-sigop-signature-operation#117359>
|
||||||
///
|
///
|
||||||
|
@ -983,7 +983,7 @@ impl Transaction {
|
||||||
count
|
count
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Includes wrapped segwit (returns 0 for taproot spends).
|
/// Includes wrapped segwit (returns 0 for Taproot spends).
|
||||||
fn count_witness_sigops<S>(&self, spent: &mut S) -> usize
|
fn count_witness_sigops<S>(&self, spent: &mut S) -> usize
|
||||||
where
|
where
|
||||||
S: FnMut(&OutPoint) -> Option<TxOut>,
|
S: FnMut(&OutPoint) -> Option<TxOut>,
|
||||||
|
@ -1523,14 +1523,14 @@ impl InputWeightPrediction {
|
||||||
/// [`InputWeightPrediction::new`].
|
/// [`InputWeightPrediction::new`].
|
||||||
pub const P2PKH_UNCOMPRESSED_MAX: Self = InputWeightPrediction::from_slice(139, &[]);
|
pub const P2PKH_UNCOMPRESSED_MAX: Self = InputWeightPrediction::from_slice(139, &[]);
|
||||||
|
|
||||||
/// Input weight prediction corresponding to spending of taproot output using the key and
|
/// Input weight prediction corresponding to spending of Taproot output using the key and
|
||||||
/// default sighash.
|
/// default sighash.
|
||||||
///
|
///
|
||||||
/// If the input in your transaction uses Taproot key spend you can use this instead of
|
/// If the input in your transaction uses Taproot key spend you can use this instead of
|
||||||
/// [`InputWeightPrediction::new`].
|
/// [`InputWeightPrediction::new`].
|
||||||
pub const P2TR_KEY_DEFAULT_SIGHASH: Self = InputWeightPrediction::from_slice(0, &[64]);
|
pub const P2TR_KEY_DEFAULT_SIGHASH: Self = InputWeightPrediction::from_slice(0, &[64]);
|
||||||
|
|
||||||
/// Input weight prediction corresponding to spending of taproot output using the key and
|
/// Input weight prediction corresponding to spending of Taproot output using the key and
|
||||||
/// **non**-default sighash.
|
/// **non**-default sighash.
|
||||||
///
|
///
|
||||||
/// If the input in your transaction uses Taproot key spend you can use this instead of
|
/// If the input in your transaction uses Taproot key spend you can use this instead of
|
||||||
|
|
|
@ -72,13 +72,13 @@ sha256t_hash_newtype! {
|
||||||
|
|
||||||
/// Taproot-tagged hash with tag \"TapSighash\".
|
/// Taproot-tagged hash with tag \"TapSighash\".
|
||||||
///
|
///
|
||||||
/// This hash type is used for computing taproot signature hash."
|
/// This hash type is used for computing Taproot signature hash."
|
||||||
pub struct TapSighash(_);
|
pub struct TapSighash(_);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_message_from_hash!(TapSighash);
|
impl_message_from_hash!(TapSighash);
|
||||||
|
|
||||||
/// 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: Borrow<Transaction>> {
|
pub struct SighashCache<T: Borrow<Transaction>> {
|
||||||
/// Access to transaction required for transaction introspection. Moreover, type
|
/// Access to transaction required for transaction introspection. Moreover, type
|
||||||
|
@ -86,17 +86,17 @@ pub struct SighashCache<T: Borrow<Transaction>> {
|
||||||
/// the 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, `None` 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 (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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Common values cached 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,
|
||||||
|
@ -115,7 +115,7 @@ 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,
|
||||||
|
@ -1166,7 +1166,7 @@ impl<'a> Encodable for Annex<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error computing a taproot sighash.
|
/// Error computing a Taproot sighash.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum TaprootError {
|
pub enum TaprootError {
|
||||||
|
@ -1196,7 +1196,7 @@ impl fmt::Display for TaprootError {
|
||||||
PrevoutsSize(ref e) => write_err!(f, "prevouts size"; e),
|
PrevoutsSize(ref e) => write_err!(f, "prevouts size"; e),
|
||||||
PrevoutsIndex(ref e) => write_err!(f, "prevouts index"; e),
|
PrevoutsIndex(ref e) => write_err!(f, "prevouts index"; e),
|
||||||
PrevoutsKind(ref e) => write_err!(f, "prevouts kind"; e),
|
PrevoutsKind(ref e) => write_err!(f, "prevouts kind"; e),
|
||||||
InvalidSighashType(hash_ty) => write!(f, "invalid taproot sighash type : {} ", hash_ty),
|
InvalidSighashType(hash_ty) => write!(f, "invalid Taproot sighash type : {} ", hash_ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// SPDX-License-Identifier: CC0-1.0
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
//! Bitcoin taproot keys.
|
//! Bitcoin Taproot keys.
|
||||||
//!
|
//!
|
||||||
//! This module provides taproot keys used in Bitcoin (including reexporting secp256k1 keys).
|
//! This module provides Taproot keys used in Bitcoin (including reexporting secp256k1 keys).
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ use crate::prelude::Vec;
|
||||||
use crate::sighash::{InvalidSighashTypeError, TapSighashType};
|
use crate::sighash::{InvalidSighashTypeError, TapSighashType};
|
||||||
use crate::taproot::serialized_signature::{self, SerializedSignature};
|
use crate::taproot::serialized_signature::{self, SerializedSignature};
|
||||||
|
|
||||||
/// A BIP340-341 serialized taproot signature with the corresponding hash type.
|
/// A BIP340-341 serialized Taproot signature with the corresponding hash type.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
||||||
|
@ -96,7 +96,7 @@ pub enum SigFromSliceError {
|
||||||
SighashType(InvalidSighashTypeError),
|
SighashType(InvalidSighashTypeError),
|
||||||
/// A secp256k1 error.
|
/// A secp256k1 error.
|
||||||
Secp256k1(secp256k1::Error),
|
Secp256k1(secp256k1::Error),
|
||||||
/// Invalid taproot signature size
|
/// Invalid Taproot signature size
|
||||||
InvalidSignatureSize(usize),
|
InvalidSignatureSize(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ impl fmt::Display for SigFromSliceError {
|
||||||
match *self {
|
match *self {
|
||||||
SighashType(ref e) => write_err!(f, "sighash"; e),
|
SighashType(ref e) => write_err!(f, "sighash"; e),
|
||||||
Secp256k1(ref e) => write_err!(f, "secp256k1"; e),
|
Secp256k1(ref e) => write_err!(f, "secp256k1"; e),
|
||||||
InvalidSignatureSize(sz) => write!(f, "invalid taproot signature size: {}", sz),
|
InvalidSignatureSize(sz) => write!(f, "invalid Taproot signature size: {}", sz),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,13 +83,13 @@ pub enum Error {
|
||||||
InvalidXOnlyPublicKey,
|
InvalidXOnlyPublicKey,
|
||||||
/// Parsing error indicating invalid ECDSA signatures
|
/// Parsing error indicating invalid ECDSA signatures
|
||||||
InvalidEcdsaSignature(crate::crypto::ecdsa::Error),
|
InvalidEcdsaSignature(crate::crypto::ecdsa::Error),
|
||||||
/// Parsing error indicating invalid taproot signatures
|
/// Parsing error indicating invalid Taproot signatures
|
||||||
InvalidTaprootSignature(crate::crypto::taproot::SigFromSliceError),
|
InvalidTaprootSignature(crate::crypto::taproot::SigFromSliceError),
|
||||||
/// Parsing error indicating invalid control block
|
/// Parsing error indicating invalid control block
|
||||||
InvalidControlBlock,
|
InvalidControlBlock,
|
||||||
/// Parsing error indicating invalid leaf version
|
/// Parsing error indicating invalid leaf version
|
||||||
InvalidLeafVersion,
|
InvalidLeafVersion,
|
||||||
/// Parsing error indicating a taproot error
|
/// Parsing error indicating a Taproot error
|
||||||
Taproot(&'static str),
|
Taproot(&'static str),
|
||||||
/// Taproot tree deserilaization error
|
/// Taproot tree deserilaization error
|
||||||
TapTree(crate::taproot::IncompleteBuilderError),
|
TapTree(crate::taproot::IncompleteBuilderError),
|
||||||
|
@ -147,11 +147,11 @@ impl fmt::Display for Error {
|
||||||
InvalidSecp256k1PublicKey(ref e) => write_err!(f, "invalid secp256k1 public key"; e),
|
InvalidSecp256k1PublicKey(ref e) => write_err!(f, "invalid secp256k1 public key"; e),
|
||||||
InvalidXOnlyPublicKey => f.write_str("invalid xonly public key"),
|
InvalidXOnlyPublicKey => f.write_str("invalid xonly public key"),
|
||||||
InvalidEcdsaSignature(ref e) => write_err!(f, "invalid ECDSA signature"; e),
|
InvalidEcdsaSignature(ref e) => write_err!(f, "invalid ECDSA signature"; e),
|
||||||
InvalidTaprootSignature(ref e) => write_err!(f, "invalid taproot signature"; e),
|
InvalidTaprootSignature(ref e) => write_err!(f, "invalid Taproot signature"; e),
|
||||||
InvalidControlBlock => f.write_str("invalid control block"),
|
InvalidControlBlock => f.write_str("invalid control block"),
|
||||||
InvalidLeafVersion => f.write_str("invalid leaf version"),
|
InvalidLeafVersion => f.write_str("invalid leaf version"),
|
||||||
Taproot(s) => write!(f, "taproot error - {}", s),
|
Taproot(s) => write!(f, "Taproot error - {}", s),
|
||||||
TapTree(ref e) => write_err!(f, "taproot tree error"; e),
|
TapTree(ref e) => write_err!(f, "Taproot tree error"; e),
|
||||||
XPubKey(s) => write!(f, "xpub key error - {}", s),
|
XPubKey(s) => write!(f, "xpub key error - {}", s),
|
||||||
Version(s) => write!(f, "version error {}", s),
|
Version(s) => write!(f, "version error {}", s),
|
||||||
PartialDataConsumption =>
|
PartialDataConsumption =>
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub struct Input {
|
||||||
/// including P2SH embedded ones.
|
/// including P2SH embedded ones.
|
||||||
pub witness_utxo: Option<TxOut>,
|
pub witness_utxo: Option<TxOut>,
|
||||||
/// A map from public keys to their corresponding signature as would be
|
/// A map from public keys to their corresponding signature as would be
|
||||||
/// pushed to the stack from a scriptSig or witness for a non-taproot inputs.
|
/// pushed to the stack from a scriptSig or witness for a non-Taproot inputs.
|
||||||
pub partial_sigs: BTreeMap<PublicKey, ecdsa::Signature>,
|
pub partial_sigs: BTreeMap<PublicKey, ecdsa::Signature>,
|
||||||
/// The sighash type to be used for this input. Signatures for this input
|
/// The sighash type to be used for this input. Signatures for this input
|
||||||
/// must use the sighash type.
|
/// must use the sighash type.
|
||||||
|
@ -109,7 +109,7 @@ pub struct Input {
|
||||||
/// HAS256 hash to preimage map.
|
/// HAS256 hash to preimage map.
|
||||||
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
|
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_byte_values"))]
|
||||||
pub hash256_preimages: BTreeMap<sha256d::Hash, Vec<u8>>,
|
pub hash256_preimages: BTreeMap<sha256d::Hash, Vec<u8>>,
|
||||||
/// Serialized taproot signature with sighash type for key spend.
|
/// Serialized Taproot signature with sighash type for key spend.
|
||||||
pub tap_key_sig: Option<taproot::Signature>,
|
pub tap_key_sig: Option<taproot::Signature>,
|
||||||
/// Map of `<xonlypubkey>|<leafhash>` with signature.
|
/// Map of `<xonlypubkey>|<leafhash>` with signature.
|
||||||
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
|
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq"))]
|
||||||
|
@ -132,7 +132,7 @@ pub struct Input {
|
||||||
pub unknown: BTreeMap<raw::Key, Vec<u8>>,
|
pub unknown: BTreeMap<raw::Key, Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Signature hash type for the corresponding input. As of taproot upgrade, the signature hash
|
/// A Signature hash type for the corresponding input. As of Taproot upgrade, the signature hash
|
||||||
/// type can be either [`EcdsaSighashType`] or [`TapSighashType`] but it is not possible to know
|
/// type can be either [`EcdsaSighashType`] or [`TapSighashType`] but it is not possible to know
|
||||||
/// directly which signature hash type the user is dealing with. Therefore, the user is responsible
|
/// directly which signature hash type the user is dealing with. Therefore, the user is responsible
|
||||||
/// for converting to/from [`PsbtSighashType`] from/to the desired signature hash type they need.
|
/// for converting to/from [`PsbtSighashType`] from/to the desired signature hash type they need.
|
||||||
|
@ -169,7 +169,7 @@ impl FromStr for PsbtSighashType {
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
// We accept strings of form: "SIGHASH_ALL" etc.
|
// We accept strings of form: "SIGHASH_ALL" etc.
|
||||||
//
|
//
|
||||||
// NB: some of Taproot sighash types are non-standard for pre-taproot
|
// NB: some of Taproot sighash types are non-standard for pre-Taproot
|
||||||
// inputs. We also do not support SIGHASH_RESERVED in verbatim form
|
// inputs. We also do not support SIGHASH_RESERVED in verbatim form
|
||||||
// ("0xFF" string should be used instead).
|
// ("0xFF" string should be used instead).
|
||||||
if let Ok(ty) = TapSighashType::from_str(s) {
|
if let Ok(ty) = TapSighashType::from_str(s) {
|
||||||
|
|
|
@ -545,7 +545,7 @@ impl Psbt {
|
||||||
Ok((Message::from(sighash), hash_ty))
|
Ok((Message::from(sighash), hash_ty))
|
||||||
}
|
}
|
||||||
Tr => {
|
Tr => {
|
||||||
// This PSBT signing API is WIP, taproot to come shortly.
|
// This PSBT signing API is WIP, Taproot to come shortly.
|
||||||
Err(SignError::Unsupported)
|
Err(SignError::Unsupported)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -899,7 +899,7 @@ pub enum OutputType {
|
||||||
ShWsh,
|
ShWsh,
|
||||||
/// A pay-to-script-hash output excluding wrapped segwit (P2SH).
|
/// A pay-to-script-hash output excluding wrapped segwit (P2SH).
|
||||||
Sh,
|
Sh,
|
||||||
/// A taproot output (P2TR).
|
/// A Taproot output (P2TR).
|
||||||
Tr,
|
Tr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,7 +954,7 @@ pub enum SignError {
|
||||||
SegwitV0Sighash(transaction::InputsIndexError),
|
SegwitV0Sighash(transaction::InputsIndexError),
|
||||||
/// Sighash computation error (p2wpkh input).
|
/// Sighash computation error (p2wpkh input).
|
||||||
P2wpkhSighash(sighash::P2wpkhError),
|
P2wpkhSighash(sighash::P2wpkhError),
|
||||||
/// Sighash computation error (taproot input).
|
/// Sighash computation error (Taproot input).
|
||||||
TaprootError(sighash::TaprootError),
|
TaprootError(sighash::TaprootError),
|
||||||
/// Unable to determine the output type.
|
/// Unable to determine the output type.
|
||||||
UnknownOutputType,
|
UnknownOutputType,
|
||||||
|
@ -984,7 +984,7 @@ impl fmt::Display for SignError {
|
||||||
NotWpkh => write!(f, "the scriptPubkey is not a P2WPKH script"),
|
NotWpkh => write!(f, "the scriptPubkey is not a P2WPKH script"),
|
||||||
SegwitV0Sighash(ref e) => write_err!(f, "segwit v0 sighash"; e),
|
SegwitV0Sighash(ref e) => write_err!(f, "segwit v0 sighash"; e),
|
||||||
P2wpkhSighash(ref e) => write_err!(f, "p2wpkh sighash"; e),
|
P2wpkhSighash(ref e) => write_err!(f, "p2wpkh sighash"; e),
|
||||||
TaprootError(ref e) => write_err!(f, "taproot sighash"; e),
|
TaprootError(ref e) => write_err!(f, "Taproot sighash"; e),
|
||||||
UnknownOutputType => write!(f, "unable to determine the output type"),
|
UnknownOutputType => write!(f, "unable to determine the output type"),
|
||||||
KeyNotFound => write!(f, "unable to find key"),
|
KeyNotFound => write!(f, "unable to find key"),
|
||||||
WrongSigningAlgorithm =>
|
WrongSigningAlgorithm =>
|
||||||
|
@ -1867,11 +1867,11 @@ mod tests {
|
||||||
assert_eq!(err.to_string(), "invalid xonly public key");
|
assert_eq!(err.to_string(), "invalid xonly public key");
|
||||||
let err = hex_psbt("70736274ff010071020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02787c01000000000016001483a7e34bd99ff03a4962ef8a1a101bb295461ece606b042a010000001600147ac369df1b20e033d6116623957b0ac49f3c52e8000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757011342173bb3d36c074afb716fec6307a069a2e450b995f3c82785945ab8df0e24260dcd703b0cbf34de399184a9481ac2b3586db6601f026a77f7e4938481bc34751701aa000000").unwrap_err();
|
let err = hex_psbt("70736274ff010071020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02787c01000000000016001483a7e34bd99ff03a4962ef8a1a101bb295461ece606b042a010000001600147ac369df1b20e033d6116623957b0ac49f3c52e8000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757011342173bb3d36c074afb716fec6307a069a2e450b995f3c82785945ab8df0e24260dcd703b0cbf34de399184a9481ac2b3586db6601f026a77f7e4938481bc34751701aa000000").unwrap_err();
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
assert_eq!(err.to_string(), "invalid taproot signature");
|
assert_eq!(err.to_string(), "invalid Taproot signature");
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
"invalid taproot signature: invalid taproot signature size: 66"
|
"invalid Taproot signature: invalid Taproot signature size: 66"
|
||||||
);
|
);
|
||||||
let err = hex_psbt("70736274ff010071020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02787c01000000000016001483a7e34bd99ff03a4962ef8a1a101bb295461ece606b042a010000001600147ac369df1b20e033d6116623957b0ac49f3c52e8000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757221602fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2321900772b2da75600008001000080000000800100000000000000000000").unwrap_err();
|
let err = hex_psbt("70736274ff010071020000000127744ababf3027fe0d6cf23a96eee2efb188ef52301954585883e69b6624b2420000000000ffffffff02787c01000000000016001483a7e34bd99ff03a4962ef8a1a101bb295461ece606b042a010000001600147ac369df1b20e033d6116623957b0ac49f3c52e8000000000001012b00f2052a010000002251205a2c2cf5b52cf31f83ad2e8da63ff03183ecd8f609c7510ae8a48e03910a0757221602fe349064c98d6e2a853fa3c9b12bd8b304a19c195c60efa7ee2393046d3fa2321900772b2da75600008001000080000000800100000000000000000000").unwrap_err();
|
||||||
assert_eq!(err.to_string(), "invalid xonly public key");
|
assert_eq!(err.to_string(), "invalid xonly public key");
|
||||||
|
@ -1889,19 +1889,19 @@ mod tests {
|
||||||
);
|
);
|
||||||
let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b094289756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb01010000").unwrap_err();
|
let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b094289756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb01010000").unwrap_err();
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
assert_eq!(err.to_string(), "invalid taproot signature");
|
assert_eq!(err.to_string(), "invalid Taproot signature");
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
"invalid taproot signature: invalid taproot signature size: 66"
|
"invalid Taproot signature: invalid Taproot signature size: 66"
|
||||||
);
|
);
|
||||||
let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b093989756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb0000").unwrap_err();
|
let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b093989756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb0000").unwrap_err();
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
assert_eq!(err.to_string(), "invalid taproot signature");
|
assert_eq!(err.to_string(), "invalid Taproot signature");
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
"invalid taproot signature: invalid taproot signature size: 57"
|
"invalid Taproot signature: invalid Taproot signature size: 57"
|
||||||
);
|
);
|
||||||
let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b6926315c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac06f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae970115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f80023202cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2acc00000").unwrap_err();
|
let err = hex_psbt("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b6926315c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac06f7d62059e9497a1a4a267569d9876da60101aff38e3529b9b939ce7f91ae970115f2e490af7cc45c4f78511f36057ce5c5a5c56325a29fb44dfc203f356e1f80023202cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2acc00000").unwrap_err();
|
||||||
assert_eq!(err.to_string(), "invalid control block");
|
assert_eq!(err.to_string(), "invalid control block");
|
||||||
|
|
|
@ -117,7 +117,7 @@ impl_psbt_hash_de_serialize!(TapNodeHash);
|
||||||
impl_psbt_hash_de_serialize!(hash160::Hash);
|
impl_psbt_hash_de_serialize!(hash160::Hash);
|
||||||
impl_psbt_hash_de_serialize!(sha256d::Hash);
|
impl_psbt_hash_de_serialize!(sha256d::Hash);
|
||||||
|
|
||||||
// taproot
|
// Taproot
|
||||||
impl_psbt_de_serialize!(Vec<TapLeafHash>);
|
impl_psbt_de_serialize!(Vec<TapLeafHash>);
|
||||||
|
|
||||||
impl Serialize for ScriptBuf {
|
impl Serialize for ScriptBuf {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
//! Bitcoin Taproot.
|
//! Bitcoin Taproot.
|
||||||
//!
|
//!
|
||||||
//! This module provides support for taproot tagged hashes.
|
//! This module provides support for Taproot tagged hashes.
|
||||||
|
|
||||||
pub mod merkle_branch;
|
pub mod merkle_branch;
|
||||||
pub mod serialized_signature;
|
pub mod serialized_signature;
|
||||||
|
@ -41,7 +41,7 @@ sha256t_hash_newtype! {
|
||||||
sha256t_hash_newtype! {
|
sha256t_hash_newtype! {
|
||||||
pub struct TapBranchTag = hash_str("TapBranch");
|
pub struct TapBranchTag = hash_str("TapBranch");
|
||||||
|
|
||||||
/// Tagged hash used in taproot trees.
|
/// Tagged hash used in Taproot trees.
|
||||||
///
|
///
|
||||||
/// See BIP-340 for tagging rules.
|
/// See BIP-340 for tagging rules.
|
||||||
pub struct TapNodeHash(_);
|
pub struct TapNodeHash(_);
|
||||||
|
@ -136,10 +136,10 @@ impl From<TapLeafHash> for TapNodeHash {
|
||||||
fn from(leaf: TapLeafHash) -> TapNodeHash { TapNodeHash::from_byte_array(leaf.to_byte_array()) }
|
fn from(leaf: TapLeafHash) -> TapNodeHash { TapNodeHash::from_byte_array(leaf.to_byte_array()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maximum depth of a taproot tree script spend path.
|
/// Maximum depth of a Taproot tree script spend path.
|
||||||
// https://github.com/bitcoin/bitcoin/blob/e826b22da252e0599c61d21c98ff89f366b3120f/src/script/interpreter.h#L229
|
// https://github.com/bitcoin/bitcoin/blob/e826b22da252e0599c61d21c98ff89f366b3120f/src/script/interpreter.h#L229
|
||||||
pub const TAPROOT_CONTROL_MAX_NODE_COUNT: usize = 128;
|
pub const TAPROOT_CONTROL_MAX_NODE_COUNT: usize = 128;
|
||||||
/// Size of a taproot control node.
|
/// Size of a Taproot control node.
|
||||||
// https://github.com/bitcoin/bitcoin/blob/e826b22da252e0599c61d21c98ff89f366b3120f/src/script/interpreter.h#L228
|
// https://github.com/bitcoin/bitcoin/blob/e826b22da252e0599c61d21c98ff89f366b3120f/src/script/interpreter.h#L228
|
||||||
pub const TAPROOT_CONTROL_NODE_SIZE: usize = 32;
|
pub const TAPROOT_CONTROL_NODE_SIZE: usize = 32;
|
||||||
/// Tapleaf mask for getting the leaf version from first byte of control block.
|
/// Tapleaf mask for getting the leaf version from first byte of control block.
|
||||||
|
@ -161,7 +161,7 @@ pub const TAPROOT_CONTROL_MAX_SIZE: usize =
|
||||||
// type alias for versioned tap script corresponding merkle proof
|
// type alias for versioned tap script corresponding merkle proof
|
||||||
type ScriptMerkleProofMap = BTreeMap<(ScriptBuf, LeafVersion), BTreeSet<TaprootMerkleBranch>>;
|
type ScriptMerkleProofMap = BTreeMap<(ScriptBuf, LeafVersion), BTreeSet<TaprootMerkleBranch>>;
|
||||||
|
|
||||||
/// Represents taproot spending information.
|
/// Represents Taproot spending information.
|
||||||
///
|
///
|
||||||
/// Taproot output corresponds to a combination of a single public key condition (known as the
|
/// Taproot output corresponds to a combination of a single public key condition (known as the
|
||||||
/// internal key), and zero or more general conditions encoded in scripts organized in the form of a
|
/// internal key), and zero or more general conditions encoded in scripts organized in the form of a
|
||||||
|
@ -176,7 +176,7 @@ type ScriptMerkleProofMap = BTreeMap<(ScriptBuf, LeafVersion), BTreeSet<TaprootM
|
||||||
/// If one or more of the spending conditions consist of just a single key (after aggregation), the
|
/// If one or more of the spending conditions consist of just a single key (after aggregation), the
|
||||||
/// most likely key should be made the internal key.
|
/// most likely key should be made the internal key.
|
||||||
/// See [BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) for more details on
|
/// See [BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) for more details on
|
||||||
/// choosing internal keys for a taproot application.
|
/// choosing internal keys for a Taproot application.
|
||||||
///
|
///
|
||||||
/// Note: This library currently does not support
|
/// Note: This library currently does not support
|
||||||
/// [annex](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-5).
|
/// [annex](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-5).
|
||||||
|
@ -224,7 +224,7 @@ impl TaprootSpendInfo {
|
||||||
/// instead of having no script path. This is achieved by computing the output key point as
|
/// instead of having no script path. This is achieved by computing the output key point as
|
||||||
/// `Q = P + int(hashTapTweak(bytes(P)))G`. See also [`TaprootSpendInfo::tap_tweak`].
|
/// `Q = P + int(hashTapTweak(bytes(P)))G`. See also [`TaprootSpendInfo::tap_tweak`].
|
||||||
///
|
///
|
||||||
/// Refer to BIP 341 footnote ('Why should the output key always have a taproot commitment, even
|
/// Refer to BIP 341 footnote ('Why should the output key always have a Taproot commitment, even
|
||||||
/// if there is no script path?') for more details.
|
/// if there is no script path?') for more details.
|
||||||
pub fn new_key_spend<C: secp256k1::Verification>(
|
pub fn new_key_spend<C: secp256k1::Verification>(
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
|
@ -264,7 +264,7 @@ impl TaprootSpendInfo {
|
||||||
|
|
||||||
/// Computes the [`TaprootSpendInfo`] from `internal_key` and `node`.
|
/// Computes the [`TaprootSpendInfo`] from `internal_key` and `node`.
|
||||||
///
|
///
|
||||||
/// This is useful when you want to manually build a taproot tree without using
|
/// This is useful when you want to manually build a Taproot tree without using
|
||||||
/// [`TaprootBuilder`].
|
/// [`TaprootBuilder`].
|
||||||
pub fn from_node_info<C: secp256k1::Verification>(
|
pub fn from_node_info<C: secp256k1::Verification>(
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
|
@ -329,7 +329,7 @@ impl From<&TaprootSpendInfo> for TapTweakHash {
|
||||||
fn from(spend_info: &TaprootSpendInfo) -> TapTweakHash { spend_info.tap_tweak() }
|
fn from(spend_info: &TaprootSpendInfo) -> TapTweakHash { spend_info.tap_tweak() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builder for building taproot iteratively. Users can specify tap leaf or omitted/hidden branches
|
/// Builder for building Taproot iteratively. Users can specify tap leaf or omitted/hidden branches
|
||||||
/// in a depth-first search (DFS) walk order to construct this tree.
|
/// in a depth-first search (DFS) walk order to construct this tree.
|
||||||
///
|
///
|
||||||
/// See Wikipedia for more details on [DFS](https://en.wikipedia.org/wiki/Depth-first_search).
|
/// See Wikipedia for more details on [DFS](https://en.wikipedia.org/wiki/Depth-first_search).
|
||||||
|
@ -709,7 +709,7 @@ impl TapTree {
|
||||||
/// Gets the inner [`NodeInfo`] of this tree root.
|
/// Gets the inner [`NodeInfo`] of this tree root.
|
||||||
pub fn into_node_info(self) -> NodeInfo { self.0 }
|
pub fn into_node_info(self) -> NodeInfo { self.0 }
|
||||||
|
|
||||||
/// Returns [`TapTreeIter<'_>`] iterator for a taproot script tree, operating in DFS order over
|
/// Returns [`TapTreeIter<'_>`] iterator for a Taproot script tree, operating in DFS order over
|
||||||
/// tree [`ScriptLeaf`]s.
|
/// tree [`ScriptLeaf`]s.
|
||||||
pub fn script_leaves(&self) -> ScriptLeaves { ScriptLeaves { leaf_iter: self.0.leaf_nodes() } }
|
pub fn script_leaves(&self) -> ScriptLeaves { ScriptLeaves { leaf_iter: self.0.leaf_nodes() } }
|
||||||
|
|
||||||
|
@ -747,7 +747,7 @@ impl TryFrom<NodeInfo> for TapTree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator for a taproot script tree, operating in DFS order yielding [`ScriptLeaf`].
|
/// Iterator for a Taproot script tree, operating in DFS order yielding [`ScriptLeaf`].
|
||||||
///
|
///
|
||||||
/// Returned by [`TapTree::script_leaves`]. [`TapTree`] does not allow hidden nodes,
|
/// Returned by [`TapTree::script_leaves`]. [`TapTree`] does not allow hidden nodes,
|
||||||
/// so this iterator is guaranteed to yield all known leaves.
|
/// so this iterator is guaranteed to yield all known leaves.
|
||||||
|
@ -774,7 +774,7 @@ impl<'tree> DoubleEndedIterator for ScriptLeaves<'tree> {
|
||||||
ScriptLeaf::from_leaf_node(self.leaf_iter.next_back()?)
|
ScriptLeaf::from_leaf_node(self.leaf_iter.next_back()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Iterator for a taproot script tree, operating in DFS order yielding [`LeafNode`].
|
/// Iterator for a Taproot script tree, operating in DFS order yielding [`LeafNode`].
|
||||||
///
|
///
|
||||||
/// Returned by [`NodeInfo::leaf_nodes`]. This can potentially yield hidden nodes.
|
/// Returned by [`NodeInfo::leaf_nodes`]. This can potentially yield hidden nodes.
|
||||||
pub struct LeafNodes<'a> {
|
pub struct LeafNodes<'a> {
|
||||||
|
@ -798,7 +798,7 @@ impl<'tree> DoubleEndedIterator for LeafNodes<'tree> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next_back(&mut self) -> Option<Self::Item> { self.leaf_iter.next_back() }
|
fn next_back(&mut self) -> Option<Self::Item> { self.leaf_iter.next_back() }
|
||||||
}
|
}
|
||||||
/// Represents the node information in taproot tree. In contrast to [`TapTree`], this
|
/// Represents the node information in Taproot tree. In contrast to [`TapTree`], this
|
||||||
/// is allowed to have hidden leaves as children.
|
/// is allowed to have hidden leaves as children.
|
||||||
///
|
///
|
||||||
/// Helper type used in merkle tree construction allowing one to build sparse merkle trees. The node
|
/// Helper type used in merkle tree construction allowing one to build sparse merkle trees. The node
|
||||||
|
@ -940,7 +940,7 @@ impl<'de> serde::Deserialize<'de> for NodeInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeInfo::try_from(builder).map_err(|e| {
|
NodeInfo::try_from(builder).map_err(|e| {
|
||||||
serde::de::Error::custom(format!("Incomplete taproot tree: {}", e))
|
serde::de::Error::custom(format!("Incomplete Taproot tree: {}", e))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -949,7 +949,7 @@ impl<'de> serde::Deserialize<'de> for NodeInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Leaf node in a taproot tree. Can be either hidden or known.
|
/// Leaf node in a Taproot tree. Can be either hidden or known.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
||||||
|
@ -980,7 +980,7 @@ impl TapLeaf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store information about taproot leaf node.
|
/// Store information about Taproot leaf node.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct LeafNode {
|
pub struct LeafNode {
|
||||||
/// The [`TapLeaf`]
|
/// The [`TapLeaf`]
|
||||||
|
@ -1009,7 +1009,7 @@ impl LeafNode {
|
||||||
|
|
||||||
/// Computes a leaf hash for this [`ScriptLeaf`] if the leaf is known.
|
/// Computes a leaf hash for this [`ScriptLeaf`] if the leaf is known.
|
||||||
///
|
///
|
||||||
/// This [`TapLeafHash`] is useful while signing taproot script spends.
|
/// This [`TapLeafHash`] is useful while signing Taproot script spends.
|
||||||
///
|
///
|
||||||
/// See [`LeafNode::node_hash`] for computing the [`TapNodeHash`] which returns the hidden node
|
/// See [`LeafNode::node_hash`] for computing the [`TapNodeHash`] which returns the hidden node
|
||||||
/// hash if the node is hidden.
|
/// hash if the node is hidden.
|
||||||
|
@ -1049,7 +1049,7 @@ impl LeafNode {
|
||||||
pub fn leaf(&self) -> &TapLeaf { &self.leaf }
|
pub fn leaf(&self) -> &TapLeaf { &self.leaf }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Script leaf node in a taproot tree along with the merkle proof to get this node.
|
/// Script leaf node in a Taproot tree along with the merkle proof to get this node.
|
||||||
/// Returned by [`TapTree::script_leaves`]
|
/// Returned by [`TapTree::script_leaves`]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct ScriptLeaf<'leaf> {
|
pub struct ScriptLeaf<'leaf> {
|
||||||
|
@ -1096,8 +1096,8 @@ pub struct ControlBlock {
|
||||||
impl ControlBlock {
|
impl ControlBlock {
|
||||||
/// Decodes bytes representing a `ControlBlock`.
|
/// Decodes bytes representing a `ControlBlock`.
|
||||||
///
|
///
|
||||||
/// This is an extra witness element that provides the proof that taproot script pubkey is
|
/// This is an extra witness element that provides the proof that Taproot script pubkey is
|
||||||
/// correctly computed with some specified leaf hash. This is the last element in taproot
|
/// correctly computed with some specified leaf hash. This is the last element in Taproot
|
||||||
/// witness when spending a output via script path.
|
/// witness when spending a output via script path.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
@ -1301,7 +1301,7 @@ impl<'de> serde::Deserialize<'de> for LeafVersion {
|
||||||
type Value = LeafVersion;
|
type Value = LeafVersion;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
formatter.write_str("a valid consensus-encoded taproot leaf version")
|
formatter.write_str("a valid consensus-encoded Taproot leaf version")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
|
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
|
||||||
|
@ -1327,7 +1327,7 @@ impl<'de> serde::Deserialize<'de> for LeafVersion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detailed error type for taproot builder.
|
/// Detailed error type for Taproot builder.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum TaprootBuilderError {
|
pub enum TaprootBuilderError {
|
||||||
|
@ -1380,7 +1380,7 @@ impl From<InvalidMerkleTreeDepthError> for TaprootBuilderError {
|
||||||
fn from(e: InvalidMerkleTreeDepthError) -> Self { Self::InvalidMerkleTreeDepth(e) }
|
fn from(e: InvalidMerkleTreeDepthError) -> Self { Self::InvalidMerkleTreeDepth(e) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detailed error type for taproot utilities.
|
/// Detailed error type for Taproot utilities.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum TaprootError {
|
pub enum TaprootError {
|
||||||
|
@ -1392,7 +1392,7 @@ pub enum TaprootError {
|
||||||
InvalidTaprootLeafVersion(InvalidTaprootLeafVersionError),
|
InvalidTaprootLeafVersion(InvalidTaprootLeafVersionError),
|
||||||
/// Invalid control block size.
|
/// Invalid control block size.
|
||||||
InvalidControlBlockSize(InvalidControlBlockSizeError),
|
InvalidControlBlockSize(InvalidControlBlockSizeError),
|
||||||
/// Invalid taproot internal key.
|
/// Invalid Taproot internal key.
|
||||||
InvalidInternalKey(secp256k1::Error),
|
InvalidInternalKey(secp256k1::Error),
|
||||||
/// Empty tap tree.
|
/// Empty tap tree.
|
||||||
EmptyTree,
|
EmptyTree,
|
||||||
|
|
Loading…
Reference in New Issue