Merge rust-bitcoin/rust-bitcoin#3408: Prepare `Witness`

3f3f30d6c7 Use iter instead of accessing content field (Tobin C. Harding)
6389d1cbb3 Stop using push_slice (Tobin C. Harding)
be163eec99 Use Witness::len instead of accessing field (Tobin C. Harding)

Pull request description:

  Prepare `Witness` to be moved to `primitives`.

  This is the first three patches out of #3406. Patch 1 and 2 are internal changes, path 3 is also internal but introduces a slight perf hit by doing multiple writes.

ACKs for top commit:
  apoelstra:
    ACK 3f3f30d6c7 successfully ran local tests

Tree-SHA512: 25e2570a22797dbfa15d6e5af9b72938243192ca264bc5fe82c2f327486e52a73993b3b61ee1161e5d17b01a7f9843960cb4031e6550561de4ecafb9f935e375
This commit is contained in:
merge-script 2024-10-01 19:42:09 +00:00
commit f3fbd0e0b9
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 13 additions and 10 deletions

View File

@ -12,8 +12,8 @@ use arbitrary::{Arbitrary, Unstructured};
use internals::compact_size; use internals::compact_size;
use io::{BufRead, Write}; use io::{BufRead, Write};
use crate::consensus::encode::{Error, ReadExt, MAX_VEC_SIZE}; use crate::consensus::encode::{self, Error, MAX_VEC_SIZE, ReadExt, WriteExt};
use crate::consensus::{Decodable, Encodable, WriteExt}; use crate::consensus::{Decodable, Encodable};
use crate::crypto::ecdsa; use crate::crypto::ecdsa;
use crate::prelude::Vec; use crate::prelude::Vec;
#[cfg(doc)] #[cfg(doc)]
@ -230,10 +230,13 @@ fn resize_if_needed(vec: &mut Vec<u8>, required_len: usize) {
impl Encodable for Witness { impl Encodable for Witness {
// `self.content` includes the varints so encoding here includes them, as expected. // `self.content` includes the varints so encoding here includes them, as expected.
fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> { fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
let content_with_indices_len = self.content.len(); let mut written = w.emit_compact_size(self.len())?;
let indices_size = self.witness_elements * 4;
let content_len = content_with_indices_len - indices_size; for element in self.iter() {
Ok(w.emit_compact_size(self.witness_elements)? + w.emit_slice(&self.content[..content_len])?) written += encode::consensus_encode_with_size(element, w)?
}
Ok(written)
} }
} }
@ -252,15 +255,15 @@ impl Witness {
/// It is expected that `pubkey` is related to the secret key used to create `signature`. /// 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 { pub fn p2wpkh(signature: ecdsa::Signature, pubkey: secp256k1::PublicKey) -> Witness {
let mut witness = Witness::new(); let mut witness = Witness::new();
witness.push_slice(&signature.serialize()); witness.push(signature.serialize());
witness.push_slice(&pubkey.serialize()); witness.push(pubkey.serialize());
witness witness
} }
/// Creates a witness required to do a key path spend of a P2TR output. /// Creates a witness required to do a key path spend of a P2TR output.
pub fn p2tr_key_spend(signature: &taproot::Signature) -> Witness { pub fn p2tr_key_spend(signature: &taproot::Signature) -> Witness {
let mut witness = Witness::new(); let mut witness = Witness::new();
witness.push_slice(&signature.serialize()); witness.push(signature.serialize());
witness witness
} }
@ -363,7 +366,7 @@ impl Witness {
/// ///
/// Pushes the DER encoded signature + sighash_type, requires an allocation. /// Pushes the DER encoded signature + sighash_type, requires an allocation.
pub fn push_ecdsa_signature(&mut self, signature: ecdsa::Signature) { pub fn push_ecdsa_signature(&mut self, signature: ecdsa::Signature) {
self.push_slice(&signature.serialize()) self.push(signature.serialize())
} }
/// Note `index` is the index into the `content` vector and should be the result of calling /// Note `index` is the index into the `content` vector and should be the result of calling