github.com/insight-chain/inb-go@v1.1.3-0.20191221022159-da049980ae38/core/types/block.go (about)

     1  // Copyright 2014 The inb-go Authors
     2  // This file is part of the inb-go library.
     3  //
     4  // The inb-go 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 inb-go 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 inb-go 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  	"io"
    23  	"math/big"
    24  	"sort"
    25  	"sync/atomic"
    26  	"time"
    27  	"unsafe"
    28  
    29  	"github.com/insight-chain/inb-go/common"
    30  	"github.com/insight-chain/inb-go/common/hexutil"
    31  	"github.com/insight-chain/inb-go/crypto/sha3"
    32  	"github.com/insight-chain/inb-go/rlp"
    33  )
    34  
    35  var (
    36  	EmptyRootHash  = DeriveSha(Transactions{})
    37  	EmptyUncleHash = CalcUncleHash(nil)
    38  )
    39  
    40  // A BlockNonce is a 64-bit hash which proves (combined with the
    41  // mix-hash) that a sufficient amount of computation has been carried
    42  // out on a block.
    43  type BlockNonce [8]byte
    44  
    45  // EncodeNonce converts the given integer to a block nonce.
    46  func EncodeNonce(i uint64) BlockNonce {
    47  	var n BlockNonce
    48  	binary.BigEndian.PutUint64(n[:], i)
    49  	return n
    50  }
    51  
    52  // Uint64 returns the integer value of a block nonce.
    53  func (n BlockNonce) Uint64() uint64 {
    54  	return binary.BigEndian.Uint64(n[:])
    55  }
    56  
    57  // MarshalText encodes n as a hex string with 0x prefix.
    58  func (n BlockNonce) MarshalText() ([]byte, error) {
    59  	return hexutil.Bytes(n[:]).MarshalText()
    60  }
    61  
    62  // UnmarshalText implements encoding.TextUnmarshaler.
    63  func (n *BlockNonce) UnmarshalText(input []byte) error {
    64  	return hexutil.UnmarshalFixedText("BlockNonce", input, n[:])
    65  }
    66  
    67  //go:generate gencodec -type Header -field-override headerMarshaling -out gen_header_json.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"            gencodec:"required"`
    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  	ResLimit         uint64             `json:"resLimit"         gencodec:"required"`
    81  	ResUsed          uint64             `json:"resUsed"          gencodec:"required"`
    82  	Time             *big.Int           `json:"timestamp"        gencodec:"required"`
    83  	Extra            []byte             `json:"extraData"        gencodec:"required"`
    84  	MixDigest        common.Hash        `json:"mixHash"`
    85  	Nonce            BlockNonce         `json:"nonce"`
    86  	DataRoot         common.Hash        `json:"dataRoot"`                              //inb by ssh 190627
    87  	Reward           string             `json:"reward"           gencodec:"required"`  //2019.6.28 inb by ghy
    88  	SpecialConsensus []byte             `json:"specialConsensus"  gencodec:"required"` //2019.7.23 inb by ghy
    89  	VdposContext     *VdposContextProto `json:"vdposContext"     gencodec:"required"`  //inb by ssh 190814
    90  }
    91  
    92  type SpecialConsensus struct {
    93  	Molecule                *big.Int                  `json:"molecule"`
    94  	Denominator             *big.Int                  `json:"denominator"`
    95  	SpecialNumber           []SpecialNumber           `json:"specialNumber"`
    96  	SpecialConsensusAddress []SpecialConsensusAddress `json:"specialConsensusAddress"`
    97  }
    98  
    99  type SpecialNumber struct {
   100  	Number *big.Int `json:"number"`
   101  }
   102  
   103  type SpecialConsensusAddress struct {
   104  	SpecialType uint           `json:"specialType"`
   105  	Address     common.Address `json:"address"`
   106  	ToAddress   common.Address `json:"toAddress"`
   107  }
   108  
   109  // field type overrides for gencodec
   110  type headerMarshaling struct {
   111  	Difficulty *hexutil.Big
   112  	Number     *hexutil.Big
   113  	ResLimit   hexutil.Uint64
   114  	ResUsed    hexutil.Uint64
   115  	Time       *hexutil.Big
   116  	Extra      hexutil.Bytes
   117  	Hash       common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
   118  }
   119  
   120  // Hash returns the block hash of the header, which is simply the keccak256 hash of its
   121  // RLP encoding.
   122  func (h *Header) Hash() common.Hash {
   123  	return rlpHash(h)
   124  }
   125  
   126  //2019.9.20 inb by ghy begin
   127  func (h *Header) GetSpecialConsensus() SpecialConsensus {
   128  	SpecialConsensus := SpecialConsensus{}
   129  	if h.SpecialConsensus != nil {
   130  		rlp.DecodeBytes(h.SpecialConsensus, &SpecialConsensus)
   131  	}
   132  	return SpecialConsensus
   133  }
   134  
   135  //func (h *Header) GetEnodesInfoByAddress(address common.Address) *common.SuperNode {
   136  //
   137  //	b := h.Extra[32 : len(h.Extra)-65]
   138  //	headerExtra := vdpos.HeaderExtra{}
   139  //	val := &headerExtra
   140  //	err := rlp.DecodeBytes(b, val)
   141  //	if err == nil {
   142  //		for _, v := range val.Enodes {
   143  //			if v.Address == address {
   144  //				return &v
   145  //			}
   146  //		}
   147  //	} else {
   148  //		return nil
   149  //	}
   150  //	return nil
   151  //}
   152  
   153  //2019.9.20 inb by ghy end
   154  
   155  // Size returns the approximate memory used by all internal contents. It is used
   156  // to approximate and limit the memory consumption of various caches.
   157  func (h *Header) Size() common.StorageSize {
   158  	return common.StorageSize(unsafe.Sizeof(*h)) + common.StorageSize(len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen()+h.Time.BitLen())/8)
   159  }
   160  
   161  func rlpHash(x interface{}) (h common.Hash) {
   162  	hw := sha3.NewKeccak256()
   163  	rlp.Encode(hw, x)
   164  	hw.Sum(h[:0])
   165  	return h
   166  }
   167  
   168  // Body is a simple (mutable, non-safe) data container for storing and moving
   169  // a block's data contents (transactions and uncles) together.
   170  type Body struct {
   171  	Transactions []*Transaction
   172  	Uncles       []*Header
   173  }
   174  
   175  // Block represents an entire block in the Ethereum blockchain.
   176  type Block struct {
   177  	header       *Header
   178  	uncles       []*Header
   179  	transactions Transactions
   180  
   181  	// caches
   182  	hash atomic.Value
   183  	size atomic.Value
   184  
   185  	// Td is used by package core to store the total difficulty
   186  	// of the chain up to and including the block.
   187  	td *big.Int
   188  
   189  	// These fields are used by package eth to track
   190  	// inter-peer block relay.
   191  	ReceivedAt   time.Time
   192  	ReceivedFrom interface{}
   193  
   194  	VdposContext *VdposContext
   195  }
   196  
   197  // DeprecatedTd is an old relic for extracting the TD of a block. It is in the
   198  // code solely to facilitate upgrading the database from the old format to the
   199  // new, after which it should be deleted. Do not use!
   200  func (b *Block) DeprecatedTd() *big.Int {
   201  	return b.td
   202  }
   203  
   204  // [deprecated by eth/63]
   205  // StorageBlock defines the RLP encoding of a Block stored in the
   206  // state database. The StorageBlock encoding contains fields that
   207  // would otherwise need to be recomputed.
   208  type StorageBlock Block
   209  
   210  // "external" block encoding. used for eth protocol, etc.
   211  type extblock struct {
   212  	Header *Header
   213  	Txs    []*Transaction
   214  	Uncles []*Header
   215  }
   216  
   217  // [deprecated by eth/63]
   218  // "storage" block encoding. used for database.
   219  type storageblock struct {
   220  	Header *Header
   221  	Txs    []*Transaction
   222  	Uncles []*Header
   223  	TD     *big.Int
   224  }
   225  
   226  // NewBlock creates a new block. The input data is copied,
   227  // changes to header and to the field values will not affect the
   228  // block.
   229  //
   230  // The values of TxHash, UncleHash, ReceiptHash and Bloom in header
   231  // are ignored and set to values derived from the given txs, uncles
   232  // and receipts.
   233  func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt) *Block {
   234  	b := &Block{header: CopyHeader(header), td: new(big.Int)}
   235  
   236  	// TODO: panic if len(txs) != len(receipts)
   237  	if len(txs) == 0 {
   238  		b.header.TxHash = EmptyRootHash
   239  	} else {
   240  		b.header.TxHash = DeriveSha(Transactions(txs))
   241  		b.transactions = make(Transactions, len(txs))
   242  		copy(b.transactions, txs)
   243  	}
   244  
   245  	if len(receipts) == 0 {
   246  		b.header.ReceiptHash = EmptyRootHash
   247  	} else {
   248  		b.header.ReceiptHash = DeriveSha(Receipts(receipts))
   249  		b.header.Bloom = CreateBloom(receipts)
   250  	}
   251  
   252  	if len(uncles) == 0 {
   253  		b.header.UncleHash = EmptyUncleHash
   254  	} else {
   255  		b.header.UncleHash = CalcUncleHash(uncles)
   256  		b.uncles = make([]*Header, len(uncles))
   257  		for i := range uncles {
   258  			b.uncles[i] = CopyHeader(uncles[i])
   259  		}
   260  	}
   261  
   262  	return b
   263  }
   264  
   265  // NewBlockWithHeader creates a block with the given header data. The
   266  // header data is copied, changes to header and to the field values
   267  // will not affect the block.
   268  func NewBlockWithHeader(header *Header) *Block {
   269  	return &Block{header: CopyHeader(header)}
   270  }
   271  
   272  // CopyHeader creates a deep copy of a block header to prevent side effects from
   273  // modifying a header variable.
   274  func CopyHeader(h *Header) *Header {
   275  	cpy := *h
   276  	if cpy.Time = new(big.Int); h.Time != nil {
   277  		cpy.Time.Set(h.Time)
   278  	}
   279  	if cpy.Difficulty = new(big.Int); h.Difficulty != nil {
   280  		cpy.Difficulty.Set(h.Difficulty)
   281  	}
   282  	if cpy.Number = new(big.Int); h.Number != nil {
   283  		cpy.Number.Set(h.Number)
   284  	}
   285  	if len(h.Extra) > 0 {
   286  		cpy.Extra = make([]byte, len(h.Extra))
   287  		copy(cpy.Extra, h.Extra)
   288  	}
   289  
   290  	// inb by ssh 190814
   291  	cpy.VdposContext = &VdposContextProto{}
   292  	if h.VdposContext != nil {
   293  		cpy.VdposContext = h.VdposContext
   294  	}
   295  	return &cpy
   296  }
   297  
   298  // DecodeRLP decodes the Ethereum
   299  func (b *Block) DecodeRLP(s *rlp.Stream) error {
   300  	var eb extblock
   301  	_, size, _ := s.Kind()
   302  	if err := s.Decode(&eb); err != nil {
   303  		return err
   304  	}
   305  	b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs
   306  	b.size.Store(common.StorageSize(rlp.ListSize(size)))
   307  	return nil
   308  }
   309  
   310  // EncodeRLP serializes b into the Ethereum RLP block format.
   311  func (b *Block) EncodeRLP(w io.Writer) error {
   312  	return rlp.Encode(w, extblock{
   313  		Header: b.header,
   314  		Txs:    b.transactions,
   315  		Uncles: b.uncles,
   316  	})
   317  }
   318  
   319  // [deprecated by eth/63]
   320  func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error {
   321  	var sb storageblock
   322  	if err := s.Decode(&sb); err != nil {
   323  		return err
   324  	}
   325  	b.header, b.uncles, b.transactions, b.td = sb.Header, sb.Uncles, sb.Txs, sb.TD
   326  	return nil
   327  }
   328  
   329  // TODO: copies
   330  
   331  func (b *Block) Uncles() []*Header          { return b.uncles }
   332  func (b *Block) Transactions() Transactions { return b.transactions }
   333  func (b *Block) SpecialConsensus() *SpecialConsensus {
   334  	SpecialConsensus := new(SpecialConsensus)
   335  
   336  	err := rlp.DecodeBytes(b.header.SpecialConsensus, SpecialConsensus)
   337  	if err != nil {
   338  		return nil
   339  	}
   340  	return SpecialConsensus
   341  } //2019.8.6 inb by ghy
   342  
   343  func (b *Block) Transaction(hash common.Hash) *Transaction {
   344  	for _, transaction := range b.transactions {
   345  		if transaction.Hash() == hash {
   346  			return transaction
   347  		}
   348  	}
   349  	return nil
   350  }
   351  
   352  func (b *Block) Number() *big.Int     { return new(big.Int).Set(b.header.Number) }
   353  func (b *Block) GasLimit() uint64     { return b.header.ResLimit }
   354  func (b *Block) GasUsed() uint64      { return b.header.ResUsed }
   355  func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
   356  func (b *Block) Time() *big.Int       { return new(big.Int).Set(b.header.Time) }
   357  
   358  func (b *Block) NumberU64() uint64        { return b.header.Number.Uint64() }
   359  func (b *Block) MixDigest() common.Hash   { return b.header.MixDigest }
   360  func (b *Block) Nonce() uint64            { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
   361  func (b *Block) Bloom() Bloom             { return b.header.Bloom }
   362  func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
   363  func (b *Block) Root() common.Hash        { return b.header.Root }
   364  func (b *Block) ParentHash() common.Hash  { return b.header.ParentHash }
   365  func (b *Block) TxHash() common.Hash      { return b.header.TxHash }
   366  func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
   367  func (b *Block) UncleHash() common.Hash   { return b.header.UncleHash }
   368  func (b *Block) Extra() []byte            { return common.CopyBytes(b.header.Extra) }
   369  
   370  func (b *Block) Header() *Header { return CopyHeader(b.header) }
   371  
   372  // Body returns the non-header content of the block.
   373  func (b *Block) Body() *Body { return &Body{b.transactions, b.uncles} }
   374  
   375  // inb by ssh 190814
   376  func (b *Block) VdposCtx() *VdposContext { return b.VdposContext }
   377  
   378  // Size returns the true RLP encoded storage size of the block, either by encoding
   379  // and returning it, or returning a previsouly cached value.
   380  func (b *Block) Size() common.StorageSize {
   381  	if size := b.size.Load(); size != nil {
   382  		return size.(common.StorageSize)
   383  	}
   384  	c := writeCounter(0)
   385  	rlp.Encode(&c, b)
   386  	b.size.Store(common.StorageSize(c))
   387  	return common.StorageSize(c)
   388  }
   389  
   390  type writeCounter common.StorageSize
   391  
   392  func (c *writeCounter) Write(b []byte) (int, error) {
   393  	*c += writeCounter(len(b))
   394  	return len(b), nil
   395  }
   396  
   397  func CalcUncleHash(uncles []*Header) common.Hash {
   398  	return rlpHash(uncles)
   399  }
   400  
   401  // WithSeal returns a new block with the data from b but the header replaced with
   402  // the sealed one.
   403  func (b *Block) WithSeal(header *Header) *Block {
   404  	cpy := *header
   405  	return &Block{
   406  		header:       &cpy,
   407  		transactions: b.transactions,
   408  		uncles:       b.uncles,
   409  		// inb by ssh 190814
   410  		VdposContext: b.VdposContext,
   411  	}
   412  }
   413  
   414  // WithBody returns a new block with the given transaction and uncle contents.
   415  func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block {
   416  	block := &Block{
   417  		header:       CopyHeader(b.header),
   418  		transactions: make([]*Transaction, len(transactions)),
   419  		uncles:       make([]*Header, len(uncles)),
   420  	}
   421  	copy(block.transactions, transactions)
   422  	for i := range uncles {
   423  		block.uncles[i] = CopyHeader(uncles[i])
   424  	}
   425  	return block
   426  }
   427  
   428  // Hash returns the keccak256 hash of b's header.
   429  // The hash is computed on the first call and cached thereafter.
   430  func (b *Block) Hash() common.Hash {
   431  	if hash := b.hash.Load(); hash != nil {
   432  		return hash.(common.Hash)
   433  	}
   434  	v := b.header.Hash()
   435  	b.hash.Store(v)
   436  	return v
   437  }
   438  
   439  type Blocks []*Block
   440  
   441  type BlockBy func(b1, b2 *Block) bool
   442  
   443  func (self BlockBy) Sort(blocks Blocks) {
   444  	bs := blockSorter{
   445  		blocks: blocks,
   446  		by:     self,
   447  	}
   448  	sort.Sort(bs)
   449  }
   450  
   451  type blockSorter struct {
   452  	blocks Blocks
   453  	by     func(b1, b2 *Block) bool
   454  }
   455  
   456  func (self blockSorter) Len() int { return len(self.blocks) }
   457  func (self blockSorter) Swap(i, j int) {
   458  	self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i]
   459  }
   460  func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
   461  
   462  func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 }