github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/bc/types/block_header.go (about) 1 package types 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 "io" 7 "time" 8 9 "github.com/bytom/bytom/encoding/blockchain" 10 "github.com/bytom/bytom/encoding/bufpool" 11 "github.com/bytom/bytom/errors" 12 "github.com/bytom/bytom/protocol/bc" 13 ) 14 15 // BlockHeader defines information about a block and is used in the Bytom 16 type BlockHeader struct { 17 Version uint64 // The version of the block. 18 Height uint64 // The height of the block. 19 PreviousBlockHash bc.Hash // The hash of the previous block. 20 Timestamp uint64 // The time of the block in seconds. 21 BlockWitness 22 SupLinks 23 BlockCommitment 24 } 25 26 // Hash returns complete hash of the block header. 27 func (bh *BlockHeader) Hash() bc.Hash { 28 h, _ := mapBlockHeader(bh) 29 return h 30 } 31 32 // Time returns the time represented by the Timestamp in block header. 33 func (bh *BlockHeader) Time() time.Time { 34 return time.Unix(int64(bh.Timestamp/1000), 0).UTC() 35 } 36 37 // MarshalText fulfills the json.Marshaler interface. This guarantees that 38 // block headers will get deserialized correctly when being parsed from HTTP 39 // requests. 40 func (bh *BlockHeader) MarshalText() ([]byte, error) { 41 buf := bufpool.Get() 42 defer bufpool.Put(buf) 43 44 if _, err := bh.WriteTo(buf); err != nil { 45 return nil, err 46 } 47 48 enc := make([]byte, hex.EncodedLen(buf.Len())) 49 hex.Encode(enc, buf.Bytes()) 50 return enc, nil 51 } 52 53 // UnmarshalText fulfills the encoding.TextUnmarshaler interface. 54 func (bh *BlockHeader) UnmarshalText(text []byte) error { 55 decoded := make([]byte, hex.DecodedLen(len(text))) 56 if _, err := hex.Decode(decoded, text); err != nil { 57 return err 58 } 59 60 serflag, err := bh.readFrom(blockchain.NewReader(decoded)) 61 if err != nil { 62 return err 63 } 64 65 if serflag == SerBlockTransactions { 66 return fmt.Errorf("unsupported serialization flags 0x%02x", serflag) 67 } 68 69 return nil 70 } 71 72 // WriteTo writes the block header to the input io.Writer 73 func (bh *BlockHeader) WriteTo(w io.Writer) (int64, error) { 74 ew := errors.NewWriter(w) 75 if err := bh.writeTo(ew, SerBlockHeader); err != nil { 76 return 0, err 77 } 78 return ew.Written(), ew.Err() 79 } 80 81 func (bh *BlockHeader) readFrom(r *blockchain.Reader) (serflag uint8, err error) { 82 var serflags [1]byte 83 if _, err := io.ReadFull(r, serflags[:]); err != nil { 84 return 0, err 85 } 86 87 serflag = serflags[0] 88 switch serflag { 89 case SerBlockHeader, SerBlockFull: 90 case SerBlockTransactions: 91 return 92 default: 93 return 0, fmt.Errorf("unsupported serialization flags 0x%x", serflags) 94 } 95 96 if bh.Version, err = blockchain.ReadVarint63(r); err != nil { 97 return 0, err 98 } 99 100 if bh.Height, err = blockchain.ReadVarint63(r); err != nil { 101 return 0, err 102 } 103 104 if _, err = bh.PreviousBlockHash.ReadFrom(r); err != nil { 105 return 0, err 106 } 107 108 if bh.Timestamp, err = blockchain.ReadVarint63(r); err != nil { 109 return 0, err 110 } 111 112 if _, err = blockchain.ReadExtensibleString(r, bh.BlockCommitment.readFrom); err != nil { 113 return 0, err 114 } 115 116 if _, err = blockchain.ReadExtensibleString(r, bh.BlockWitness.readFrom); err != nil { 117 return 0, err 118 } 119 120 if _, err = blockchain.ReadExtensibleString(r, bh.SupLinks.readFrom); err != nil { 121 return 0, err 122 } 123 124 return 125 } 126 127 func (bh *BlockHeader) writeTo(w io.Writer, serflags uint8) (err error) { 128 w.Write([]byte{serflags}) 129 if serflags == SerBlockTransactions { 130 return nil 131 } 132 133 if _, err = blockchain.WriteVarint63(w, bh.Version); err != nil { 134 return err 135 } 136 137 if _, err = blockchain.WriteVarint63(w, bh.Height); err != nil { 138 return err 139 } 140 141 if _, err = bh.PreviousBlockHash.WriteTo(w); err != nil { 142 return err 143 } 144 145 if _, err = blockchain.WriteVarint63(w, bh.Timestamp); err != nil { 146 return err 147 } 148 149 if _, err = blockchain.WriteExtensibleString(w, nil, bh.BlockCommitment.writeTo); err != nil { 150 return err 151 } 152 153 if _, err = blockchain.WriteExtensibleString(w, nil, bh.BlockWitness.writeTo); err != nil { 154 return err 155 } 156 157 if _, err = blockchain.WriteExtensibleString(w, nil, bh.SupLinks.writeTo); err != nil { 158 return err 159 } 160 161 return 162 }