p2p: Remove legacy encoding from `merkle_tree`
What changed, and why it matters
This commit removes old-style encoding and decoding code for two Bitcoin peer-to-peer message types (MerkleBlock and PartialMerkleTree) and replaces it with a newer encoding system already present in the file. There is no direct evidence in the commit that this fixes a security vulnerability; it appears to be a routine cleanup or migration to a newer serialization API.
No immediate security action required. Treat as a normal refactoring commit. If auditing, verify that the remaining `encoding::Encode`/`Decode` implementations provide equivalent or stronger input validation compared to the removed legacy implementations.
Security signals we found
Removal of legacy serialization code
No new bounds checks or validation logic added
No references to security issues, CVEs, or vulnerability reports in commit message
Evidence from the diff
The diff deletes the legacy Encodable/Decodable trait implementations for MerkleBlock and PartialMerkleTree in p2p/src/merkle_tree.rs. These implementations used bitcoin::consensus::encode and io::{BufRead, Write}. Equivalent encoding::Encode/encoding::Decode implementations remain in the file, so the functionality is preserved through the newer encoding module. The change removes 60 lines of duplicated/legacy code and updates imports accordingly.
Changed components
p2p/src/merkle_tree.rsMerkleBlock serializationPartialMerkleTree serializationInspect captured patch +0 / −60
diff --git a/p2p/src/merkle_tree.rs b/p2p/src/merkle_tree.rs
index f19cb949..d287408c 100644
--- a/p2p/src/merkle_tree.rs
+++ b/p2p/src/merkle_tree.rs
@@ -14,13 +14,11 @@ use alloc::vec::Vec;
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
-use bitcoin::consensus::encode::{self, Decodable, Encodable, ReadExt, WriteExt, MAX_VEC_SIZE};
use encoding::{
ArrayDecoder, ArrayEncoder, ByteVecDecoder, CompactSizeEncoder, Decoder2, Decoder3, Encoder2,
Encoder3, SliceEncoder, VecDecoder,
};
use internals::ToU64 as _;
-use io::{BufRead, Write};
use primitives::block::{self, Block, Checked, HeaderDecoder, HeaderEncoder};
use primitives::merkle_tree::TxMerkleNode;
use primitives::transaction::{Transaction, Txid};
@@ -175,19 +173,6 @@ impl encoding::Decode for MerkleBlock {
}
}
-impl Encodable for MerkleBlock {
- fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
- let len = self.header.consensus_encode(w)? + self.txn.consensus_encode(w)?;
- Ok(len)
- }
-}
-
-impl Decodable for MerkleBlock {
- fn consensus_decode<R: BufRead + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
- Ok(Self { header: Decodable::consensus_decode(r)?, txn: Decodable::consensus_decode(r)? })
- }
-}
-
/// Data structure that represents a partial Merkle tree.
///
/// It represents a subset of the txid's of a known block, in a way that
@@ -572,51 +557,6 @@ impl encoding::Decode for PartialMerkleTree {
}
}
-impl Encodable for PartialMerkleTree {
- fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
- let mut ret = self.num_transactions.consensus_encode(w)?;
- ret += self.hashes.consensus_encode(w)?;
-
- let nb_bytes_for_bits = self.bits.len().div_ceil(8);
- ret += w.emit_compact_size(nb_bytes_for_bits)?;
- for chunk in self.bits.chunks(8) {
- let mut byte = 0u8;
- for (i, bit) in chunk.iter().enumerate() {
- byte |= u8::from(*bit) << i;
- }
- ret += byte.consensus_encode(w)?;
- }
- Ok(ret)
- }
-}
-
-impl Decodable for PartialMerkleTree {
- fn consensus_decode_from_finite_reader<R: BufRead + ?Sized>(
- r: &mut R,
- ) -> Result<Self, encode::Error> {
- let num_transactions: u32 = Decodable::consensus_decode(r)?;
- let hashes: Vec<TxMerkleNode> = Decodable::consensus_decode(r)?;
-
- let nb_bytes_for_bits = r.read_compact_size()? as usize;
- if nb_bytes_for_bits > MAX_VEC_SIZE {
- return Err(encode::ParseError::OversizedVectorAllocation {
- requested: nb_bytes_for_bits,
- max: MAX_VEC_SIZE,
- }
- .into());
- }
- let mut bits = vec![false; nb_bytes_for_bits * 8];
- for chunk in bits.chunks_mut(8) {
- let byte = u8::consensus_decode(r)?;
- for (i, bit) in chunk.iter_mut().enumerate() {
- *bit = (byte & (1 << i)) != 0;
- }
- }
-
- Ok(Self { num_transactions, bits, hashes })
- }
-}
-
/// Error types for merkle tree messages.
pub mod error {
use core::convert::Infallible;
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.