github.com/amazechain/amc@v0.1.3/common/block/header.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package block 18 19 import ( 20 "encoding/binary" 21 "encoding/json" 22 "fmt" 23 "github.com/amazechain/amc/utils" 24 "github.com/holiman/uint256" 25 "google.golang.org/protobuf/proto" 26 "sync/atomic" 27 28 "github.com/amazechain/amc/api/protocol/types_pb" 29 "github.com/amazechain/amc/common/hexutil" 30 "github.com/amazechain/amc/common/types" 31 ) 32 33 type BlockNonce [8]byte 34 35 // EncodeNonce converts the given integer to a block nonce. 36 func EncodeNonce(i uint64) BlockNonce { 37 var n BlockNonce 38 binary.BigEndian.PutUint64(n[:], i) 39 return n 40 } 41 42 // Uint64 returns the integer value of a block nonce. 43 func (n BlockNonce) Uint64() uint64 { 44 return binary.BigEndian.Uint64(n[:]) 45 } 46 47 // MarshalText todo copy eth 48 func (n BlockNonce) MarshalText() ([]byte, error) { 49 return hexutil.Bytes(n[:]).MarshalText() 50 } 51 52 // UnmarshalText implements encoding.TextUnmarshaler. 53 func (n *BlockNonce) UnmarshalText(input []byte) error { 54 return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) 55 } 56 57 type Header struct { 58 ParentHash types.Hash `json:"parentHash" gencodec:"required"` 59 Coinbase types.Address `json:"miner"` 60 Root types.Hash `json:"stateRoot" gencodec:"required"` 61 TxHash types.Hash `json:"transactionsRoot" gencodec:"required"` 62 ReceiptHash types.Hash `json:"receiptsRoot" gencodec:"required"` 63 Bloom Bloom `json:"logsBloom" gencodec:"required"` 64 Difficulty *uint256.Int `json:"difficulty" gencodec:"required"` 65 Number *uint256.Int `json:"number" gencodec:"required"` 66 GasLimit uint64 `json:"gasLimit" gencodec:"required"` 67 GasUsed uint64 `json:"gasUsed" gencodec:"required"` 68 Time uint64 `json:"timestamp" gencodec:"required"` 69 MixDigest types.Hash `json:"mixHash"` 70 Nonce BlockNonce `json:"nonce"` 71 Extra []byte `json:"extraData" gencodec:"required"` 72 73 // BaseFee was added by EIP-1559 and is ignored in legacy headers. 74 BaseFee *uint256.Int `json:"baseFeePerGas" rlp:"optional"` 75 76 hash atomic.Value 77 78 Signature types.Signature `json:"signature"` 79 } 80 81 func (h *Header) Number64() *uint256.Int { 82 return h.Number 83 } 84 85 func (h *Header) StateRoot() types.Hash { 86 return h.Root 87 } 88 89 func (h *Header) BaseFee64() *uint256.Int { 90 return h.BaseFee 91 } 92 93 func (h Header) Hash() types.Hash { 94 if hash := h.hash.Load(); hash != nil { 95 return hash.(types.Hash) 96 } 97 98 if h.BaseFee == nil { 99 h.BaseFee = uint256.NewInt(0) 100 } 101 102 if h.Difficulty == nil { 103 h.Difficulty = uint256.NewInt(0) 104 } 105 106 buf, err := json.Marshal(h) 107 if err != nil { 108 return types.Hash{} 109 } 110 111 if h.Number.Uint64() == 0 { 112 //log.Tracef("genesis header json Marshal: %s", string(buf)) 113 } 114 115 hash := types.BytesHash(buf) 116 h.hash.Store(hash) 117 return hash 118 } 119 120 func (h *Header) ToProtoMessage() proto.Message { 121 return &types_pb.Header{ 122 ParentHash: utils.ConvertHashToH256(h.ParentHash), 123 Coinbase: utils.ConvertAddressToH160(h.Coinbase), 124 Root: utils.ConvertHashToH256(h.Root), 125 TxHash: utils.ConvertHashToH256(h.TxHash), 126 ReceiptHash: utils.ConvertHashToH256(h.ReceiptHash), 127 Difficulty: utils.ConvertUint256IntToH256(h.Difficulty), 128 Number: utils.ConvertUint256IntToH256(h.Number), 129 GasLimit: h.GasLimit, 130 GasUsed: h.GasUsed, 131 Time: h.Time, 132 Nonce: h.Nonce.Uint64(), 133 BaseFee: utils.ConvertUint256IntToH256(h.BaseFee), 134 Extra: h.Extra, 135 Signature: utils.ConvertSignatureToH768(h.Signature), 136 Bloom: utils.ConvertBytesToH2048(h.Bloom.Bytes()), 137 MixDigest: utils.ConvertHashToH256(h.MixDigest), 138 } 139 } 140 141 func (h *Header) FromProtoMessage(message proto.Message) error { 142 var ( 143 pbHeader *types_pb.Header 144 ok bool 145 ) 146 147 if pbHeader, ok = message.(*types_pb.Header); !ok { 148 return fmt.Errorf("type conversion failure") 149 } 150 151 h.ParentHash = utils.ConvertH256ToHash(pbHeader.ParentHash) 152 h.Coinbase = utils.ConvertH160toAddress(pbHeader.Coinbase) 153 h.Root = utils.ConvertH256ToHash(pbHeader.Root) 154 h.TxHash = utils.ConvertH256ToHash(pbHeader.TxHash) 155 h.ReceiptHash = utils.ConvertH256ToHash(pbHeader.ReceiptHash) 156 h.Difficulty = utils.ConvertH256ToUint256Int(pbHeader.Difficulty) 157 h.Number = utils.ConvertH256ToUint256Int(pbHeader.Number) 158 h.GasLimit = pbHeader.GasLimit 159 h.GasUsed = pbHeader.GasUsed 160 h.Time = pbHeader.Time 161 h.Nonce = EncodeNonce(pbHeader.Nonce) 162 h.BaseFee = utils.ConvertH256ToUint256Int(pbHeader.BaseFee) 163 h.Extra = pbHeader.Extra 164 h.Signature = utils.ConvertH768ToSignature(pbHeader.Signature) 165 h.Bloom = utils.ConvertH2048ToBloom(pbHeader.Bloom) 166 h.MixDigest = utils.ConvertH256ToHash(pbHeader.MixDigest) 167 return nil 168 } 169 170 func (h *Header) Marshal() ([]byte, error) { 171 pbHeader := h.ToProtoMessage() 172 return proto.Marshal(pbHeader) 173 } 174 175 func (h *Header) Unmarshal(data []byte) error { 176 var pbHeader types_pb.Header 177 if err := proto.Unmarshal(data, &pbHeader); err != nil { 178 return err 179 } 180 if err := h.FromProtoMessage(&pbHeader); err != nil { 181 return err 182 } 183 return nil 184 } 185 186 func CopyHeader(h *Header) *Header { 187 cpy := *h 188 189 if cpy.Difficulty = uint256.NewInt(0); h.Difficulty != nil { 190 cpy.Difficulty.SetBytes(h.Difficulty.Bytes()) 191 } 192 if cpy.Number = uint256.NewInt(0); h.Number != nil { 193 cpy.Number.SetBytes(h.Number.Bytes()) 194 } 195 196 if h.BaseFee != nil { 197 cpy.BaseFee = uint256.NewInt(0).SetBytes(h.BaseFee.Bytes()) 198 } 199 200 if len(h.Extra) > 0 { 201 cpy.Extra = make([]byte, len(h.Extra)) 202 copy(cpy.Extra, h.Extra) 203 } 204 return &cpy 205 } 206 207 func CopyReward(rewards []*Reward) []*Reward { 208 var cpyReward []*Reward 209 210 for _, reward := range rewards { 211 addr, amount := types.Address{}, uint256.Int{} 212 213 addr.SetBytes(reward.Address[:]) 214 cpyReward = append(cpyReward, &Reward{ 215 Address: addr, 216 Amount: amount.SetBytes(reward.Amount.Bytes()), 217 }) 218 } 219 220 return cpyReward 221 }