diff --git a/bitcoin/src/blockdata/witness.rs b/bitcoin/src/blockdata/witness.rs index d60ce398b7..d51fd14c4a 100644 --- a/bitcoin/src/blockdata/witness.rs +++ b/bitcoin/src/blockdata/witness.rs @@ -12,8 +12,8 @@ use arbitrary::{Arbitrary, Unstructured}; use internals::compact_size; use io::{BufRead, Write}; -use crate::consensus::encode::{Error, ReadExt, MAX_VEC_SIZE}; -use crate::consensus::{Decodable, Encodable, WriteExt}; +use crate::consensus::encode::{self, Error, MAX_VEC_SIZE, ReadExt, WriteExt}; +use crate::consensus::{Decodable, Encodable}; use crate::crypto::ecdsa; use crate::prelude::Vec; #[cfg(doc)] @@ -230,10 +230,13 @@ fn resize_if_needed(vec: &mut Vec, required_len: usize) { impl Encodable for Witness { // `self.content` includes the varints so encoding here includes them, as expected. fn consensus_encode(&self, w: &mut W) -> Result { - let content_with_indices_len = self.content.len(); - let indices_size = self.witness_elements * 4; - let content_len = content_with_indices_len - indices_size; - Ok(w.emit_compact_size(self.witness_elements)? + w.emit_slice(&self.content[..content_len])?) + let mut written = w.emit_compact_size(self.len())?; + + for element in self.iter() { + 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`. 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.push(signature.serialize()); + witness.push(pubkey.serialize()); witness } /// Creates a witness required to do a key path spend of a P2TR output. pub fn p2tr_key_spend(signature: &taproot::Signature) -> Witness { let mut witness = Witness::new(); - witness.push_slice(&signature.serialize()); + witness.push(signature.serialize()); witness } @@ -363,7 +366,7 @@ impl Witness { /// /// 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()) + self.push(signature.serialize()) } /// Note `index` is the index into the `content` vector and should be the result of calling