Skip to main content

bitcoin_primitives/
block.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Bitcoin blocks.
4//!
5//! A block is a bundle of transactions with a proof-of-work attached,
6//! which commits to an earlier block to form the blockchain. This
7//! module describes structures and functions needed to describe
8//! these blocks and the blockchain.
9
10use core::fmt;
11#[cfg(feature = "alloc")]
12use core::marker::PhantomData;
13
14#[cfg(feature = "arbitrary")]
15use arbitrary::{Arbitrary, Unstructured};
16use encoding::{ArrayDecoder, Decoder6};
17#[cfg(feature = "alloc")]
18use encoding::{Decoder2, Encoder2, PrefixedSliceEncoder, VecDecoder};
19use hashes::sha256d;
20#[cfg(feature = "alloc")]
21use hashes::HashEngine as _;
22
23#[cfg(feature = "hex")]
24use crate::hex_codec::HexPrimitive;
25#[cfg(feature = "alloc")]
26use crate::merkle_tree::WitnessMerkleNode;
27use crate::merkle_tree::{TxMerkleNode, TxMerkleNodeDecoder};
28use crate::pow::CompactTargetDecoder;
29#[cfg(feature = "alloc")]
30use crate::prelude::Vec;
31use crate::time::BlockTimeDecoder;
32use crate::{BlockTime, CompactTarget};
33#[cfg(feature = "alloc")]
34use crate::{Transaction, Wtxid};
35
36#[rustfmt::skip]                // Keep public re-exports separate.
37#[doc(inline)]
38pub use units::block::{BlockHeight, BlockHeightDecoder, BlockHeightEncoder, BlockHeightInterval, BlockMtp, BlockMtpInterval};
39
40#[rustfmt::skip]                // Keep public re-exports separate.
41#[cfg(feature = "alloc")]
42#[doc(no_inline)]
43pub use self::error::{BlockDecoderError, InvalidBlockError};
44#[doc(no_inline)]
45pub use self::error::{
46    BlockHashDecoderError, BlockHeightDecoderError, HeaderDecoderError,
47    TooBigForRelativeHeightError, VersionDecoderError,
48};
49#[doc(inline)]
50pub use crate::hash_types::{BlockHash, BlockHashDecoder, BlockHashEncoder, WitnessCommitment};
51
52// Consists of OP_RETURN, OP_PUSHBYTES_36, and four "witness header" bytes.
53#[cfg(feature = "alloc")]
54const WITNESS_COMMITMENT_MAGIC: [u8; 6] = [0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed];
55
56/// Marker for whether or not a block has been validated.
57///
58/// We define valid as:
59///
60/// * The Merkle root of the header matches Merkle root of the transaction list.
61/// * The witness commitment in coinbase matches the transaction list.
62///
63/// See `bitcoin::block::BlockUncheckedExt::validate()`.
64#[cfg(feature = "alloc")]
65pub trait Validation: sealed::Validation + Sync + Send + Sized + Unpin {
66    /// Indicates whether this `Validation` is `Checked` or not.
67    const IS_CHECKED: bool;
68}
69
70/// Bitcoin block.
71///
72/// A collection of transactions with an attached proof of work.
73///
74/// See [Bitcoin Wiki: Block][wiki-block] for more information.
75///
76/// [wiki-block]: https://en.bitcoin.it/wiki/Block
77///
78/// # Bitcoin Core References
79///
80/// * [CBlock definition](https://github.com/bitcoin/bitcoin/blob/345457b542b6a980ccfbc868af0970a6f91d1b82/src/primitives/block.h#L62)
81#[cfg(feature = "alloc")]
82#[derive(PartialEq, Eq, Clone, Debug)]
83pub struct Block<V = Unchecked>
84where
85    V: Validation,
86{
87    /// The block header
88    header: Header,
89    /// List of transactions contained in the block
90    transactions: Vec<Transaction>,
91    /// Cached witness root if it's been computed.
92    witness_root: Option<WitnessMerkleNode>,
93    /// Validation marker.
94    _marker: PhantomData<V>,
95}
96
97#[cfg(feature = "alloc")]
98impl Block<Unchecked> {
99    /// Constructs a new `Block` without doing any validation.
100    #[inline]
101    pub fn new_unchecked(header: Header, transactions: Vec<Transaction>) -> Self {
102        Self { header, transactions, witness_root: None, _marker: PhantomData::<Unchecked> }
103    }
104
105    /// Ignores block validation logic and just assumes you know what you are doing.
106    ///
107    /// You should only use this function if you trust the block i.e., it comes from a trusted node.
108    #[must_use]
109    #[inline]
110    pub fn assume_checked(self, witness_root: Option<WitnessMerkleNode>) -> Block<Checked> {
111        Block {
112            header: self.header,
113            transactions: self.transactions,
114            witness_root,
115            _marker: PhantomData::<Checked>,
116        }
117    }
118
119    /// Decomposes block into its constituent parts.
120    #[inline]
121    pub fn into_parts(self) -> (Header, Vec<Transaction>) { (self.header, self.transactions) }
122
123    /// Returns the constituent parts of the block by reference.
124    #[inline]
125    pub fn as_parts(&self) -> (&Header, &[Transaction]) { (&self.header, &self.transactions) }
126
127    /// Validates (or checks) a block.
128    ///
129    /// We define valid as:
130    ///
131    /// * The Merkle root of the header matches Merkle root of the transaction list.
132    /// * The witness commitment in coinbase matches the transaction list.
133    ///
134    /// # Errors
135    ///
136    /// Returns an error if:
137    /// * The block has no transactions.
138    /// * The first transaction is not a coinbase transaction.
139    /// * The Merkle root of the header does not match the Merkle root of the transaction list.
140    /// * The witness commitment in the coinbase does not match the transaction list.
141    pub fn validate(self) -> Result<Block<Checked>, InvalidBlockError> {
142        if self.transactions.is_empty() {
143            return Err(InvalidBlockError::NoTransactions);
144        }
145
146        if !self.transactions[0].is_coinbase() {
147            return Err(InvalidBlockError::InvalidCoinbase);
148        }
149
150        if !self.check_merkle_root() {
151            return Err(InvalidBlockError::InvalidMerkleRoot);
152        }
153
154        match self.check_witness_commitment() {
155            (false, _) => Err(InvalidBlockError::InvalidWitnessCommitment),
156            (true, witness_root) => {
157                let block = Self::new_unchecked(self.header, self.transactions);
158                Ok(block.assume_checked(witness_root))
159            }
160        }
161    }
162
163    /// Checks if Merkle root of header matches Merkle root of the transaction list.
164    pub fn check_merkle_root(&self) -> bool {
165        match compute_merkle_root(&self.transactions) {
166            Some(merkle_root) => self.header.merkle_root == merkle_root,
167            None => false,
168        }
169    }
170
171    /// Computes the witness commitment for a list of transactions.
172    pub fn compute_witness_commitment(
173        &self,
174        witness_reserved_value: &[u8],
175    ) -> Option<(WitnessMerkleNode, WitnessCommitment)> {
176        compute_witness_root(&self.transactions).map(|witness_root| {
177            let mut encoder = sha256d::Hash::engine();
178            hashes::encode_to_engine(&witness_root, &mut encoder);
179            encoder.input(witness_reserved_value);
180            let witness_commitment = WitnessCommitment::from_byte_array(
181                sha256d::Hash::from_engine(encoder).to_byte_array(),
182            );
183            (witness_root, witness_commitment)
184        })
185    }
186
187    /// Checks if witness commitment in coinbase matches the transaction list.
188    // Returns the Merkle root if it was computed (so it can be cached in `assume_checked`).
189    pub fn check_witness_commitment(&self) -> (bool, Option<WitnessMerkleNode>) {
190        if self.transactions.is_empty() {
191            return (false, None);
192        }
193
194        if self.transactions[0].is_coinbase() {
195            let coinbase = self.transactions[0].clone();
196            if let Some(commitment) = witness_commitment_from_coinbase(&coinbase) {
197                // Witness reserved value is in coinbase input witness.
198                let witness_vec: Vec<_> = coinbase.inputs[0].witness.iter().collect();
199                if witness_vec.len() == 1 && witness_vec[0].len() == 32 {
200                    if let Some((witness_root, witness_commitment)) =
201                        self.compute_witness_commitment(witness_vec[0])
202                    {
203                        if commitment == witness_commitment {
204                            return (true, Some(witness_root));
205                        }
206                    }
207                }
208
209                return (false, None);
210            }
211        }
212
213        // Witness commitment is optional if there are no transactions using SegWit in the block.
214        if self.transactions.iter().all(|t| t.inputs.iter().all(|i| i.witness.is_empty())) {
215            return (true, None);
216        }
217
218        (false, None)
219    }
220}
221
222#[cfg(feature = "alloc")]
223impl Block<Checked> {
224    /// Gets a reference to the block header.
225    #[inline]
226    pub fn header(&self) -> &Header { &self.header }
227
228    /// Gets a reference to the block's list of transactions.
229    #[inline]
230    pub fn transactions(&self) -> &[Transaction] { &self.transactions }
231
232    /// Returns the cached witness root if one is present.
233    ///
234    /// It is assumed that a block will have the witness root calculated and cached as part of the
235    /// validation process.
236    #[inline]
237    pub fn cached_witness_root(&self) -> Option<WitnessMerkleNode> { self.witness_root }
238}
239
240#[cfg(feature = "alloc")]
241impl<V: Validation> Block<V> {
242    /// Returns the block hash.
243    #[inline]
244    pub fn block_hash(&self) -> BlockHash { self.header.block_hash() }
245}
246
247#[cfg(feature = "alloc")]
248impl From<Block> for BlockHash {
249    #[inline]
250    fn from(block: Block) -> Self { block.block_hash() }
251}
252
253#[cfg(feature = "alloc")]
254impl From<&Block> for BlockHash {
255    #[inline]
256    fn from(block: &Block) -> Self { block.block_hash() }
257}
258
259/// Marker that the block's merkle root has been successfully validated.
260#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
261#[cfg(feature = "alloc")]
262pub enum Checked {}
263
264#[cfg(feature = "alloc")]
265impl Validation for Checked {
266    const IS_CHECKED: bool = true;
267}
268
269/// Marker that the block's merkle root has not been validated.
270#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
271#[cfg(feature = "alloc")]
272pub enum Unchecked {}
273
274#[cfg(feature = "alloc")]
275impl Validation for Unchecked {
276    const IS_CHECKED: bool = false;
277}
278
279#[cfg(feature = "alloc")]
280mod sealed {
281    /// Seals the block validation marker traits.
282    pub trait Validation {}
283    impl Validation for super::Checked {}
284    impl Validation for super::Unchecked {}
285}
286
287#[cfg(feature = "alloc")]
288#[cfg(feature = "hex")]
289impl core::str::FromStr for Block<Unchecked>
290where
291    Self: encoding::Decode,
292{
293    type Err = encoding::FromHexError<BlockDecoderError>;
294
295    fn from_str(s: &str) -> Result<Self, Self::Err> { encoding::decode_from_hex(s) }
296}
297
298#[cfg(feature = "alloc")]
299#[cfg(feature = "hex")]
300impl<V: Validation> fmt::Display for Block<V>
301where
302    Self: encoding::Encode,
303{
304    #[allow(clippy::use_self)]
305    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
306        fmt::Display::fmt(&HexPrimitive(self), f)
307    }
308}
309
310#[cfg(feature = "alloc")]
311#[cfg(feature = "hex")]
312impl<V: Validation> fmt::LowerHex for Block<V> {
313    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
314        fmt::LowerHex::fmt(&HexPrimitive(self), f)
315    }
316}
317
318#[cfg(feature = "alloc")]
319#[cfg(feature = "hex")]
320impl<V: Validation> fmt::UpperHex for Block<V> {
321    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
322        fmt::UpperHex::fmt(&HexPrimitive(self), f)
323    }
324}
325
326#[cfg(feature = "alloc")]
327impl<V> encoding::Encode for Block<V>
328where
329    V: Validation,
330{
331    type Encoder<'e>
332        = BlockEncoder<'e>
333    where
334        Self: 'e;
335
336    fn encoder(&self) -> Self::Encoder<'_> {
337        BlockEncoder::new(Encoder2::new(
338            self.header.encoder(),
339            PrefixedSliceEncoder::new(&self.transactions),
340        ))
341    }
342}
343
344#[cfg(feature = "alloc")]
345impl encoding::Decode for Block<Unchecked> {
346    type Decoder = BlockDecoder;
347}
348
349#[cfg(feature = "alloc")]
350encoding::encoder_newtype! {
351    /// The encoder for the [`Block`] type.
352    #[derive(Debug, Clone)]
353    pub struct BlockEncoder<'e>(
354        Encoder2<HeaderEncoder<'e>, PrefixedSliceEncoder<'e, Transaction>>
355    );
356}
357
358#[cfg(feature = "alloc")]
359type BlockInnerDecoder = Decoder2<HeaderDecoder, VecDecoder<Transaction>>;
360
361#[cfg(feature = "alloc")]
362crate::decoder_newtype! {
363    /// The decoder for the [`Block`] type.
364    ///
365    /// This decoder can only produce a `Block<Unchecked>`.
366    #[derive(Debug, Clone)]
367    pub struct BlockDecoder(BlockInnerDecoder);
368
369    /// Constructs a new [`Block`] decoder.
370    pub const fn new() -> Self { Self(Decoder2::new(HeaderDecoder::new(), VecDecoder::new())) }
371
372    fn end(result: Result<(Header, Vec<Transaction>), <BlockInnerDecoder as encoding::Decoder>::Error>) -> Result<Block, BlockDecoderError> {
373        let (header, transactions) = result.map_err(BlockDecoderError)?;
374        Ok(Self::Output::new_unchecked(header, transactions))
375    }
376}
377
378/// Computes the Merkle root for a list of transactions.
379///
380/// Returns `None` if the iterator was empty, or if the transaction list contains
381/// consecutive duplicates which would trigger CVE 2012-2459. Blocks with duplicate
382/// transactions will always be invalid, so there is no harm in us refusing to
383/// compute their merkle roots.
384///
385/// Unless you are certain your transaction list is nonempty and has no duplicates,
386/// you should not unwrap the `Option` returned by this method!
387#[cfg(feature = "alloc")]
388pub fn compute_merkle_root(transactions: &[Transaction]) -> Option<TxMerkleNode> {
389    let hashes = transactions.iter().map(Transaction::compute_txid);
390    TxMerkleNode::calculate_root(hashes)
391}
392
393/// Computes the Merkle root of transactions hashed for witness.
394///
395/// Returns `None` if the iterator was empty, or if the transaction list contains
396/// consecutive duplicates which would trigger CVE 2012-2459. Blocks with duplicate
397/// transactions will always be invalid, so there is no harm in us refusing to
398/// compute their merkle roots.
399///
400/// Unless you are certain your transaction list is nonempty and has no duplicates,
401/// you should not unwrap the `Option` returned by this method!
402#[cfg(feature = "alloc")]
403pub fn compute_witness_root(transactions: &[Transaction]) -> Option<WitnessMerkleNode> {
404    let hashes = transactions.iter().enumerate().map(|(i, t)| {
405        if i == 0 {
406            // Replace the first hash with zeroes.
407            Wtxid::COINBASE
408        } else {
409            t.compute_wtxid()
410        }
411    });
412    WitnessMerkleNode::calculate_root(hashes)
413}
414
415#[cfg(feature = "alloc")]
416fn witness_commitment_from_coinbase(coinbase: &Transaction) -> Option<WitnessCommitment> {
417    if !coinbase.is_coinbase() {
418        return None;
419    }
420
421    // Commitment is in the last output that starts with magic bytes.
422    if let Some(pos) = coinbase.outputs.iter().rposition(|o| {
423        o.script_pubkey.len() >= 38 && o.script_pubkey.as_bytes()[0..6] == WITNESS_COMMITMENT_MAGIC
424    }) {
425        let bytes =
426            <[u8; 32]>::try_from(&coinbase.outputs[pos].script_pubkey.as_bytes()[6..38]).unwrap();
427        Some(WitnessCommitment::from_byte_array(bytes))
428    } else {
429        None
430    }
431}
432
433/// Bitcoin block header.
434///
435/// Contains all the block's information except the actual transactions, but
436/// including a root of a [Merkle tree] committing to all transactions in the block.
437///
438/// [Merkle tree]: https://en.wikipedia.org/wiki/Merkle_tree
439///
440/// # Bitcoin Core References
441///
442/// * [CBlockHeader definition](https://github.com/bitcoin/bitcoin/blob/345457b542b6a980ccfbc868af0970a6f91d1b82/src/primitives/block.h#L20)
443#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
444pub struct Header {
445    /// Block version, now repurposed for soft fork signalling.
446    pub version: Version,
447    /// Reference to the previous block in the chain.
448    pub prev_blockhash: BlockHash,
449    /// The root hash of the Merkle tree of transactions in the block.
450    pub merkle_root: TxMerkleNode,
451    /// The timestamp of the block, as claimed by the miner.
452    pub time: BlockTime,
453    /// The target value below which the blockhash must lie.
454    pub bits: CompactTarget,
455    /// The nonce, selected to obtain a low enough blockhash.
456    pub nonce: u32,
457}
458
459impl Header {
460    /// The number of bytes that the block header contributes to the size of a block.
461    // Serialized length of fields (version, prev_blockhash, merkle_root, time, bits, nonce)
462    pub const SIZE: usize = 4 + 32 + 32 + 4 + 4 + 4; // 80
463
464    /// Returns the block hash.
465    // This is the same as `Encodable` but done manually because `Encodable` isn't in `primitives`.
466    pub fn block_hash(&self) -> BlockHash {
467        let hash = hashes::encode_to_hash::<_, sha256d::HashEngine>(self);
468        BlockHash::from_byte_array(hash.to_byte_array())
469    }
470}
471
472#[cfg(feature = "hex")]
473impl core::str::FromStr for Header {
474    type Err = encoding::FromHexError<HeaderDecoderError>;
475
476    fn from_str(s: &str) -> Result<Self, Self::Err> { encoding::decode_from_hex(s) }
477}
478
479#[cfg(feature = "hex")]
480impl fmt::Display for Header {
481    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
482        fmt::Display::fmt(&HexPrimitive(self), f)
483    }
484}
485
486#[cfg(feature = "hex")]
487impl fmt::LowerHex for Header {
488    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
489        fmt::LowerHex::fmt(&HexPrimitive(self), f)
490    }
491}
492
493#[cfg(feature = "hex")]
494impl fmt::UpperHex for Header {
495    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
496        fmt::UpperHex::fmt(&HexPrimitive(self), f)
497    }
498}
499
500impl fmt::Debug for Header {
501    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
502        f.debug_struct("Header")
503            .field("block_hash", &self.block_hash())
504            .field("version", &self.version)
505            .field("prev_blockhash", &self.prev_blockhash)
506            .field("merkle_root", &self.merkle_root)
507            .field("time", &self.time)
508            .field("bits", &self.bits)
509            .field("nonce", &self.nonce)
510            .finish()
511    }
512}
513
514impl encoding::Encode for Header {
515    type Encoder<'e> = HeaderEncoder<'e>;
516
517    fn encoder(&self) -> Self::Encoder<'_> {
518        HeaderEncoder::new(encoding::Encoder6::new(
519            self.version.encoder(),
520            self.prev_blockhash.encoder(),
521            self.merkle_root.encoder(),
522            self.time.encoder(),
523            self.bits.encoder(),
524            encoding::ArrayEncoder::without_length_prefix(self.nonce.to_le_bytes()),
525        ))
526    }
527}
528
529impl encoding::Decode for Header {
530    type Decoder = HeaderDecoder;
531}
532
533encoding::encoder_newtype_exact! {
534    /// The encoder for the [`Header`] type.
535    #[derive(Debug, Clone)]
536    pub struct HeaderEncoder<'e>(
537        encoding::Encoder6<
538            VersionEncoder<'e>,
539            BlockHashEncoder<'e>,
540            crate::merkle_tree::TxMerkleNodeEncoder<'e>,
541            crate::time::BlockTimeEncoder<'e>,
542            crate::pow::CompactTargetEncoder<'e>,
543            encoding::ArrayEncoder<4>,
544        >
545    );
546}
547
548type HeaderInnerDecoder = Decoder6<
549    VersionDecoder,
550    BlockHashDecoder,
551    TxMerkleNodeDecoder,
552    BlockTimeDecoder,
553    CompactTargetDecoder,
554    encoding::ArrayDecoder<4>, // Nonce
555>;
556
557crate::decoder_newtype! {
558    /// The decoder for the [`Header`] type.
559    #[derive(Debug, Clone)]
560    pub struct HeaderDecoder(HeaderInnerDecoder);
561
562    /// Constructs a new [`Header`] decoder.
563    pub const fn new() -> Self {
564        Self(Decoder6::new(
565            VersionDecoder::new(),
566            BlockHashDecoder::new(),
567            TxMerkleNodeDecoder::new(),
568            BlockTimeDecoder::new(),
569            CompactTargetDecoder::new(),
570            ArrayDecoder::new(),
571        ))
572    }
573
574    fn map_push_bytes_err(err: <HeaderInnerDecoder as encoding::Decoder>::Error) -> HeaderDecoderError {
575        Self::from_inner(err)
576    }
577
578    fn end(
579        result: Result<<HeaderInnerDecoder as encoding::Decoder>::Output, <HeaderInnerDecoder as encoding::Decoder>::Error>
580    ) -> Result<Header, HeaderDecoderError> {
581        let (version, prev_blockhash, merkle_root, time, bits, nonce) = result.map_err(Self::from_inner)?;
582        let nonce = u32::from_le_bytes(nonce);
583        Ok(Header { version, prev_blockhash, merkle_root, time, bits, nonce })
584    }
585}
586
587impl HeaderDecoder {
588    fn from_inner(e: <HeaderInnerDecoder as encoding::Decoder>::Error) -> HeaderDecoderError {
589        match e {
590            encoding::Decoder6Error::First(e) => HeaderDecoderError::Version(e),
591            encoding::Decoder6Error::Second(e) => HeaderDecoderError::PrevBlockhash(e),
592            encoding::Decoder6Error::Third(e) => HeaderDecoderError::MerkleRoot(e),
593            encoding::Decoder6Error::Fourth(e) => HeaderDecoderError::Time(e),
594            encoding::Decoder6Error::Fifth(e) => HeaderDecoderError::Bits(e),
595            encoding::Decoder6Error::Sixth(e) => HeaderDecoderError::Nonce(e),
596        }
597    }
598}
599
600impl From<Header> for BlockHash {
601    #[inline]
602    fn from(header: Header) -> Self { header.block_hash() }
603}
604
605impl From<&Header> for BlockHash {
606    #[inline]
607    fn from(header: &Header) -> Self { header.block_hash() }
608}
609
610/// Bitcoin block version number.
611///
612/// Originally used as a protocol version, but repurposed for soft-fork signaling.
613///
614/// The inner value is a signed integer in Bitcoin Core for historical reasons, if the version bits are
615/// being used the top three bits must be 001, this gives us a useful range of [0x20000000...0x3FFFFFFF].
616///
617/// > When a block nVersion does not have top bits 001, it is treated as if all bits are 0 for the purposes of deployments.
618///
619/// # Relevant BIPs
620///
621/// * [BIP-0009 - Version bits with timeout and delay](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki) (current usage)
622/// * [BIP-0034 - Block v2, Height in Coinbase](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki)
623#[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)]
624#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
625pub struct Version(i32);
626
627impl Version {
628    /// The original Bitcoin Block v1.
629    pub const ONE: Self = Self(1);
630
631    /// BIP-0034 Block v2.
632    pub const TWO: Self = Self(2);
633
634    /// BIP-0009 compatible version number that does not signal for any softforks.
635    pub const NO_SOFT_FORK_SIGNALLING: Self = Self(Self::USE_VERSION_BITS as i32);
636
637    /// BIP-0009 soft fork signal bits mask.
638    const VERSION_BITS_MASK: u32 = 0x1FFF_FFFF;
639
640    /// 32bit value starting with `001` to use version bits.
641    ///
642    /// The value has the top three bits `001` which enables the use of version bits to signal for soft forks.
643    const USE_VERSION_BITS: u32 = 0x2000_0000;
644
645    /// Constructs a new [`Version`] from a signed 32 bit integer value.
646    ///
647    /// This is the data type used in consensus code in Bitcoin Core.
648    #[inline]
649    pub const fn from_consensus(v: i32) -> Self { Self(v) }
650
651    /// Returns the inner `i32` value.
652    ///
653    /// This is the data type used in consensus code in Bitcoin Core.
654    #[inline]
655    pub const fn to_consensus(self) -> i32 { self.0 }
656
657    /// Checks whether the version number is signalling a soft fork at the given bit.
658    ///
659    /// A block is signalling for a soft fork under BIP-0009 if the first 3 bits are `001` and
660    /// the version bit for the specific soft fork is toggled on.
661    pub fn is_signalling_soft_fork(self, bit: u8) -> bool {
662        // Only bits [0, 28] inclusive are used for signalling.
663        if bit > 28 {
664            return false;
665        }
666
667        // To signal using version bits, the first three bits must be `001`.
668        if (self.0 as u32) & !Self::VERSION_BITS_MASK != Self::USE_VERSION_BITS {
669            return false;
670        }
671
672        // The bit is set if signalling a soft fork.
673        (self.0 as u32 & Self::VERSION_BITS_MASK) & (1 << bit) > 0
674    }
675}
676
677impl fmt::Display for Version {
678    #[inline]
679    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
680}
681
682impl fmt::LowerHex for Version {
683    #[inline]
684    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
685}
686
687impl fmt::UpperHex for Version {
688    #[inline]
689    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
690}
691
692impl fmt::Octal for Version {
693    #[inline]
694    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Octal::fmt(&self.0, f) }
695}
696
697impl fmt::Binary for Version {
698    #[inline]
699    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Binary::fmt(&self.0, f) }
700}
701
702impl Default for Version {
703    #[inline]
704    fn default() -> Self { Self::NO_SOFT_FORK_SIGNALLING }
705}
706
707impl encoding::Encode for Version {
708    type Encoder<'e> = VersionEncoder<'e>;
709    fn encoder(&self) -> Self::Encoder<'_> {
710        VersionEncoder::new(encoding::ArrayEncoder::without_length_prefix(
711            self.to_consensus().to_le_bytes(),
712        ))
713    }
714}
715
716impl encoding::Decode for Version {
717    type Decoder = VersionDecoder;
718}
719
720encoding::encoder_newtype_exact! {
721    /// The encoder for the [`Version`] type.
722    #[derive(Debug, Clone)]
723    pub struct VersionEncoder<'e>(encoding::ArrayEncoder<4>);
724}
725
726crate::decoder_newtype! {
727    /// The decoder for the [`Version`] type.
728    #[derive(Debug, Clone)]
729    pub struct VersionDecoder(encoding::ArrayDecoder<4>);
730
731    /// Constructs a new [`Version`] decoder.
732    pub const fn new() -> Self { Self(encoding::ArrayDecoder::new()) }
733
734    fn end(result: Result<[u8; 4], encoding::UnexpectedEofError>) -> Result<Version, VersionDecoderError> {
735        let value = result.map_err(VersionDecoderError)?;
736        let n = i32::from_le_bytes(value);
737        Ok(Version::from_consensus(n))
738    }
739}
740
741/// Error types for Bitcoin blocks.
742pub mod error {
743    use core::convert::Infallible;
744    use core::fmt;
745
746    use internals::write_err;
747
748    use crate::merkle_tree::TxMerkleNodeDecoderError;
749    use crate::pow::CompactTargetDecoderError;
750    use crate::time::BlockTimeDecoderError;
751
752    #[rustfmt::skip]                // Keep public re-exports separate.
753    #[doc(no_inline)]
754    pub use units::block::{BlockHeightDecoderError, TooBigForRelativeHeightError};
755    #[doc(inline)]
756    pub use crate::hash_types::BlockHashDecoderError;
757
758    /// An error consensus decoding a [`Block`](super::Block).
759    #[cfg(feature = "alloc")]
760    #[derive(Debug, Clone, PartialEq, Eq)]
761    pub struct BlockDecoderError(pub(super) <super::BlockInnerDecoder as encoding::Decoder>::Error);
762
763    #[cfg(feature = "alloc")]
764    impl From<Infallible> for BlockDecoderError {
765        fn from(never: Infallible) -> Self { match never {} }
766    }
767
768    #[cfg(feature = "alloc")]
769    impl fmt::Display for BlockDecoderError {
770        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
771            write_err!(f, "block decoder error"; self.0)
772        }
773    }
774
775    #[cfg(feature = "alloc")]
776    #[cfg(feature = "std")]
777    impl std::error::Error for BlockDecoderError {
778        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
779    }
780
781    /// Invalid block error.
782    #[cfg(feature = "alloc")]
783    #[derive(Debug, Clone, PartialEq, Eq)]
784    #[non_exhaustive]
785    pub enum InvalidBlockError {
786        /// Header Merkle root does not match the calculated Merkle root.
787        InvalidMerkleRoot,
788        /// The witness commitment in coinbase transaction does not match the calculated `witness_root`.
789        InvalidWitnessCommitment,
790        /// Block has no transactions (missing coinbase).
791        NoTransactions,
792        /// The first transaction is not a valid coinbase transaction.
793        InvalidCoinbase,
794    }
795
796    #[cfg(feature = "alloc")]
797    impl From<Infallible> for InvalidBlockError {
798        fn from(never: Infallible) -> Self { match never {} }
799    }
800
801    #[cfg(feature = "alloc")]
802    impl fmt::Display for InvalidBlockError {
803        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
804            match self {
805                Self::InvalidMerkleRoot =>
806                    write!(f, "header Merkle root does not match the calculated Merkle root"),
807                Self::InvalidWitnessCommitment => write!(f, "the witness commitment in coinbase transaction does not match the calculated witness_root"),
808                Self::NoTransactions => write!(f, "block has no transactions (missing coinbase)"),
809                Self::InvalidCoinbase =>
810                    write!(f, "the first transaction is not a valid coinbase transaction"),
811            }
812        }
813    }
814
815    #[cfg(feature = "alloc")]
816    #[cfg(feature = "std")]
817    impl std::error::Error for InvalidBlockError {
818        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
819            match self {
820                Self::InvalidMerkleRoot => None,
821                Self::InvalidWitnessCommitment => None,
822                Self::NoTransactions => None,
823                Self::InvalidCoinbase => None,
824            }
825        }
826    }
827
828    /// An error consensus decoding a `Header`.
829    #[derive(Debug, Clone, PartialEq, Eq)]
830    #[non_exhaustive]
831    pub enum HeaderDecoderError {
832        /// Error while decoding the `version`.
833        Version(VersionDecoderError),
834        /// Error while decoding the `prev_blockhash`.
835        PrevBlockhash(BlockHashDecoderError),
836        /// Error while decoding the `merkle_root`.
837        MerkleRoot(TxMerkleNodeDecoderError),
838        /// Error while decoding the `time`.
839        Time(BlockTimeDecoderError),
840        /// Error while decoding the `bits`.
841        Bits(CompactTargetDecoderError),
842        /// Error while decoding the `nonce`.
843        Nonce(encoding::UnexpectedEofError),
844    }
845
846    impl From<Infallible> for HeaderDecoderError {
847        fn from(never: Infallible) -> Self { match never {} }
848    }
849
850    impl fmt::Display for HeaderDecoderError {
851        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
852            match *self {
853                Self::Version(ref e) => write_err!(f, "header decoder error"; e),
854                Self::PrevBlockhash(ref e) => write_err!(f, "header decoder error"; e),
855                Self::MerkleRoot(ref e) => write_err!(f, "header decoder error"; e),
856                Self::Time(ref e) => write_err!(f, "header decoder error"; e),
857                Self::Bits(ref e) => write_err!(f, "header decoder error"; e),
858                Self::Nonce(ref e) => write_err!(f, "header decoder error"; e),
859            }
860        }
861    }
862
863    #[cfg(feature = "std")]
864    impl std::error::Error for HeaderDecoderError {
865        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
866            match *self {
867                Self::Version(ref e) => Some(e),
868                Self::PrevBlockhash(ref e) => Some(e),
869                Self::MerkleRoot(ref e) => Some(e),
870                Self::Time(ref e) => Some(e),
871                Self::Bits(ref e) => Some(e),
872                Self::Nonce(ref e) => Some(e),
873            }
874        }
875    }
876
877    /// An error consensus decoding a `Version`.
878    #[derive(Debug, Clone, PartialEq, Eq)]
879    pub struct VersionDecoderError(pub(super) encoding::UnexpectedEofError);
880
881    impl From<Infallible> for VersionDecoderError {
882        fn from(never: Infallible) -> Self { match never {} }
883    }
884
885    impl fmt::Display for VersionDecoderError {
886        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
887            write_err!(f, "version decoder error"; self.0)
888        }
889    }
890
891    #[cfg(feature = "std")]
892    impl std::error::Error for VersionDecoderError {
893        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
894    }
895}
896
897#[cfg(feature = "arbitrary")]
898#[cfg(feature = "alloc")]
899impl<'a> Arbitrary<'a> for Block {
900    fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
901        let header = Header::arbitrary(u)?;
902        let transactions = Vec::<Transaction>::arbitrary(u)?;
903        Ok(Self::new_unchecked(header, transactions))
904    }
905}
906
907#[cfg(feature = "arbitrary")]
908impl<'a> Arbitrary<'a> for Header {
909    fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
910        Ok(Self {
911            version: Version::arbitrary(u)?,
912            prev_blockhash: BlockHash::from_byte_array(u.arbitrary()?),
913            merkle_root: TxMerkleNode::from_byte_array(u.arbitrary()?),
914            time: u.arbitrary()?,
915            bits: CompactTarget::from_consensus(u.arbitrary()?),
916            nonce: u.arbitrary()?,
917        })
918    }
919}
920
921#[cfg(feature = "arbitrary")]
922impl<'a> Arbitrary<'a> for Version {
923    fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
924        // Equally weight known versions and arbitrary versions
925        let choice = u.int_in_range(0..=3)?;
926        match choice {
927            0 => Ok(Self::ONE),
928            1 => Ok(Self::TWO),
929            2 => Ok(Self::NO_SOFT_FORK_SIGNALLING),
930            _ => Ok(Self::from_consensus(u.arbitrary()?)),
931        }
932    }
933}
934
935#[cfg(test)]
936mod tests {
937    #[cfg(feature = "alloc")]
938    use alloc::string::ToString;
939    #[cfg(feature = "alloc")]
940    use alloc::{format, vec};
941    #[cfg(feature = "alloc")]
942    #[cfg(feature = "hex")]
943    use core::str::FromStr as _;
944
945    #[cfg(feature = "alloc")]
946    use encoding::Decode as _;
947    use encoding::{check_encode, Decoder as _};
948    #[cfg(feature = "hex")]
949    use hex::hex;
950    #[cfg(feature = "alloc")]
951    #[cfg(feature = "hex")]
952    #[cfg(feature = "serde")]
953    use serde::{Deserialize, Serialize};
954
955    use super::*;
956
957    fn dummy_header() -> Header {
958        Header {
959            version: Version::ONE,
960            prev_blockhash: BlockHash::from_byte_array([0x99; 32]),
961            merkle_root: TxMerkleNode::from_byte_array([0x77; 32]),
962            time: BlockTime::from(2),
963            bits: CompactTarget::from_consensus(3),
964            nonce: 4,
965        }
966    }
967
968    #[test]
969    fn version_is_not_signalling_with_invalid_bit() {
970        let arbitrary_version = Version::from_consensus(1_234_567_890);
971        // The max bit number to signal is 28.
972        assert!(!Version::is_signalling_soft_fork(arbitrary_version, 29));
973    }
974
975    #[test]
976    fn version_is_not_signalling_when_use_version_bit_not_set() {
977        let version = Version::from_consensus(0b0100_0000_0000_0000_0000_0000_0000_0000);
978        // Top three bits must be 001 to signal.
979        assert!(!Version::is_signalling_soft_fork(version, 1));
980    }
981
982    #[test]
983    fn version_is_signalling() {
984        let version = Version::from_consensus(0b0010_0000_0000_0000_0000_0000_0000_0010);
985        assert!(Version::is_signalling_soft_fork(version, 1));
986        let version = Version::from_consensus(0b0011_0000_0000_0000_0000_0000_0000_0000);
987        assert!(Version::is_signalling_soft_fork(version, 28));
988    }
989
990    #[test]
991    fn version_is_not_signalling() {
992        let version = Version::from_consensus(0b0010_0000_0000_0000_0000_0000_0000_0010);
993        assert!(!Version::is_signalling_soft_fork(version, 0));
994    }
995
996    #[test]
997    fn soft_fork_signalling() {
998        for i in 0..31 {
999            let version_int = (0x2000_0000u32 ^ (1 << i)) as i32;
1000            let version = Version::from_consensus(version_int);
1001            if i < 29 {
1002                assert!(version.is_signalling_soft_fork(i));
1003            } else {
1004                assert!(!version.is_signalling_soft_fork(i));
1005            }
1006        }
1007
1008        let segwit_signal = Version::from_consensus(0x2000_0000 ^ (1 << 1));
1009        assert!(!segwit_signal.is_signalling_soft_fork(0));
1010        assert!(segwit_signal.is_signalling_soft_fork(1));
1011        assert!(!segwit_signal.is_signalling_soft_fork(2));
1012    }
1013
1014    #[test]
1015    fn version_to_consensus() {
1016        let version = Version::from_consensus(1_234_567_890);
1017        assert_eq!(version.to_consensus(), 1_234_567_890);
1018    }
1019
1020    #[test]
1021    fn version_default() {
1022        let version = Version::default();
1023        assert_eq!(version.to_consensus(), Version::NO_SOFT_FORK_SIGNALLING.to_consensus());
1024    }
1025
1026    #[test]
1027    #[cfg(feature = "alloc")]
1028    fn version_display() {
1029        let version = Version(75);
1030        assert_eq!(format!("{}", version), "75");
1031        assert_eq!(format!("{:x}", version), "4b");
1032        assert_eq!(format!("{:#x}", version), "0x4b");
1033        assert_eq!(format!("{:X}", version), "4B");
1034        assert_eq!(format!("{:#X}", version), "0x4B");
1035        assert_eq!(format!("{:o}", version), "113");
1036        assert_eq!(format!("{:#o}", version), "0o113");
1037        assert_eq!(format!("{:b}", version), "1001011");
1038        assert_eq!(format!("{:#b}", version), "0b1001011");
1039    }
1040
1041    // Check that the size of the header consensus serialization matches the const SIZE value
1042    #[test]
1043    fn header_size() {
1044        let header = dummy_header();
1045
1046        // Calculate the size of the block header in bytes from the sum of the serialized lengths
1047        // its fields: version, prev_blockhash, merkle_root, time, bits, nonce.
1048        let header_size = header.version.to_consensus().to_le_bytes().len()
1049            + header.prev_blockhash.as_byte_array().len()
1050            + header.merkle_root.as_byte_array().len()
1051            + header.time.to_u32().to_le_bytes().len()
1052            + header.bits.to_consensus().to_le_bytes().len()
1053            + header.nonce.to_le_bytes().len();
1054
1055        assert_eq!(header_size, Header::SIZE);
1056    }
1057
1058    #[test]
1059    #[cfg(feature = "alloc")]
1060    fn block_new_unchecked() {
1061        let header = dummy_header();
1062        let transactions = vec![];
1063        let block = Block::new_unchecked(header, transactions.clone());
1064        assert_eq!(block.header, header);
1065        assert_eq!(block.transactions, transactions);
1066    }
1067
1068    #[test]
1069    #[cfg(feature = "alloc")]
1070    fn block_assume_checked() {
1071        let header = dummy_header();
1072        let transactions = vec![];
1073        let block = Block::new_unchecked(header, transactions.clone());
1074        let witness_root = Some(WitnessMerkleNode::from_byte_array([0x88; 32]));
1075        let checked_block = block.assume_checked(witness_root);
1076        assert_eq!(checked_block.header(), &header);
1077        assert_eq!(checked_block.transactions(), &transactions);
1078        assert_eq!(checked_block.cached_witness_root(), witness_root);
1079    }
1080
1081    #[test]
1082    #[cfg(feature = "alloc")]
1083    fn block_into_parts() {
1084        let header = dummy_header();
1085        let transactions = vec![];
1086        let block = Block::new_unchecked(header, transactions.clone());
1087        let (block_header, block_transactions) = block.into_parts();
1088        assert_eq!(block_header, header);
1089        assert_eq!(block_transactions, transactions);
1090    }
1091
1092    #[test]
1093    #[cfg(feature = "alloc")]
1094    fn block_as_parts() {
1095        let header = dummy_header();
1096        let transactions = vec![];
1097        let block = Block::new_unchecked(header, transactions.clone());
1098        let (block_header, block_transactions) = block.as_parts();
1099        assert_eq!(block_header, &header);
1100        assert_eq!(block_transactions, &transactions);
1101    }
1102
1103    #[test]
1104    #[cfg(feature = "alloc")]
1105    fn block_cached_witness_root() {
1106        let header = dummy_header();
1107        let transactions = vec![];
1108        let block = Block::new_unchecked(header, transactions);
1109        let witness_root = Some(WitnessMerkleNode::from_byte_array([0x88; 32]));
1110        let checked_block = block.assume_checked(witness_root);
1111        assert_eq!(checked_block.cached_witness_root(), witness_root);
1112    }
1113
1114    #[test]
1115    #[cfg(feature = "alloc")]
1116    fn block_validation_no_transactions() {
1117        let header = dummy_header();
1118        let transactions = Vec::new(); // Empty transactions
1119
1120        let block = Block::new_unchecked(header, transactions);
1121        let err = block.validate().unwrap_err();
1122        assert_eq!(err, InvalidBlockError::NoTransactions);
1123    }
1124
1125    #[test]
1126    #[cfg(feature = "alloc")]
1127    fn block_validation_invalid_coinbase() {
1128        let header = dummy_header();
1129
1130        // Create a non-coinbase transaction (has a real previous output, not all zeros)
1131        let non_coinbase_tx = Transaction {
1132            version: crate::transaction::Version::TWO,
1133            lock_time: crate::absolute::LockTime::ZERO,
1134            inputs: vec![crate::TxIn {
1135                previous_output: crate::OutPoint {
1136                    txid: crate::Txid::from_byte_array([1; 32]), // Not all zeros
1137                    vout: 0,
1138                },
1139                script_sig: crate::ScriptSigBuf::new(),
1140                sequence: units::Sequence::ENABLE_LOCKTIME_AND_RBF,
1141                witness: crate::Witness::new(),
1142            }],
1143            outputs: vec![crate::TxOut {
1144                amount: units::Amount::ONE_BTC,
1145                script_pubkey: crate::ScriptPubKeyBuf::new(),
1146            }],
1147        };
1148
1149        let transactions = vec![non_coinbase_tx];
1150        let block = Block::new_unchecked(header, transactions);
1151
1152        let err = block.validate().unwrap_err();
1153        assert_eq!(err, InvalidBlockError::InvalidCoinbase);
1154    }
1155
1156    #[test]
1157    #[cfg(feature = "alloc")]
1158    fn block_decoder_read_limit() {
1159        let mut coinbase_in = crate::TxIn::EMPTY_COINBASE;
1160        coinbase_in.script_sig = crate::ScriptSigBuf::from_bytes(vec![0u8; 2]);
1161
1162        let block = Block::new_unchecked(
1163            dummy_header(),
1164            vec![Transaction {
1165                version: crate::transaction::Version::ONE,
1166                lock_time: crate::absolute::LockTime::ZERO,
1167                inputs: vec![coinbase_in],
1168                outputs: vec![crate::TxOut {
1169                    amount: units::Amount::MIN,
1170                    script_pubkey: crate::ScriptPubKeyBuf::new(),
1171                }],
1172            }],
1173        );
1174
1175        let bytes = encoding::encode_to_vec(&block);
1176        let mut view = bytes.as_slice();
1177
1178        let mut decoder = Block::decoder();
1179        assert!(decoder.read_limit() > 0);
1180        let status = decoder.push_bytes(&mut view).unwrap();
1181        assert!(status.is_ready());
1182        assert_eq!(decoder.read_limit(), 0);
1183        assert_eq!(decoder.end().unwrap(), block);
1184    }
1185
1186    #[test]
1187    #[cfg(feature = "alloc")]
1188    fn block_decoder_new() {
1189        let decoder = BlockDecoder::new();
1190        assert!(decoder.read_limit() > 0);
1191    }
1192
1193    #[test]
1194    #[cfg(feature = "alloc")]
1195    fn block_decoder_default() {
1196        let decoder = BlockDecoder::default();
1197        assert!(decoder.read_limit() > 0);
1198    }
1199
1200    #[test]
1201    #[cfg(feature = "alloc")]
1202    fn header_decoder_read_limit() {
1203        let header = dummy_header();
1204        let bytes = encoding::encode_to_vec(&header);
1205        let mut view = bytes.as_slice();
1206
1207        let mut decoder = Header::decoder();
1208        assert!(decoder.read_limit() > 0);
1209        let status = decoder.push_bytes(&mut view).unwrap();
1210        assert!(status.is_ready());
1211        assert_eq!(decoder.read_limit(), 0);
1212        assert_eq!(decoder.end().unwrap(), header);
1213    }
1214
1215    #[test]
1216    fn header_decoder_new() {
1217        let decoder = HeaderDecoder::new();
1218        assert!(decoder.read_limit() > 0);
1219    }
1220
1221    #[test]
1222    fn header_decoder_default() {
1223        let decoder = HeaderDecoder::default();
1224        assert!(decoder.read_limit() > 0);
1225    }
1226
1227    #[test]
1228    #[cfg(feature = "alloc")]
1229    fn block_check_witness_commitment_optional() {
1230        // Valid block with optional witness commitment
1231        let mut header = dummy_header();
1232        header.merkle_root = TxMerkleNode::from_byte_array([0u8; 32]);
1233        let coinbase = Transaction {
1234            version: crate::transaction::Version::ONE,
1235            lock_time: crate::absolute::LockTime::ZERO,
1236            inputs: vec![crate::TxIn::EMPTY_COINBASE],
1237            outputs: vec![],
1238        };
1239
1240        let transactions = vec![coinbase];
1241        let block = Block::new_unchecked(header, transactions);
1242
1243        let result = block.check_witness_commitment();
1244        assert_eq!(result, (true, None));
1245    }
1246
1247    #[test]
1248    #[cfg(feature = "alloc")]
1249    fn block_rejects_empty_coinbase_witness_commitment() {
1250        let mut script = Vec::from(WITNESS_COMMITMENT_MAGIC);
1251        script.extend_from_slice(&[0; 32]);
1252
1253        let coinbase = Transaction {
1254            version: crate::transaction::Version::ONE,
1255            lock_time: crate::absolute::LockTime::ZERO,
1256            inputs: vec![crate::TxIn::EMPTY_COINBASE],
1257            outputs: vec![crate::TxOut {
1258                amount: units::Amount::ZERO,
1259                script_pubkey: crate::script::ScriptBuf::from_bytes(script),
1260            }],
1261        };
1262
1263        let transactions = vec![coinbase];
1264        let mut header = dummy_header();
1265        header.merkle_root = compute_merkle_root(&transactions).unwrap();
1266
1267        let block = Block::new_unchecked(header, transactions);
1268        assert_eq!(block.check_witness_commitment(), (false, None));
1269        assert!(matches!(block.validate(), Err(InvalidBlockError::InvalidWitnessCommitment)));
1270    }
1271
1272    #[test]
1273    #[cfg(feature = "alloc")]
1274    fn block_block_hash() {
1275        let header = dummy_header();
1276        let transactions = vec![];
1277        let block = Block::new_unchecked(header, transactions);
1278        assert_eq!(block.block_hash(), header.block_hash());
1279    }
1280
1281    #[test]
1282    fn block_hash_from_header() {
1283        let header = dummy_header();
1284        let block_hash = header.block_hash();
1285        assert_eq!(block_hash, BlockHash::from(header));
1286    }
1287
1288    #[test]
1289    fn block_hash_from_header_ref() {
1290        let header = dummy_header();
1291        let block_hash: BlockHash = BlockHash::from(&header);
1292        assert_eq!(block_hash, header.block_hash());
1293    }
1294
1295    #[test]
1296    #[cfg(feature = "alloc")]
1297    fn block_hash_from_block() {
1298        let header = dummy_header();
1299        let transactions = vec![];
1300        let block = Block::new_unchecked(header, transactions);
1301        let block_hash: BlockHash = BlockHash::from(block);
1302        assert_eq!(block_hash, header.block_hash());
1303    }
1304
1305    #[test]
1306    #[cfg(feature = "alloc")]
1307    fn block_hash_from_block_ref() {
1308        let header = dummy_header();
1309        let transactions = vec![];
1310        let block = Block::new_unchecked(header, transactions);
1311        let block_hash: BlockHash = BlockHash::from(&block);
1312        assert_eq!(block_hash, header.block_hash());
1313    }
1314
1315    #[test]
1316    #[cfg(feature = "alloc")]
1317    fn header_debug() {
1318        let header = dummy_header();
1319        let expected = format!(
1320            "Header {{ block_hash: {:?}, version: {:?}, prev_blockhash: {:?}, merkle_root: {:?}, time: {:?}, bits: {:?}, nonce: {:?} }}",
1321            header.block_hash(),
1322            header.version,
1323            header.prev_blockhash,
1324            header.merkle_root,
1325            header.time,
1326            header.bits,
1327            header.nonce
1328        );
1329        assert_eq!(format!("{:?}", header), expected);
1330    }
1331
1332    #[test]
1333    #[cfg(feature = "hex")]
1334    #[cfg(feature = "alloc")]
1335    fn header_display() {
1336        let seconds: u32 = 1_653_195_600; // Arbitrary timestamp: May 22nd, 5am UTC.
1337
1338        let header = Header {
1339            version: Version::TWO,
1340            prev_blockhash: BlockHash::from_byte_array([0xab; 32]),
1341            merkle_root: TxMerkleNode::from_byte_array([0xcd; 32]),
1342            time: BlockTime::from(seconds),
1343            bits: CompactTarget::from_consensus(0xbeef),
1344            nonce: 0xcafe,
1345        };
1346
1347        let want = concat!(
1348            "02000000",                                                         // version
1349            "abababababababababababababababababababababababababababababababab", // prev_blockhash
1350            "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", // merkle_root
1351            "50c38962",                                                         // time
1352            "efbe0000",                                                         // bits
1353            "feca0000",                                                         // nonce
1354        );
1355        assert_eq!(want.len(), 160);
1356        assert_eq!(format!("{}", header), want);
1357
1358        // Check how formatting options are handled.
1359        let want = format!("{:.20}", want);
1360        let got = format!("{:.20}", header);
1361        assert_eq!(got, want);
1362
1363        let want = format!("{:.0}", want);
1364        let got = format!("{:.0}", header);
1365        assert_eq!(got, want);
1366    }
1367
1368    #[test]
1369    #[cfg(feature = "hex")]
1370    #[cfg(feature = "alloc")]
1371    fn header_hex() {
1372        let header = dummy_header();
1373
1374        let lower_hex = concat!(
1375            "01000000",                                                         // version
1376            "9999999999999999999999999999999999999999999999999999999999999999", // prev_blockhash
1377            "7777777777777777777777777777777777777777777777777777777777777777", // merkle_root
1378            "02000000",                                                         // time
1379            "03000000",                                                         // bits
1380            "04000000",                                                         // nonce
1381        );
1382
1383        // All of these should yield a lowercase hex
1384        assert_eq!(lower_hex, format!("{:x}", header));
1385        assert_eq!(lower_hex, format!("{}", header));
1386
1387        // And these should yield uppercase hex
1388        let upper_hex = lower_hex.to_ascii_uppercase();
1389        assert_eq!(upper_hex, format!("{:X}", header));
1390
1391        // Check padding (right, left, center, custom char)
1392        assert_eq!(format!("{:>164}", lower_hex), format!("{:>164x}", header));
1393        assert_eq!(format!("{:<164}", lower_hex), format!("{:<164x}", header));
1394        assert_eq!(format!("{:^164}", lower_hex), format!("{:^164x}", header));
1395        assert_eq!(format!("{:_>164}", lower_hex), format!("{:_>164x}", header));
1396
1397        // Alt forms
1398        let lower_hex_alt = format!("0x{}", lower_hex);
1399        assert_eq!(lower_hex_alt, format!("{:#x}", header));
1400        assert_eq!(format!("0X{}", upper_hex), format!("{:#X}", header));
1401
1402        // Alternate + padding
1403        assert_eq!(format!("{:>166}", lower_hex_alt), format!("{:>#166x}", header));
1404        assert_eq!(format!("{:<166}", lower_hex_alt), format!("{:<#166x}", header));
1405        assert_eq!(format!("{:^166}", lower_hex_alt), format!("{:^#166x}", header));
1406
1407        // Alt + truncate
1408        assert_eq!(format!("{:>.20}", lower_hex_alt), format!("{:>#.20x}", header));
1409        assert_eq!(format!("{:<.20}", lower_hex_alt), format!("{:<#.20x}", header));
1410        assert_eq!(format!("{:^.20}", lower_hex_alt), format!("{:^#.20x}", header));
1411    }
1412
1413    #[test]
1414    #[cfg(feature = "hex")]
1415    #[cfg(feature = "alloc")]
1416    fn header_from_hex_str_round_trip() {
1417        // Create a header and convert it to a hex string
1418        let header = dummy_header();
1419
1420        let lower_hex_header = format!("{:x}", header);
1421        let upper_hex_header = format!("{:X}", header);
1422
1423        // Parse the hex strings back into headers
1424        let parsed_lower = Header::from_str(&lower_hex_header).unwrap();
1425        let parsed_upper = Header::from_str(&upper_hex_header).unwrap();
1426
1427        // The parsed header should match the originals
1428        assert_eq!(header, parsed_lower);
1429        assert_eq!(header, parsed_upper);
1430    }
1431
1432    #[cfg(feature = "alloc")]
1433    fn dummy_block() -> Block {
1434        let header = Header {
1435            version: Version::ONE,
1436            #[rustfmt::skip]
1437            prev_blockhash: BlockHash::from_byte_array([
1438                0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA,
1439                0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA,
1440                0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA,
1441                0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA, 0xDC, 0xBA,
1442            ]),
1443            #[rustfmt::skip]
1444            merkle_root: TxMerkleNode::from_byte_array([
1445                0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD,
1446                0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD,
1447                0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD,
1448                0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD, 0xAB, 0xCD,
1449            ]),
1450            time: BlockTime::from(1_742_979_600), // 26 Mar 2025 9:00 UTC
1451            bits: CompactTarget::from_consensus(12_345_678),
1452            nonce: 1024,
1453        };
1454
1455        let block: u32 = 741_521;
1456        let transactions = vec![Transaction {
1457            version: crate::transaction::Version::ONE,
1458            lock_time: units::absolute::LockTime::from_height(block).unwrap(),
1459            inputs: vec![crate::transaction::TxIn {
1460                previous_output: crate::transaction::OutPoint::COINBASE_PREVOUT,
1461                // Coinbase scriptSig must be 2-100 bytes
1462                script_sig: crate::script::ScriptSigBuf::from_bytes(vec![0x51, 0x51]),
1463                sequence: crate::sequence::Sequence::MAX,
1464                witness: crate::witness::Witness::new(),
1465            }],
1466            outputs: vec![crate::transaction::TxOut {
1467                amount: units::Amount::ONE_SAT,
1468                script_pubkey: crate::script::ScriptPubKeyBuf::new(),
1469            }],
1470        }];
1471        Block::new_unchecked(header, transactions)
1472    }
1473
1474    #[test]
1475    #[cfg(feature = "hex")]
1476    #[cfg(feature = "alloc")]
1477    fn block_hex() {
1478        let header = dummy_header();
1479        let transactions = vec![Transaction {
1480            version: crate::transaction::Version::ONE,
1481            lock_time: crate::locktime::absolute::LockTime::ZERO,
1482            inputs: vec![],
1483            outputs: vec![],
1484        }];
1485        let block = Block::new_unchecked(header, transactions);
1486
1487        // Transaction with no inputs uses segwit serialization:
1488        // version (4) + marker (1) + flag (1) + input_count (1) + output_count (1) + lock_time (4)
1489        let want = "010000009999999999999999999999999999999999999999999999999999999999999999777777777777777777777777777777777777777777777777777777777777777702000000030000000400000001010000000001000000000000";
1490
1491        assert_eq!(format!("{}", block), want);
1492        assert_eq!(format!("{:x}", block), want);
1493        assert_eq!(format!("0x{want}"), format!("{:#x}", block));
1494        assert_eq!(format!("0X{}", want.to_ascii_uppercase()), format!("{:#X}", block));
1495        assert_eq!(format!("{:>166}", format!("0x{want}")), format!("{:>#166x}", block));
1496        assert_eq!(format!("{:.20}", want), format!("{:.20x}", block));
1497
1498        // Note this is pointless because the hex does not have letters in it, only numbers.
1499        let want =
1500            want.chars().map(|chr| chr.to_ascii_uppercase()).collect::<alloc::string::String>();
1501        assert_eq!(want, format!("{:X}", block));
1502    }
1503
1504    #[test]
1505    #[cfg(feature = "hex")]
1506    #[cfg(feature = "alloc")]
1507    fn block_from_hex_str_round_trip() {
1508        let block = dummy_block();
1509
1510        let lower_hex_block = format!("{:x}", block);
1511        let upper_hex_block = format!("{:X}", block);
1512
1513        let parsed_lower = Block::from_str(&lower_hex_block).unwrap();
1514        let parsed_upper = Block::from_str(&upper_hex_block).unwrap();
1515
1516        assert_eq!(parsed_lower, block);
1517        assert_eq!(parsed_upper, block);
1518    }
1519
1520    #[test]
1521    #[cfg(feature = "alloc")]
1522    fn block_decode() {
1523        let original = dummy_block();
1524
1525        let encoded = encoding::encode_to_vec(&original);
1526        let decoded: Block = encoding::decode_from_slice(encoded.as_slice()).unwrap();
1527
1528        assert_eq!(decoded, original);
1529    }
1530
1531    // Test vector provided by tm0 in issue #5023
1532    #[test]
1533    #[cfg(feature = "alloc")]
1534    #[cfg(feature = "hex")]
1535    fn merkle_tree_hash_collision() {
1536        // https://learnmeabitcoin.com/explorer/block/00000000000008a662b4a95a46e4c54cb04852525ac0ef67d1bcac85238416d4
1537        // this block has 7 transactions
1538        const BLOCK_128461_HEX: &str = "01000000166208c96de305f2a304130a1b53727abf8fb77e8a3cfe2a831e000000000000d4fd086755b4d46221362a09a4228bed60d729d22362b87803ff44b72c138ec04a8ce94d2194261af9551f720701000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08042194261a026005ffffffff018076242a01000000434104390e51c3d66d5ee10327395872e33bc232e9e1660225c9f88fa594fdcdcd785d86b1152fb380a63cdf57d8cf2345a55878412a6864656b158704e0b734b3fd9dac000000000100000001f591edc180a889b21a45b6bd5b5e0017d4137dae9695703107ac1e6e878c9f02000000008b483045022100e066df28b29bf18bfcd8da11ea576a6f502f59e7b1d37e2e849ee4648008962b022023be840ec01ffa6860b5577bf0b8546541f40c287eb57b8b421a1396c7aea583014104add16286f51f68cee1b436d0c29a41a59fa8bd224eb6bec34b073512303c70fc3d630cb4952416ef02340c56bee2eef294659b4023ea8a3d90a297bdb54321f9ffffffff02508470b5000000001976a91472579bbeaeca0802fde07ce88f946b64da63989388ac40aeeb02000000001976a914d2a7410246b5ece345aa821af89bff0b6fa3bcaa88ac0000000001000000016197cb143d4cef51389076fdee3f62c294b65bc9aff217a6c71b9dd987e22754000000008c493046022100bf174e942e4619f4e470b5d8b1c0c8ded9e2f7a6616c073c5ab05cc9d699ede3022100a642fa9d0bcc89523635f9468e4813a120b233a249678de0ebf7ba398a4205f6014104122979c0ac1c3af2aa84b4c1d6a9b3b6fa491827f1a2ba37c4b58bdecd644438da715497a44b16aedbadbd18cf9765cdb36851284f643ed743c4365798dd314affffffff02c0404384000000001976a91443cd8fbad7421a53f9e899a2c9761259705d465b88acc0f4f50e000000001976a9142f6c963506b0a2c93a09a92171957e9e7e11a7a388ac00000000010000000228a11f953c26d558a8299ad9dc61279d7abc9a4059820b614bf403c05e471c481d0000008b48304502205baff189016e6fee8e0faa9eebdc8f150d2d3815007719ceccabd995607bb0b0022100f4cc49ef0b29561e976bf6f6f7ae135f665b8dd38a67634bb6bbe74c0da9c1f7014104dd5920aedc3f79ace9c8061f3724812f5b218ea81d175dd990071175874d6c79025f9db516ab23975e510645aabc4ee699cc5c24358a403d15a7736a504399f8ffffffff191b06773a7cec0bb30539f185edbf1d139f9756071c6ae395c1c29f3e2484f6010000008c493046022100c7123436476f923cd8dacbe132f5128b529baa194c9aedc570402d8d2d7902ac02210094e6974695265d96d5859ab493df00c90b62a84dcc33a05753aea23b38c249670141041d878bc5438ff439490e71d059e6b687e511336c0aa53e0d129663c91db71cfe20008891f1e4780bf1139ec9c9e81bfd2e3ea9009608a78d96a5a3a5bf7812baffffffff0200093d00000000001976a914fd0d4c3d0963db8358bd01ba6f386d4c5ef2e30288ac0084d717000000001976a914dcb1e8e699eb9f07a1ddfd5d764aa74359ddd93088ac00000000010000000118e2286c42643e6146669b0f5ee35454fe256aac2b1401dbeefd941f2e6d2074000000008b483045022100edec1c5078fed29d808282d62f167eb3f0ea6a6655f3869c12eca9c63d8463c2022031a3ae430be137932059b4a3e3fb7f1e1f2a05065dbc47c3142972de45c76daa01410423162e5ac10ec46c4a142fea3197cc66e614b9f28f014882ebc8271c4ab6022e474ccdc246445dd2479f9de217e8aaf4d770da15aff1078d329c02e0f4de8d77ffffffff02b00ac165000000001976a914f543a7f0dfcd621a05c646810ba94da791ed14c488ac80de8002000000001976a9144763f6309b3aca0bff49ed6365ffbd791b1afc5d88ac0000000001000000014e3632994e6cbcae4122bf9e8de242aa1d7c13bf6d045392fa69fa92353f13cf000000008c493046022100c6879938322e9945dae2404a2b104b534df7fdab5927a30a57a12418d619c3b8022100c53331f402010cbdc8297d7a827154e42263fc2f6cef6e56b85bbc061d5e30810141047e717e70b8c5e928bc2c482662dbe9007113f7a5fb0360da1d2f193add960fed97ab3163e85c02b127829d694ab4a796326918d4f639d0b19345f7558406667dffffffff0270c8b165000000001976a9146c908731300d5c0a4215ba3bb3041b4f313d14f688ac40420f00000000001976a91457b01e2a6bf178a10a0e36cd3e301a41ac58b68b88ac000000000100000001a2e94f26db15d7098104a3616b650cc7490eca961a23111c12c3d94f593ab3bc000000008c493046022100b355076f2c956d7565d44fdf589ebdbdff70abcd806c71845b47d31c3579cbc00221008352a03c5276ba481ae92a2327307ad1ce9b234be7386c105fb914ceb9c63341014104872ee8390f11c8ac309df772362614ff7c99f98e1fd68888c5e8765d630c93ae86fcd33922b17f5da490ea14a9f9002ef4e7fb11166ba399f9794296ca02e401ffffffff02f07d5460000000001976a914ff1da11fbd50b9906e78c694169c19902d2ee20388ac804a5d05000000001976a91444d5774b8277c59a07ed9dce1225e2d24a3faab188ac00000000";
1539        let bytes = hex::decode_to_array::<1948>(BLOCK_128461_HEX).unwrap();
1540        let valid_block: Block<Unchecked> = encoding::decode_from_slice(&bytes).unwrap();
1541        let (header, mut transactions) = valid_block.clone().into_parts();
1542        transactions.push(transactions[6].clone());
1543        let forged_block = Block::new_unchecked(header, transactions);
1544
1545        assert!(valid_block.validate().is_ok());
1546        assert!(forged_block.validate().is_err());
1547    }
1548
1549    #[test]
1550    #[cfg(feature = "alloc")]
1551    fn witness_commitment_from_coinbase_simple() {
1552        // Add witness commitment to the coinbase
1553        let mut pubkey_bytes = [0; 38];
1554        pubkey_bytes[0..6].copy_from_slice(&WITNESS_COMMITMENT_MAGIC);
1555        let witness_commitment =
1556            WitnessCommitment::from_byte_array(pubkey_bytes[6..38].try_into().unwrap());
1557        let commitment_script = crate::script::ScriptBuf::from_bytes(pubkey_bytes.to_vec());
1558
1559        // Create a coinbase transaction with witness commitment
1560        let tx = Transaction {
1561            version: crate::transaction::Version::ONE,
1562            lock_time: crate::absolute::LockTime::ZERO,
1563            inputs: vec![crate::TxIn::EMPTY_COINBASE],
1564            outputs: vec![crate::TxOut {
1565                amount: units::Amount::MIN,
1566                script_pubkey: commitment_script,
1567            }],
1568        };
1569
1570        // Test if the witness commitment is extracted properly
1571        let extracted = witness_commitment_from_coinbase(&tx);
1572        assert_eq!(extracted, Some(witness_commitment));
1573    }
1574
1575    #[test]
1576    #[cfg(feature = "alloc")]
1577    fn witness_commitment_from_non_coinbase_returns_none() {
1578        let tx = Transaction {
1579            version: crate::transaction::Version::ONE,
1580            lock_time: crate::absolute::LockTime::ZERO,
1581            inputs: vec![crate::TxIn {
1582                previous_output: crate::OutPoint {
1583                    txid: crate::Txid::from_byte_array([1; 32]),
1584                    vout: 0,
1585                },
1586                script_sig: crate::ScriptSigBuf::new(),
1587                sequence: units::Sequence::ENABLE_LOCKTIME_AND_RBF,
1588                witness: crate::Witness::new(),
1589            }],
1590            outputs: vec![crate::TxOut {
1591                amount: units::Amount::MIN,
1592                script_pubkey: crate::ScriptPubKeyBuf::new(),
1593            }],
1594        };
1595
1596        assert!(witness_commitment_from_coinbase(&tx).is_none());
1597    }
1598
1599    #[test]
1600    #[cfg(feature = "alloc")]
1601    fn block_check_witness_commitment_empty_script_pubkey() {
1602        let mut txin = crate::TxIn::EMPTY_COINBASE;
1603        let push = [11_u8];
1604        txin.witness.push(push);
1605
1606        let tx = Transaction {
1607            version: crate::transaction::Version::ONE,
1608            lock_time: crate::absolute::LockTime::ZERO,
1609            inputs: vec![txin],
1610            outputs: vec![crate::TxOut {
1611                amount: units::Amount::MIN,
1612                // Empty scriptbuf means there is no witness commitment due to no magic bytes.
1613                script_pubkey: crate::script::ScriptBuf::new(),
1614            }],
1615        };
1616
1617        let block = Block::new_unchecked(dummy_header(), vec![tx]);
1618        let result = block.check_witness_commitment();
1619        assert_eq!(result, (false, None)); // (false, None) since there's no valid witness commitment
1620    }
1621
1622    #[test]
1623    #[cfg(feature = "alloc")]
1624    fn block_check_witness_commitment_non_coinbase() {
1625        let tx = Transaction {
1626            version: crate::transaction::Version::ONE,
1627            lock_time: crate::absolute::LockTime::ZERO,
1628            inputs: vec![crate::TxIn {
1629                previous_output: crate::OutPoint {
1630                    txid: crate::Txid::from_byte_array([1; 32]),
1631                    vout: 0,
1632                },
1633                script_sig: crate::ScriptSigBuf::new(),
1634                sequence: units::Sequence::ENABLE_LOCKTIME_AND_RBF,
1635                witness: crate::Witness::from_slice(&[&[11_u8; 32][..]]),
1636            }],
1637            outputs: vec![crate::TxOut {
1638                amount: units::Amount::MIN,
1639                script_pubkey: crate::ScriptPubKeyBuf::new(),
1640            }],
1641        };
1642
1643        let block = Block::new_unchecked(dummy_header(), vec![tx]);
1644        assert_eq!(block.check_witness_commitment(), (false, None));
1645    }
1646
1647    #[test]
1648    #[cfg(feature = "alloc")]
1649    fn block_check_witness_commitment_no_transactions() {
1650        // Test case of block with no transactions
1651        let empty_block = Block::new_unchecked(dummy_header(), vec![]);
1652        let result = empty_block.check_witness_commitment();
1653        assert_eq!(result, (false, None));
1654    }
1655
1656    #[test]
1657    #[cfg(feature = "alloc")]
1658    #[cfg(feature = "hex")]
1659    fn block_check_witness_commitment_with_witness() {
1660        let mut txin = crate::TxIn::EMPTY_COINBASE;
1661        // Single witness item of 32 bytes.
1662        let witness_bytes: [u8; 32] = [11u8; 32];
1663        txin.witness.push(witness_bytes);
1664
1665        // pubkey bytes must match the magic bytes followed by the hash of the witness bytes.
1666        let script_pubkey_bytes = hex::decode_to_array::<38>(
1667            "6a24aa21a9ed3cde9e0b9f4ad8f9d0fd66d6b9326cd68597c04fa22ab64b8e455f08d2e31ceb",
1668        )
1669        .unwrap();
1670        let tx1 = Transaction {
1671            version: crate::transaction::Version::ONE,
1672            lock_time: crate::absolute::LockTime::ZERO,
1673            inputs: vec![txin],
1674            outputs: vec![crate::TxOut {
1675                amount: units::Amount::MIN,
1676                script_pubkey: crate::script::ScriptBuf::from_bytes(script_pubkey_bytes.to_vec()),
1677            }],
1678        };
1679
1680        let tx2 = Transaction {
1681            version: crate::transaction::Version::ONE,
1682            lock_time: crate::absolute::LockTime::ZERO,
1683            inputs: vec![crate::TxIn::EMPTY_COINBASE],
1684            outputs: vec![crate::TxOut {
1685                amount: units::Amount::MIN,
1686                script_pubkey: crate::script::ScriptBuf::new(),
1687            }],
1688        };
1689
1690        let block = Block::new_unchecked(dummy_header(), vec![tx1, tx2]);
1691        let result = block.check_witness_commitment();
1692
1693        let exp_bytes = hex::decode_to_array::<32>(
1694            "fb848679079938b249a12f14b72d56aeb116df79254e17cdf72b46523bcb49db",
1695        )
1696        .unwrap();
1697        let expected = WitnessMerkleNode::from_byte_array(exp_bytes);
1698        assert_eq!(result, (true, Some(expected)));
1699    }
1700
1701    #[test]
1702    #[cfg(feature = "alloc")]
1703    #[cfg(feature = "hex")]
1704    fn block_check_witness_commitment_invalid_witness() {
1705        let mut txin = crate::TxIn::EMPTY_COINBASE;
1706        let witness_bytes: [u8; 32] = [11u8; 32];
1707        // First witness item is 32 bytes, but there are two witness elements.
1708        txin.witness.push(witness_bytes);
1709        txin.witness.push([12u8]);
1710
1711        let script_pubkey_bytes = hex::decode_to_array::<38>(
1712            "6a24aa21a9ed3cde9e0b9f4ad8f9d0fd66d6b9326cd68597c04fa22ab64b8e455f08d2e31ceb",
1713        )
1714        .unwrap();
1715        let tx1 = Transaction {
1716            version: crate::transaction::Version::ONE,
1717            lock_time: crate::absolute::LockTime::ZERO,
1718            inputs: vec![txin],
1719            outputs: vec![crate::TxOut {
1720                amount: units::Amount::MIN,
1721                script_pubkey: crate::script::ScriptBuf::from_bytes(script_pubkey_bytes.to_vec()),
1722            }],
1723        };
1724
1725        let tx2 = Transaction {
1726            version: crate::transaction::Version::ONE,
1727            lock_time: crate::absolute::LockTime::ZERO,
1728            inputs: vec![crate::TxIn::EMPTY_COINBASE],
1729            outputs: vec![crate::TxOut {
1730                amount: units::Amount::MIN,
1731                script_pubkey: crate::script::ScriptBuf::new(),
1732            }],
1733        };
1734
1735        let mut header = dummy_header();
1736        let transactions = vec![tx1, tx2];
1737        header.merkle_root = compute_merkle_root(&transactions).unwrap();
1738
1739        let block = Block::new_unchecked(header, transactions);
1740        assert_eq!(block.check_witness_commitment(), (false, None));
1741        assert!(matches!(block.validate(), Err(InvalidBlockError::InvalidWitnessCommitment)));
1742    }
1743
1744    #[test]
1745    #[cfg(feature = "alloc")]
1746    #[cfg(feature = "hex")]
1747    fn block_check_witness_commitment_invalid_commitment() {
1748        let mut txin = crate::TxIn::EMPTY_COINBASE;
1749        txin.witness.push([11u8; 32]);
1750
1751        let mut script_pubkey_bytes = hex::decode_to_array::<38>(
1752            "6a24aa21a9ed3cde9e0b9f4ad8f9d0fd66d6b9326cd68597c04fa22ab64b8e455f08d2e31ceb",
1753        )
1754        .unwrap();
1755        script_pubkey_bytes[37] ^= 1;
1756
1757        let tx1 = Transaction {
1758            version: crate::transaction::Version::ONE,
1759            lock_time: crate::absolute::LockTime::ZERO,
1760            inputs: vec![txin],
1761            outputs: vec![crate::TxOut {
1762                amount: units::Amount::MIN,
1763                script_pubkey: crate::script::ScriptBuf::from_bytes(script_pubkey_bytes.to_vec()),
1764            }],
1765        };
1766
1767        let tx2 = Transaction {
1768            version: crate::transaction::Version::ONE,
1769            lock_time: crate::absolute::LockTime::ZERO,
1770            inputs: vec![crate::TxIn::EMPTY_COINBASE],
1771            outputs: vec![crate::TxOut {
1772                amount: units::Amount::MIN,
1773                script_pubkey: crate::script::ScriptBuf::new(),
1774            }],
1775        };
1776
1777        let block = Block::new_unchecked(dummy_header(), vec![tx1, tx2]);
1778        assert_eq!(block.check_witness_commitment(), (false, None));
1779    }
1780
1781    #[test]
1782    fn version_encoder_emits_consensus_bytes() {
1783        let version = Version::from_consensus(123_456_789);
1784
1785        check_encode(&version, &version.to_consensus().to_le_bytes());
1786    }
1787
1788    #[test]
1789    fn version_decoder_end_and_read_limit() {
1790        let mut decoder = VersionDecoder::new();
1791        let bytes_arr = Version::TWO.to_consensus().to_le_bytes();
1792        let mut bytes = bytes_arr.as_slice();
1793
1794        assert!(decoder.read_limit() > 0);
1795
1796        let status = decoder.push_bytes(&mut bytes).unwrap();
1797        assert!(status.is_ready());
1798        assert!(bytes.is_empty());
1799
1800        assert_eq!(decoder.read_limit(), 0);
1801        let decoded = decoder.end().unwrap();
1802        assert_eq!(decoded, Version::TWO);
1803    }
1804
1805    #[test]
1806    fn version_decoder_default_roundtrip() {
1807        let version = Version::from_consensus(123_456_789);
1808        let mut decoder = VersionDecoder::default();
1809        let consensus = version.to_consensus().to_le_bytes();
1810        let mut bytes = consensus.as_slice();
1811        decoder.push_bytes(&mut bytes).unwrap();
1812
1813        assert_eq!(decoder.end().unwrap(), version);
1814    }
1815
1816    #[test]
1817    #[cfg(feature = "alloc")]
1818    fn version_decodable_decoder() {
1819        let decoder = Version::decoder();
1820        assert!(decoder.read_limit() > 0);
1821    }
1822
1823    #[test]
1824    #[cfg(feature = "alloc")]
1825    fn block_decoder_error() {
1826        fn is_first(err: &BlockDecoderError) -> bool {
1827            match err.0 {
1828                encoding::Decoder2Error::First(_) => true,
1829                encoding::Decoder2Error::Second(_) => false,
1830            }
1831        }
1832
1833        fn is_second(err: &BlockDecoderError) -> bool {
1834            match err.0 {
1835                encoding::Decoder2Error::First(_) => false,
1836                encoding::Decoder2Error::Second(_) => true,
1837            }
1838        }
1839
1840        let err_first = Block::decoder().end().unwrap_err();
1841        assert!(is_first(&err_first));
1842        assert!(!is_second(&err_first));
1843        assert!(!err_first.to_string().is_empty());
1844        #[cfg(feature = "std")]
1845        assert!(std::error::Error::source(&err_first).is_some());
1846
1847        // Provide a complete header and a vec length prefix (1 tx) but omit any tx bytes.
1848        // This forces the inner VecDecoder to error when finalizing.
1849        let mut bytes = encoding::encode_to_vec(&dummy_header());
1850        bytes.push(1u8);
1851        let mut view = bytes.as_slice();
1852
1853        let mut decoder = Block::decoder();
1854        assert!(decoder.push_bytes(&mut view).unwrap().needs_more());
1855        assert!(view.is_empty());
1856
1857        let err_second = decoder.end().unwrap_err();
1858        assert!(is_second(&err_second));
1859        assert!(!is_first(&err_second));
1860        assert!(!err_second.to_string().is_empty());
1861        #[cfg(feature = "std")]
1862        assert!(std::error::Error::source(&err_second).is_some());
1863    }
1864
1865    #[test]
1866    #[cfg(feature = "alloc")]
1867    fn header_decoder_error() {
1868        let header_bytes = encoding::encode_to_vec(&dummy_header());
1869        // Number of bytes in the encoding up to the start of each field.
1870        let lengths = [0usize, 4, 36, 68, 72, 76];
1871
1872        for &len in &lengths {
1873            let mut decoder = Header::decoder();
1874            let mut slice = header_bytes[..len].as_ref();
1875            decoder.push_bytes(&mut slice).unwrap();
1876            let err = decoder.end().unwrap_err();
1877            match len {
1878                0 => assert!(matches!(err, HeaderDecoderError::Version(_))),
1879                4 => assert!(matches!(err, HeaderDecoderError::PrevBlockhash(_))),
1880                36 => assert!(matches!(err, HeaderDecoderError::MerkleRoot(_))),
1881                68 => assert!(matches!(err, HeaderDecoderError::Time(_))),
1882                72 => assert!(matches!(err, HeaderDecoderError::Bits(_))),
1883                76 => assert!(matches!(err, HeaderDecoderError::Nonce(_))),
1884                _ => unreachable!(),
1885            }
1886            assert!(!err.to_string().is_empty());
1887            #[cfg(feature = "std")]
1888            assert!(std::error::Error::source(&err).is_some());
1889        }
1890    }
1891
1892    #[test]
1893    #[cfg(feature = "alloc")]
1894    fn invalid_block_error() {
1895        #[cfg(feature = "std")]
1896        use std::error::Error as _;
1897
1898        let variants = [
1899            InvalidBlockError::InvalidMerkleRoot,
1900            InvalidBlockError::InvalidWitnessCommitment,
1901            InvalidBlockError::NoTransactions,
1902            InvalidBlockError::InvalidCoinbase,
1903        ];
1904
1905        for variant in variants {
1906            assert!(!variant.to_string().is_empty());
1907            #[cfg(feature = "std")]
1908            assert!(variant.source().is_none());
1909        }
1910    }
1911
1912    #[test]
1913    #[cfg(feature = "alloc")]
1914    fn version_decoder_error() {
1915        let err = VersionDecoder::new().end().unwrap_err();
1916        assert!(!err.to_string().is_empty());
1917        #[cfg(feature = "std")]
1918        assert!(std::error::Error::source(&err).is_some());
1919    }
1920
1921    #[test]
1922    #[cfg(feature = "alloc")]
1923    #[cfg(feature = "hex")]
1924    fn parse_block_error() {
1925        let err = Block::from_str("00").unwrap_err();
1926        assert!(!err.to_string().is_empty());
1927        #[cfg(feature = "std")]
1928        assert!(std::error::Error::source(&err).is_some());
1929    }
1930
1931    #[test]
1932    #[cfg(feature = "alloc")]
1933    #[cfg(feature = "hex")]
1934    fn parse_header_error() {
1935        let err = Header::from_str("00").unwrap_err();
1936        assert!(!err.to_string().is_empty());
1937        #[cfg(feature = "std")]
1938        assert!(std::error::Error::source(&err).is_some());
1939    }
1940
1941    /// A type that has a `Block` field and a `Header` field.
1942    #[cfg(feature = "alloc")]
1943    #[cfg(feature = "hex")]
1944    #[cfg(feature = "serde")]
1945    #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
1946    struct Adt {
1947        #[serde(with = "encoding::serde_as_consensus")]
1948        header: Header,
1949        #[serde(with = "encoding::serde_as_consensus")]
1950        block: Block,
1951    }
1952
1953    #[test]
1954    #[cfg(feature = "alloc")]
1955    #[cfg(feature = "hex")]
1956    #[cfg(feature = "serde")]
1957    fn can_serde_as_consensus_json() {
1958        let orig = Adt { header: dummy_header(), block: dummy_block() };
1959
1960        let json = serde_json::to_string(&orig).expect("failed to serialize");
1961
1962        let want = "{\"header\":\"0100000099999999999999999999999999999999999999999999999999999999999999997777777777777777777777777777777777777777777777777777777777777777020000000300000004000000\",\"block\":\"01000000dcbadcbadcbadcbadcbadcbadcbadcbadcbadcbadcbadcbadcbadcbadcbadcbaabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd10c2e3674e61bc00000400000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025151ffffffff0101000000000000000091500b00\"}";
1963        assert_eq!(json, want);
1964
1965        let roundtrip: Adt = serde_json::from_str(&json).expect("failed to deserialize");
1966        assert_eq!(roundtrip, orig);
1967    }
1968
1969    #[test]
1970    #[cfg(feature = "alloc")]
1971    #[cfg(feature = "hex")]
1972    #[cfg(feature = "serde")]
1973    fn can_serde_as_consensus_bincode() {
1974        let orig = Adt { header: dummy_header(), block: dummy_block() };
1975
1976        // Bincode is non-human-readable, so it should use bytes
1977        let bytes = bincode::serialize(&orig).expect("failed to serialize");
1978
1979        let roundtrip: Adt = bincode::deserialize(&bytes).expect("failed to deserialize");
1980        assert_eq!(roundtrip, orig);
1981    }
1982
1983    #[test]
1984    #[cfg(feature = "alloc")]
1985    #[cfg(feature = "hex")]
1986    fn block_version() {
1987        let block = hex!("ffffff7f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
1988        let decode: Result<Block<Unchecked>, _> = encoding::decode_from_slice(&block);
1989        assert!(decode.is_ok());
1990
1991        let real_decode = decode.unwrap().assume_checked(None);
1992        assert_eq!(real_decode.header().version, Version::from_consensus(2_147_483_647));
1993
1994        let block2 = hex!("000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
1995        let decode2: Result<Block<Unchecked>, _> = encoding::decode_from_slice(&block2);
1996        assert!(decode2.is_ok());
1997        let real_decode2 = decode2.unwrap().assume_checked(None);
1998        assert_eq!(real_decode2.header().version, Version::from_consensus(-2_147_483_648));
1999    }
2000}