github.com/immesys/bw2bc@v1.1.0/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  	"bytes"
    22  	"encoding/binary"
    23  	"encoding/json"
    24  	"fmt"
    25  	"io"
    26  	"math/big"
    27  	"sort"
    28  	"sync/atomic"
    29  	"time"
    30  
    31  	"github.com/ethereum/go-ethereum/common"
    32  	"github.com/ethereum/go-ethereum/crypto/sha3"
    33  	"github.com/ethereum/go-ethereum/rlp"
    34  )
    35  
    36  // A BlockNonce is a 64-bit hash which proves (combined with the
    37  // mix-hash) that a suffcient amount of computation has been carried
    38  // out on a block.
    39  type BlockNonce [8]byte
    40  
    41  func EncodeNonce(i uint64) BlockNonce {
    42  	var n BlockNonce
    43  	binary.BigEndian.PutUint64(n[:], i)
    44  	return n
    45  }
    46  
    47  func (n BlockNonce) Uint64() uint64 {
    48  	return binary.BigEndian.Uint64(n[:])
    49  }
    50  
    51  type Header struct {
    52  	ParentHash  common.Hash    // Hash to the previous block
    53  	UncleHash   common.Hash    // Uncles of this block
    54  	Coinbase    common.Address // The coin base address
    55  	Root        common.Hash    // Block Trie state
    56  	TxHash      common.Hash    // Tx sha
    57  	ReceiptHash common.Hash    // Receipt sha
    58  	Bloom       Bloom          // Bloom
    59  	Difficulty  *big.Int       // Difficulty for the current block
    60  	Number      *big.Int       // The block number
    61  	GasLimit    *big.Int       // Gas limit
    62  	GasUsed     *big.Int       // Gas used
    63  	Time        *big.Int       // Creation time
    64  	Extra       []byte         // Extra data
    65  	MixDigest   common.Hash    // for quick difficulty verification
    66  	Nonce       BlockNonce
    67  }
    68  
    69  func (h *Header) Hash() common.Hash {
    70  	return rlpHash(h)
    71  }
    72  
    73  func (h *Header) HashNoNonce() common.Hash {
    74  	return rlpHash([]interface{}{
    75  		h.ParentHash,
    76  		h.UncleHash,
    77  		h.Coinbase,
    78  		h.Root,
    79  		h.TxHash,
    80  		h.ReceiptHash,
    81  		h.Bloom,
    82  		h.Difficulty,
    83  		h.Number,
    84  		h.GasLimit,
    85  		h.GasUsed,
    86  		h.Time,
    87  		h.Extra,
    88  	})
    89  }
    90  
    91  func (h *Header) UnmarshalJSON(data []byte) error {
    92  	var ext struct {
    93  		ParentHash string
    94  		Coinbase   string
    95  		Difficulty string
    96  		GasLimit   string
    97  		Time       *big.Int
    98  		Extra      string
    99  	}
   100  	dec := json.NewDecoder(bytes.NewReader(data))
   101  	if err := dec.Decode(&ext); err != nil {
   102  		return err
   103  	}
   104  
   105  	h.ParentHash = common.HexToHash(ext.ParentHash)
   106  	h.Coinbase = common.HexToAddress(ext.Coinbase)
   107  	h.Difficulty = common.String2Big(ext.Difficulty)
   108  	h.Time = ext.Time
   109  	h.Extra = []byte(ext.Extra)
   110  	return nil
   111  }
   112  
   113  func rlpHash(x interface{}) (h common.Hash) {
   114  	hw := sha3.NewKeccak256()
   115  	rlp.Encode(hw, x)
   116  	hw.Sum(h[:0])
   117  	return h
   118  }
   119  
   120  type Block struct {
   121  	header       *Header
   122  	uncles       []*Header
   123  	transactions Transactions
   124  	receipts     Receipts
   125  
   126  	// caches
   127  	hash atomic.Value
   128  	size atomic.Value
   129  
   130  	// Td is used by package core to store the total difficulty
   131  	// of the chain up to and including the block.
   132  	Td *big.Int
   133  
   134  	// ReceivedAt is used by package eth to track block propagation time.
   135  	ReceivedAt time.Time
   136  }
   137  
   138  // StorageBlock defines the RLP encoding of a Block stored in the
   139  // state database. The StorageBlock encoding contains fields that
   140  // would otherwise need to be recomputed.
   141  type StorageBlock Block
   142  
   143  // "external" block encoding. used for eth protocol, etc.
   144  type extblock struct {
   145  	Header *Header
   146  	Txs    []*Transaction
   147  	Uncles []*Header
   148  }
   149  
   150  // "storage" block encoding. used for database.
   151  type storageblock struct {
   152  	Header *Header
   153  	Txs    []*Transaction
   154  	Uncles []*Header
   155  	TD     *big.Int
   156  }
   157  
   158  var (
   159  	emptyRootHash  = DeriveSha(Transactions{})
   160  	emptyUncleHash = CalcUncleHash(nil)
   161  )
   162  
   163  // NewBlock creates a new block. The input data is copied,
   164  // changes to header and to the field values will not affect the
   165  // block.
   166  //
   167  // The values of TxHash, UncleHash, ReceiptHash and Bloom in header
   168  // are ignored and set to values derived from the given txs, uncles
   169  // and receipts.
   170  func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt) *Block {
   171  	b := &Block{header: copyHeader(header), Td: new(big.Int)}
   172  
   173  	// TODO: panic if len(txs) != len(receipts)
   174  	if len(txs) == 0 {
   175  		b.header.TxHash = emptyRootHash
   176  	} else {
   177  		b.header.TxHash = DeriveSha(Transactions(txs))
   178  		b.transactions = make(Transactions, len(txs))
   179  		copy(b.transactions, txs)
   180  	}
   181  
   182  	if len(receipts) == 0 {
   183  		b.header.ReceiptHash = emptyRootHash
   184  	} else {
   185  		b.header.ReceiptHash = DeriveSha(Receipts(receipts))
   186  		b.header.Bloom = CreateBloom(receipts)
   187  		b.receipts = make([]*Receipt, len(receipts))
   188  		copy(b.receipts, receipts)
   189  	}
   190  
   191  	if len(uncles) == 0 {
   192  		b.header.UncleHash = emptyUncleHash
   193  	} else {
   194  		b.header.UncleHash = CalcUncleHash(uncles)
   195  		b.uncles = make([]*Header, len(uncles))
   196  		for i := range uncles {
   197  			b.uncles[i] = copyHeader(uncles[i])
   198  		}
   199  	}
   200  
   201  	return b
   202  }
   203  
   204  // NewBlockWithHeader creates a block with the given header data. The
   205  // header data is copied, changes to header and to the field values
   206  // will not affect the block.
   207  func NewBlockWithHeader(header *Header) *Block {
   208  	return &Block{header: copyHeader(header)}
   209  }
   210  
   211  func copyHeader(h *Header) *Header {
   212  	cpy := *h
   213  	if cpy.Time = new(big.Int); h.Time != nil {
   214  		cpy.Time.Set(h.Time)
   215  	}
   216  	if cpy.Difficulty = new(big.Int); h.Difficulty != nil {
   217  		cpy.Difficulty.Set(h.Difficulty)
   218  	}
   219  	if cpy.Number = new(big.Int); h.Number != nil {
   220  		cpy.Number.Set(h.Number)
   221  	}
   222  	if cpy.GasLimit = new(big.Int); h.GasLimit != nil {
   223  		cpy.GasLimit.Set(h.GasLimit)
   224  	}
   225  	if cpy.GasUsed = new(big.Int); h.GasUsed != nil {
   226  		cpy.GasUsed.Set(h.GasUsed)
   227  	}
   228  	if len(h.Extra) > 0 {
   229  		cpy.Extra = make([]byte, len(h.Extra))
   230  		copy(cpy.Extra, h.Extra)
   231  	}
   232  	return &cpy
   233  }
   234  
   235  func (b *Block) ValidateFields() error {
   236  	if b.header == nil {
   237  		return fmt.Errorf("header is nil")
   238  	}
   239  	for i, transaction := range b.transactions {
   240  		if transaction == nil {
   241  			return fmt.Errorf("transaction %d is nil", i)
   242  		}
   243  	}
   244  	for i, uncle := range b.uncles {
   245  		if uncle == nil {
   246  			return fmt.Errorf("uncle %d is nil", i)
   247  		}
   248  	}
   249  	return nil
   250  }
   251  
   252  func (b *Block) DecodeRLP(s *rlp.Stream) error {
   253  	var eb extblock
   254  	_, size, _ := s.Kind()
   255  	if err := s.Decode(&eb); err != nil {
   256  		return err
   257  	}
   258  	b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs
   259  	b.size.Store(common.StorageSize(rlp.ListSize(size)))
   260  	return nil
   261  }
   262  
   263  func (b *Block) EncodeRLP(w io.Writer) error {
   264  	return rlp.Encode(w, extblock{
   265  		Header: b.header,
   266  		Txs:    b.transactions,
   267  		Uncles: b.uncles,
   268  	})
   269  }
   270  
   271  func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error {
   272  	var sb storageblock
   273  	if err := s.Decode(&sb); err != nil {
   274  		return err
   275  	}
   276  	b.header, b.uncles, b.transactions, b.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
   277  	return nil
   278  }
   279  
   280  func (b *StorageBlock) EncodeRLP(w io.Writer) error {
   281  	return rlp.Encode(w, storageblock{
   282  		Header: b.header,
   283  		Txs:    b.transactions,
   284  		Uncles: b.uncles,
   285  		TD:     b.Td,
   286  	})
   287  }
   288  
   289  // TODO: copies
   290  func (b *Block) Uncles() []*Header          { return b.uncles }
   291  func (b *Block) Transactions() Transactions { return b.transactions }
   292  func (b *Block) Receipts() Receipts         { return b.receipts }
   293  
   294  func (b *Block) Transaction(hash common.Hash) *Transaction {
   295  	for _, transaction := range b.transactions {
   296  		if transaction.Hash() == hash {
   297  			return transaction
   298  		}
   299  	}
   300  	return nil
   301  }
   302  
   303  func (b *Block) Number() *big.Int     { return new(big.Int).Set(b.header.Number) }
   304  func (b *Block) GasLimit() *big.Int   { return new(big.Int).Set(b.header.GasLimit) }
   305  func (b *Block) GasUsed() *big.Int    { return new(big.Int).Set(b.header.GasUsed) }
   306  func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
   307  func (b *Block) Time() *big.Int       { return new(big.Int).Set(b.header.Time) }
   308  
   309  func (b *Block) NumberU64() uint64        { return b.header.Number.Uint64() }
   310  func (b *Block) MixDigest() common.Hash   { return b.header.MixDigest }
   311  func (b *Block) Nonce() uint64            { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
   312  func (b *Block) Bloom() Bloom             { return b.header.Bloom }
   313  func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
   314  func (b *Block) Root() common.Hash        { return b.header.Root }
   315  func (b *Block) ParentHash() common.Hash  { return b.header.ParentHash }
   316  func (b *Block) TxHash() common.Hash      { return b.header.TxHash }
   317  func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
   318  func (b *Block) UncleHash() common.Hash   { return b.header.UncleHash }
   319  func (b *Block) Extra() []byte            { return common.CopyBytes(b.header.Extra) }
   320  
   321  func (b *Block) Header() *Header { return copyHeader(b.header) }
   322  
   323  func (b *Block) HashNoNonce() common.Hash {
   324  	return b.header.HashNoNonce()
   325  }
   326  
   327  func (b *Block) Size() common.StorageSize {
   328  	if size := b.size.Load(); size != nil {
   329  		return size.(common.StorageSize)
   330  	}
   331  	c := writeCounter(0)
   332  	rlp.Encode(&c, b)
   333  	b.size.Store(common.StorageSize(c))
   334  	return common.StorageSize(c)
   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  	return rlpHash(uncles)
   346  }
   347  
   348  // WithMiningResult returns a new block with the data from b
   349  // where nonce and mix digest are set to the provided values.
   350  func (b *Block) WithMiningResult(nonce uint64, mixDigest common.Hash) *Block {
   351  	cpy := *b.header
   352  	binary.BigEndian.PutUint64(cpy.Nonce[:], nonce)
   353  	cpy.MixDigest = mixDigest
   354  	return &Block{
   355  		header:       &cpy,
   356  		transactions: b.transactions,
   357  		receipts:     b.receipts,
   358  		uncles:       b.uncles,
   359  		Td:           b.Td,
   360  	}
   361  }
   362  
   363  // Implement pow.Block
   364  
   365  func (b *Block) Hash() common.Hash {
   366  	if hash := b.hash.Load(); hash != nil {
   367  		return hash.(common.Hash)
   368  	}
   369  	v := rlpHash(b.header)
   370  	b.hash.Store(v)
   371  	return v
   372  }
   373  
   374  func (b *Block) String() string {
   375  	str := fmt.Sprintf(`Block(#%v): Size: %v TD: %v {
   376  MinerHash: %x
   377  %v
   378  Transactions:
   379  %v
   380  Uncles:
   381  %v
   382  }
   383  `, b.Number(), b.Size(), b.Td, b.header.HashNoNonce(), b.header, b.transactions, b.uncles)
   384  	return str
   385  }
   386  
   387  func (h *Header) String() string {
   388  	return fmt.Sprintf(`Header(%x):
   389  [
   390  	ParentHash:	    %x
   391  	UncleHash:	    %x
   392  	Coinbase:	    %x
   393  	Root:		    %x
   394  	TxSha		    %x
   395  	ReceiptSha:	    %x
   396  	Bloom:		    %x
   397  	Difficulty:	    %v
   398  	Number:		    %v
   399  	GasLimit:	    %v
   400  	GasUsed:	    %v
   401  	Time:		    %v
   402  	Extra:		    %s
   403  	MixDigest:      %x
   404  	Nonce:		    %x
   405  ]`, h.Hash(), h.ParentHash, h.UncleHash, h.Coinbase, h.Root, h.TxHash, h.ReceiptHash, h.Bloom, h.Difficulty, h.Number, h.GasLimit, h.GasUsed, h.Time, h.Extra, h.MixDigest, h.Nonce)
   406  }
   407  
   408  type Blocks []*Block
   409  
   410  type BlockBy func(b1, b2 *Block) bool
   411  
   412  func (self BlockBy) Sort(blocks Blocks) {
   413  	bs := blockSorter{
   414  		blocks: blocks,
   415  		by:     self,
   416  	}
   417  	sort.Sort(bs)
   418  }
   419  
   420  type blockSorter struct {
   421  	blocks Blocks
   422  	by     func(b1, b2 *Block) bool
   423  }
   424  
   425  func (self blockSorter) Len() int { return len(self.blocks) }
   426  func (self blockSorter) Swap(i, j int) {
   427  	self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i]
   428  }
   429  func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
   430  
   431  func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 }