primitives: Implement BlockDecoder for Block
What changed, and why it matters
This commit adds a missing decoder for Bitcoin blocks in the rust-bitcoin library. It is a routine feature addition that lets the library read block bytes back into a Block object, complementing the already-existing encoder. There is no indication of a security bug being fixed.
No security action required; treat as normal feature/parity improvement.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change introduces BlockDecoder, BlockDecoderError, and an impl Decodable for Block in primitives/src/block.rs. It composes HeaderDecoder and VecDecoder
Changed components
primitives/src/block.rsapi/primitives/all-features.txtapi/primitives/alloc-only.txtInspect captured patch +183 / −1
diff --git a/api/primitives/all-features.txt b/api/primitives/all-features.txt
index f67f448d..04d7c50b 100644
--- a/api/primitives/all-features.txt
+++ b/api/primitives/all-features.txt
@@ -3,6 +3,7 @@
#[repr(transparent)] pub struct bitcoin_primitives::script::Script<T>(_, _)
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::BlockHash
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::TxMerkleNode
+impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::block::Block
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::block::Header
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::block::Version
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::pow::CompactTarget
@@ -12,6 +13,7 @@ impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::trans
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::transaction::TxOut
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::transaction::Version
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::witness::Witness
+impl bitcoin_consensus_encoding::decode::Decoder for bitcoin_primitives::block::BlockDecoder
impl bitcoin_consensus_encoding::decode::Decoder for bitcoin_primitives::block::BlockHashDecoder
impl bitcoin_consensus_encoding::decode::Decoder for bitcoin_primitives::block::HeaderDecoder
impl bitcoin_consensus_encoding::decode::Decoder for bitcoin_primitives::block::VersionDecoder
@@ -106,6 +108,7 @@ impl core::clone::Clone for bitcoin_primitives::Txid
impl core::clone::Clone for bitcoin_primitives::WitnessCommitment
impl core::clone::Clone for bitcoin_primitives::WitnessMerkleNode
impl core::clone::Clone for bitcoin_primitives::Wtxid
+impl core::clone::Clone for bitcoin_primitives::block::BlockDecoderError
impl core::clone::Clone for bitcoin_primitives::block::BlockHashDecoderError
impl core::clone::Clone for bitcoin_primitives::block::Checked
impl core::clone::Clone for bitcoin_primitives::block::Header
@@ -147,6 +150,7 @@ impl core::cmp::Eq for bitcoin_primitives::Txid
impl core::cmp::Eq for bitcoin_primitives::WitnessCommitment
impl core::cmp::Eq for bitcoin_primitives::WitnessMerkleNode
impl core::cmp::Eq for bitcoin_primitives::Wtxid
+impl core::cmp::Eq for bitcoin_primitives::block::BlockDecoderError
impl core::cmp::Eq for bitcoin_primitives::block::BlockHashDecoderError
impl core::cmp::Eq for bitcoin_primitives::block::Checked
impl core::cmp::Eq for bitcoin_primitives::block::Header
@@ -213,6 +217,7 @@ impl core::cmp::PartialEq for bitcoin_primitives::Txid
impl core::cmp::PartialEq for bitcoin_primitives::WitnessCommitment
impl core::cmp::PartialEq for bitcoin_primitives::WitnessMerkleNode
impl core::cmp::PartialEq for bitcoin_primitives::Wtxid
+impl core::cmp::PartialEq for bitcoin_primitives::block::BlockDecoderError
impl core::cmp::PartialEq for bitcoin_primitives::block::BlockHashDecoderError
impl core::cmp::PartialEq for bitcoin_primitives::block::Checked
impl core::cmp::PartialEq for bitcoin_primitives::block::Header
@@ -313,6 +318,7 @@ impl core::convert::From<bitcoin_primitives::transaction::Version> for u32
impl core::convert::From<bitcoin_primitives::transaction::VersionDecoderError> for bitcoin_primitives::transaction::TransactionDecoderError
impl core::convert::From<bitcoin_primitives::witness::WitnessDecoderError> for bitcoin_primitives::transaction::TransactionDecoderError
impl core::convert::From<bitcoin_units::locktime::absolute::error::LockTimeDecoderError> for bitcoin_primitives::transaction::TransactionDecoderError
+impl core::convert::From<core::convert::Infallible> for bitcoin_primitives::block::BlockDecoderError
impl core::convert::From<core::convert::Infallible> for bitcoin_primitives::block::BlockHashDecoderError
impl core::convert::From<core::convert::Infallible> for bitcoin_primitives::block::HeaderDecoderError
impl core::convert::From<core::convert::Infallible> for bitcoin_primitives::block::VersionDecoderError
@@ -340,6 +346,7 @@ impl core::default::Default for bitcoin_primitives::transaction::TxMerkleNodeDec
impl core::default::Default for bitcoin_primitives::transaction::VersionDecoder
impl core::default::Default for bitcoin_primitives::witness::Witness
impl core::default::Default for bitcoin_primitives::witness::WitnessDecoder
+impl core::error::Error for bitcoin_primitives::block::BlockDecoderError
impl core::error::Error for bitcoin_primitives::block::BlockHashDecoderError
impl core::error::Error for bitcoin_primitives::block::HeaderDecoderError
impl core::error::Error for bitcoin_primitives::block::VersionDecoderError
@@ -363,6 +370,7 @@ impl core::fmt::Debug for bitcoin_primitives::Txid
impl core::fmt::Debug for bitcoin_primitives::WitnessCommitment
impl core::fmt::Debug for bitcoin_primitives::WitnessMerkleNode
impl core::fmt::Debug for bitcoin_primitives::Wtxid
+impl core::fmt::Debug for bitcoin_primitives::block::BlockDecoderError
impl core::fmt::Debug for bitcoin_primitives::block::BlockHashDecoderError
impl core::fmt::Debug for bitcoin_primitives::block::Checked
impl core::fmt::Debug for bitcoin_primitives::block::Header
@@ -399,6 +407,7 @@ impl core::fmt::Display for bitcoin_primitives::Txid
impl core::fmt::Display for bitcoin_primitives::WitnessCommitment
impl core::fmt::Display for bitcoin_primitives::WitnessMerkleNode
impl core::fmt::Display for bitcoin_primitives::Wtxid
+impl core::fmt::Display for bitcoin_primitives::block::BlockDecoderError
impl core::fmt::Display for bitcoin_primitives::block::BlockHashDecoderError
impl core::fmt::Display for bitcoin_primitives::block::Header
impl core::fmt::Display for bitcoin_primitives::block::HeaderDecoderError
@@ -487,6 +496,8 @@ impl core::marker::Freeze for bitcoin_primitives::Txid
impl core::marker::Freeze for bitcoin_primitives::WitnessCommitment
impl core::marker::Freeze for bitcoin_primitives::WitnessMerkleNode
impl core::marker::Freeze for bitcoin_primitives::Wtxid
+impl core::marker::Freeze for bitcoin_primitives::block::BlockDecoder
+impl core::marker::Freeze for bitcoin_primitives::block::BlockDecoderError
impl core::marker::Freeze for bitcoin_primitives::block::BlockHashDecoder
impl core::marker::Freeze for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::Freeze for bitcoin_primitives::block::BlockHashEncoder
@@ -545,6 +556,8 @@ impl core::marker::Send for bitcoin_primitives::Txid
impl core::marker::Send for bitcoin_primitives::WitnessCommitment
impl core::marker::Send for bitcoin_primitives::WitnessMerkleNode
impl core::marker::Send for bitcoin_primitives::Wtxid
+impl core::marker::Send for bitcoin_primitives::block::BlockDecoder
+impl core::marker::Send for bitcoin_primitives::block::BlockDecoderError
impl core::marker::Send for bitcoin_primitives::block::BlockHashDecoder
impl core::marker::Send for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::Send for bitcoin_primitives::block::BlockHashEncoder
@@ -603,6 +616,7 @@ impl core::marker::StructuralPartialEq for bitcoin_primitives::Txid
impl core::marker::StructuralPartialEq for bitcoin_primitives::WitnessCommitment
impl core::marker::StructuralPartialEq for bitcoin_primitives::WitnessMerkleNode
impl core::marker::StructuralPartialEq for bitcoin_primitives::Wtxid
+impl core::marker::StructuralPartialEq for bitcoin_primitives::block::BlockDecoderError
impl core::marker::StructuralPartialEq for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::StructuralPartialEq for bitcoin_primitives::block::Checked
impl core::marker::StructuralPartialEq for bitcoin_primitives::block::Header
@@ -644,6 +658,8 @@ impl core::marker::Sync for bitcoin_primitives::Txid
impl core::marker::Sync for bitcoin_primitives::WitnessCommitment
impl core::marker::Sync for bitcoin_primitives::WitnessMerkleNode
impl core::marker::Sync for bitcoin_primitives::Wtxid
+impl core::marker::Sync for bitcoin_primitives::block::BlockDecoder
+impl core::marker::Sync for bitcoin_primitives::block::BlockDecoderError
impl core::marker::Sync for bitcoin_primitives::block::BlockHashDecoder
impl core::marker::Sync for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::Sync for bitcoin_primitives::block::BlockHashEncoder
@@ -702,6 +718,8 @@ impl core::marker::Unpin for bitcoin_primitives::Txid
impl core::marker::Unpin for bitcoin_primitives::WitnessCommitment
impl core::marker::Unpin for bitcoin_primitives::WitnessMerkleNode
impl core::marker::Unpin for bitcoin_primitives::Wtxid
+impl core::marker::Unpin for bitcoin_primitives::block::BlockDecoder
+impl core::marker::Unpin for bitcoin_primitives::block::BlockDecoderError
impl core::marker::Unpin for bitcoin_primitives::block::BlockHashDecoder
impl core::marker::Unpin for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::Unpin for bitcoin_primitives::block::BlockHashEncoder
@@ -761,6 +779,8 @@ impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::Txid
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::WitnessCommitment
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::WitnessMerkleNode
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::Wtxid
+impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockDecoder
+impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockDecoderError
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockHashDecoder
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockHashDecoderError
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockHashEncoder
@@ -819,6 +839,8 @@ impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::Txid
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::WitnessCommitment
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::WitnessMerkleNode
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::Wtxid
+impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockDecoder
+impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockDecoderError
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockHashDecoder
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockHashDecoderError
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockHashEncoder
@@ -1368,6 +1390,7 @@ pub fn bitcoin_primitives::Wtxid::hash<__H: core::hash::Hasher>(&self, state: &m
pub fn bitcoin_primitives::Wtxid::partial_cmp(&self, other: &bitcoin_primitives::Wtxid) -> core::option::Option<core::cmp::Ordering>
pub fn bitcoin_primitives::Wtxid::serialize<S: serde::ser::Serializer>(&self, s: S) -> core::result::Result<<S as serde::ser::Serializer>::Ok, <S as serde::ser::Serializer>::Error>
pub fn bitcoin_primitives::block::Block::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
+pub fn bitcoin_primitives::block::Block::decoder() -> Self::Decoder
pub fn bitcoin_primitives::block::Block::encoder(&self) -> Self::Encoder
pub fn bitcoin_primitives::block::Block<V>::block_hash(&self) -> bitcoin_primitives::BlockHash
pub fn bitcoin_primitives::block::Block<V>::clone(&self) -> bitcoin_primitives::block::Block<V>
@@ -1379,6 +1402,14 @@ pub fn bitcoin_primitives::block::Block<bitcoin_primitives::block::Checked>::tra
pub fn bitcoin_primitives::block::Block<bitcoin_primitives::block::Unchecked>::assume_checked(self, witness_root: core::option::Option<bitcoin_primitives::WitnessMerkleNode>) -> bitcoin_primitives::block::Block<bitcoin_primitives::block::Checked>
pub fn bitcoin_primitives::block::Block<bitcoin_primitives::block::Unchecked>::into_parts(self) -> (bitcoin_primitives::block::Header, alloc::vec::Vec<bitcoin_primitives::transaction::Transaction>)
pub fn bitcoin_primitives::block::Block<bitcoin_primitives::block::Unchecked>::new_unchecked(header: bitcoin_primitives::block::Header, transactions: alloc::vec::Vec<bitcoin_primitives::transaction::Transaction>) -> Self
+pub fn bitcoin_primitives::block::BlockDecoder::end(self) -> core::result::Result<Self::Output, Self::Error>
+pub fn bitcoin_primitives::block::BlockDecoder::push_bytes(&mut self, bytes: &mut &[u8]) -> core::result::Result<bool, Self::Error>
+pub fn bitcoin_primitives::block::BlockDecoder::read_limit(&self) -> usize
+pub fn bitcoin_primitives::block::BlockDecoderError::clone(&self) -> bitcoin_primitives::block::BlockDecoderError
+pub fn bitcoin_primitives::block::BlockDecoderError::eq(&self, other: &bitcoin_primitives::block::BlockDecoderError) -> bool
+pub fn bitcoin_primitives::block::BlockDecoderError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub fn bitcoin_primitives::block::BlockDecoderError::from(never: core::convert::Infallible) -> Self
+pub fn bitcoin_primitives::block::BlockDecoderError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)>
pub fn bitcoin_primitives::block::BlockEncoder<'e>::advance(&mut self) -> bool
pub fn bitcoin_primitives::block::BlockEncoder<'e>::current_chunk(&self) -> &[u8]
pub fn bitcoin_primitives::block::BlockHashDecoder::default() -> Self
@@ -1849,6 +1880,8 @@ pub struct bitcoin_primitives::WitnessCommitment(_)
pub struct bitcoin_primitives::WitnessMerkleNode(_)
pub struct bitcoin_primitives::Wtxid(_)
pub struct bitcoin_primitives::block::Block<V> where V: bitcoin_primitives::block::Validation
+pub struct bitcoin_primitives::block::BlockDecoder(_)
+pub struct bitcoin_primitives::block::BlockDecoderError(_)
pub struct bitcoin_primitives::block::BlockEncoder<'e>(_)
pub struct bitcoin_primitives::block::BlockHash(_)
pub struct bitcoin_primitives::block::BlockHashDecoder(_)
@@ -1938,7 +1971,10 @@ pub type bitcoin_primitives::WitnessMerkleNode::Err = hex_conservative::error::D
pub type bitcoin_primitives::WitnessScript = bitcoin_primitives::script::Script<bitcoin_primitives::script::WitnessScriptTag>
pub type bitcoin_primitives::WitnessScriptBuf = bitcoin_primitives::script::ScriptBuf<bitcoin_primitives::script::WitnessScriptTag>
pub type bitcoin_primitives::Wtxid::Err = hex_conservative::error::DecodeFixedLengthBytesError
+pub type bitcoin_primitives::block::Block::Decoder = bitcoin_primitives::block::BlockDecoder
pub type bitcoin_primitives::block::Block::Encoder<'e> where Self: 'e = bitcoin_consensus_encoding::encode::encoders::Encoder2<bitcoin_primitives::block::HeaderEncoder, bitcoin_consensus_encoding::encode::encoders::Encoder2<bitcoin_consensus_encoding::encode::encoders::CompactSizeEncoder, bitcoin_consensus_encoding::encode::encoders::SliceEncoder<'e, bitcoin_primitives::transaction::Transaction>>>
+pub type bitcoin_primitives::block::BlockDecoder::Error = bitcoin_primitives::block::BlockDecoderError
+pub type bitcoin_primitives::block::BlockDecoder::Output = bitcoin_primitives::block::Block
pub type bitcoin_primitives::block::BlockHashDecoder::Error = bitcoin_primitives::block::BlockHashDecoderError
pub type bitcoin_primitives::block::BlockHashDecoder::Output = bitcoin_primitives::BlockHash
pub type bitcoin_primitives::block::Header::Decoder = bitcoin_primitives::block::HeaderDecoder
diff --git a/api/primitives/alloc-only.txt b/api/primitives/alloc-only.txt
index 53a7bf84..bd56264d 100644
--- a/api/primitives/alloc-only.txt
+++ b/api/primitives/alloc-only.txt
@@ -2,6 +2,7 @@
#[repr(transparent)] pub struct bitcoin_primitives::script::Script<T>(_, _)
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::BlockHash
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::TxMerkleNode
+impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::block::Block
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::block::Header
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::block::Version
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::pow::CompactTarget
@@ -11,6 +12,7 @@ impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::trans
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::transaction::TxOut
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::transaction::Version
impl bitcoin_consensus_encoding::decode::Decodable for bitcoin_primitives::witness::Witness
+impl bitcoin_consensus_encoding::decode::Decoder for bitcoin_primitives::block::BlockDecoder
impl bitcoin_consensus_encoding::decode::Decoder for bitcoin_primitives::block::BlockHashDecoder
impl bitcoin_consensus_encoding::decode::Decoder for bitcoin_primitives::block::HeaderDecoder
impl bitcoin_consensus_encoding::decode::Decoder for bitcoin_primitives::block::VersionDecoder
@@ -105,6 +107,7 @@ impl core::clone::Clone for bitcoin_primitives::Txid
impl core::clone::Clone for bitcoin_primitives::WitnessCommitment
impl core::clone::Clone for bitcoin_primitives::WitnessMerkleNode
impl core::clone::Clone for bitcoin_primitives::Wtxid
+impl core::clone::Clone for bitcoin_primitives::block::BlockDecoderError
impl core::clone::Clone for bitcoin_primitives::block::BlockHashDecoderError
impl core::clone::Clone for bitcoin_primitives::block::Checked
impl core::clone::Clone for bitcoin_primitives::block::Header
@@ -145,6 +148,7 @@ impl core::cmp::Eq for bitcoin_primitives::Txid
impl core::cmp::Eq for bitcoin_primitives::WitnessCommitment
impl core::cmp::Eq for bitcoin_primitives::WitnessMerkleNode
impl core::cmp::Eq for bitcoin_primitives::Wtxid
+impl core::cmp::Eq for bitcoin_primitives::block::BlockDecoderError
impl core::cmp::Eq for bitcoin_primitives::block::BlockHashDecoderError
impl core::cmp::Eq for bitcoin_primitives::block::Checked
impl core::cmp::Eq for bitcoin_primitives::block::Header
@@ -210,6 +214,7 @@ impl core::cmp::PartialEq for bitcoin_primitives::Txid
impl core::cmp::PartialEq for bitcoin_primitives::WitnessCommitment
impl core::cmp::PartialEq for bitcoin_primitives::WitnessMerkleNode
impl core::cmp::PartialEq for bitcoin_primitives::Wtxid
+impl core::cmp::PartialEq for bitcoin_primitives::block::BlockDecoderError
impl core::cmp::PartialEq for bitcoin_primitives::block::BlockHashDecoderError
impl core::cmp::PartialEq for bitcoin_primitives::block::Checked
impl core::cmp::PartialEq for bitcoin_primitives::block::Header
@@ -309,6 +314,7 @@ impl core::convert::From<bitcoin_primitives::transaction::Version> for u32
impl core::convert::From<bitcoin_primitives::transaction::VersionDecoderError> for bitcoin_primitives::transaction::TransactionDecoderError
impl core::convert::From<bitcoin_primitives::witness::WitnessDecoderError> for bitcoin_primitives::transaction::TransactionDecoderError
impl core::convert::From<bitcoin_units::locktime::absolute::error::LockTimeDecoderError> for bitcoin_primitives::transaction::TransactionDecoderError
+impl core::convert::From<core::convert::Infallible> for bitcoin_primitives::block::BlockDecoderError
impl core::convert::From<core::convert::Infallible> for bitcoin_primitives::block::BlockHashDecoderError
impl core::convert::From<core::convert::Infallible> for bitcoin_primitives::block::HeaderDecoderError
impl core::convert::From<core::convert::Infallible> for bitcoin_primitives::block::VersionDecoderError
@@ -342,6 +348,7 @@ impl core::fmt::Debug for bitcoin_primitives::Txid
impl core::fmt::Debug for bitcoin_primitives::WitnessCommitment
impl core::fmt::Debug for bitcoin_primitives::WitnessMerkleNode
impl core::fmt::Debug for bitcoin_primitives::Wtxid
+impl core::fmt::Debug for bitcoin_primitives::block::BlockDecoderError
impl core::fmt::Debug for bitcoin_primitives::block::BlockHashDecoderError
impl core::fmt::Debug for bitcoin_primitives::block::Checked
impl core::fmt::Debug for bitcoin_primitives::block::Header
@@ -370,6 +377,7 @@ impl core::fmt::Debug for bitcoin_primitives::transaction::VersionDecoderError
impl core::fmt::Debug for bitcoin_primitives::witness::UnexpectedEofError
impl core::fmt::Debug for bitcoin_primitives::witness::Witness
impl core::fmt::Debug for bitcoin_primitives::witness::WitnessDecoderError
+impl core::fmt::Display for bitcoin_primitives::block::BlockDecoderError
impl core::fmt::Display for bitcoin_primitives::block::BlockHashDecoderError
impl core::fmt::Display for bitcoin_primitives::block::HeaderDecoderError
impl core::fmt::Display for bitcoin_primitives::block::VersionDecoderError
@@ -435,6 +443,8 @@ impl core::marker::Freeze for bitcoin_primitives::Txid
impl core::marker::Freeze for bitcoin_primitives::WitnessCommitment
impl core::marker::Freeze for bitcoin_primitives::WitnessMerkleNode
impl core::marker::Freeze for bitcoin_primitives::Wtxid
+impl core::marker::Freeze for bitcoin_primitives::block::BlockDecoder
+impl core::marker::Freeze for bitcoin_primitives::block::BlockDecoderError
impl core::marker::Freeze for bitcoin_primitives::block::BlockHashDecoder
impl core::marker::Freeze for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::Freeze for bitcoin_primitives::block::BlockHashEncoder
@@ -492,6 +502,8 @@ impl core::marker::Send for bitcoin_primitives::Txid
impl core::marker::Send for bitcoin_primitives::WitnessCommitment
impl core::marker::Send for bitcoin_primitives::WitnessMerkleNode
impl core::marker::Send for bitcoin_primitives::Wtxid
+impl core::marker::Send for bitcoin_primitives::block::BlockDecoder
+impl core::marker::Send for bitcoin_primitives::block::BlockDecoderError
impl core::marker::Send for bitcoin_primitives::block::BlockHashDecoder
impl core::marker::Send for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::Send for bitcoin_primitives::block::BlockHashEncoder
@@ -549,6 +561,7 @@ impl core::marker::StructuralPartialEq for bitcoin_primitives::Txid
impl core::marker::StructuralPartialEq for bitcoin_primitives::WitnessCommitment
impl core::marker::StructuralPartialEq for bitcoin_primitives::WitnessMerkleNode
impl core::marker::StructuralPartialEq for bitcoin_primitives::Wtxid
+impl core::marker::StructuralPartialEq for bitcoin_primitives::block::BlockDecoderError
impl core::marker::StructuralPartialEq for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::StructuralPartialEq for bitcoin_primitives::block::Checked
impl core::marker::StructuralPartialEq for bitcoin_primitives::block::Header
@@ -589,6 +602,8 @@ impl core::marker::Sync for bitcoin_primitives::Txid
impl core::marker::Sync for bitcoin_primitives::WitnessCommitment
impl core::marker::Sync for bitcoin_primitives::WitnessMerkleNode
impl core::marker::Sync for bitcoin_primitives::Wtxid
+impl core::marker::Sync for bitcoin_primitives::block::BlockDecoder
+impl core::marker::Sync for bitcoin_primitives::block::BlockDecoderError
impl core::marker::Sync for bitcoin_primitives::block::BlockHashDecoder
impl core::marker::Sync for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::Sync for bitcoin_primitives::block::BlockHashEncoder
@@ -646,6 +661,8 @@ impl core::marker::Unpin for bitcoin_primitives::Txid
impl core::marker::Unpin for bitcoin_primitives::WitnessCommitment
impl core::marker::Unpin for bitcoin_primitives::WitnessMerkleNode
impl core::marker::Unpin for bitcoin_primitives::Wtxid
+impl core::marker::Unpin for bitcoin_primitives::block::BlockDecoder
+impl core::marker::Unpin for bitcoin_primitives::block::BlockDecoderError
impl core::marker::Unpin for bitcoin_primitives::block::BlockHashDecoder
impl core::marker::Unpin for bitcoin_primitives::block::BlockHashDecoderError
impl core::marker::Unpin for bitcoin_primitives::block::BlockHashEncoder
@@ -704,6 +721,8 @@ impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::Txid
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::WitnessCommitment
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::WitnessMerkleNode
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::Wtxid
+impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockDecoder
+impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockDecoderError
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockHashDecoder
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockHashDecoderError
impl core::panic::unwind_safe::RefUnwindSafe for bitcoin_primitives::block::BlockHashEncoder
@@ -761,6 +780,8 @@ impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::Txid
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::WitnessCommitment
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::WitnessMerkleNode
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::Wtxid
+impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockDecoder
+impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockDecoderError
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockHashDecoder
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockHashDecoderError
impl core::panic::unwind_safe::UnwindSafe for bitcoin_primitives::block::BlockHashEncoder
@@ -1206,6 +1227,7 @@ pub fn bitcoin_primitives::Wtxid::from(tx: &bitcoin_primitives::transaction::Tra
pub fn bitcoin_primitives::Wtxid::from(tx: bitcoin_primitives::transaction::Transaction) -> Self
pub fn bitcoin_primitives::Wtxid::hash<__H: core::hash::Hasher>(&self, state: &mut __H)
pub fn bitcoin_primitives::Wtxid::partial_cmp(&self, other: &bitcoin_primitives::Wtxid) -> core::option::Option<core::cmp::Ordering>
+pub fn bitcoin_primitives::block::Block::decoder() -> Self::Decoder
pub fn bitcoin_primitives::block::Block::encoder(&self) -> Self::Encoder
pub fn bitcoin_primitives::block::Block<V>::block_hash(&self) -> bitcoin_primitives::BlockHash
pub fn bitcoin_primitives::block::Block<V>::clone(&self) -> bitcoin_primitives::block::Block<V>
@@ -1217,6 +1239,13 @@ pub fn bitcoin_primitives::block::Block<bitcoin_primitives::block::Checked>::tra
pub fn bitcoin_primitives::block::Block<bitcoin_primitives::block::Unchecked>::assume_checked(self, witness_root: core::option::Option<bitcoin_primitives::WitnessMerkleNode>) -> bitcoin_primitives::block::Block<bitcoin_primitives::block::Checked>
pub fn bitcoin_primitives::block::Block<bitcoin_primitives::block::Unchecked>::into_parts(self) -> (bitcoin_primitives::block::Header, alloc::vec::Vec<bitcoin_primitives::transaction::Transaction>)
pub fn bitcoin_primitives::block::Block<bitcoin_primitives::block::Unchecked>::new_unchecked(header: bitcoin_primitives::block::Header, transactions: alloc::vec::Vec<bitcoin_primitives::transaction::Transaction>) -> Self
+pub fn bitcoin_primitives::block::BlockDecoder::end(self) -> core::result::Result<Self::Output, Self::Error>
+pub fn bitcoin_primitives::block::BlockDecoder::push_bytes(&mut self, bytes: &mut &[u8]) -> core::result::Result<bool, Self::Error>
+pub fn bitcoin_primitives::block::BlockDecoder::read_limit(&self) -> usize
+pub fn bitcoin_primitives::block::BlockDecoderError::clone(&self) -> bitcoin_primitives::block::BlockDecoderError
+pub fn bitcoin_primitives::block::BlockDecoderError::eq(&self, other: &bitcoin_primitives::block::BlockDecoderError) -> bool
+pub fn bitcoin_primitives::block::BlockDecoderError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub fn bitcoin_primitives::block::BlockDecoderError::from(never: core::convert::Infallible) -> Self
pub fn bitcoin_primitives::block::BlockEncoder<'e>::advance(&mut self) -> bool
pub fn bitcoin_primitives::block::BlockEncoder<'e>::current_chunk(&self) -> &[u8]
pub fn bitcoin_primitives::block::BlockHashDecoder::default() -> Self
@@ -1636,6 +1665,8 @@ pub struct bitcoin_primitives::WitnessCommitment(_)
pub struct bitcoin_primitives::WitnessMerkleNode(_)
pub struct bitcoin_primitives::Wtxid(_)
pub struct bitcoin_primitives::block::Block<V> where V: bitcoin_primitives::block::Validation
+pub struct bitcoin_primitives::block::BlockDecoder(_)
+pub struct bitcoin_primitives::block::BlockDecoderError(_)
pub struct bitcoin_primitives::block::BlockEncoder<'e>(_)
pub struct bitcoin_primitives::block::BlockHash(_)
pub struct bitcoin_primitives::block::BlockHashDecoder(_)
@@ -1718,7 +1749,10 @@ pub type bitcoin_primitives::TxMerkleNode::Decoder = bitcoin_primitives::transac
pub type bitcoin_primitives::TxMerkleNode::Encoder<'e> = bitcoin_primitives::merkle_tree::TxMerkleNodeEncoder
pub type bitcoin_primitives::WitnessScript = bitcoin_primitives::script::Script<bitcoin_primitives::script::WitnessScriptTag>
pub type bitcoin_primitives::WitnessScriptBuf = bitcoin_primitives::script::ScriptBuf<bitcoin_primitives::script::WitnessScriptTag>
+pub type bitcoin_primitives::block::Block::Decoder = bitcoin_primitives::block::BlockDecoder
pub type bitcoin_primitives::block::Block::Encoder<'e> where Self: 'e = bitcoin_consensus_encoding::encode::encoders::Encoder2<bitcoin_primitives::block::HeaderEncoder, bitcoin_consensus_encoding::encode::encoders::Encoder2<bitcoin_consensus_encoding::encode::encoders::CompactSizeEncoder, bitcoin_consensus_encoding::encode::encoders::SliceEncoder<'e, bitcoin_primitives::transaction::Transaction>>>
+pub type bitcoin_primitives::block::BlockDecoder::Error = bitcoin_primitives::block::BlockDecoderError
+pub type bitcoin_primitives::block::BlockDecoder::Output = bitcoin_primitives::block::Block
pub type bitcoin_primitives::block::BlockHashDecoder::Error = bitcoin_primitives::block::BlockHashDecoderError
pub type bitcoin_primitives::block::BlockHashDecoder::Output = bitcoin_primitives::BlockHash
pub type bitcoin_primitives::block::Header::Decoder = bitcoin_primitives::block::HeaderDecoder
diff --git a/primitives/src/block.rs b/primitives/src/block.rs
index 63470560..7776900a 100644
--- a/primitives/src/block.rs
+++ b/primitives/src/block.rs
@@ -16,7 +16,7 @@ use core::marker::PhantomData;
use arbitrary::{Arbitrary, Unstructured};
use encoding::Encodable;
#[cfg(feature = "alloc")]
-use encoding::{CompactSizeEncoder, Decodable, Decoder, Decoder6, Encoder2, SliceEncoder};
+use encoding::{CompactSizeEncoder, Decodable, Decoder, Decoder2, Decoder6, Encoder2, SliceEncoder, VecDecoder};
use hashes::{sha256d, HashEngine as _};
use internals::write_err;
@@ -201,6 +201,77 @@ impl Encodable for Block {
}
}
+#[cfg(feature = "alloc")]
+type BlockInnerDecoder = Decoder2<HeaderDecoder, VecDecoder<Transaction>>;
+
+/// The decoder for the [`Block`] type.
+///
+/// This decoder can only produce a `Block<Unchecked>`.
+#[cfg(feature = "alloc")]
+pub struct BlockDecoder(BlockInnerDecoder);
+
+#[cfg(feature = "alloc")]
+impl Decoder for BlockDecoder {
+ type Output = Block;
+ type Error = BlockDecoderError;
+
+ #[inline]
+ fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
+ self.0.push_bytes(bytes).map_err(BlockDecoderError)
+ }
+
+ #[inline]
+ fn end(self) -> Result<Self::Output, Self::Error> {
+ let (header, transactions) = self.0.end().map_err(BlockDecoderError)?;
+ Ok(Self::Output::new_unchecked(header, transactions))
+ }
+
+ #[inline]
+ fn read_limit(&self) -> usize { self.0.read_limit() }
+}
+
+#[cfg(feature = "alloc")]
+impl Decodable for Block {
+ type Decoder = BlockDecoder;
+ fn decoder() -> Self::Decoder {
+ BlockDecoder(Decoder2::new(
+ Header::decoder(),
+ VecDecoder::<Transaction>::new(),
+ ))
+ }
+}
+
+/// An error consensus decoding a [`Block`].
+#[cfg(feature = "alloc")]
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct BlockDecoderError(<BlockInnerDecoder as Decoder>::Error);
+
+#[cfg(feature = "alloc")]
+impl From<Infallible> for BlockDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+#[cfg(feature = "alloc")]
+impl fmt::Display for BlockDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match &self.0 {
+ encoding::Decoder2Error::First(ref e) => write_err!(f, "block decoder error"; e),
+ encoding::Decoder2Error::Second(ref e) => write_err!(f, "block decoder error"; e),
+ }
+ }
+}
+
+#[cfg(feature = "alloc")]
+#[cfg(feature = "std")]
+impl std::error::Error for BlockDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match &self.0 {
+ encoding::Decoder2Error::First(ref e) => Some(e),
+ encoding::Decoder2Error::Second(ref e) => Some(e),
+ }
+ }
+}
+
/// Bitcoin block header.
///
/// Contains all the block's information except the actual transactions, but
@@ -827,4 +898,45 @@ mod tests {
let got = format!("{:.20}", header);
assert_eq!(got, want);
}
+
+ #[test]
+ #[cfg(feature = "alloc")]
+ fn block_decode() {
+ // Make a simple block, encode then decode. Verify equivalence.
+ let header = Header {
+ version: Version::ONE,
+ prev_blockhash: BlockHash::from_byte_array([
+ 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA,
+ 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA,
+ 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA,
+ 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA,
+ ]),
+ merkle_root: TxMerkleNode::from_byte_array([
+ 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD,
+ 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD,
+ 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD,
+ 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD,
+ ]),
+ time: BlockTime::from(1_742_979_600), // 26 Mar 2025 9:00 UTC
+ bits: CompactTarget::from_consensus(12_345_678),
+ nonce: 1024,
+ };
+
+ let block: u32 = 741_521;
+ let transactions = vec![
+ Transaction {
+ version: crate::transaction::Version::ONE,
+ lock_time: units::absolute::LockTime::from_height(block).unwrap(),
+ inputs: vec![crate::transaction::TxIn::EMPTY_COINBASE],
+ outputs: Vec::new(),
+ },
+ ];
+ let original_block = Block::new_unchecked(header, transactions);
+
+ // Encode + decode the block
+ let encoded = encoding::encode_to_vec(&original_block);
+ let decoded_block = encoding::decode_from_slice(encoded.as_slice()).unwrap();
+
+ assert_eq!(original_block, decoded_block);
+ }
}
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.