Merge rust-bitcoin/rust-bitcoin#1163: Remove old deprecated code

dfb8ef97dc Remove deprecated MerkleBlock methods (Tobin C. Harding)
b171f88bc3 Remove deprecated SighashComponents struct (Tobin C. Harding)
c2bbf7c343 Use SighashCache instead of SigHashCache (Tobin C. Harding)
1c04a99ec3 Use sighash::SighashCache for bip143 unit tests (Tobin C. Harding)
f65e034742 Refactor test module imports (Tobin C. Harding)

Pull request description:

  I'm not sure what the exact policy we decided on for deprecating is but we have code deprecated since v0.24.0 and v.026.2, both of these seem reasonable safe to remove.

  Removal of `SighashCompontents` uncovered the fact that we never moved the BIP 143 test vector code over to the new `SighashCache`.

  - Patch 1: Trivial preparatory cleanup
  - Patch 2: Re-write bip143 test vectors using `sighash::SighashCache`
  - Patch 3: Trivial, use `SighashCache` instead of `SigHashCache`
  - Patch 4: Remove `SighashComponents` struct deprecated in 0.24.0
  - Patch 5: Remove `MerkleBlock` methods deprecated in 0.26.2

ACKs for top commit:
  apoelstra:
    ACK dfb8ef97dc
  sanket1729:
    ACK dfb8ef97dc

Tree-SHA512: 493525859a131307fbe3ea17f8edb70045dc56526d5579a4fc0d6e7c3fded58c890304721502d1cfceed0a61f4b3d1827a60760e42af0114f3b3ba29b136238c
This commit is contained in:
Andrew Poelstra 2022-08-11 13:23:59 +00:00
commit cc5b6ef53a
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
3 changed files with 124 additions and 238 deletions

View File

@ -13,90 +13,13 @@ use crate::hashes::Hash;
use crate::hash_types::Sighash; use crate::hash_types::Sighash;
use crate::blockdata::script::Script; use crate::blockdata::script::Script;
use crate::blockdata::witness::Witness; use crate::blockdata::witness::Witness;
use crate::blockdata::transaction::{Transaction, TxIn, EcdsaSighashType}; use crate::blockdata::transaction::{Transaction, EcdsaSighashType};
use crate::blockdata::locktime::LockTime; use crate::consensus::encode;
use crate::consensus::{encode, Encodable};
use crate::io; use crate::io;
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
use crate::util::sighash; use crate::util::sighash;
/// Parts of a sighash which are common across inputs or signatures, and which are
/// sufficient (in conjunction with a private key) to sign the transaction
#[derive(Clone, PartialEq, Eq, Debug)]
#[deprecated(since = "0.24.0", note = "please use [sighash::SighashCache] instead")]
pub struct SighashComponents {
tx_version: i32,
tx_locktime: LockTime,
/// Hash of all the previous outputs
pub hash_prevouts: Sighash,
/// Hash of all the input sequence nos
pub hash_sequence: Sighash,
/// Hash of all the outputs in this transaction
pub hash_outputs: Sighash,
}
#[allow(deprecated)]
impl SighashComponents {
/// Compute the sighash components from an unsigned transaction and auxiliary
/// information about its inputs.
/// For the generated sighashes to be valid, no fields in the transaction may change except for
/// script_sig and witnesses.
pub fn new(tx: &Transaction) -> SighashComponents {
let hash_prevouts = {
let mut enc = Sighash::engine();
for txin in &tx.input {
txin.previous_output.consensus_encode(&mut enc).expect("engines don't error");
}
Sighash::from_engine(enc)
};
let hash_sequence = {
let mut enc = Sighash::engine();
for txin in &tx.input {
txin.sequence.consensus_encode(&mut enc).expect("engines don't error");
}
Sighash::from_engine(enc)
};
let hash_outputs = {
let mut enc = Sighash::engine();
for txout in &tx.output {
txout.consensus_encode(&mut enc).expect("engines don't error");
}
Sighash::from_engine(enc)
};
SighashComponents {
tx_version: tx.version,
tx_locktime: tx.lock_time.into(),
hash_prevouts,
hash_sequence,
hash_outputs,
}
}
/// Compute the BIP143 sighash for a `SIGHASH_ALL` signature for the given
/// input.
pub fn sighash_all(&self, txin: &TxIn, script_code: &Script, value: u64) -> Sighash {
let mut enc = Sighash::engine();
self.tx_version.consensus_encode(&mut enc).expect("engines don't error");
self.hash_prevouts.consensus_encode(&mut enc).expect("engines don't error");
self.hash_sequence.consensus_encode(&mut enc).expect("engines don't error");
txin
.previous_output
.consensus_encode(&mut enc)
.expect("engines don't error");
script_code.consensus_encode(&mut enc).expect("engines don't error");
value.consensus_encode(&mut enc).expect("engines don't error");
txin.sequence.consensus_encode(&mut enc).expect("engines don't error");
self.hash_outputs.consensus_encode(&mut enc).expect("engines don't error");
self.tx_locktime.consensus_encode(&mut enc).expect("engines don't error");
1u32.consensus_encode(&mut enc).expect("engines don't error"); // hashtype
Sighash::from_engine(enc)
}
}
/// A replacement for SigHashComponents which supports all sighash modes /// A replacement for SigHashComponents which supports all sighash modes
#[deprecated(since = "0.28.0", note = "please use [sighash::SighashCache] instead")] #[deprecated(since = "0.28.0", note = "please use [sighash::SighashCache] instead")]
pub struct SigHashCache<R: Deref<Target = Transaction>> { pub struct SigHashCache<R: Deref<Target = Transaction>> {
@ -129,8 +52,7 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
Ok(()) Ok(())
} }
/// Compute the BIP143 sighash for any flag type. See SighashComponents::sighash_all simpler /// Compute the BIP143 sighash for any flag type.
/// API for the most common case
pub fn signature_hash( pub fn signature_hash(
&mut self, &mut self,
input_index: usize, input_index: usize,
@ -178,152 +100,26 @@ impl<R: DerefMut<Target = Transaction>> SigHashCache<R> {
#[cfg(test)] #[cfg(test)]
#[allow(deprecated)] #[allow(deprecated)]
mod tests { mod tests {
use std::str::FromStr;
use crate::hash_types::Sighash; use crate::hash_types::Sighash;
use crate::blockdata::script::Script; use crate::blockdata::script::Script;
use crate::blockdata::transaction::Transaction; use crate::blockdata::transaction::Transaction;
use crate::blockdata::locktime::LockTime;
use crate::consensus::encode::deserialize; use crate::consensus::encode::deserialize;
use crate::network::constants::Network;
use crate::util::address::Address;
use crate::util::key::PublicKey;
use crate::hashes::hex::FromHex; use crate::hashes::hex::FromHex;
use crate::internal_macros::{hex_hash, hex_script}; use crate::util::sighash::SighashCache;
use super::*; use super::*;
fn p2pkh_hex(pk: &str) -> Script {
let pk: PublicKey = PublicKey::from_str(pk).unwrap();
Address::p2pkh(&pk, Network::Bitcoin).script_pubkey()
}
fn run_test_sighash_bip143(tx: &str, script: &str, input_index: usize, value: u64, hash_type: u32, expected_result: &str) { fn run_test_sighash_bip143(tx: &str, script: &str, input_index: usize, value: u64, hash_type: u32, expected_result: &str) {
let tx: Transaction = deserialize(&Vec::<u8>::from_hex(tx).unwrap()[..]).unwrap(); let tx: Transaction = deserialize(&Vec::<u8>::from_hex(tx).unwrap()[..]).unwrap();
let script = Script::from(Vec::<u8>::from_hex(script).unwrap()); let script = Script::from(Vec::<u8>::from_hex(script).unwrap());
let raw_expected = Sighash::from_hex(expected_result).unwrap(); let raw_expected = Sighash::from_hex(expected_result).unwrap();
let expected_result = Sighash::from_slice(&raw_expected[..]).unwrap(); let expected_result = Sighash::from_slice(&raw_expected[..]).unwrap();
let mut cache = SigHashCache::new(&tx); let mut cache = SighashCache::new(&tx);
let sighash_type = EcdsaSighashType::from_u32_consensus(hash_type); let sighash_type = EcdsaSighashType::from_u32_consensus(hash_type);
let actual_result = cache.signature_hash(input_index, &script, value, sighash_type); let actual_result = cache.segwit_signature_hash(input_index, &script, value, sighash_type).unwrap();
assert_eq!(actual_result, expected_result); assert_eq!(actual_result, expected_result);
} }
#[test]
fn bip143_p2wpkh() {
let tx = deserialize::<Transaction>(
&Vec::from_hex(
"0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f000000\
0000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a01000000\
00ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093\
510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000",
).unwrap()[..],
).unwrap();
let witness_script = p2pkh_hex("025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357");
let value = 600_000_000;
let comp = SighashComponents::new(&tx);
assert_eq!(
comp,
SighashComponents {
tx_version: 1,
tx_locktime: LockTime::from_consensus(17),
hash_prevouts: hex_hash!(
Sighash, "96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37"
),
hash_sequence: hex_hash!(
Sighash, "52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b"
),
hash_outputs: hex_hash!(
Sighash, "863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5"
),
}
);
assert_eq!(
comp.sighash_all(&tx.input[1], &witness_script, value),
hex_hash!(Sighash, "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670")
);
}
#[test]
fn bip143_p2wpkh_nested_in_p2sh() {
let tx = deserialize::<Transaction>(
&Vec::from_hex(
"0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000\
0000feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac00\
08af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac92040000",
).unwrap()[..],
).unwrap();
let witness_script = p2pkh_hex("03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873");
let value = 1_000_000_000;
let comp = SighashComponents::new(&tx);
assert_eq!(
comp,
SighashComponents {
tx_version: 1,
tx_locktime: LockTime::from_consensus(1170),
hash_prevouts: hex_hash!(
Sighash, "b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a"
),
hash_sequence: hex_hash!(
Sighash, "18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198"
),
hash_outputs: hex_hash!(
Sighash, "de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83"
),
}
);
assert_eq!(
comp.sighash_all(&tx.input[0], &witness_script, value),
hex_hash!(Sighash, "64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6")
);
}
#[test]
fn bip143_p2wsh_nested_in_p2sh() {
let tx = deserialize::<Transaction>(
&Vec::from_hex(
"010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000\
ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f\
05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000").unwrap()[..],
).unwrap();
let witness_script = hex_script!(
"56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28\
bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b\
9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58\
c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b1486\
2c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b\
56ae"
);
let value = 987654321;
let comp = SighashComponents::new(&tx);
assert_eq!(
comp,
SighashComponents {
tx_version: 1,
tx_locktime: LockTime::ZERO,
hash_prevouts: hex_hash!(
Sighash, "74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0"
),
hash_sequence: hex_hash!(
Sighash, "3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044"
),
hash_outputs: hex_hash!(
Sighash, "bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc"
),
}
);
assert_eq!(
comp.sighash_all(&tx.input[0], &witness_script, value),
hex_hash!(Sighash, "185c0be5263dce5b4bb50a047973c1b6272bfbd0103a89444597dc40b248ee7c")
);
}
#[test] #[test]
fn bip143_sighash_flags() { fn bip143_sighash_flags() {
// All examples generated via Bitcoin Core RPC using signrawtransactionwithwallet // All examples generated via Bitcoin Core RPC using signrawtransactionwithwallet

View File

@ -431,14 +431,6 @@ impl MerkleBlock {
Self::from_header_txids_with_predicate(&block.header, &block_txids, match_txids) Self::from_header_txids_with_predicate(&block.header, &block_txids, match_txids)
} }
/// Create a MerkleBlock from a block, that contains proofs for specific txids.
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[deprecated(since = "0.26.2", note = "use from_block_with_predicate")]
pub fn from_block(block: &Block, match_txids: &::std::collections::HashSet<Txid>) -> Self {
Self::from_block_with_predicate(block, |t| match_txids.contains(t))
}
/// Create a MerkleBlock from the block's header and txids, that contain proofs for specific txids. /// Create a MerkleBlock from the block's header and txids, that contain proofs for specific txids.
/// ///
/// The `header` is the block header, `block_txids` is the full list of txids included in the block and /// The `header` is the block header, `block_txids` is the full list of txids included in the block and
@ -463,18 +455,6 @@ impl MerkleBlock {
} }
} }
/// Create a MerkleBlock from the block's header and txids, that should contain proofs for match_txids.
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[deprecated(since = "0.26.2", note = "use from_header_txids_with_predicate")]
pub fn from_header_txids(
header: &BlockHeader,
block_txids: &[Txid],
match_txids: &::std::collections::HashSet<Txid>,
) -> Self {
Self::from_header_txids_with_predicate(header, block_txids, |t| match_txids.contains(t))
}
/// Extract the matching txid's represented by this partial merkle tree /// Extract the matching txid's represented by this partial merkle tree
/// and their respective indices within the partial tree. /// and their respective indices within the partial tree.
/// returns Ok(()) on success, or error in case of failure /// returns Ok(()) on success, or error in case of failure

View File

@ -923,19 +923,24 @@ fn is_invalid_use_of_sighash_single(sighash: u32, input_index: usize, output_len
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use std::str::FromStr;
use secp256k1::{self, SecretKey, XOnlyPublicKey};
use crate::{Script, Transaction, TxIn, TxOut, EcdsaSighashType, Address};
use crate::blockdata::locktime::PackedLockTime; use crate::blockdata::locktime::PackedLockTime;
use crate::consensus::deserialize; use crate::consensus::deserialize;
use crate::hashes::hex::FromHex; use crate::hashes::hex::{FromHex, ToHex};
use crate::hashes::{Hash, HashEngine}; use crate::hashes::{Hash, HashEngine};
use crate::util::sighash::{Annex, Error, Prevouts, ScriptPath, SighashCache}; use crate::hash_types::Sighash;
use std::str::FromStr;
use crate::hashes::hex::ToHex;
use crate::util::taproot::{TapTweakHash, TapSighashHash, TapBranchHash, TapLeafHash};
use secp256k1::{self, SecretKey, XOnlyPublicKey};
use crate::internal_macros::{hex_hash, hex_script, hex_decode}; use crate::internal_macros::{hex_hash, hex_script, hex_decode};
extern crate serde_json; use crate::network::constants::Network;
use crate::util::key::PublicKey;
use crate::util::sighash::{Annex, Error, Prevouts, ScriptPath, SighashCache};
use crate::util::taproot::{TapTweakHash, TapSighashHash, TapBranchHash, TapLeafHash};
use crate::{Script, Transaction, TxIn, TxOut}; extern crate serde_json;
#[test] #[test]
fn sighash_single_bug() { fn sighash_single_bug() {
@ -1368,4 +1373,109 @@ mod tests {
assert_eq!(SchnorrSighashType::from_str(s).unwrap_err().to_string(), format!("Unrecognized SIGHASH string '{}'", s)); assert_eq!(SchnorrSighashType::from_str(s).unwrap_err().to_string(), format!("Unrecognized SIGHASH string '{}'", s));
} }
} }
fn p2pkh_hex(pk: &str) -> Script {
let pk: PublicKey = PublicKey::from_str(pk).unwrap();
Address::p2pkh(&pk, Network::Bitcoin).script_pubkey()
}
#[test]
fn bip143_p2wpkh() {
let tx = deserialize::<Transaction>(
&Vec::from_hex(
"0100000002fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f000000\
0000eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a01000000\
00ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093\
510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac11000000",
).unwrap()[..],
).unwrap();
let witness_script = p2pkh_hex("025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357");
let value = 600_000_000;
let mut cache = SighashCache::new(&tx);
assert_eq!(
cache.segwit_signature_hash(1, &witness_script, value, EcdsaSighashType::All).unwrap(),
hex_hash!(Sighash, "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670")
);
let cache = cache.segwit_cache();
assert_eq!(cache.prevouts, hex_hash!(
Hash, "96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37"
));
assert_eq!(cache.sequences, hex_hash!(
Hash, "52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b"
));
assert_eq!(cache.outputs, hex_hash!(
Hash, "863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5"
));
}
#[test]
fn bip143_p2wpkh_nested_in_p2sh() {
let tx = deserialize::<Transaction>(
&Vec::from_hex(
"0100000001db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000\
0000feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac00\
08af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac92040000",
).unwrap()[..],
).unwrap();
let witness_script = p2pkh_hex("03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873");
let value = 1_000_000_000;
let mut cache = SighashCache::new(&tx);
assert_eq!(
cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
hex_hash!(Sighash, "64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6")
);
let cache = cache.segwit_cache();
assert_eq!(cache.prevouts, hex_hash!(
Hash, "b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a"
));
assert_eq!(cache.sequences, hex_hash!(
Hash, "18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198"
));
assert_eq!(cache.outputs, hex_hash!(
Hash, "de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83"
));
}
#[test]
fn bip143_p2wsh_nested_in_p2sh() {
let tx = deserialize::<Transaction>(
&Vec::from_hex(
"010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000\
ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f\
05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000").unwrap()[..],
).unwrap();
let witness_script = hex_script!(
"56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28\
bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b\
9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58\
c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b1486\
2c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b\
56ae"
);
let value = 987654321;
let mut cache = SighashCache::new(&tx);
assert_eq!(
cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
hex_hash!(Sighash, "185c0be5263dce5b4bb50a047973c1b6272bfbd0103a89444597dc40b248ee7c")
);
let cache = cache.segwit_cache();
assert_eq!(cache.prevouts, hex_hash!(
Hash, "74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0"
));
assert_eq!(cache.sequences, hex_hash!(
Hash, "3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044"
));
assert_eq!(cache.outputs, hex_hash!(
Hash, "bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc"
));
}
} }