github.com/klaytn/klaytn@v1.10.2/blockchain/types/block.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from core/types/block.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package types 22 23 import ( 24 "fmt" 25 "io" 26 "math/big" 27 "sort" 28 "sync/atomic" 29 "time" 30 "unsafe" 31 32 "github.com/klaytn/klaytn/common" 33 "github.com/klaytn/klaytn/common/hexutil" 34 "github.com/klaytn/klaytn/crypto/sha3" 35 "github.com/klaytn/klaytn/rlp" 36 ) 37 38 const ( 39 Engine_IBFT int = iota 40 Engine_Clique 41 Engine_Gxhash 42 ) 43 44 var EngineType = Engine_IBFT 45 46 //go:generate gencodec -type Header -field-override headerMarshaling -out gen_header_json.go 47 48 // Header represents a block header in the Klaytn blockchain. 49 type Header struct { 50 ParentHash common.Hash `json:"parentHash" gencodec:"required"` 51 Rewardbase common.Address `json:"reward" gencodec:"required"` 52 Root common.Hash `json:"stateRoot" gencodec:"required"` 53 TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` 54 ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` 55 Bloom Bloom `json:"logsBloom" gencodec:"required"` 56 BlockScore *big.Int `json:"blockScore" gencodec:"required"` 57 Number *big.Int `json:"number" gencodec:"required"` 58 GasUsed uint64 `json:"gasUsed" gencodec:"required"` 59 Time *big.Int `json:"timestamp" gencodec:"required"` 60 // TimeFoS represents a fraction of a second since `Time`. 61 TimeFoS uint8 `json:"timestampFoS" gencodec:"required"` 62 Extra []byte `json:"extraData" gencodec:"required"` 63 Governance []byte `json:"governanceData" gencodec:"required"` 64 Vote []byte `json:"voteData,omitempty"` 65 66 BaseFee *big.Int `json:"baseFeePerGas,omitempty" rlp:"optional"` 67 } 68 69 // field type overrides for gencodec 70 type headerMarshaling struct { 71 BlockScore *hexutil.Big 72 Number *hexutil.Big 73 GasUsed hexutil.Uint64 74 Time *hexutil.Big 75 TimeFoS hexutil.Uint 76 Extra hexutil.Bytes 77 BaseFee *hexutil.Big 78 Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON 79 Governance hexutil.Bytes 80 Vote hexutil.Bytes 81 } 82 83 // Hash returns the block hash of the header, which is simply the keccak256 hash of its 84 // RLP encoding. 85 func (h *Header) Hash() common.Hash { 86 // If the mix digest is equivalent to the predefined Istanbul digest, use Istanbul 87 // specific hash calculation. 88 if EngineType == Engine_IBFT { 89 // Seal is reserved in extra-data. To prove block is signed by the proposer. 90 if istanbulHeader := IstanbulFilteredHeader(h, true); istanbulHeader != nil { 91 return rlpHash(istanbulHeader) 92 } 93 } 94 return rlpHash(h) 95 } 96 97 // HashNoNonce returns the hash which is used as input for the proof-of-work search. 98 func (h *Header) HashNoNonce() common.Hash { 99 return rlpHash([]interface{}{ 100 h.ParentHash, 101 h.Rewardbase, 102 h.Root, 103 h.TxHash, 104 h.ReceiptHash, 105 h.Bloom, 106 h.BlockScore, 107 h.Number, 108 h.GasUsed, 109 h.Time, 110 h.TimeFoS, 111 h.Extra, 112 }) 113 } 114 115 // Size returns the approximate memory used by all internal contents. It is used 116 // to approximate and limit the memory consumption of various caches. 117 func (h *Header) Size() common.StorageSize { 118 return common.StorageSize(unsafe.Sizeof(*h)) + common.StorageSize(len(h.Extra)+(h.BlockScore.BitLen()+h.Number.BitLen()+h.Time.BitLen())/8) 119 } 120 121 func (h *Header) Round() byte { 122 return byte(h.Extra[IstanbulExtraVanity-1]) 123 } 124 125 func rlpHash(x interface{}) (h common.Hash) { 126 hw := sha3.NewKeccak256() 127 rlp.Encode(hw, x) 128 hw.Sum(h[:0]) 129 return h 130 } 131 132 // prefixedRlpHash writes the prefix into the hasher before rlp-encoding the 133 // given interface. It's used for ethereum typed transactions. 134 func prefixedRlpHash(prefix byte, x interface{}) (h common.Hash) { 135 hw := sha3.NewKeccak256() 136 hw.Reset() 137 hw.Write([]byte{prefix}) 138 rlp.Encode(hw, x) 139 hw.Sum(h[:0]) 140 return h 141 } 142 143 // EmptyBody returns true if there is no additional 'body' to complete the header 144 // that is: no transactions. 145 func (h *Header) EmptyBody() bool { 146 return h.TxHash == EmptyRootHash(h.Number) 147 } 148 149 // EmptyReceipts returns true if there are no receipts for this header/block. 150 func (h *Header) EmptyReceipts() bool { 151 return h.ReceiptHash == EmptyRootHash(h.Number) 152 } 153 154 // Body is a simple (mutable, non-safe) data container for storing and moving 155 // a block's data contents (transactions) together. 156 type Body struct { 157 Transactions []*Transaction 158 } 159 160 // Block represents an entire block in the Klaytn blockchain. 161 type Block struct { 162 header *Header 163 transactions Transactions 164 165 // caches 166 hash atomic.Value 167 size atomic.Value 168 169 // Td is used by package blockchain to store the total blockscore 170 // of the chain up to and including the block. 171 td *big.Int 172 173 // These fields are used to track inter-peer block relay. 174 ReceivedAt time.Time 175 ReceivedFrom interface{} 176 } 177 178 type Result struct { 179 Block *Block 180 Round int64 181 } 182 183 // extblock represents external block encoding used for Klaytn protocol, etc. 184 type extblock struct { 185 Header *Header 186 Txs []*Transaction 187 } 188 189 // NewBlock creates a new block. The input data is copied, 190 // changes to header and to the field values will not affect the 191 // block. 192 // 193 // The values of TxHash, ReceiptHash and Bloom in header 194 // are ignored and set to values derived from the given txs and receipts. 195 func NewBlock(header *Header, txs []*Transaction, receipts []*Receipt) *Block { 196 b := &Block{header: CopyHeader(header), td: new(big.Int)} 197 198 // TODO: panic if len(txs) != len(receipts) 199 if len(txs) == 0 { 200 b.header.TxHash = EmptyRootHash(header.Number) 201 } else { 202 b.header.TxHash = DeriveSha(Transactions(txs), header.Number) 203 b.transactions = make(Transactions, len(txs)) 204 copy(b.transactions, txs) 205 } 206 207 if len(receipts) == 0 { 208 b.header.ReceiptHash = EmptyRootHash(header.Number) 209 } else { 210 b.header.ReceiptHash = DeriveSha(Receipts(receipts), header.Number) 211 b.header.Bloom = CreateBloom(receipts) 212 } 213 214 return b 215 } 216 217 // NewBlockWithHeader creates a block with the given header data. The 218 // header data is copied, changes to header and to the field values 219 // will not affect the block. 220 func NewBlockWithHeader(header *Header) *Block { 221 return &Block{header: CopyHeader(header)} 222 } 223 224 // CopyHeader creates a deep copy of a block header to prevent side effects from 225 // modifying a header variable. 226 func CopyHeader(h *Header) *Header { 227 cpy := *h 228 if cpy.Time = new(big.Int); h.Time != nil { 229 cpy.Time.Set(h.Time) 230 } 231 if cpy.BlockScore = new(big.Int); h.BlockScore != nil { 232 cpy.BlockScore.Set(h.BlockScore) 233 } 234 if cpy.Number = new(big.Int); h.Number != nil { 235 cpy.Number.Set(h.Number) 236 } 237 if h.BaseFee != nil { 238 // This field exists after magma hardfork 239 cpy.BaseFee = new(big.Int).Set(h.BaseFee) 240 } 241 if len(h.Extra) > 0 { 242 cpy.Extra = make([]byte, len(h.Extra)) 243 copy(cpy.Extra, h.Extra) 244 } 245 if len(h.Governance) > 0 { 246 cpy.Governance = make([]byte, len(h.Governance)) 247 copy(cpy.Governance, h.Governance) 248 } 249 if len(h.Vote) > 0 { 250 cpy.Vote = make([]byte, len(h.Vote)) 251 copy(cpy.Vote, h.Vote) 252 } 253 return &cpy 254 } 255 256 // DecodeRLP decodes the Klaytn 257 func (b *Block) DecodeRLP(s *rlp.Stream) error { 258 var eb extblock 259 _, size, _ := s.Kind() 260 if err := s.Decode(&eb); err != nil { 261 return err 262 } 263 b.header, b.transactions = eb.Header, eb.Txs 264 b.size.Store(common.StorageSize(rlp.ListSize(size))) 265 return nil 266 } 267 268 // EncodeRLP serializes a block into the Klaytn RLP block format. 269 func (b *Block) EncodeRLP(w io.Writer) error { 270 return rlp.Encode(w, extblock{ 271 Header: b.header, 272 Txs: b.transactions, 273 }) 274 } 275 276 func (b *Block) Transactions() Transactions { return b.transactions } 277 278 func (b *Block) Transaction(hash common.Hash) *Transaction { 279 for _, transaction := range b.transactions { 280 if transaction.Hash() == hash { 281 return transaction 282 } 283 } 284 return nil 285 } 286 287 func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) } 288 func (b *Block) GasUsed() uint64 { return b.header.GasUsed } 289 func (b *Block) BlockScore() *big.Int { return new(big.Int).Set(b.header.BlockScore) } 290 func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) } 291 func (b *Block) TimeFoS() uint8 { return b.header.TimeFoS } 292 293 func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() } 294 func (b *Block) Bloom() Bloom { return b.header.Bloom } 295 func (b *Block) Rewardbase() common.Address { return b.header.Rewardbase } 296 func (b *Block) Root() common.Hash { return b.header.Root } 297 func (b *Block) ParentHash() common.Hash { return b.header.ParentHash } 298 func (b *Block) TxHash() common.Hash { return b.header.TxHash } 299 func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash } 300 func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) } 301 302 func (b *Block) Header() *Header { return CopyHeader(b.header) } 303 304 // Body returns the non-header content of the block. 305 func (b *Block) Body() *Body { return &Body{b.transactions} } 306 307 func (b *Block) HashNoNonce() common.Hash { 308 return b.header.HashNoNonce() 309 } 310 311 // Size returns the true RLP encoded storage size of the block, either by encoding 312 // and returning it, or returning a previsouly cached value. 313 func (b *Block) Size() common.StorageSize { 314 if size := b.size.Load(); size != nil { 315 return size.(common.StorageSize) 316 } 317 c := writeCounter(0) 318 rlp.Encode(&c, b) 319 b.size.Store(common.StorageSize(c)) 320 return common.StorageSize(c) 321 } 322 323 type writeCounter common.StorageSize 324 325 func (c *writeCounter) Write(b []byte) (int, error) { 326 *c += writeCounter(len(b)) 327 return len(b), nil 328 } 329 330 // WithSeal returns a new block with the data from b but the header replaced with 331 // the sealed one. 332 func (b *Block) WithSeal(header *Header) *Block { 333 cpy := *header 334 335 return &Block{ 336 header: &cpy, 337 transactions: b.transactions, 338 } 339 } 340 341 // WithBody returns a new block with the given transactions. 342 func (b *Block) WithBody(transactions []*Transaction) *Block { 343 block := &Block{ 344 header: CopyHeader(b.header), 345 transactions: make([]*Transaction, len(transactions)), 346 } 347 copy(block.transactions, transactions) 348 return block 349 } 350 351 // Hash returns the keccak256 hash of b's header. 352 // The hash is computed on the first call and cached thereafter. 353 func (b *Block) Hash() common.Hash { 354 if hash := b.hash.Load(); hash != nil { 355 return hash.(common.Hash) 356 } 357 v := b.header.Hash() 358 b.hash.Store(v) 359 return v 360 } 361 362 func (b *Block) String() string { 363 str := fmt.Sprintf(`Block(#%v): Size: %v { 364 MinerHash: %x 365 %v 366 Transactions: 367 %v 368 } 369 `, b.Number(), b.Size(), b.header.HashNoNonce(), b.header, b.transactions) 370 return str 371 } 372 373 func (h *Header) String() string { 374 prefix := `Header(%x): 375 [` 376 strBaseHeader := ` 377 ParentHash: %x 378 Rewardbase: %x 379 Root: %x 380 TxSha: %x 381 ReceiptSha: %x 382 Bloom: %x 383 BlockScore: %v 384 Number: %v 385 GasUsed: %v 386 Time: %v 387 TimeFoS: %v 388 Extra: %s 389 Governance: %x 390 Vote: %x 391 ` 392 suffix := ` 393 ]` 394 strHeader := "" 395 if h.BaseFee != nil { 396 strBaseHeader = strBaseHeader + ` BaseFee: %x 397 ` 398 strHeader = fmt.Sprintf(prefix+strBaseHeader+suffix, h.Hash(), h.ParentHash, h.Rewardbase, h.Root, h.TxHash, h.ReceiptHash, h.Bloom, h.BlockScore, h.Number, h.GasUsed, h.Time, h.TimeFoS, h.Extra, h.Governance, h.Vote, h.BaseFee) 399 } else { 400 strHeader = fmt.Sprintf(prefix+strBaseHeader+suffix, h.Hash(), h.ParentHash, h.Rewardbase, h.Root, h.TxHash, h.ReceiptHash, h.Bloom, h.BlockScore, h.Number, h.GasUsed, h.Time, h.TimeFoS, h.Extra, h.Governance, h.Vote) 401 } 402 return strHeader 403 } 404 405 type Blocks []*Block 406 407 type BlockBy func(b1, b2 *Block) bool 408 409 func (self BlockBy) Sort(blocks Blocks) { 410 bs := blockSorter{ 411 blocks: blocks, 412 by: self, 413 } 414 sort.Sort(bs) 415 } 416 417 type blockSorter struct { 418 blocks Blocks 419 by func(b1, b2 *Block) bool 420 } 421 422 func (self blockSorter) Len() int { return len(self.blocks) } 423 func (self blockSorter) Swap(i, j int) { 424 self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i] 425 } 426 func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) } 427 428 func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 }