77//! module describes structures and functions needed to describe
88//! these blocks and the blockchain.
99
10+ use core:: convert:: Infallible ;
1011use core:: fmt;
1112#[ cfg( feature = "alloc" ) ]
1213use core:: marker:: PhantomData ;
1314
1415#[ cfg( feature = "arbitrary" ) ]
1516use arbitrary:: { Arbitrary , Unstructured } ;
16- use encoding:: { CompactSizeEncoder , Encodable , Encoder2 , SliceEncoder } ;
17+ use encoding:: Encodable ;
18+ #[ cfg( feature = "alloc" ) ]
19+ use encoding:: { CompactSizeEncoder , Decodable , Decoder , Decoder6 , Encoder2 , SliceEncoder } ;
1720use hashes:: { sha256d, HashEngine as _} ;
21+ use internals:: write_err;
1822
23+ #[ cfg( feature = "alloc" ) ]
24+ use crate :: pow:: { CompactTargetDecoder , CompactTargetDecoderError } ;
1925#[ cfg( feature = "alloc" ) ]
2026use crate :: prelude:: Vec ;
27+ #[ cfg( feature = "alloc" ) ]
28+ use crate :: transaction:: { TxMerkleNodeDecoder , TxMerkleNodeDecoderError } ;
2129use crate :: { BlockTime , CompactTarget , TxMerkleNode } ;
2230#[ cfg( feature = "alloc" ) ]
23- use crate :: { Transaction , WitnessMerkleNode } ;
31+ use crate :: { BlockTimeDecoder , BlockTimeDecoderError , Transaction , WitnessMerkleNode } ;
2432
2533#[ rustfmt:: skip] // Keep public re-exports separate.
2634#[ doc( inline) ]
@@ -30,7 +38,9 @@ pub use units::block::{BlockHeight, BlockHeightInterval, BlockMtp, BlockMtpInter
3038pub use units:: block:: TooBigForRelativeHeightError ;
3139
3240#[ doc( inline) ]
33- pub use crate :: hash_types:: { BlockHash , BlockHashEncoder , WitnessCommitment } ;
41+ pub use crate :: hash_types:: {
42+ BlockHash , BlockHashDecoder , BlockHashDecoderError , BlockHashEncoder , WitnessCommitment ,
43+ } ;
3444
3545/// Marker for whether or not a block has been validated.
3646///
@@ -295,6 +305,139 @@ impl Encodable for Header {
295305 }
296306}
297307
308+ /// The decoder for the [`Header`] type.
309+ #[ cfg( feature = "alloc" ) ]
310+ pub struct HeaderDecoder (
311+ Decoder6 <
312+ VersionDecoder ,
313+ BlockHashDecoder ,
314+ TxMerkleNodeDecoder ,
315+ BlockTimeDecoder ,
316+ CompactTargetDecoder ,
317+ encoding:: ArrayDecoder < 4 > , // Nonce
318+ HeaderDecoderError ,
319+ > ,
320+ ) ;
321+
322+ #[ cfg( feature = "alloc" ) ]
323+ impl Decoder for HeaderDecoder {
324+ type Output = Header ;
325+ type Error = HeaderDecoderError ;
326+
327+ #[ inline]
328+ fn push_bytes ( & mut self , bytes : & mut & [ u8 ] ) -> Result < bool , Self :: Error > {
329+ self . 0 . push_bytes ( bytes)
330+ }
331+
332+ #[ inline]
333+ fn end ( self ) -> Result < Self :: Output , Self :: Error > {
334+ let ( version, prev_blockhash, merkle_root, time, bits, nonce) = self . 0 . end ( ) ?;
335+ let nonce = u32:: from_le_bytes ( nonce) ;
336+ Ok ( Header { version, prev_blockhash, merkle_root, time, bits, nonce } )
337+ }
338+
339+ #[ inline]
340+ fn read_limit ( & self ) -> usize { self . 0 . read_limit ( ) }
341+ }
342+
343+ #[ cfg( feature = "alloc" ) ]
344+ impl Decodable for Header {
345+ type Decoder = HeaderDecoder ;
346+ fn decoder ( ) -> Self :: Decoder {
347+ HeaderDecoder ( Decoder6 :: new (
348+ VersionDecoder :: new ( ) ,
349+ BlockHashDecoder :: new ( ) ,
350+ TxMerkleNodeDecoder :: new ( ) ,
351+ BlockTimeDecoder :: new ( ) ,
352+ CompactTargetDecoder :: new ( ) ,
353+ encoding:: ArrayDecoder :: new ( ) ,
354+ ) )
355+ }
356+ }
357+
358+ /// An error consensus decoding a `Header`.
359+ #[ cfg( feature = "alloc" ) ]
360+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
361+ #[ non_exhaustive]
362+ pub enum HeaderDecoderError {
363+ /// Error while decoding the `version`.
364+ Version ( VersionDecoderError ) ,
365+ /// Error while decoding the `prev_blockhash`.
366+ PrevBlockhash ( BlockHashDecoderError ) ,
367+ /// Error while decoding the `merkle_root`.
368+ MerkleRoot ( TxMerkleNodeDecoderError ) ,
369+ /// Error while decoding the `time`.
370+ Time ( BlockTimeDecoderError ) ,
371+ /// Error while decoding the `bits`.
372+ Bits ( CompactTargetDecoderError ) ,
373+ /// Error while decoding the `nonce`.
374+ Nonce ( encoding:: UnexpectedEofError ) ,
375+ }
376+
377+ #[ cfg( feature = "alloc" ) ]
378+ impl From < Infallible > for HeaderDecoderError {
379+ fn from ( never : Infallible ) -> Self { match never { } }
380+ }
381+
382+ #[ cfg( feature = "alloc" ) ]
383+ impl From < VersionDecoderError > for HeaderDecoderError {
384+ fn from ( e : VersionDecoderError ) -> Self { Self :: Version ( e) }
385+ }
386+
387+ #[ cfg( feature = "alloc" ) ]
388+ impl From < BlockHashDecoderError > for HeaderDecoderError {
389+ fn from ( e : BlockHashDecoderError ) -> Self { Self :: PrevBlockhash ( e) }
390+ }
391+
392+ #[ cfg( feature = "alloc" ) ]
393+ impl From < TxMerkleNodeDecoderError > for HeaderDecoderError {
394+ fn from ( e : TxMerkleNodeDecoderError ) -> Self { Self :: MerkleRoot ( e) }
395+ }
396+
397+ #[ cfg( feature = "alloc" ) ]
398+ impl From < BlockTimeDecoderError > for HeaderDecoderError {
399+ fn from ( e : BlockTimeDecoderError ) -> Self { Self :: Time ( e) }
400+ }
401+
402+ #[ cfg( feature = "alloc" ) ]
403+ impl From < CompactTargetDecoderError > for HeaderDecoderError {
404+ fn from ( e : CompactTargetDecoderError ) -> Self { Self :: Bits ( e) }
405+ }
406+
407+ #[ cfg( feature = "alloc" ) ]
408+ impl From < encoding:: UnexpectedEofError > for HeaderDecoderError {
409+ fn from ( e : encoding:: UnexpectedEofError ) -> Self { Self :: Nonce ( e) }
410+ }
411+
412+ #[ cfg( feature = "alloc" ) ]
413+ impl fmt:: Display for HeaderDecoderError {
414+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
415+ match * self {
416+ Self :: Version ( ref e) => write_err ! ( f, "header decoder error" ; e) ,
417+ Self :: PrevBlockhash ( ref e) => write_err ! ( f, "header decoder error" ; e) ,
418+ Self :: MerkleRoot ( ref e) => write_err ! ( f, "header decoder error" ; e) ,
419+ Self :: Time ( ref e) => write_err ! ( f, "header decoder error" ; e) ,
420+ Self :: Bits ( ref e) => write_err ! ( f, "header decoder error" ; e) ,
421+ Self :: Nonce ( ref e) => write_err ! ( f, "header decoder error" ; e) ,
422+ }
423+ }
424+ }
425+
426+ #[ cfg( feature = "std" ) ]
427+ #[ cfg( feature = "alloc" ) ]
428+ impl std:: error:: Error for HeaderDecoderError {
429+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
430+ match * self {
431+ Self :: Version ( ref e) => Some ( e) ,
432+ Self :: PrevBlockhash ( ref e) => Some ( e) ,
433+ Self :: MerkleRoot ( ref e) => Some ( e) ,
434+ Self :: Time ( ref e) => Some ( e) ,
435+ Self :: Bits ( ref e) => Some ( e) ,
436+ Self :: Nonce ( ref e) => Some ( e) ,
437+ }
438+ }
439+ }
440+
298441impl From < Header > for BlockHash {
299442 #[ inline]
300443 fn from ( header : Header ) -> BlockHash { header. block_hash ( ) }
@@ -391,6 +534,65 @@ impl Encodable for Version {
391534 }
392535}
393536
537+ /// The decoder for the [`Version`] type.
538+ pub struct VersionDecoder ( encoding:: ArrayDecoder < 4 > ) ;
539+
540+ impl VersionDecoder {
541+ /// Constructs a new [`Version`] decoder.
542+ pub fn new ( ) -> Self { Self ( encoding:: ArrayDecoder :: new ( ) ) }
543+ }
544+
545+ impl Default for VersionDecoder {
546+ fn default ( ) -> Self { Self :: new ( ) }
547+ }
548+
549+ impl encoding:: Decoder for VersionDecoder {
550+ type Output = Version ;
551+ type Error = VersionDecoderError ;
552+
553+ #[ inline]
554+ fn push_bytes ( & mut self , bytes : & mut & [ u8 ] ) -> Result < bool , Self :: Error > {
555+ Ok ( self . 0 . push_bytes ( bytes) ?)
556+ }
557+
558+ #[ inline]
559+ fn end ( self ) -> Result < Self :: Output , Self :: Error > {
560+ let n = i32:: from_le_bytes ( self . 0 . end ( ) ?) ;
561+ Ok ( Version :: from_consensus ( n) )
562+ }
563+
564+ #[ inline]
565+ fn read_limit ( & self ) -> usize { self . 0 . read_limit ( ) }
566+ }
567+
568+ impl encoding:: Decodable for Version {
569+ type Decoder = VersionDecoder ;
570+ fn decoder ( ) -> Self :: Decoder { VersionDecoder ( encoding:: ArrayDecoder :: < 4 > :: new ( ) ) }
571+ }
572+
573+ /// An error consensus decoding an `Version`.
574+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
575+ pub struct VersionDecoderError ( encoding:: UnexpectedEofError ) ;
576+
577+ impl From < Infallible > for VersionDecoderError {
578+ fn from ( never : Infallible ) -> Self { match never { } }
579+ }
580+
581+ impl From < encoding:: UnexpectedEofError > for VersionDecoderError {
582+ fn from ( e : encoding:: UnexpectedEofError ) -> Self { Self ( e) }
583+ }
584+
585+ impl fmt:: Display for VersionDecoderError {
586+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
587+ write_err ! ( f, "version decoder error" ; self . 0 )
588+ }
589+ }
590+
591+ #[ cfg( feature = "std" ) ]
592+ impl std:: error:: Error for VersionDecoderError {
593+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > { Some ( & self . 0 ) }
594+ }
595+
394596#[ cfg( feature = "arbitrary" ) ]
395597#[ cfg( feature = "alloc" ) ]
396598impl < ' a > Arbitrary < ' a > for Block {
0 commit comments