p2p: Move merkle_tree module errors to error submodule
What changed, and why it matters
This commit is a straightforward internal code reorganization. It moves three error types (MerkleBlockDecoderError, PartialMerkleTreeDecoderError, and MerkleBlockError) from the main merkle_tree module into a new error submodule and re-exports them. There is no change to how the code behaves, no bug fix, and no security improvement or regression.
No security action needed. Treat as a normal maintainability refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors p2p/src/merkle_tree.rs by creating a public error submodule and relocating error type definitions there with pub use re-exports. It removes the top-level definitions and adds #[doc(no_inline)] on the re-exports. The error types retain the same derives, Display/std::error::Error implementations, variants, and visibility semantics (with one internal field now pub(super) instead of implicitly private, which is equivalent because the type remains pub and the field was only usable within the same module). No logic, parsing, validation, or API behavior is changed.
Changed components
p2p/src/merkle_tree.rsInspect captured patch +116 / −100
diff --git a/p2p/src/merkle_tree.rs b/p2p/src/merkle_tree.rs
index 4bb67674..55624fdd 100644
--- a/p2p/src/merkle_tree.rs
+++ b/p2p/src/merkle_tree.rs
@@ -11,8 +11,6 @@
use alloc::vec;
use alloc::vec::Vec;
-use core::convert::Infallible;
-use core::fmt;
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
@@ -21,13 +19,17 @@ use encoding::{
ArrayDecoder, ArrayEncoder, ByteVecDecoder, CompactSizeEncoder, Decoder2, Decoder3, Encoder2,
Encoder3, SliceEncoder, VecDecoder,
};
-use internals::{write_err, ToU64 as _};
+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};
use primitives::Weight;
+#[rustfmt::skip] // Keep public re-exports separate.
+#[doc(no_inline)]
+pub use self::error::{MerkleBlockDecoderError, MerkleBlockError, PartialMerkleTreeDecoderError};
+
/// Data structure that represents a block header paired to a partial Merkle tree.
///
/// NOTE: This assumes that the given Block has *at least* 1 transaction. If the Block has 0 txs,
@@ -173,25 +175,6 @@ impl encoding::Decodable for MerkleBlock {
}
}
-/// An error occuring when decoding a [`MerkleBlock`].
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct MerkleBlockDecoderError(<MerkleBlockInnerDecoder as encoding::Decoder>::Error);
-
-impl From<Infallible> for MerkleBlockDecoderError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl fmt::Display for MerkleBlockDecoderError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write_err!(f, "merkleblock error"; self.0)
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for MerkleBlockDecoderError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
-}
-
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)?;
@@ -589,27 +572,6 @@ impl encoding::Decodable for PartialMerkleTree {
}
}
-/// An error occuring when decoding a [`PartialMerkleTree`].
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct PartialMerkleTreeDecoderError(
- <PartialMerkleTreeInnerDecoder as encoding::Decoder>::Error,
-);
-
-impl From<Infallible> for PartialMerkleTreeDecoderError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl fmt::Display for PartialMerkleTreeDecoderError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write_err!(f, "partial merkletree error"; self.0)
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for PartialMerkleTreeDecoderError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
-}
-
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)?;
@@ -655,68 +617,122 @@ impl Decodable for PartialMerkleTree {
}
}
-/// An error when verifying the Merkle block.
-#[derive(Debug, Clone, PartialEq, Eq)]
-#[non_exhaustive]
-pub enum MerkleBlockError {
- /// Merkle root in the header doesn't match to the root calculated from partial Merkle tree.
- MerkleRootMismatch,
- /// Partial Merkle tree contains no transactions.
- NoTransactions,
- /// There are too many transactions.
- TooManyTransactions,
- /// There are too many hashes
- TooManyHashes,
- /// There must be at least one bit per node in the partial tree,
- /// and at least one node per hash
- NotEnoughBits,
- /// Not all bits were consumed
- NotAllBitsConsumed,
- /// Not all hashes were consumed
- NotAllHashesConsumed,
- /// Overflowed the bits array
- BitsArrayOverflow,
- /// Overflowed the hashes array
- HashesArrayOverflow,
- /// The left and right branches should never be identical
- IdenticalHashesFound,
-}
+/// Error types for merkle tree messages.
+pub mod error {
+ use core::convert::Infallible;
+ use core::fmt;
-impl From<Infallible> for MerkleBlockError {
- fn from(never: Infallible) -> Self { match never {} }
-}
+ use internals::write_err;
+
+ /// An error occuring when decoding a [`MerkleBlock`].
+ ///
+ /// [`MerkleBlock`]: super::MerkleBlock
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub struct MerkleBlockDecoderError(
+ pub(super) <super::MerkleBlockInnerDecoder as encoding::Decoder>::Error,
+ );
+
+ impl From<Infallible> for MerkleBlockDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+ }
-impl fmt::Display for MerkleBlockError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Self::MerkleRootMismatch => write!(f, "Merkle header root doesn't match to the root calculated from the partial Merkle tree"),
- Self::NoTransactions => write!(f, "partial Merkle tree contains no transactions"),
- Self::TooManyTransactions => write!(f, "too many transactions"),
- Self::TooManyHashes => write!(f, "proof contains more hashes than transactions"),
- Self::NotEnoughBits => write!(f, "proof contains fewer bits than hashes"),
- Self::NotAllBitsConsumed => write!(f, "not all bits were consumed"),
- Self::NotAllHashesConsumed => write!(f, "not all hashes were consumed"),
- Self::BitsArrayOverflow => write!(f, "overflowed the bits array"),
- Self::HashesArrayOverflow => write!(f, "overflowed the hashes array"),
- Self::IdenticalHashesFound => write!(f, "found identical transaction hashes"),
+ impl fmt::Display for MerkleBlockDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write_err!(f, "merkleblock error"; self.0)
+ }
+ }
+
+ #[cfg(feature = "std")]
+ impl std::error::Error for MerkleBlockDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
+ }
+
+ /// An error occuring when decoding a [`PartialMerkleTree`].
+ ///
+ /// [`PartialMerkleTree`]: super::PartialMerkleTree
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub struct PartialMerkleTreeDecoderError(
+ pub(super) <super::PartialMerkleTreeInnerDecoder as encoding::Decoder>::Error,
+ );
+
+ impl From<Infallible> for PartialMerkleTreeDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+ }
+
+ impl fmt::Display for PartialMerkleTreeDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write_err!(f, "partial merkletree error"; self.0)
}
}
-}
-#[cfg(feature = "std")]
-impl std::error::Error for MerkleBlockError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match self {
- Self::MerkleRootMismatch
- | Self::NoTransactions
- | Self::TooManyTransactions
- | Self::TooManyHashes
- | Self::NotEnoughBits
- | Self::NotAllBitsConsumed
- | Self::NotAllHashesConsumed
- | Self::BitsArrayOverflow
- | Self::HashesArrayOverflow
- | Self::IdenticalHashesFound => None,
+ #[cfg(feature = "std")]
+ impl std::error::Error for PartialMerkleTreeDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
+ }
+
+ /// An error when verifying the Merkle block.
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ #[non_exhaustive]
+ pub enum MerkleBlockError {
+ /// Merkle root in the header doesn't match to the root calculated from partial Merkle tree.
+ MerkleRootMismatch,
+ /// Partial Merkle tree contains no transactions.
+ NoTransactions,
+ /// There are too many transactions.
+ TooManyTransactions,
+ /// There are too many hashes
+ TooManyHashes,
+ /// There must be at least one bit per node in the partial tree,
+ /// and at least one node per hash
+ NotEnoughBits,
+ /// Not all bits were consumed
+ NotAllBitsConsumed,
+ /// Not all hashes were consumed
+ NotAllHashesConsumed,
+ /// Overflowed the bits array
+ BitsArrayOverflow,
+ /// Overflowed the hashes array
+ HashesArrayOverflow,
+ /// The left and right branches should never be identical
+ IdenticalHashesFound,
+ }
+
+ impl From<Infallible> for MerkleBlockError {
+ fn from(never: Infallible) -> Self { match never {} }
+ }
+
+ impl fmt::Display for MerkleBlockError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Self::MerkleRootMismatch => write!(f, "Merkle header root doesn't match to the root calculated from the partial Merkle tree"),
+ Self::NoTransactions => write!(f, "partial Merkle tree contains no transactions"),
+ Self::TooManyTransactions => write!(f, "too many transactions"),
+ Self::TooManyHashes => write!(f, "proof contains more hashes than transactions"),
+ Self::NotEnoughBits => write!(f, "proof contains fewer bits than hashes"),
+ Self::NotAllBitsConsumed => write!(f, "not all bits were consumed"),
+ Self::NotAllHashesConsumed => write!(f, "not all hashes were consumed"),
+ Self::BitsArrayOverflow => write!(f, "overflowed the bits array"),
+ Self::HashesArrayOverflow => write!(f, "overflowed the hashes array"),
+ Self::IdenticalHashesFound => write!(f, "found identical transaction hashes"),
+ }
+ }
+ }
+
+ #[cfg(feature = "std")]
+ impl std::error::Error for MerkleBlockError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::MerkleRootMismatch
+ | Self::NoTransactions
+ | Self::TooManyTransactions
+ | Self::TooManyHashes
+ | Self::NotEnoughBits
+ | Self::NotAllBitsConsumed
+ | Self::NotAllHashesConsumed
+ | Self::BitsArrayOverflow
+ | Self::HashesArrayOverflow
+ | Self::IdenticalHashesFound => None,
+ }
}
}
}
Why this scored 15/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.