Merge rust-bitcoin/rust-bitcoin#2084: Add `Witness::p2wpkh` constructor
5901d35095
Add push_p2wpkh function on Witness (Tobin C. Harding)8cd409d561
Deprecate push_bitcoin_signature (Tobin C. Harding) Pull request description: In order to create the witness to spend p2wpkh output one must create a `Witness` that includes the signature and the pubkey, we should have a function for this. ## Notes The PR originally added a `push_p2wphk` method, this is now instead a constrcutor `Witness:p2wpkh` (after review discussion below). - Patch 1 changes `push_bitcoin_signature` to take an `ecdsa::Sigtnture` instead of an `ecdsa::SerializedSignature` - Patch 2 takes a `secp256k1::PublicKey` removing the need for an error path (discussed below). ACKs for top commit: sanket1729: ACK5901d35095
apoelstra: ACK5901d35095
Tree-SHA512: 646014d97daafbf0909106d8990debaf481ac6f3578f0ddf232d739c3e2d55ae1d0275abe5a4a1db1c5c192c8c5f0b5546fc65aac37b91a3729db881c5ad3dec
This commit is contained in:
commit
1c29dd97ce
|
@ -9,10 +9,9 @@ use core::convert::TryInto;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::ops::Index;
|
use core::ops::Index;
|
||||||
|
|
||||||
use secp256k1::ecdsa;
|
|
||||||
|
|
||||||
use crate::consensus::encode::{Error, MAX_VEC_SIZE};
|
use crate::consensus::encode::{Error, MAX_VEC_SIZE};
|
||||||
use crate::consensus::{Decodable, Encodable, WriteExt};
|
use crate::consensus::{Decodable, Encodable, WriteExt};
|
||||||
|
use crate::crypto::ecdsa;
|
||||||
use crate::io::{self, Read, Write};
|
use crate::io::{self, Read, Write};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::sighash::EcdsaSighashType;
|
use crate::sighash::EcdsaSighashType;
|
||||||
|
@ -237,6 +236,19 @@ impl Witness {
|
||||||
/// Creates a new empty [`Witness`].
|
/// Creates a new empty [`Witness`].
|
||||||
pub fn new() -> Self { Witness::default() }
|
pub fn new() -> Self { Witness::default() }
|
||||||
|
|
||||||
|
/// Creates a witness required to spend a P2WPKH output.
|
||||||
|
///
|
||||||
|
/// The witness will be made up of the DER encoded signature + sighash_type followed by the
|
||||||
|
/// serialized public key. Also useful for spending a P2SH-P2WPKH output.
|
||||||
|
///
|
||||||
|
/// It is expected that `pubkey` is related to the secret key used to create `signature`.
|
||||||
|
pub fn p2wpkh(signature: &ecdsa::Signature, pubkey: &secp256k1::PublicKey) -> Witness {
|
||||||
|
let mut witness = Witness::new();
|
||||||
|
witness.push_slice(&signature.serialize());
|
||||||
|
witness.push_slice(&pubkey.serialize());
|
||||||
|
witness
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a [`Witness`] object from a slice of bytes slices where each slice is a witness item.
|
/// Creates a [`Witness`] object from a slice of bytes slices where each slice is a witness item.
|
||||||
pub fn from_slice<T: AsRef<[u8]>>(slice: &[T]) -> Self {
|
pub fn from_slice<T: AsRef<[u8]>>(slice: &[T]) -> Self {
|
||||||
let witness_elements = slice.len();
|
let witness_elements = slice.len();
|
||||||
|
@ -321,9 +333,10 @@ impl Witness {
|
||||||
|
|
||||||
/// Pushes a DER-encoded ECDSA signature with a signature hash type as a new element on the
|
/// Pushes a DER-encoded ECDSA signature with a signature hash type as a new element on the
|
||||||
/// witness, requires an allocation.
|
/// witness, requires an allocation.
|
||||||
|
#[deprecated(since = "0.30.0", note = "use push_ecdsa_signature instead")]
|
||||||
pub fn push_bitcoin_signature(
|
pub fn push_bitcoin_signature(
|
||||||
&mut self,
|
&mut self,
|
||||||
signature: &ecdsa::SerializedSignature,
|
signature: &secp256k1::ecdsa::SerializedSignature,
|
||||||
hash_type: EcdsaSighashType,
|
hash_type: EcdsaSighashType,
|
||||||
) {
|
) {
|
||||||
// Note that a maximal length ECDSA signature is 72 bytes, plus the sighash type makes 73
|
// Note that a maximal length ECDSA signature is 72 bytes, plus the sighash type makes 73
|
||||||
|
@ -333,6 +346,13 @@ impl Witness {
|
||||||
self.push(&sig[..signature.len() + 1]);
|
self.push(&sig[..signature.len() + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pushes, as a new element on the witness, an ECDSA signature.
|
||||||
|
///
|
||||||
|
/// Pushes the DER encoded signature + sighash_type, requires an allocation.
|
||||||
|
pub fn push_ecdsa_signature(&mut self, signature: &ecdsa::Signature) {
|
||||||
|
self.push_slice(&signature.serialize())
|
||||||
|
}
|
||||||
|
|
||||||
fn element_at(&self, index: usize) -> Option<&[u8]> {
|
fn element_at(&self, index: usize) -> Option<&[u8]> {
|
||||||
let varint = VarInt::consensus_decode(&mut &self.content[index..]).ok()?;
|
let varint = VarInt::consensus_decode(&mut &self.content[index..]).ok()?;
|
||||||
let start = index + varint.len();
|
let start = index + varint.len();
|
||||||
|
@ -525,8 +545,6 @@ impl From<Vec<&[u8]>> for Witness {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use secp256k1::ecdsa;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::consensus::{deserialize, serialize};
|
use crate::consensus::{deserialize, serialize};
|
||||||
use crate::internal_macros::hex;
|
use crate::internal_macros::hex;
|
||||||
|
@ -624,9 +642,10 @@ mod test {
|
||||||
// The very first signature in block 734,958
|
// The very first signature in block 734,958
|
||||||
let sig_bytes =
|
let sig_bytes =
|
||||||
hex!("304402207c800d698f4b0298c5aac830b822f011bb02df41eb114ade9a6702f364d5e39c0220366900d2a60cab903e77ef7dd415d46509b1f78ac78906e3296f495aa1b1b541");
|
hex!("304402207c800d698f4b0298c5aac830b822f011bb02df41eb114ade9a6702f364d5e39c0220366900d2a60cab903e77ef7dd415d46509b1f78ac78906e3296f495aa1b1b541");
|
||||||
let sig = ecdsa::Signature::from_der(&sig_bytes).unwrap();
|
let sig = secp256k1::ecdsa::Signature::from_der(&sig_bytes).unwrap();
|
||||||
let mut witness = Witness::default();
|
let mut witness = Witness::default();
|
||||||
witness.push_bitcoin_signature(&sig.serialize_der(), EcdsaSighashType::All);
|
let signature = ecdsa::Signature { sig, hash_ty: EcdsaSighashType::All };
|
||||||
|
witness.push_ecdsa_signature(&signature);
|
||||||
let expected_witness = vec![hex!(
|
let expected_witness = vec![hex!(
|
||||||
"304402207c800d698f4b0298c5aac830b822f011bb02df41eb114ade9a6702f364d5e39c0220366900d2a60cab903e77ef7dd415d46509b1f78ac78906e3296f495aa1b1b54101")
|
"304402207c800d698f4b0298c5aac830b822f011bb02df41eb114ade9a6702f364d5e39c0220366900d2a60cab903e77ef7dd415d46509b1f78ac78906e3296f495aa1b1b54101")
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in New Issue