github.com/ethw3/go-ethereuma@v0.0.0-20221013053120-c14602a4c23c/core/types/block.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package types contains data types related to Ethereum consensus.
    18  package types
    19  
    20  import (
    21  	"encoding/binary"
    22  	"fmt"
    23  	"io"
    24  	"math/big"
    25  	"reflect"
    26  	"sync/atomic"
    27  	"time"
    28  
    29  	"github.com/ethw3/go-ethereuma/common"
    30  	"github.com/ethw3/go-ethereuma/common/hexutil"
    31  	"github.com/ethw3/go-ethereuma/rlp"
    32  )
    33  
    34  var (
    35  	EmptyRootHash  = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
    36  	EmptyUncleHash = rlpHash([]*Header(nil))
    37  )
    38  
    39  // A BlockNonce is a 64-bit hash which proves (combined with the
    40  // mix-hash) that a sufficient amount of computation has been carried
    41  // out on a block.
    42  type BlockNonce [8]byte
    43  
    44  // EncodeNonce converts the given integer to a block nonce.
    45  func EncodeNonce(i uint64) BlockNonce {
    46  	var n BlockNonce
    47  	binary.BigEndian.PutUint64(n[:], i)
    48  	return n
    49  }
    50  
    51  // Uint64 returns the integer value of a block nonce.
    52  func (n BlockNonce) Uint64() uint64 {
    53  	return binary.BigEndian.Uint64(n[:])
    54  }
    55  
    56  // MarshalText encodes n as a hex string with 0x prefix.
    57  func (n BlockNonce) MarshalText() ([]byte, error) {
    58  	return hexutil.Bytes(n[:]).MarshalText()
    59  }
    60  
    61  // UnmarshalText implements encoding.TextUnmarshaler.
    62  func (n *BlockNonce) UnmarshalText(input []byte) error {
    63  	return hexutil.UnmarshalFixedText("BlockNonce", input, n[:])
    64  }
    65  
    66  //go:generate go run github.com/fjl/gencodec -type Header -field-override headerMarshaling -out gen_header_json.go
    67  //go:generate go run ../../rlp/rlpgen -type Header -out gen_header_rlp.go
    68  
    69  // Header represents a block header in the Ethereum blockchain.
    70  type Header struct {
    71  	ParentHash  common.Hash    `json:"parentHash"       gencodec:"required"`
    72  	UncleHash   common.Hash    `json:"sha3Uncles"       gencodec:"required"`
    73  	Coinbase    common.Address `json:"miner"`
    74  	Root        common.Hash    `json:"stateRoot"        gencodec:"required"`
    75  	TxHash      common.Hash    `json:"transactionsRoot" gencodec:"required"`
    76  	ReceiptHash common.Hash    `json:"receiptsRoot"     gencodec:"required"`
    77  	Bloom       Bloom          `json:"logsBloom"        gencodec:"required"`
    78  	Difficulty  *big.Int       `json:"difficulty"       gencodec:"required"`
    79  	Number      *big.Int       `json:"number"           gencodec:"required"`
    80  	GasLimit    uint64         `json:"gasLimit"         gencodec:"required"`
    81  	GasUsed     uint64         `json:"gasUsed"          gencodec:"required"`
    82  	Time        uint64         `json:"timestamp"        gencodec:"required"`
    83  	Extra       []byte         `json:"extraData"        gencodec:"required"`
    84  	MixDigest   common.Hash    `json:"mixHash"`
    85  	Nonce       BlockNonce     `json:"nonce"`
    86  
    87  	// BaseFee was added by EIP-1559 and is ignored in legacy headers.
    88  	BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"`
    89  
    90  	/*
    91  		TODO (MariusVanDerWijden) Add this field once needed
    92  		// Random was added during the merge and contains the BeaconState randomness
    93  		Random common.Hash `json:"random" rlp:"optional"`
    94  	*/
    95  }
    96  
    97  // field type overrides for gencodec
    98  type headerMarshaling struct {
    99  	Difficulty *hexutil.Big
   100  	Number     *hexutil.Big
   101  	GasLimit   hexutil.Uint64
   102  	GasUsed    hexutil.Uint64
   103  	Time       hexutil.Uint64
   104  	Extra      hexutil.Bytes
   105  	BaseFee    *hexutil.Big
   106  	Hash       common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
   107  }
   108  
   109  // Hash returns the block hash of the header, which is simply the keccak256 hash of its
   110  // RLP encoding.
   111  func (h *Header) Hash() common.Hash {
   112  	return rlpHash(h)
   113  }
   114  
   115  var headerSize = common.StorageSize(reflect.TypeOf(Header{}).Size())
   116  
   117  // Size returns the approximate memory used by all internal contents. It is used
   118  // to approximate and limit the memory consumption of various caches.
   119  func (h *Header) Size() common.StorageSize {
   120  	return headerSize + common.StorageSize(len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen())/8)
   121  }
   122  
   123  // SanityCheck checks a few basic things -- these checks are way beyond what
   124  // any 'sane' production values should hold, and can mainly be used to prevent
   125  // that the unbounded fields are stuffed with junk data to add processing
   126  // overhead
   127  func (h *Header) SanityCheck() error {
   128  	if h.Number != nil && !h.Number.IsUint64() {
   129  		return fmt.Errorf("too large block number: bitlen %d", h.Number.BitLen())
   130  	}
   131  	if h.Difficulty != nil {
   132  		if diffLen := h.Difficulty.BitLen(); diffLen > 80 {
   133  			return fmt.Errorf("too large block difficulty: bitlen %d", diffLen)
   134  		}
   135  	}
   136  	if eLen := len(h.Extra); eLen > 100*1024 {
   137  		return fmt.Errorf("too large block extradata: size %d", eLen)
   138  	}
   139  	if h.BaseFee != nil {
   140  		if bfLen := h.BaseFee.BitLen(); bfLen > 256 {
   141  			return fmt.Errorf("too large base fee: bitlen %d", bfLen)
   142  		}
   143  	}
   144  	return nil
   145  }
   146  
   147  // EmptyBody returns true if there is no additional 'body' to complete the header
   148  // that is: no transactions and no uncles.
   149  func (h *Header) EmptyBody() bool {
   150  	return h.TxHash == EmptyRootHash && h.UncleHash == EmptyUncleHash
   151  }
   152  
   153  // EmptyReceipts returns true if there are no receipts for this header/block.
   154  func (h *Header) EmptyReceipts() bool {
   155  	return h.ReceiptHash == EmptyRootHash
   156  }
   157  
   158  // Body is a simple (mutable, non-safe) data container for storing and moving
   159  // a block's data contents (transactions and uncles) together.
   160  type Body struct {
   161  	Transactions []*Transaction
   162  	Uncles       []*Header
   163  }
   164  
   165  // Block represents an entire block in the Ethereum blockchain.
   166  type Block struct {
   167  	header       *Header
   168  	uncles       []*Header
   169  	transactions Transactions
   170  
   171  	// caches
   172  	hash atomic.Value
   173  	size atomic.Value
   174  
   175  	// These fields are used by package eth to track
   176  	// inter-peer block relay.
   177  	ReceivedAt   time.Time
   178  	ReceivedFrom interface{}
   179  }
   180  
   181  // "external" block encoding. used for eth protocol, etc.
   182  type extblock struct {
   183  	Header *Header
   184  	Txs    []*Transaction
   185  	Uncles []*Header
   186  }
   187  
   188  // NewBlock creates a new block. The input data is copied,
   189  // changes to header and to the field values will not affect the
   190  // block.
   191  //
   192  // The values of TxHash, UncleHash, ReceiptHash and Bloom in header
   193  // are ignored and set to values derived from the given txs, uncles
   194  // and receipts.
   195  func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, hasher TrieHasher) *Block {
   196  	b := &Block{header: CopyHeader(header)}
   197  
   198  	// TODO: panic if len(txs) != len(receipts)
   199  	if len(txs) == 0 {
   200  		b.header.TxHash = EmptyRootHash
   201  	} else {
   202  		b.header.TxHash = DeriveSha(Transactions(txs), hasher)
   203  		b.transactions = make(Transactions, len(txs))
   204  		copy(b.transactions, txs)
   205  	}
   206  
   207  	if len(receipts) == 0 {
   208  		b.header.ReceiptHash = EmptyRootHash
   209  	} else {
   210  		b.header.ReceiptHash = DeriveSha(Receipts(receipts), hasher)
   211  		b.header.Bloom = CreateBloom(receipts)
   212  	}
   213  
   214  	if len(uncles) == 0 {
   215  		b.header.UncleHash = EmptyUncleHash
   216  	} else {
   217  		b.header.UncleHash = CalcUncleHash(uncles)
   218  		b.uncles = make([]*Header, len(uncles))
   219  		for i := range uncles {
   220  			b.uncles[i] = CopyHeader(uncles[i])
   221  		}
   222  	}
   223  
   224  	return b
   225  }
   226  
   227  // NewBlockWithHeader creates a block with the given header data. The
   228  // header data is copied, changes to header and to the field values
   229  // will not affect the block.
   230  func NewBlockWithHeader(header *Header) *Block {
   231  	return &Block{header: CopyHeader(header)}
   232  }
   233  
   234  // CopyHeader creates a deep copy of a block header to prevent side effects from
   235  // modifying a header variable.
   236  func CopyHeader(h *Header) *Header {
   237  	cpy := *h
   238  	if cpy.Difficulty = new(big.Int); h.Difficulty != nil {
   239  		cpy.Difficulty.Set(h.Difficulty)
   240  	}
   241  	if cpy.Number = new(big.Int); h.Number != nil {
   242  		cpy.Number.Set(h.Number)
   243  	}
   244  	if h.BaseFee != nil {
   245  		cpy.BaseFee = new(big.Int).Set(h.BaseFee)
   246  	}
   247  	if len(h.Extra) > 0 {
   248  		cpy.Extra = make([]byte, len(h.Extra))
   249  		copy(cpy.Extra, h.Extra)
   250  	}
   251  	return &cpy
   252  }
   253  
   254  // DecodeRLP decodes the Ethereum
   255  func (b *Block) DecodeRLP(s *rlp.Stream) error {
   256  	var eb extblock
   257  	_, size, _ := s.Kind()
   258  	if err := s.Decode(&eb); err != nil {
   259  		return err
   260  	}
   261  	b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs
   262  	b.size.Store(common.StorageSize(rlp.ListSize(size)))
   263  	return nil
   264  }
   265  
   266  // EncodeRLP serializes b into the Ethereum RLP block format.
   267  func (b *Block) EncodeRLP(w io.Writer) error {
   268  	return rlp.Encode(w, extblock{
   269  		Header: b.header,
   270  		Txs:    b.transactions,
   271  		Uncles: b.uncles,
   272  	})
   273  }
   274  
   275  // TODO: copies
   276  
   277  func (b *Block) Uncles() []*Header          { return b.uncles }
   278  func (b *Block) Transactions() Transactions { return b.transactions }
   279  
   280  func (b *Block) Transaction(hash common.Hash) *Transaction {
   281  	for _, transaction := range b.transactions {
   282  		if transaction.Hash() == hash {
   283  			return transaction
   284  		}
   285  	}
   286  	return nil
   287  }
   288  
   289  func (b *Block) Number() *big.Int     { return new(big.Int).Set(b.header.Number) }
   290  func (b *Block) GasLimit() uint64     { return b.header.GasLimit }
   291  func (b *Block) GasUsed() uint64      { return b.header.GasUsed }
   292  func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
   293  func (b *Block) Time() uint64         { return b.header.Time }
   294  
   295  func (b *Block) NumberU64() uint64        { return b.header.Number.Uint64() }
   296  func (b *Block) MixDigest() common.Hash   { return b.header.MixDigest }
   297  func (b *Block) Nonce() uint64            { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
   298  func (b *Block) Bloom() Bloom             { return b.header.Bloom }
   299  func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
   300  func (b *Block) Root() common.Hash        { return b.header.Root }
   301  func (b *Block) ParentHash() common.Hash  { return b.header.ParentHash }
   302  func (b *Block) TxHash() common.Hash      { return b.header.TxHash }
   303  func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
   304  func (b *Block) UncleHash() common.Hash   { return b.header.UncleHash }
   305  func (b *Block) Extra() []byte            { return common.CopyBytes(b.header.Extra) }
   306  
   307  func (b *Block) BaseFee() *big.Int {
   308  	if b.header.BaseFee == nil {
   309  		return nil
   310  	}
   311  	return new(big.Int).Set(b.header.BaseFee)
   312  }
   313  
   314  func (b *Block) Header() *Header { return CopyHeader(b.header) }
   315  
   316  // Body returns the non-header content of the block.
   317  func (b *Block) Body() *Body { return &Body{b.transactions, b.uncles} }
   318  
   319  // Size returns the true RLP encoded storage size of the block, either by encoding
   320  // and returning it, or returning a previously cached value.
   321  func (b *Block) Size() common.StorageSize {
   322  	if size := b.size.Load(); size != nil {
   323  		return size.(common.StorageSize)
   324  	}
   325  	c := writeCounter(0)
   326  	rlp.Encode(&c, b)
   327  	b.size.Store(common.StorageSize(c))
   328  	return common.StorageSize(c)
   329  }
   330  
   331  // SanityCheck can be used to prevent that unbounded fields are
   332  // stuffed with junk data to add processing overhead
   333  func (b *Block) SanityCheck() error {
   334  	return b.header.SanityCheck()
   335  }
   336  
   337  type writeCounter common.StorageSize
   338  
   339  func (c *writeCounter) Write(b []byte) (int, error) {
   340  	*c += writeCounter(len(b))
   341  	return len(b), nil
   342  }
   343  
   344  func CalcUncleHash(uncles []*Header) common.Hash {
   345  	if len(uncles) == 0 {
   346  		return EmptyUncleHash
   347  	}
   348  	return rlpHash(uncles)
   349  }
   350  
   351  // WithSeal returns a new block with the data from b but the header replaced with
   352  // the sealed one.
   353  func (b *Block) WithSeal(header *Header) *Block {
   354  	cpy := *header
   355  
   356  	return &Block{
   357  		header:       &cpy,
   358  		transactions: b.transactions,
   359  		uncles:       b.uncles,
   360  	}
   361  }
   362  
   363  // WithBody returns a new block with the given transaction and uncle contents.
   364  func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block {
   365  	block := &Block{
   366  		header:       CopyHeader(b.header),
   367  		transactions: make([]*Transaction, len(transactions)),
   368  		uncles:       make([]*Header, len(uncles)),
   369  	}
   370  	copy(block.transactions, transactions)
   371  	for i := range uncles {
   372  		block.uncles[i] = CopyHeader(uncles[i])
   373  	}
   374  	return block
   375  }
   376  
   377  // Hash returns the keccak256 hash of b's header.
   378  // The hash is computed on the first call and cached thereafter.
   379  func (b *Block) Hash() common.Hash {
   380  	if hash := b.hash.Load(); hash != nil {
   381  		return hash.(common.Hash)
   382  	}
   383  	v := b.header.Hash()
   384  	b.hash.Store(v)
   385  	return v
   386  }
   387  
   388  type Blocks []*Block
   389  
   390  // HeaderParentHashFromRLP returns the parentHash of an RLP-encoded
   391  // header. If 'header' is invalid, the zero hash is returned.
   392  func HeaderParentHashFromRLP(header []byte) common.Hash {
   393  	// parentHash is the first list element.
   394  	listContent, _, err := rlp.SplitList(header)
   395  	if err != nil {
   396  		return common.Hash{}
   397  	}
   398  	parentHash, _, err := rlp.SplitString(listContent)
   399  	if err != nil {
   400  		return common.Hash{}
   401  	}
   402  	if len(parentHash) != 32 {
   403  		return common.Hash{}
   404  	}
   405  	return common.BytesToHash(parentHash)
   406  }