Merge rust-bitcoin/rust-bitcoin#2392: Add functionality to serialize signatures to a writer
3cfd746bbc
Add functionality to serialize signatures to a writer (Tobin C. Harding) Pull request description: Serializing the ecdsa and taproot `Signature` straight to a writer is a useful thing to be able to do. Add `to_writer` to both `SerializedSignature`s and also to the `Signature`s (calling through to `SerializedSignature`). Remove TODO comments from code. ACKs for top commit: Kixunil: ACK3cfd746bbc
Tree-SHA512: 82eb6d42c7b327cdfe5e89348890e45ea39c664420f7ea17d7826a5c388c7aaae917b1334e3f3df645fc4a81a11b59d97c7d6958e99077fbd67193e2a588f2eb
This commit is contained in:
commit
2f7d6451f8
|
@ -9,6 +9,7 @@ use core::{fmt, iter};
|
|||
|
||||
use hex::FromHex;
|
||||
use internals::write_err;
|
||||
use io::Write;
|
||||
use secp256k1;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
@ -58,7 +59,6 @@ impl Signature {
|
|||
/// Note: this performs an extra heap allocation, you might prefer the
|
||||
/// [`serialize`](Self::serialize) method instead.
|
||||
pub fn to_vec(self) -> Vec<u8> {
|
||||
// TODO: add support to serialize to a writer to SerializedSig
|
||||
self.signature
|
||||
.serialize_der()
|
||||
.iter()
|
||||
|
@ -66,6 +66,13 @@ impl Signature {
|
|||
.chain(iter::once(self.sighash_type as u8))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Serializes an ECDSA signature (inner secp256k1 signature in DER format) to a `writer`.
|
||||
#[inline]
|
||||
pub fn serialize_to_writer<W: Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
|
||||
let sig = self.serialize();
|
||||
sig.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Signature {
|
||||
|
@ -105,6 +112,12 @@ impl SerializedSignature {
|
|||
/// Returns an iterator over bytes of the signature.
|
||||
#[inline]
|
||||
pub fn iter(&self) -> core::slice::Iter<'_, u8> { self.into_iter() }
|
||||
|
||||
/// Writes this serialized signature to a `writer`.
|
||||
#[inline]
|
||||
pub fn write_to<W: Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
|
||||
writer.write_all(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::Deref for SerializedSignature {
|
||||
|
@ -239,3 +252,22 @@ impl From<NonStandardSighashTypeError> for Error {
|
|||
impl From<hex::HexToBytesError> for Error {
|
||||
fn from(err: hex::HexToBytesError) -> Self { Error::Hex(err) }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn write_serialized_signature() {
|
||||
let hex = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45";
|
||||
let sig = Signature {
|
||||
signature: secp256k1::ecdsa::Signature::from_str(hex).unwrap(),
|
||||
sighash_type: EcdsaSighashType::All,
|
||||
};
|
||||
|
||||
let mut buf = vec![];
|
||||
sig.serialize_to_writer(&mut buf).expect("write failed");
|
||||
|
||||
assert_eq!(sig.to_vec(), buf)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
use core::fmt;
|
||||
|
||||
use internals::write_err;
|
||||
use io::Write;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::sighash::{InvalidSighashTypeError, TapSighashType};
|
||||
|
@ -47,7 +48,6 @@ impl Signature {
|
|||
///
|
||||
/// Note: this allocates on the heap, prefer [`serialize`](Self::serialize) if vec is not needed.
|
||||
pub fn to_vec(self) -> Vec<u8> {
|
||||
// TODO: add support to serialize to a writer to SerializedSig
|
||||
let mut ser_sig = self.signature.as_ref().to_vec();
|
||||
if self.sighash_type == TapSighashType::Default {
|
||||
// default sighash type, don't add extra sighash byte
|
||||
|
@ -57,6 +57,13 @@ impl Signature {
|
|||
ser_sig
|
||||
}
|
||||
|
||||
/// Serializes the signature to `writer`.
|
||||
#[inline]
|
||||
pub fn serialize_to_writer<W: Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
|
||||
let sig = self.serialize();
|
||||
sig.write_to(writer)
|
||||
}
|
||||
|
||||
/// Serializes the signature (without heap allocation)
|
||||
///
|
||||
/// This returns a type with an API very similar to that of `Box<[u8]>`.
|
||||
|
|
|
@ -10,6 +10,7 @@ use core::convert::TryFrom;
|
|||
use core::{fmt, ops};
|
||||
|
||||
pub use into_iter::IntoIter;
|
||||
use io::Write;
|
||||
|
||||
use super::{SigFromSliceError, Signature};
|
||||
|
||||
|
@ -166,6 +167,12 @@ impl SerializedSignature {
|
|||
/// (this serializes it)
|
||||
#[inline]
|
||||
pub fn from_signature(sig: &Signature) -> SerializedSignature { sig.serialize() }
|
||||
|
||||
/// Writes this serialized signature to a `writer`.
|
||||
#[inline]
|
||||
pub fn write_to<W: Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
|
||||
writer.write_all(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Separate mod to prevent outside code from accidentally breaking invariants.
|
||||
|
|
Loading…
Reference in New Issue