github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/core/chain_manager.go (about)

     1  // Copyright 2015 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 core
    18  
    19  import (
    20  	"fmt"
    21  	"math/big"
    22  
    23  	"github.com/ethereumproject/go-ethereum/common"
    24  	"github.com/ethereumproject/go-ethereum/core/state"
    25  	"github.com/ethereumproject/go-ethereum/core/types"
    26  	"github.com/ethereumproject/go-ethereum/ethdb"
    27  	"github.com/ethereumproject/go-ethereum/event"
    28  	"github.com/ethereumproject/go-ethereum/pow"
    29  )
    30  
    31  /*
    32   * TODO: move this to another package.
    33   */
    34  
    35  // MakeChainConfig returns a new ChainConfig with the ethereum default chain settings.
    36  func MakeChainConfig() *ChainConfig {
    37  	return &ChainConfig{
    38  		Forks: []*Fork{
    39  			{
    40  				Name:  "Homestead",
    41  				Block: big.NewInt(0),
    42  				Features: []*ForkFeature{
    43  					{
    44  						ID: "difficulty",
    45  						Options: ChainFeatureConfigOptions{
    46  							"type": "homestead",
    47  						},
    48  					},
    49  				},
    50  			},
    51  		},
    52  	}
    53  }
    54  
    55  func MakeDiehardChainConfig() *ChainConfig {
    56  	return &ChainConfig{
    57  		Forks: []*Fork{
    58  			{
    59  				Name:  "Diehard",
    60  				Block: big.NewInt(0),
    61  				Features: []*ForkFeature{
    62  					{
    63  						ID: "eip155",
    64  						Options: ChainFeatureConfigOptions{
    65  							"chainID": 63,
    66  						},
    67  					},
    68  					{ // ecip1010 bomb delay
    69  						ID: "gastable",
    70  						Options: ChainFeatureConfigOptions{
    71  							"type": "eip160",
    72  						},
    73  					},
    74  					{ // ecip1010 bomb delay
    75  						ID: "difficulty",
    76  						Options: ChainFeatureConfigOptions{
    77  							"type":   "ecip1010",
    78  							"length": 2000000,
    79  						},
    80  					},
    81  				},
    82  			},
    83  		},
    84  	}
    85  }
    86  
    87  // FakePow is a non-validating proof of work implementation.
    88  // It returns true from Verify for any block.
    89  type FakePow struct{}
    90  
    91  func (f FakePow) Search(block pow.Block, stop <-chan struct{}, index int) (uint64, []byte) {
    92  	return 0, nil
    93  }
    94  func (f FakePow) Verify(block pow.Block) bool { return true }
    95  func (f FakePow) GetHashrate() int64          { return 0 }
    96  func (f FakePow) Turbo(bool)                  {}
    97  
    98  // So we can deterministically seed different blockchains
    99  var (
   100  	canonicalSeed = 1
   101  	forkSeed      = 2
   102  )
   103  
   104  // BlockGen creates blocks for testing.
   105  // See GenerateChain for a detailed explanation.
   106  type BlockGen struct {
   107  	i       int
   108  	parent  *types.Block
   109  	chain   []*types.Block
   110  	header  *types.Header
   111  	statedb *state.StateDB
   112  
   113  	gasPool  *GasPool
   114  	txs      []*types.Transaction
   115  	receipts []*types.Receipt
   116  	uncles   []*types.Header
   117  	config   *ChainConfig
   118  }
   119  
   120  // SetCoinbase sets the coinbase of the generated block.
   121  // It can be called at most once.
   122  func (b *BlockGen) SetCoinbase(addr common.Address) {
   123  	if b.gasPool != nil {
   124  		if len(b.txs) > 0 {
   125  			panic("coinbase must be set before adding transactions")
   126  		}
   127  		panic("coinbase can only be set once")
   128  	}
   129  	b.header.Coinbase = addr
   130  	b.gasPool = new(GasPool).AddGas(b.header.GasLimit)
   131  }
   132  
   133  // SetExtra sets the extra data field of the generated block.
   134  func (b *BlockGen) SetExtra(data []byte) {
   135  	b.header.Extra = data
   136  }
   137  
   138  // AddTx adds a transaction to the generated block. If no coinbase has
   139  // been set, the block's coinbase is set to the zero address.
   140  //
   141  // AddTx panics if the transaction cannot be executed. In addition to
   142  // the protocol-imposed limitations (gas limit, etc.), there are some
   143  // further limitations on the content of transactions that can be
   144  // added. Notably, contract code relying on the BLOCKHASH instruction
   145  // will panic during execution.
   146  func (b *BlockGen) AddTx(tx *types.Transaction) {
   147  	if b.gasPool == nil {
   148  		b.SetCoinbase(common.Address{})
   149  	}
   150  	b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
   151  	receipt, _, _, err := ApplyTransaction(b.config, nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed)
   152  	if err != nil {
   153  		panic(err)
   154  	}
   155  	b.txs = append(b.txs, tx)
   156  	b.receipts = append(b.receipts, receipt)
   157  }
   158  
   159  // Number returns the block number of the block being generated.
   160  func (b *BlockGen) Number() *big.Int {
   161  	return new(big.Int).Set(b.header.Number)
   162  }
   163  
   164  // AddUncheckedReceipts forcefully adds a receipts to the block without a
   165  // backing transaction.
   166  //
   167  // AddUncheckedReceipts will cause consensus failures when used during real
   168  // chain processing. This is best used in conjunction with raw block insertion.
   169  func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) {
   170  	b.receipts = append(b.receipts, receipt)
   171  }
   172  
   173  // TxNonce returns the next valid transaction nonce for the
   174  // account at addr. It panics if the account does not exist.
   175  func (b *BlockGen) TxNonce(addr common.Address) uint64 {
   176  	if !b.statedb.Exist(addr) {
   177  		panic("account does not exist")
   178  	}
   179  	return b.statedb.GetNonce(addr)
   180  }
   181  
   182  // AddUncle adds an uncle header to the generated block.
   183  func (b *BlockGen) AddUncle(h *types.Header) {
   184  	b.uncles = append(b.uncles, h)
   185  }
   186  
   187  // PrevBlock returns a previously generated block by number. It panics if
   188  // num is greater or equal to the number of the block being generated.
   189  // For index -1, PrevBlock returns the parent block given to GenerateChain.
   190  func (b *BlockGen) PrevBlock(index int) *types.Block {
   191  	if index >= b.i {
   192  		panic("block index out of range")
   193  	}
   194  	if index == -1 {
   195  		return b.parent
   196  	}
   197  	return b.chain[index]
   198  }
   199  
   200  // OffsetTime modifies the time instance of a block, implicitly changing its
   201  // associated difficulty. It's useful to test scenarios where forking is not
   202  // tied to chain length directly.
   203  func (b *BlockGen) OffsetTime(seconds int64) {
   204  	b.header.Time.Add(b.header.Time, new(big.Int).SetInt64(seconds))
   205  	if b.header.Time.Cmp(b.parent.Header().Time) <= 0 {
   206  		panic("block time out of range")
   207  	}
   208  	b.header.Difficulty = CalcDifficulty(MakeChainConfig(), b.header.Time.Uint64(), b.parent.Time().Uint64(), b.parent.Number(), b.parent.Difficulty())
   209  }
   210  
   211  // GenerateChain creates a chain of n blocks. The first block's
   212  // parent will be the provided parent. db is used to store
   213  // intermediate states and should contain the parent's state trie.
   214  //
   215  // The generator function is called with a new block generator for
   216  // every block. Any transactions and uncles added to the generator
   217  // become part of the block. If gen is nil, the blocks will be empty
   218  // and their coinbase will be the zero address.
   219  //
   220  // Blocks created by GenerateChain do not contain valid proof of work
   221  // values. Inserting them into BlockChain requires use of FakePow or
   222  // a similar non-validating proof of work implementation.
   223  func GenerateChain(config *ChainConfig, parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) {
   224  	blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
   225  	genblock := func(i int, h *types.Header, statedb *state.StateDB) (*types.Block, types.Receipts) {
   226  		b := &BlockGen{parent: parent, i: i, chain: blocks, header: h, statedb: statedb, config: config}
   227  
   228  		// Mutate the state and block according to any hard-fork specs
   229  		if config == nil {
   230  			config = DefaultConfigMainnet.ChainConfig // MakeChainConfig()
   231  		}
   232  		// Execute any user modifications to the block and finalize it
   233  		if gen != nil {
   234  			gen(i, b)
   235  		}
   236  		AccumulateRewards(config, statedb, h, b.uncles)
   237  		root, err := statedb.CommitTo(db, false)
   238  		if err != nil {
   239  			panic(fmt.Sprintf("state write error: %v", err))
   240  		}
   241  		h.Root = root
   242  		return types.NewBlock(h, b.txs, b.uncles, b.receipts), b.receipts
   243  	}
   244  	for i := 0; i < n; i++ {
   245  		statedb, err := state.New(parent.Root(), state.NewDatabase(db))
   246  		if err != nil {
   247  			panic(err)
   248  		}
   249  		header := makeHeader(config, parent, statedb)
   250  		block, receipt := genblock(i, header, statedb)
   251  		blocks[i] = block
   252  		receipts[i] = receipt
   253  		parent = block
   254  	}
   255  	return blocks, receipts
   256  }
   257  
   258  func makeHeader(config *ChainConfig, parent *types.Block, state *state.StateDB) *types.Header {
   259  	var time *big.Int
   260  	if parent.Time() == nil {
   261  		time = big.NewInt(10)
   262  	} else {
   263  		time = new(big.Int).Add(parent.Time(), big.NewInt(10)) // block time is fixed at 10 seconds
   264  	}
   265  	return &types.Header{
   266  		Root:       state.IntermediateRoot(false),
   267  		ParentHash: parent.Hash(),
   268  		Coinbase:   parent.Coinbase(),
   269  		Difficulty: CalcDifficulty(config, time.Uint64(), new(big.Int).Sub(time, big.NewInt(10)).Uint64(), parent.Number(), parent.Difficulty()),
   270  		GasLimit:   CalcGasLimit(parent),
   271  		GasUsed:    new(big.Int),
   272  		Number:     new(big.Int).Add(parent.Number(), common.Big1),
   273  		Time:       time,
   274  	}
   275  }
   276  
   277  // newCanonical creates a chain database, and injects a deterministic canonical
   278  // chain. Depending on the full flag, if creates either a full block chain or a
   279  // header only chain.
   280  func newCanonical(config *ChainConfig, n int, full bool) (ethdb.Database, *BlockChain, error) {
   281  	// Create the new chain database
   282  	db, err := ethdb.NewMemDatabase()
   283  	if err != nil {
   284  		return nil, nil, err
   285  	}
   286  
   287  	evmux := &event.TypeMux{}
   288  
   289  	// Initialize a fresh chain with only a genesis block
   290  	genesis, err := WriteGenesisBlock(db, DefaultConfigMorden.Genesis)
   291  	if err != nil {
   292  		return nil, nil, err
   293  	}
   294  
   295  	blockchain, err := NewBlockChain(db, MakeChainConfig(), FakePow{}, evmux)
   296  	if err != nil {
   297  		return nil, nil, err
   298  	}
   299  
   300  	// Create and inject the requested chain
   301  	if n == 0 {
   302  		return db, blockchain, nil
   303  	}
   304  	if full {
   305  		// Full block-chain requested
   306  		blocks := makeBlockChain(config, genesis, n, db, canonicalSeed)
   307  		res := blockchain.InsertChain(blocks)
   308  		return db, blockchain, res.Error
   309  	}
   310  	// Header-only chain requested
   311  	headers := makeHeaderChain(config, genesis.Header(), n, db, canonicalSeed)
   312  	res := blockchain.InsertHeaderChain(headers, 1)
   313  	return db, blockchain, res.Error
   314  }
   315  
   316  // makeHeaderChain creates a deterministic chain of headers rooted at parent.
   317  func makeHeaderChain(config *ChainConfig, parent *types.Header, n int, db ethdb.Database, seed int) []*types.Header {
   318  	blocks := makeBlockChain(config, types.NewBlockWithHeader(parent), n, db, seed)
   319  	headers := make([]*types.Header, len(blocks))
   320  	for i, block := range blocks {
   321  		headers[i] = block.Header()
   322  	}
   323  	return headers
   324  }
   325  
   326  // makeBlockChain creates a deterministic chain of blocks rooted at parent.
   327  func makeBlockChain(config *ChainConfig, parent *types.Block, n int, db ethdb.Database, seed int) []*types.Block {
   328  	blocks, _ := GenerateChain(config, parent, db, n, func(i int, b *BlockGen) {
   329  		b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
   330  	})
   331  	return blocks
   332  }