Rename EcdsaSigHashType -> EcdsaSighashType
Our usage of `SigHash` implies that 'sighash' is _two_ words; 'sighash' is a well known word in the Bitcoin ecosystem it should appear in identifiers as `Sighash`. Rename `EcdsaSigHashType` to `EcdsaSighashType`.
This commit is contained in:
parent
58a958e3f7
commit
5522454583
|
@ -319,10 +319,10 @@ impl Transaction {
|
|||
/// sighash flag can be computed.
|
||||
///
|
||||
/// To actually produce a scriptSig, this hash needs to be run through an ECDSA signer, the
|
||||
/// [`EcdsaSigHashType`] appended to the resulting sig, and a script written around this, but
|
||||
/// [`EcdsaSighashType`] appended to the resulting sig, and a script written around this, but
|
||||
/// this is the general (and hard) part.
|
||||
///
|
||||
/// The `sighash_type` supports an arbitrary `u32` value, instead of just [`EcdsaSigHashType`],
|
||||
/// The `sighash_type` supports an arbitrary `u32` value, instead of just [`EcdsaSighashType`],
|
||||
/// because internally 4 bytes are being hashed, even though only the lowest byte is appended to
|
||||
/// signature in a transaction.
|
||||
///
|
||||
|
@ -356,7 +356,7 @@ impl Transaction {
|
|||
return Ok(())
|
||||
}
|
||||
|
||||
let (sighash, anyone_can_pay) = EcdsaSigHashType::from_consensus(sighash_type).split_anyonecanpay_flag();
|
||||
let (sighash, anyone_can_pay) = EcdsaSighashType::from_consensus(sighash_type).split_anyonecanpay_flag();
|
||||
|
||||
// Build tx to sign
|
||||
let mut tx = Transaction {
|
||||
|
@ -379,22 +379,22 @@ impl Transaction {
|
|||
tx.input.push(TxIn {
|
||||
previous_output: input.previous_output,
|
||||
script_sig: if n == input_index { script_pubkey.clone() } else { Script::new() },
|
||||
sequence: if n != input_index && (sighash == EcdsaSigHashType::Single || sighash == EcdsaSigHashType::None) { 0 } else { input.sequence },
|
||||
sequence: if n != input_index && (sighash == EcdsaSighashType::Single || sighash == EcdsaSighashType::None) { 0 } else { input.sequence },
|
||||
witness: Witness::default(),
|
||||
});
|
||||
}
|
||||
}
|
||||
// ..then all outputs
|
||||
tx.output = match sighash {
|
||||
EcdsaSigHashType::All => self.output.clone(),
|
||||
EcdsaSigHashType::Single => {
|
||||
EcdsaSighashType::All => self.output.clone(),
|
||||
EcdsaSighashType::Single => {
|
||||
let output_iter = self.output.iter()
|
||||
.take(input_index + 1) // sign all outputs up to and including this one, but erase
|
||||
.enumerate() // all of them except for this one
|
||||
.map(|(n, out)| if n == input_index { out.clone() } else { TxOut::default() });
|
||||
output_iter.collect()
|
||||
}
|
||||
EcdsaSigHashType::None => vec![],
|
||||
EcdsaSighashType::None => vec![],
|
||||
_ => unreachable!()
|
||||
};
|
||||
// hash the result
|
||||
|
@ -407,10 +407,10 @@ impl Transaction {
|
|||
/// Computes a signature hash for a given input index with a given sighash flag.
|
||||
///
|
||||
/// To actually produce a scriptSig, this hash needs to be run through an ECDSA signer, the
|
||||
/// [`EcdsaSigHashType`] appended to the resulting sig, and a script written around this, but
|
||||
/// [`EcdsaSighashType`] appended to the resulting sig, and a script written around this, but
|
||||
/// this is the general (and hard) part.
|
||||
///
|
||||
/// The `sighash_type` supports an arbitrary `u32` value, instead of just [`EcdsaSigHashType`],
|
||||
/// The `sighash_type` supports an arbitrary `u32` value, instead of just [`EcdsaSighashType`],
|
||||
/// because internally 4 bytes are being hashed, even though only the lowest byte is appended to
|
||||
/// signature in a transaction.
|
||||
///
|
||||
|
@ -444,8 +444,8 @@ impl Transaction {
|
|||
}
|
||||
|
||||
fn is_invalid_use_of_sighash_single(&self, sighash: u32, input_index: usize) -> bool {
|
||||
let ty = EcdsaSigHashType::from_consensus(sighash);
|
||||
ty == EcdsaSigHashType::Single && input_index >= self.output.len()
|
||||
let ty = EcdsaSighashType::from_consensus(sighash);
|
||||
ty == EcdsaSighashType::Single && input_index >= self.output.len()
|
||||
}
|
||||
|
||||
/// Returns the "weight" of this transaction, as defined by BIP141.
|
||||
|
@ -736,15 +736,15 @@ impl fmt::Display for NonStandardSigHashType {
|
|||
impl error::Error for NonStandardSigHashType {}
|
||||
|
||||
/// Legacy Hashtype of an input's signature
|
||||
#[deprecated(since = "0.28.0", note = "Please use [`EcdsaSigHashType`] instead")]
|
||||
pub type SigHashType = EcdsaSigHashType;
|
||||
#[deprecated(since = "0.28.0", note = "Please use [`EcdsaSighashType`] instead")]
|
||||
pub type SigHashType = EcdsaSighashType;
|
||||
|
||||
/// Hashtype of an input's signature, encoded in the last byte of the signature.
|
||||
///
|
||||
/// Fixed values so they can be cast as integer types for encoding (see also
|
||||
/// [`SchnorrSigHashType`]).
|
||||
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
|
||||
pub enum EcdsaSigHashType {
|
||||
pub enum EcdsaSighashType {
|
||||
/// 0x1: Sign all outputs.
|
||||
All = 0x01,
|
||||
/// 0x2: Sign no outputs --- anyone can choose the destination.
|
||||
|
@ -761,67 +761,67 @@ pub enum EcdsaSigHashType {
|
|||
/// 0x83: Sign one output and only this input (see `Single` for what "one output" means).
|
||||
SinglePlusAnyoneCanPay = 0x83
|
||||
}
|
||||
serde_string_impl!(EcdsaSigHashType, "a EcdsaSigHashType data");
|
||||
serde_string_impl!(EcdsaSighashType, "a EcdsaSighashType data");
|
||||
|
||||
impl fmt::Display for EcdsaSigHashType {
|
||||
impl fmt::Display for EcdsaSighashType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = match self {
|
||||
EcdsaSigHashType::All => "SIGHASH_ALL",
|
||||
EcdsaSigHashType::None => "SIGHASH_NONE",
|
||||
EcdsaSigHashType::Single => "SIGHASH_SINGLE",
|
||||
EcdsaSigHashType::AllPlusAnyoneCanPay => "SIGHASH_ALL|SIGHASH_ANYONECANPAY",
|
||||
EcdsaSigHashType::NonePlusAnyoneCanPay => "SIGHASH_NONE|SIGHASH_ANYONECANPAY",
|
||||
EcdsaSigHashType::SinglePlusAnyoneCanPay => "SIGHASH_SINGLE|SIGHASH_ANYONECANPAY",
|
||||
EcdsaSighashType::All => "SIGHASH_ALL",
|
||||
EcdsaSighashType::None => "SIGHASH_NONE",
|
||||
EcdsaSighashType::Single => "SIGHASH_SINGLE",
|
||||
EcdsaSighashType::AllPlusAnyoneCanPay => "SIGHASH_ALL|SIGHASH_ANYONECANPAY",
|
||||
EcdsaSighashType::NonePlusAnyoneCanPay => "SIGHASH_NONE|SIGHASH_ANYONECANPAY",
|
||||
EcdsaSighashType::SinglePlusAnyoneCanPay => "SIGHASH_SINGLE|SIGHASH_ANYONECANPAY",
|
||||
};
|
||||
f.write_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl str::FromStr for EcdsaSigHashType {
|
||||
impl str::FromStr for EcdsaSighashType {
|
||||
type Err = SigHashTypeParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"SIGHASH_ALL" => Ok(EcdsaSigHashType::All),
|
||||
"SIGHASH_NONE" => Ok(EcdsaSigHashType::None),
|
||||
"SIGHASH_SINGLE" => Ok(EcdsaSigHashType::Single),
|
||||
"SIGHASH_ALL|SIGHASH_ANYONECANPAY" => Ok(EcdsaSigHashType::AllPlusAnyoneCanPay),
|
||||
"SIGHASH_NONE|SIGHASH_ANYONECANPAY" => Ok(EcdsaSigHashType::NonePlusAnyoneCanPay),
|
||||
"SIGHASH_SINGLE|SIGHASH_ANYONECANPAY" => Ok(EcdsaSigHashType::SinglePlusAnyoneCanPay),
|
||||
"SIGHASH_ALL" => Ok(EcdsaSighashType::All),
|
||||
"SIGHASH_NONE" => Ok(EcdsaSighashType::None),
|
||||
"SIGHASH_SINGLE" => Ok(EcdsaSighashType::Single),
|
||||
"SIGHASH_ALL|SIGHASH_ANYONECANPAY" => Ok(EcdsaSighashType::AllPlusAnyoneCanPay),
|
||||
"SIGHASH_NONE|SIGHASH_ANYONECANPAY" => Ok(EcdsaSighashType::NonePlusAnyoneCanPay),
|
||||
"SIGHASH_SINGLE|SIGHASH_ANYONECANPAY" => Ok(EcdsaSighashType::SinglePlusAnyoneCanPay),
|
||||
_ => Err(SigHashTypeParseError { unrecognized: s.to_owned() }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EcdsaSigHashType {
|
||||
impl EcdsaSighashType {
|
||||
/// Splits the sighash flag into the "real" sighash flag and the ANYONECANPAY boolean.
|
||||
pub(crate) fn split_anyonecanpay_flag(self) -> (EcdsaSigHashType, bool) {
|
||||
pub(crate) fn split_anyonecanpay_flag(self) -> (EcdsaSighashType, bool) {
|
||||
match self {
|
||||
EcdsaSigHashType::All => (EcdsaSigHashType::All, false),
|
||||
EcdsaSigHashType::None => (EcdsaSigHashType::None, false),
|
||||
EcdsaSigHashType::Single => (EcdsaSigHashType::Single, false),
|
||||
EcdsaSigHashType::AllPlusAnyoneCanPay => (EcdsaSigHashType::All, true),
|
||||
EcdsaSigHashType::NonePlusAnyoneCanPay => (EcdsaSigHashType::None, true),
|
||||
EcdsaSigHashType::SinglePlusAnyoneCanPay => (EcdsaSigHashType::Single, true)
|
||||
EcdsaSighashType::All => (EcdsaSighashType::All, false),
|
||||
EcdsaSighashType::None => (EcdsaSighashType::None, false),
|
||||
EcdsaSighashType::Single => (EcdsaSighashType::Single, false),
|
||||
EcdsaSighashType::AllPlusAnyoneCanPay => (EcdsaSighashType::All, true),
|
||||
EcdsaSighashType::NonePlusAnyoneCanPay => (EcdsaSighashType::None, true),
|
||||
EcdsaSighashType::SinglePlusAnyoneCanPay => (EcdsaSighashType::Single, true)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a [`EcdsaSigHashType`] from a raw `u32`.
|
||||
/// Creates a [`EcdsaSighashType`] from a raw `u32`.
|
||||
#[deprecated(since="0.28.0", note="please use `from_consensus`")]
|
||||
pub fn from_u32_consensus(n: u32) -> EcdsaSigHashType {
|
||||
EcdsaSigHashType::from_consensus(n)
|
||||
pub fn from_u32_consensus(n: u32) -> EcdsaSighashType {
|
||||
EcdsaSighashType::from_consensus(n)
|
||||
}
|
||||
|
||||
/// Creates a [`EcdsaSigHashType`] from a raw `u32`.
|
||||
/// Creates a [`EcdsaSighashType`] from a raw `u32`.
|
||||
///
|
||||
/// **Note**: this replicates consensus behaviour, for current standardness rules correctness
|
||||
/// you probably want [`Self::from_standard`].
|
||||
///
|
||||
/// This might cause unexpected behavior because it does not roundtrip. That is,
|
||||
/// `EcdsaSigHashType::from_consensus(n) as u32 != n` for non-standard values of `n`. While
|
||||
/// `EcdsaSighashType::from_consensus(n) as u32 != n` for non-standard values of `n`. While
|
||||
/// verifying signatures, the user should retain the `n` and use it compute the signature hash
|
||||
/// message.
|
||||
pub fn from_consensus(n: u32) -> EcdsaSigHashType {
|
||||
pub fn from_consensus(n: u32) -> EcdsaSighashType {
|
||||
// In Bitcoin Core, the SignatureHash function will mask the (int32) value with
|
||||
// 0x1f to (apparently) deactivate ACP when checking for SINGLE and NONE bits.
|
||||
// We however want to be matching also against on ACP-masked ALL, SINGLE, and NONE.
|
||||
|
@ -829,43 +829,43 @@ impl EcdsaSigHashType {
|
|||
let mask = 0x1f | 0x80;
|
||||
match n & mask {
|
||||
// "real" sighashes
|
||||
0x01 => EcdsaSigHashType::All,
|
||||
0x02 => EcdsaSigHashType::None,
|
||||
0x03 => EcdsaSigHashType::Single,
|
||||
0x81 => EcdsaSigHashType::AllPlusAnyoneCanPay,
|
||||
0x82 => EcdsaSigHashType::NonePlusAnyoneCanPay,
|
||||
0x83 => EcdsaSigHashType::SinglePlusAnyoneCanPay,
|
||||
0x01 => EcdsaSighashType::All,
|
||||
0x02 => EcdsaSighashType::None,
|
||||
0x03 => EcdsaSighashType::Single,
|
||||
0x81 => EcdsaSighashType::AllPlusAnyoneCanPay,
|
||||
0x82 => EcdsaSighashType::NonePlusAnyoneCanPay,
|
||||
0x83 => EcdsaSighashType::SinglePlusAnyoneCanPay,
|
||||
// catchalls
|
||||
x if x & 0x80 == 0x80 => EcdsaSigHashType::AllPlusAnyoneCanPay,
|
||||
_ => EcdsaSigHashType::All
|
||||
x if x & 0x80 == 0x80 => EcdsaSighashType::AllPlusAnyoneCanPay,
|
||||
_ => EcdsaSighashType::All
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a [`EcdsaSigHashType`] from a raw `u32`.
|
||||
/// Creates a [`EcdsaSighashType`] from a raw `u32`.
|
||||
#[deprecated(since="0.28.0", note="please use `from_standard`")]
|
||||
pub fn from_u32_standard(n: u32) -> Result<EcdsaSigHashType, NonStandardSigHashType> {
|
||||
EcdsaSigHashType::from_standard(n)
|
||||
pub fn from_u32_standard(n: u32) -> Result<EcdsaSighashType, NonStandardSigHashType> {
|
||||
EcdsaSighashType::from_standard(n)
|
||||
}
|
||||
|
||||
/// Creates a [`EcdsaSigHashType`] from a raw `u32`.
|
||||
/// Creates a [`EcdsaSighashType`] from a raw `u32`.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If `n` is a non-standard sighash value.
|
||||
pub fn from_standard(n: u32) -> Result<EcdsaSigHashType, NonStandardSigHashType> {
|
||||
pub fn from_standard(n: u32) -> Result<EcdsaSighashType, NonStandardSigHashType> {
|
||||
match n {
|
||||
// Standard sighashes, see https://github.com/bitcoin/bitcoin/blob/b805dbb0b9c90dadef0424e5b3bf86ac308e103e/src/script/interpreter.cpp#L189-L198
|
||||
0x01 => Ok(EcdsaSigHashType::All),
|
||||
0x02 => Ok(EcdsaSigHashType::None),
|
||||
0x03 => Ok(EcdsaSigHashType::Single),
|
||||
0x81 => Ok(EcdsaSigHashType::AllPlusAnyoneCanPay),
|
||||
0x82 => Ok(EcdsaSigHashType::NonePlusAnyoneCanPay),
|
||||
0x83 => Ok(EcdsaSigHashType::SinglePlusAnyoneCanPay),
|
||||
0x01 => Ok(EcdsaSighashType::All),
|
||||
0x02 => Ok(EcdsaSighashType::None),
|
||||
0x03 => Ok(EcdsaSighashType::Single),
|
||||
0x81 => Ok(EcdsaSighashType::AllPlusAnyoneCanPay),
|
||||
0x82 => Ok(EcdsaSighashType::NonePlusAnyoneCanPay),
|
||||
0x83 => Ok(EcdsaSighashType::SinglePlusAnyoneCanPay),
|
||||
non_standard => Err(NonStandardSigHashType(non_standard))
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts [`EcdsaSigHashType`] to a `u32` sighash flag.
|
||||
/// Converts [`EcdsaSighashType`] to a `u32` sighash flag.
|
||||
///
|
||||
/// The returned value is guaranteed to be a valid according to standardness rules.
|
||||
pub fn to_u32(self) -> u32 { self as u32 }
|
||||
|
@ -904,7 +904,7 @@ mod tests {
|
|||
use hashes::hex::FromHex;
|
||||
|
||||
use hash_types::*;
|
||||
use super::EcdsaSigHashType;
|
||||
use super::EcdsaSighashType;
|
||||
use util::sighash::SigHashCache;
|
||||
|
||||
#[test]
|
||||
|
@ -1167,16 +1167,16 @@ mod tests {
|
|||
#[test]
|
||||
fn test_sighashtype_fromstr_display() {
|
||||
let sighashtypes = vec![
|
||||
("SIGHASH_ALL", EcdsaSigHashType::All),
|
||||
("SIGHASH_NONE", EcdsaSigHashType::None),
|
||||
("SIGHASH_SINGLE", EcdsaSigHashType::Single),
|
||||
("SIGHASH_ALL|SIGHASH_ANYONECANPAY", EcdsaSigHashType::AllPlusAnyoneCanPay),
|
||||
("SIGHASH_NONE|SIGHASH_ANYONECANPAY", EcdsaSigHashType::NonePlusAnyoneCanPay),
|
||||
("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY", EcdsaSigHashType::SinglePlusAnyoneCanPay)
|
||||
("SIGHASH_ALL", EcdsaSighashType::All),
|
||||
("SIGHASH_NONE", EcdsaSighashType::None),
|
||||
("SIGHASH_SINGLE", EcdsaSighashType::Single),
|
||||
("SIGHASH_ALL|SIGHASH_ANYONECANPAY", EcdsaSighashType::AllPlusAnyoneCanPay),
|
||||
("SIGHASH_NONE|SIGHASH_ANYONECANPAY", EcdsaSighashType::NonePlusAnyoneCanPay),
|
||||
("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY", EcdsaSighashType::SinglePlusAnyoneCanPay)
|
||||
];
|
||||
for (s, sht) in sighashtypes {
|
||||
assert_eq!(sht.to_string(), s);
|
||||
assert_eq!(EcdsaSigHashType::from_str(s).unwrap(), sht);
|
||||
assert_eq!(EcdsaSighashType::from_str(s).unwrap(), sht);
|
||||
}
|
||||
let sht_mistakes = vec![
|
||||
"SIGHASH_ALL | SIGHASH_ANYONECANPAY",
|
||||
|
@ -1191,7 +1191,7 @@ mod tests {
|
|||
"SigHash_NONE",
|
||||
];
|
||||
for s in sht_mistakes {
|
||||
assert_eq!(EcdsaSigHashType::from_str(s).unwrap_err().to_string(), format!("Unrecognized SIGHASH string '{}'", s));
|
||||
assert_eq!(EcdsaSighashType::from_str(s).unwrap_err().to_string(), format!("Unrecognized SIGHASH string '{}'", s));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1200,9 +1200,9 @@ mod tests {
|
|||
fn test_sighashtype_standard() {
|
||||
let nonstandard_hashtype = 0x04;
|
||||
// This type is not well defined, by consensus it becomes ALL
|
||||
assert_eq!(EcdsaSigHashType::from_u32_consensus(nonstandard_hashtype), EcdsaSigHashType::All);
|
||||
assert_eq!(EcdsaSighashType::from_u32_consensus(nonstandard_hashtype), EcdsaSighashType::All);
|
||||
// But it's policy-invalid to use it!
|
||||
assert_eq!(EcdsaSigHashType::from_u32_standard(nonstandard_hashtype), Err(NonStandardSigHashType(0x04)));
|
||||
assert_eq!(EcdsaSighashType::from_u32_standard(nonstandard_hashtype), Err(NonStandardSigHashType(0x04)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -123,7 +123,7 @@ pub use blockdata::transaction::Transaction;
|
|||
pub use blockdata::transaction::TxIn;
|
||||
pub use blockdata::transaction::TxOut;
|
||||
pub use blockdata::transaction::OutPoint;
|
||||
pub use blockdata::transaction::EcdsaSigHashType;
|
||||
pub use blockdata::transaction::EcdsaSighashType;
|
||||
pub use blockdata::witness::Witness;
|
||||
pub use consensus::encode::VarInt;
|
||||
pub use network::constants::Network;
|
||||
|
|
|
@ -23,7 +23,7 @@ use hashes::Hash;
|
|||
use hash_types::SigHash;
|
||||
use blockdata::script::Script;
|
||||
use blockdata::witness::Witness;
|
||||
use blockdata::transaction::{Transaction, TxIn, EcdsaSigHashType};
|
||||
use blockdata::transaction::{Transaction, TxIn, EcdsaSighashType};
|
||||
use consensus::{encode, Encodable};
|
||||
|
||||
use io;
|
||||
|
@ -130,7 +130,7 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
|
|||
input_index: usize,
|
||||
script_code: &Script,
|
||||
value: u64,
|
||||
sighash_type: EcdsaSigHashType,
|
||||
sighash_type: EcdsaSighashType,
|
||||
) -> Result<(), encode::Error> {
|
||||
self.cache
|
||||
.segwit_encode_signing_data_to(writer, input_index, script_code, value, sighash_type)
|
||||
|
@ -145,7 +145,7 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
|
|||
input_index: usize,
|
||||
script_code: &Script,
|
||||
value: u64,
|
||||
sighash_type: EcdsaSigHashType
|
||||
sighash_type: EcdsaSighashType
|
||||
) -> SigHash {
|
||||
let mut enc = SigHash::engine();
|
||||
self.encode_signing_data_to(&mut enc, input_index, script_code, value, sighash_type)
|
||||
|
@ -164,7 +164,7 @@ impl<R: DerefMut<Target = Transaction>> SigHashCache<R> {
|
|||
/// panics if `input_index` is out of bounds with respect of the number of inputs
|
||||
///
|
||||
/// ```
|
||||
/// use bitcoin::blockdata::transaction::{Transaction, EcdsaSigHashType};
|
||||
/// use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType};
|
||||
/// use bitcoin::util::bip143::SigHashCache;
|
||||
/// use bitcoin::Script;
|
||||
///
|
||||
|
@ -174,7 +174,7 @@ impl<R: DerefMut<Target = Transaction>> SigHashCache<R> {
|
|||
/// let mut sig_hasher = SigHashCache::new(&mut tx_to_sign);
|
||||
/// for inp in 0..input_count {
|
||||
/// let prevout_script = Script::new();
|
||||
/// let _sighash = sig_hasher.signature_hash(inp, &prevout_script, 42, EcdsaSigHashType::All);
|
||||
/// let _sighash = sig_hasher.signature_hash(inp, &prevout_script, 42, EcdsaSighashType::All);
|
||||
/// // ... sign the sighash
|
||||
/// sig_hasher.access_witness(inp).push(&[]);
|
||||
/// }
|
||||
|
@ -211,7 +211,7 @@ mod tests {
|
|||
let raw_expected = SigHash::from_hex(expected_result).unwrap();
|
||||
let expected_result = SigHash::from_slice(&raw_expected[..]).unwrap();
|
||||
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);
|
||||
assert_eq!(actual_result, expected_result);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use core::{fmt, iter};
|
|||
use hashes::hex::{self, FromHex};
|
||||
use blockdata::transaction::NonStandardSigHashType;
|
||||
use secp256k1;
|
||||
use EcdsaSigHashType;
|
||||
use EcdsaSighashType;
|
||||
|
||||
/// An ECDSA signature with the corresponding hash type.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
|
@ -31,23 +31,23 @@ pub struct EcdsaSig {
|
|||
/// The underlying ECDSA Signature
|
||||
pub sig: secp256k1::ecdsa::Signature,
|
||||
/// The corresponding hash type
|
||||
pub hash_ty: EcdsaSigHashType,
|
||||
pub hash_ty: EcdsaSighashType,
|
||||
}
|
||||
|
||||
impl EcdsaSig {
|
||||
/// Constructs ECDSA bitcoin signature for [`EcdsaSigHashType::All`]
|
||||
/// Constructs ECDSA bitcoin signature for [`EcdsaSighashType::All`]
|
||||
pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> EcdsaSig {
|
||||
EcdsaSig {
|
||||
sig,
|
||||
hash_ty: EcdsaSigHashType::All
|
||||
hash_ty: EcdsaSighashType::All
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialize from slice following the standardness rules for [`EcdsaSigHashType`]
|
||||
/// Deserialize from slice following the standardness rules for [`EcdsaSighashType`]
|
||||
pub fn from_slice(sl: &[u8]) -> Result<Self, EcdsaSigError> {
|
||||
let (hash_ty, sig) = sl.split_last()
|
||||
.ok_or(EcdsaSigError::EmptySignature)?;
|
||||
let hash_ty = EcdsaSigHashType::from_standard(*hash_ty as u32)
|
||||
let hash_ty = EcdsaSighashType::from_standard(*hash_ty as u32)
|
||||
.map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty as u32))?;
|
||||
let sig = secp256k1::ecdsa::Signature::from_der(sig)
|
||||
.map_err(EcdsaSigError::Secp256k1)?;
|
||||
|
@ -80,7 +80,7 @@ impl FromStr for EcdsaSig {
|
|||
.ok_or(EcdsaSigError::EmptySignature)?;
|
||||
Ok(EcdsaSig {
|
||||
sig: secp256k1::ecdsa::Signature::from_der(signature)?,
|
||||
hash_ty: EcdsaSigHashType::from_standard(*sighash_byte as u32)?
|
||||
hash_ty: EcdsaSighashType::from_standard(*sighash_byte as u32)?
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ use util::key::PublicKey;
|
|||
|
||||
use util::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapBranchHash};
|
||||
use util::sighash;
|
||||
use {EcdsaSigHashType, SchnorrSigHashType, EcdsaSig, SchnorrSig};
|
||||
use {EcdsaSighashType, SchnorrSigHashType, EcdsaSig, SchnorrSig};
|
||||
|
||||
/// Type: Non-Witness UTXO PSBT_IN_NON_WITNESS_UTXO = 0x00
|
||||
const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00;
|
||||
|
@ -148,7 +148,7 @@ pub struct Input {
|
|||
|
||||
|
||||
/// A Signature hash type for the corresponding input. As of taproot upgrade, the signature hash
|
||||
/// type can be either [`EcdsaSigHashType`] or [`SchnorrSigHashType`] but it is not possible to know
|
||||
/// type can be either [`EcdsaSighashType`] or [`SchnorrSigHashType`] but it is not possible to know
|
||||
/// 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.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -191,8 +191,8 @@ impl FromStr for PsbtSigHashType {
|
|||
Err(SigHashTypeParseError{ unrecognized: s.to_owned() })
|
||||
}
|
||||
}
|
||||
impl From<EcdsaSigHashType> for PsbtSigHashType {
|
||||
fn from(ecdsa_hash_ty: EcdsaSigHashType) -> Self {
|
||||
impl From<EcdsaSighashType> for PsbtSigHashType {
|
||||
fn from(ecdsa_hash_ty: EcdsaSighashType) -> Self {
|
||||
PsbtSigHashType { inner: ecdsa_hash_ty as u32 }
|
||||
}
|
||||
}
|
||||
|
@ -204,10 +204,10 @@ impl From<SchnorrSigHashType> for PsbtSigHashType {
|
|||
}
|
||||
|
||||
impl PsbtSigHashType {
|
||||
/// Returns the [`EcdsaSigHashType`] if the [`PsbtSigHashType`] can be
|
||||
/// Returns the [`EcdsaSighashType`] if the [`PsbtSigHashType`] can be
|
||||
/// converted to one.
|
||||
pub fn ecdsa_hash_ty(self) -> Result<EcdsaSigHashType, NonStandardSigHashType> {
|
||||
EcdsaSigHashType::from_standard(self.inner)
|
||||
pub fn ecdsa_hash_ty(self) -> Result<EcdsaSighashType, NonStandardSigHashType> {
|
||||
EcdsaSighashType::from_standard(self.inner)
|
||||
}
|
||||
|
||||
/// Returns the [`SchnorrSigHashType`] if the [`PsbtSigHashType`] can be
|
||||
|
@ -223,7 +223,7 @@ impl PsbtSigHashType {
|
|||
/// Creates a [`PsbtSigHashType`] from a raw `u32`.
|
||||
///
|
||||
/// Allows construction of a non-standard or non-valid sighash flag
|
||||
/// ([`EcdsaSigHashType`], [`SchnorrSigHashType`] respectively).
|
||||
/// ([`EcdsaSighashType`], [`SchnorrSigHashType`] respectively).
|
||||
pub fn from_u32(n: u32) -> PsbtSigHashType {
|
||||
PsbtSigHashType { inner: n }
|
||||
}
|
||||
|
@ -238,16 +238,16 @@ impl PsbtSigHashType {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
/// Obtains the [`EcdsaSigHashType`] for this input if one is specified. If no sighash type is
|
||||
/// specified, returns [`EcdsaSigHashType::All`].
|
||||
/// Obtains the [`EcdsaSighashType`] for this input if one is specified. If no sighash type is
|
||||
/// specified, returns [`EcdsaSighashType::All`].
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// If the `sighash_type` field is set to a non-standard ECDSA sighash value.
|
||||
pub fn ecdsa_hash_ty(&self) -> Result<EcdsaSigHashType, NonStandardSigHashType> {
|
||||
pub fn ecdsa_hash_ty(&self) -> Result<EcdsaSighashType, NonStandardSigHashType> {
|
||||
self.sighash_type
|
||||
.map(|sighash_type| sighash_type.ecdsa_hash_ty())
|
||||
.unwrap_or(Ok(EcdsaSigHashType::All))
|
||||
.unwrap_or(Ok(EcdsaSighashType::All))
|
||||
}
|
||||
|
||||
/// Obtains the [`SchnorrSigHashType`] for this input if one is specified. If no sighash type is
|
||||
|
@ -544,12 +544,12 @@ mod test {
|
|||
#[test]
|
||||
fn psbt_sighash_type_ecdsa() {
|
||||
for ecdsa in &[
|
||||
EcdsaSigHashType::All,
|
||||
EcdsaSigHashType::None,
|
||||
EcdsaSigHashType::Single,
|
||||
EcdsaSigHashType::AllPlusAnyoneCanPay,
|
||||
EcdsaSigHashType::NonePlusAnyoneCanPay,
|
||||
EcdsaSigHashType::SinglePlusAnyoneCanPay,
|
||||
EcdsaSighashType::All,
|
||||
EcdsaSighashType::None,
|
||||
EcdsaSighashType::Single,
|
||||
EcdsaSighashType::AllPlusAnyoneCanPay,
|
||||
EcdsaSighashType::NonePlusAnyoneCanPay,
|
||||
EcdsaSighashType::SinglePlusAnyoneCanPay,
|
||||
] {
|
||||
let sighash = PsbtSigHashType::from(*ecdsa);
|
||||
let s = format!("{}", sighash);
|
||||
|
|
|
@ -468,7 +468,7 @@ mod tests {
|
|||
//! Create a full PSBT value with various fields filled and make sure it can be JSONized.
|
||||
use hashes::sha256d;
|
||||
use util::psbt::map::Input;
|
||||
use EcdsaSigHashType;
|
||||
use EcdsaSighashType;
|
||||
|
||||
// create some values to use in the PSBT
|
||||
let tx = Transaction {
|
||||
|
@ -532,7 +532,7 @@ mod tests {
|
|||
value: 190303501938,
|
||||
script_pubkey: hex_script!("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587"),
|
||||
}),
|
||||
sighash_type: Some("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse::<EcdsaSigHashType>().unwrap().into()),
|
||||
sighash_type: Some("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse::<EcdsaSighashType>().unwrap().into()),
|
||||
redeem_script: Some(vec![0x51].into()),
|
||||
witness_script: None,
|
||||
partial_sigs: vec![(
|
||||
|
@ -569,7 +569,7 @@ mod tests {
|
|||
use hash_types::Txid;
|
||||
|
||||
use blockdata::script::Script;
|
||||
use blockdata::transaction::{EcdsaSigHashType, Transaction, TxIn, TxOut, OutPoint};
|
||||
use blockdata::transaction::{EcdsaSighashType, Transaction, TxIn, TxOut, OutPoint};
|
||||
use consensus::encode::serialize_hex;
|
||||
use util::psbt::map::{Map, Input, Output};
|
||||
use util::psbt::raw;
|
||||
|
@ -795,7 +795,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
(&psbt.inputs[0].sighash_type).as_ref().unwrap().ecdsa_hash_ty().unwrap(),
|
||||
EcdsaSigHashType::All
|
||||
EcdsaSighashType::All
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ impl Deserialize for EcdsaSig {
|
|||
//
|
||||
// 1) the current implementation of from_u32_consensus(`flag`) does not preserve
|
||||
// the sighash byte `flag` mapping all unknown values to EcdsaSighashType::All or
|
||||
// EcdsaSigHashType::AllPlusAnyOneCanPay. Therefore, break the invariant
|
||||
// EcdsaSighashType::AllPlusAnyOneCanPay. Therefore, break the invariant
|
||||
// EcdsaSig::from_slice(&sl[..]).to_vec = sl.
|
||||
//
|
||||
// 2) This would cause to have invalid signatures because the sighash message
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
use prelude::*;
|
||||
|
||||
pub use blockdata::transaction::{EcdsaSigHashType, SigHashTypeParseError};
|
||||
pub use blockdata::transaction::{EcdsaSighashType, SigHashTypeParseError};
|
||||
use blockdata::witness::Witness;
|
||||
use consensus::{encode, Encodable};
|
||||
use core::{str, fmt};
|
||||
|
@ -288,15 +288,15 @@ impl<'s> From<ScriptPath<'s>> for TapLeafHash {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<EcdsaSigHashType> for SchnorrSigHashType {
|
||||
fn from(s: EcdsaSigHashType) -> Self {
|
||||
impl From<EcdsaSighashType> for SchnorrSigHashType {
|
||||
fn from(s: EcdsaSighashType) -> Self {
|
||||
match s {
|
||||
EcdsaSigHashType::All => SchnorrSigHashType::All,
|
||||
EcdsaSigHashType::None => SchnorrSigHashType::None,
|
||||
EcdsaSigHashType::Single => SchnorrSigHashType::Single,
|
||||
EcdsaSigHashType::AllPlusAnyoneCanPay => SchnorrSigHashType::AllPlusAnyoneCanPay,
|
||||
EcdsaSigHashType::NonePlusAnyoneCanPay => SchnorrSigHashType::NonePlusAnyoneCanPay,
|
||||
EcdsaSigHashType::SinglePlusAnyoneCanPay => SchnorrSigHashType::SinglePlusAnyoneCanPay,
|
||||
EcdsaSighashType::All => SchnorrSigHashType::All,
|
||||
EcdsaSighashType::None => SchnorrSigHashType::None,
|
||||
EcdsaSighashType::Single => SchnorrSigHashType::Single,
|
||||
EcdsaSighashType::AllPlusAnyoneCanPay => SchnorrSigHashType::AllPlusAnyoneCanPay,
|
||||
EcdsaSighashType::NonePlusAnyoneCanPay => SchnorrSigHashType::NonePlusAnyoneCanPay,
|
||||
EcdsaSighashType::SinglePlusAnyoneCanPay => SchnorrSigHashType::SinglePlusAnyoneCanPay,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -548,7 +548,7 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
|
|||
input_index: usize,
|
||||
script_code: &Script,
|
||||
value: u64,
|
||||
sighash_type: EcdsaSigHashType,
|
||||
sighash_type: EcdsaSighashType,
|
||||
) -> Result<(), Error> {
|
||||
let zero_hash = sha256d::Hash::default();
|
||||
|
||||
|
@ -563,8 +563,8 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
|
|||
}
|
||||
|
||||
if !anyone_can_pay
|
||||
&& sighash != EcdsaSigHashType::Single
|
||||
&& sighash != EcdsaSigHashType::None
|
||||
&& sighash != EcdsaSighashType::Single
|
||||
&& sighash != EcdsaSighashType::None
|
||||
{
|
||||
self.segwit_cache()
|
||||
.sequences
|
||||
|
@ -590,9 +590,9 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
|
|||
txin.sequence.consensus_encode(&mut writer)?;
|
||||
}
|
||||
|
||||
if sighash != EcdsaSigHashType::Single && sighash != EcdsaSigHashType::None {
|
||||
if sighash != EcdsaSighashType::Single && sighash != EcdsaSighashType::None {
|
||||
self.segwit_cache().outputs.consensus_encode(&mut writer)?;
|
||||
} else if sighash == EcdsaSigHashType::Single && input_index < self.tx.output.len() {
|
||||
} else if sighash == EcdsaSighashType::Single && input_index < self.tx.output.len() {
|
||||
let mut single_enc = SigHash::engine();
|
||||
self.tx.output[input_index].consensus_encode(&mut single_enc)?;
|
||||
SigHash::from_engine(single_enc).consensus_encode(&mut writer)?;
|
||||
|
@ -611,7 +611,7 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
|
|||
input_index: usize,
|
||||
script_code: &Script,
|
||||
value: u64,
|
||||
sighash_type: EcdsaSigHashType,
|
||||
sighash_type: EcdsaSighashType,
|
||||
) -> Result<SigHash, Error> {
|
||||
let mut enc = SigHash::engine();
|
||||
self.segwit_encode_signing_data_to(
|
||||
|
@ -735,7 +735,7 @@ impl<R: DerefMut<Target=Transaction>> SigHashCache<R> {
|
|||
///
|
||||
/// This allows in-line signing such as
|
||||
/// ```
|
||||
/// use bitcoin::blockdata::transaction::{Transaction, EcdsaSigHashType};
|
||||
/// use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType};
|
||||
/// use bitcoin::util::sighash::SigHashCache;
|
||||
/// use bitcoin::Script;
|
||||
///
|
||||
|
@ -745,7 +745,7 @@ impl<R: DerefMut<Target=Transaction>> SigHashCache<R> {
|
|||
/// let mut sig_hasher = SigHashCache::new(&mut tx_to_sign);
|
||||
/// for inp in 0..input_count {
|
||||
/// let prevout_script = Script::new();
|
||||
/// let _sighash = sig_hasher.segwit_signature_hash(inp, &prevout_script, 42, EcdsaSigHashType::All);
|
||||
/// let _sighash = sig_hasher.segwit_signature_hash(inp, &prevout_script, 42, EcdsaSighashType::All);
|
||||
/// // ... sign the sighash
|
||||
/// sig_hasher.witness_mut(inp).unwrap().push(&Vec::new());
|
||||
/// }
|
||||
|
|
Loading…
Reference in New Issue