Merge rust-bitcoin/rust-bitcoin#4113: Fix `is_invalid_use_of_sighash_single()` incompatibility with Bitcoin Core
7ab2f5be40
Add test for sighash_single_bug incompatility fix (Liu-Cheng Xu)5d38073afb
Fix `is_invalid_use_of_sighash_single()` incompatibility with Bitcoin Core (Liu-Cheng Xu) Pull request description: Close https://github.com/rust-bitcoin/rust-bitcoin/issues/4112 ACKs for top commit: tcharding: ACK7ab2f5be40
Kixunil: ACK7ab2f5be40
apoelstra: ACK 7ab2f5be4076c22e60eefcaa943444808eae3e3f; successfully ran local tests Tree-SHA512: d47143d188653d3e845951e64e9b410fdbdac8e51906f33532b8d71519f0bd1454a46135dfdd6073a6d1ced9854dc3e13f3c35de60b7fdd45c22ef37f9a0fc75
This commit is contained in:
commit
e80ce4a89c
|
@ -429,6 +429,16 @@ impl EcdsaSighashType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if the sighash type is [`Self::Single`] or [`Self::SinglePlusAnyoneCanPay`].
|
||||||
|
///
|
||||||
|
/// This matches Bitcoin Core's behavior where SIGHASH_SINGLE bug check is based on the base
|
||||||
|
/// type (after masking with 0x1f), regardless of the ANYONECANPAY flag.
|
||||||
|
///
|
||||||
|
/// See: <https://github.com/bitcoin/bitcoin/blob/e486597/src/script/interpreter.cpp#L1618-L1619>
|
||||||
|
pub fn is_single(&self) -> bool {
|
||||||
|
matches!(self, Self::Single | Self::SinglePlusAnyoneCanPay)
|
||||||
|
}
|
||||||
|
|
||||||
/// Constructs a new [`EcdsaSighashType`] from a raw `u32`.
|
/// Constructs a new [`EcdsaSighashType`] from a raw `u32`.
|
||||||
///
|
///
|
||||||
/// **Note**: this replicates consensus behaviour, for current standardness rules correctness
|
/// **Note**: this replicates consensus behaviour, for current standardness rules correctness
|
||||||
|
@ -1363,7 +1373,7 @@ impl std::error::Error for AnnexError {
|
||||||
|
|
||||||
fn is_invalid_use_of_sighash_single(sighash: u32, input_index: usize, outputs_len: usize) -> bool {
|
fn is_invalid_use_of_sighash_single(sighash: u32, input_index: usize, outputs_len: usize) -> bool {
|
||||||
let ty = EcdsaSighashType::from_consensus(sighash);
|
let ty = EcdsaSighashType::from_consensus(sighash);
|
||||||
ty == EcdsaSighashType::Single && input_index >= outputs_len
|
ty.is_single() && input_index >= outputs_len
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Result of [`SighashCache::legacy_encode_signing_data_to`].
|
/// Result of [`SighashCache::legacy_encode_signing_data_to`].
|
||||||
|
@ -1538,8 +1548,6 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sighash_single_bug() {
|
fn sighash_single_bug() {
|
||||||
const SIGHASH_SINGLE: u32 = 3;
|
|
||||||
|
|
||||||
// We need a tx with more inputs than outputs.
|
// We need a tx with more inputs than outputs.
|
||||||
let tx = Transaction {
|
let tx = Transaction {
|
||||||
version: transaction::Version::ONE,
|
version: transaction::Version::ONE,
|
||||||
|
@ -1550,10 +1558,16 @@ mod tests {
|
||||||
let script = ScriptBuf::new();
|
let script = ScriptBuf::new();
|
||||||
let cache = SighashCache::new(&tx);
|
let cache = SighashCache::new(&tx);
|
||||||
|
|
||||||
let got = cache.legacy_signature_hash(1, &script, SIGHASH_SINGLE).expect("sighash");
|
let sighash_single = 3;
|
||||||
|
let got = cache.legacy_signature_hash(1, &script, sighash_single).expect("sighash");
|
||||||
let want = LegacySighash::from_byte_array(UINT256_ONE);
|
let want = LegacySighash::from_byte_array(UINT256_ONE);
|
||||||
|
assert_eq!(got, want);
|
||||||
|
|
||||||
assert_eq!(got, want)
|
// https://github.com/rust-bitcoin/rust-bitcoin/issues/4112
|
||||||
|
let sighash_single = 131;
|
||||||
|
let got = cache.legacy_signature_hash(1, &script, sighash_single).expect("sighash");
|
||||||
|
let want = LegacySighash::from_byte_array(UINT256_ONE);
|
||||||
|
assert_eq!(got, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue