Skip to content

Commit 40e3035

Browse files
committed
Merge #160: Make TxOut generic in Prevouts
dc6f520 Make TxOut generic in Prevouts (Christian Lewe) Pull request description: Useful when prevouts are saved in a vector. ACKs for top commit: apoelstra: ACK dc6f520 Tree-SHA512: c9981753ed6a7bbf492541e4a17a3e6be36dabb7e26f57453cb14e7befbc13f5f0c3181cfc8c10a110734dc186870834a2a96af47884c1c5a22a974855d82fc6
2 parents 4be1a87 + dc6f520 commit 40e3035

1 file changed

Lines changed: 26 additions & 21 deletions

File tree

src/sighash.rs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
//! signatures, which are placed in the scriptSig.
2020
//!
2121
22+
use std::borrow::Borrow;
2223
use crate::encode::{self, Encodable};
2324
use crate::hash_types::SigHash;
2425
use crate::hashes::{sha256d, Hash, sha256};
@@ -87,14 +88,14 @@ struct TaprootCache {
8788
/// Contains outputs of previous transactions.
8889
/// In the case [`SchnorrSigHashType`] variant is `ANYONECANPAY`, [`Prevouts::One`] may be provided
8990
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
90-
pub enum Prevouts<'u> {
91+
pub enum Prevouts<'u, T> where T: 'u + Borrow<TxOut> {
9192
/// `One` variant allows to provide the single Prevout needed. It's useful for example
9293
/// when modifier `ANYONECANPAY` is provided, only prevout of the current input is needed.
9394
/// The first `usize` argument is the input index this [`TxOut`] is referring to.
94-
One(usize, &'u TxOut),
95+
One(usize, T),
9596
/// When `ANYONECANPAY` is not provided, or the caller is handy giving all prevouts so the same
9697
/// variable can be used for multiple inputs.
97-
All(&'u [TxOut]),
98+
All(&'u [T]),
9899
}
99100

100101
const KEY_VERSION_0: u8 = 0u8;
@@ -166,7 +167,7 @@ impl fmt::Display for Error {
166167

167168
impl ::std::error::Error for Error {}
168169

169-
impl<'u> Prevouts<'u> {
170+
impl<'u, T> Prevouts<'u, T> where T: Borrow<TxOut> {
170171
fn check_all(&self, tx: &Transaction) -> Result<(), Error> {
171172
if let Prevouts::All(prevouts) = self {
172173
if prevouts.len() != tx.input.len() {
@@ -176,9 +177,9 @@ impl<'u> Prevouts<'u> {
176177
Ok(())
177178
}
178179

179-
fn get_all(&self) -> Result<&[TxOut], Error> {
180+
fn get_all(&self) -> Result<&[T], Error> {
180181
match self {
181-
Prevouts::All(prevouts) => Ok(prevouts),
182+
Prevouts::All(prevouts) => Ok(*prevouts),
182183
_ => Err(Error::PrevoutKind),
183184
}
184185
}
@@ -187,12 +188,15 @@ impl<'u> Prevouts<'u> {
187188
match self {
188189
Prevouts::One(index, prevout) => {
189190
if input_index == *index {
190-
Ok(prevout)
191+
Ok(prevout.borrow())
191192
} else {
192193
Err(Error::PrevoutIndex)
193194
}
194195
}
195-
Prevouts::All(prevouts) => prevouts.get(input_index).ok_or(Error::PrevoutIndex),
196+
Prevouts::All(prevouts) => prevouts
197+
.get(input_index)
198+
.map(|x| x.borrow())
199+
.ok_or(Error::PrevoutIndex),
196200
}
197201
}
198202
}
@@ -244,11 +248,11 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
244248

245249
/// Encode the BIP341 signing data for any flag type into a given object implementing a
246250
/// io::Write trait.
247-
pub fn taproot_encode_signing_data_to<Write: io::Write>(
251+
pub fn taproot_encode_signing_data_to<Write: io::Write, T: Borrow<TxOut>>(
248252
&mut self,
249253
mut writer: Write,
250254
input_index: usize,
251-
prevouts: &Prevouts,
255+
prevouts: &Prevouts<T>,
252256
annex: Option<Annex>,
253257
leaf_hash_code_separator: Option<(TapLeafHash, u32)>,
254258
sighash_type: SchnorrSigHashType,
@@ -417,10 +421,10 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
417421
}
418422

419423
/// Compute the BIP341 sighash for any flag type.
420-
pub fn taproot_sighash(
424+
pub fn taproot_sighash<T: Borrow<TxOut>>(
421425
&mut self,
422426
input_index: usize,
423-
prevouts: &Prevouts,
427+
prevouts: &Prevouts<T>,
424428
annex: Option<Annex>,
425429
leaf_hash_code_separator: Option<(TapLeafHash, u32)>,
426430
sighash_type: SchnorrSigHashType,
@@ -440,10 +444,10 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
440444
}
441445

442446
/// Compute the BIP341 sighash for a key spend
443-
pub fn taproot_key_spend_signature_hash(
447+
pub fn taproot_key_spend_signature_hash<T: Borrow<TxOut>>(
444448
&mut self,
445449
input_index: usize,
446-
prevouts: &Prevouts,
450+
prevouts: &Prevouts<T>,
447451
sighash_type: SchnorrSigHashType,
448452
genesis_hash: BlockHash,
449453
) -> Result<TapSighashHash, Error> {
@@ -464,10 +468,10 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
464468
///
465469
/// Assumes the default `OP_CODESEPARATOR` position of `0xFFFFFFFF`. Custom values can be
466470
/// provided through the more fine-grained API of [`SighashCache::taproot_encode_signing_data_to`].
467-
pub fn taproot_script_spend_signature_hash<S: Into<TapLeafHash>>(
471+
pub fn taproot_script_spend_signature_hash<S: Into<TapLeafHash>, T: Borrow<TxOut>>(
468472
&mut self,
469473
input_index: usize,
470-
prevouts: &Prevouts,
474+
prevouts: &Prevouts<T>,
471475
leaf_hash: S,
472476
sighash_type: SchnorrSigHashType,
473477
genesis_hash: BlockHash,
@@ -760,14 +764,14 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
760764
}
761765

762766
#[inline]
763-
fn taproot_cache(&mut self, prevouts: &[TxOut]) -> &TaprootCache {
767+
fn taproot_cache<T: Borrow<TxOut>>(&mut self, prevouts: &[T]) -> &TaprootCache {
764768
Self::taproot_cache_minimal_borrow(&mut self.taproot_cache, &self.tx, prevouts)
765769
}
766770

767-
fn taproot_cache_minimal_borrow<'a>(
771+
fn taproot_cache_minimal_borrow<'a, T: Borrow<TxOut>>(
768772
taproot_cache: &'a mut Option<TaprootCache>,
769773
tx: &R,
770-
prevouts: &[TxOut],
774+
prevouts: &[T],
771775
) -> &'a TaprootCache {
772776
taproot_cache.get_or_insert_with(|| {
773777
let mut enc_asset_amounts = sha256::Hash::engine();
@@ -776,9 +780,10 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
776780
let mut enc_issuance_rangeproofs = sha256::Hash::engine();
777781
let mut enc_output_witnesses = sha256::Hash::engine();
778782
for prevout in prevouts {
779-
prevout.asset.consensus_encode(&mut enc_asset_amounts).unwrap();
780-
prevout.value.consensus_encode(&mut enc_asset_amounts).unwrap();
783+
prevout.borrow().asset.consensus_encode(&mut enc_asset_amounts).unwrap();
784+
prevout.borrow().value.consensus_encode(&mut enc_asset_amounts).unwrap();
781785
prevout
786+
.borrow()
782787
.script_pubkey
783788
.consensus_encode(&mut enc_script_pubkeys)
784789
.unwrap();

0 commit comments

Comments
 (0)