@@ -2,6 +2,9 @@ package block
22
33import (
44 "encoding/hex"
5+ "fmt"
6+ "github.com/fxamacker/cbor/v2"
7+ "golang.org/x/crypto/blake2b"
58)
69
710type Blake2b256 [32 ]byte
@@ -15,3 +18,108 @@ type Blake2b224 [28]byte
1518func (b Blake2b224 ) String () string {
1619 return hex .EncodeToString ([]byte (b [:]))
1720}
21+
22+ func NewBlockFromCbor (blockType uint , data []byte ) (interface {}, error ) {
23+ var err error
24+ // Parse outer list to get at header CBOR
25+ var rawBlock []cbor.RawMessage
26+ if err := cbor .Unmarshal (data , & rawBlock ); err != nil {
27+ return nil , err
28+ }
29+ switch blockType {
30+ case BLOCK_TYPE_BYRON_EBB :
31+ var byronEbbBlock ByronEpochBoundaryBlock
32+ if err := cbor .Unmarshal (data , & byronEbbBlock ); err != nil {
33+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
34+ }
35+ // Prepend bytes for CBOR list wrapper
36+ // The block hash is calculated with these extra bytes, so we have to add them to
37+ // get the correct value
38+ byronEbbBlock .Header .id , err = generateBlockHeaderHash (rawBlock [0 ], []byte {0x82 , BLOCK_TYPE_BYRON_EBB })
39+ return & byronEbbBlock , err
40+ case BLOCK_TYPE_BYRON_MAIN :
41+ var byronMainBlock ByronMainBlock
42+ if err := cbor .Unmarshal (data , & byronMainBlock ); err != nil {
43+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
44+ }
45+ // Prepend bytes for CBOR list wrapper
46+ // The block hash is calculated with these extra bytes, so we have to add them to
47+ // get the correct value
48+ byronMainBlock .Header .id , err = generateBlockHeaderHash (rawBlock [0 ], []byte {0x82 , BLOCK_TYPE_BYRON_MAIN })
49+ return & byronMainBlock , err
50+ case BLOCK_TYPE_SHELLEY :
51+ var shelleyBlock ShelleyBlock
52+ if err := cbor .Unmarshal (data , & shelleyBlock ); err != nil {
53+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
54+ }
55+ shelleyBlock .Header .id , err = generateBlockHeaderHash (rawBlock [0 ], nil )
56+ return & shelleyBlock , err
57+ case BLOCK_TYPE_ALLEGRA :
58+ var allegraBlock AllegraBlock
59+ if err := cbor .Unmarshal (data , & allegraBlock ); err != nil {
60+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
61+ }
62+ allegraBlock .Header .id , err = generateBlockHeaderHash (rawBlock [0 ], nil )
63+ return & allegraBlock , err
64+ case BLOCK_TYPE_MARY :
65+ var maryBlock MaryBlock
66+ if err := cbor .Unmarshal (data , & maryBlock ); err != nil {
67+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
68+ }
69+ maryBlock .Header .id , err = generateBlockHeaderHash (rawBlock [0 ], nil )
70+ return & maryBlock , err
71+ case BLOCK_TYPE_ALONZO :
72+ var alonzoBlock AlonzoBlock
73+ if err := cbor .Unmarshal (data , & alonzoBlock ); err != nil {
74+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
75+ }
76+ alonzoBlock .Header .id , err = generateBlockHeaderHash (rawBlock [0 ], nil )
77+ return & alonzoBlock , err
78+ }
79+ return nil , nil
80+ }
81+
82+ func NewBlockHeaderFromCbor (blockType uint , data []byte ) (interface {}, error ) {
83+ var err error
84+ switch blockType {
85+ case BLOCK_TYPE_BYRON_EBB :
86+ var byronEbbBlockHeader ByronEpochBoundaryBlockHeader
87+ if err := cbor .Unmarshal (data , & byronEbbBlockHeader ); err != nil {
88+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
89+ }
90+ // Prepend bytes for CBOR list wrapper
91+ // The block hash is calculated with these extra bytes, so we have to add them to
92+ // get the correct value
93+ byronEbbBlockHeader .id , err = generateBlockHeaderHash (data , []byte {0x82 , BLOCK_TYPE_BYRON_EBB })
94+ return & byronEbbBlockHeader , err
95+ case BLOCK_TYPE_BYRON_MAIN :
96+ var byronMainBlockHeader ByronMainBlockHeader
97+ if err := cbor .Unmarshal (data , & byronMainBlockHeader ); err != nil {
98+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
99+ }
100+ // Prepend bytes for CBOR list wrapper
101+ // The block hash is calculated with these extra bytes, so we have to add them to
102+ // get the correct value
103+ byronMainBlockHeader .id , err = generateBlockHeaderHash (data , []byte {0x82 , BLOCK_TYPE_BYRON_MAIN })
104+ return & byronMainBlockHeader , err
105+ default :
106+ var shelleyBlockHeader ShelleyBlockHeader
107+ if err := cbor .Unmarshal (data , & shelleyBlockHeader ); err != nil {
108+ return nil , fmt .Errorf ("chain-sync: decode error: %s" , err )
109+ }
110+ shelleyBlockHeader .id , err = generateBlockHeaderHash (data , nil )
111+ return & shelleyBlockHeader , err
112+ }
113+ }
114+
115+ func generateBlockHeaderHash (data []byte , prefix []byte ) (string , error ) {
116+ tmpHash , err := blake2b .New256 (nil )
117+ if err != nil {
118+ return "" , err
119+ }
120+ if prefix != nil {
121+ tmpHash .Write (prefix )
122+ }
123+ tmpHash .Write (data )
124+ return hex .EncodeToString (tmpHash .Sum (nil )), nil
125+ }
0 commit comments