From 3f3f30d6c7ab8351b7f7f8a0b81b76a6e1096be0 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 24 Sep 2024 10:50:43 +1000 Subject: [PATCH] Use iter instead of accessing content field We would like to move the `Witness` to `primitives` however in the `Encodable` implementation we are currently accessing the private `content` field. Instead of accessing `content` we can iterate over the witness elements and write each individually, this has the same result but does a bunch of additional calls to `Write::write_all` (via `emit_slice`). This patch effects performance negatively but makes no changes to the encoding. --- bitcoin/src/blockdata/witness.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bitcoin/src/blockdata/witness.rs b/bitcoin/src/blockdata/witness.rs index 3ece6fcc8..d51fd14c4 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.len() * 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) } }