| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | package core | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-08-18 14:14:45 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-03-03 17:55:23 +01:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-04-01 23:58:26 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/state" | 
					
						
							| 
									
										
										
										
											2015-03-16 23:48:18 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2016-03-01 23:32:43 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/vm" | 
					
						
							| 
									
										
										
										
											2015-09-14 09:35:57 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/ethdb" | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 	"github.com/ethereum/go-ethereum/event" | 
					
						
							| 
									
										
										
										
											2016-07-14 18:17:03 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/params" | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 	"github.com/ethereum/go-ethereum/pow" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-01 23:32:43 +01:00
										 |  |  | /* | 
					
						
							|  |  |  |  * TODO: move this to another package. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MakeChainConfig returns a new ChainConfig with the ethereum default chain settings. | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | func MakeChainConfig() *params.ChainConfig { | 
					
						
							|  |  |  | 	return ¶ms.ChainConfig{ | 
					
						
							| 
									
										
										
										
											2016-07-14 18:17:03 +03:00
										 |  |  | 		HomesteadBlock: big.NewInt(0), | 
					
						
							|  |  |  | 		DAOForkBlock:   nil, | 
					
						
							|  |  |  | 		DAOForkSupport: true, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-01 23:32:43 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // FakePow is a non-validating proof of work implementation. | 
					
						
							|  |  |  | // It returns true from Verify for any block. | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | type FakePow struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-12 07:45:23 +02:00
										 |  |  | func (f FakePow) Search(block pow.Block, stop <-chan struct{}, index int) (uint64, []byte) { | 
					
						
							| 
									
										
										
										
											2015-05-05 08:24:15 +02:00
										 |  |  | 	return 0, nil | 
					
						
							| 
									
										
										
										
											2015-02-28 14:58:37 -05:00
										 |  |  | } | 
					
						
							|  |  |  | func (f FakePow) Verify(block pow.Block) bool { return true } | 
					
						
							|  |  |  | func (f FakePow) GetHashrate() int64          { return 0 } | 
					
						
							|  |  |  | func (f FakePow) Turbo(bool)                  {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // So we can deterministically seed different blockchains | 
					
						
							|  |  |  | var ( | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	canonicalSeed = 1 | 
					
						
							|  |  |  | 	forkSeed      = 2 | 
					
						
							| 
									
										
										
										
											2015-02-28 14:58:37 -05:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // BlockGen creates blocks for testing. | 
					
						
							|  |  |  | // See GenerateChain for a detailed explanation. | 
					
						
							|  |  |  | type BlockGen struct { | 
					
						
							|  |  |  | 	i       int | 
					
						
							|  |  |  | 	parent  *types.Block | 
					
						
							|  |  |  | 	chain   []*types.Block | 
					
						
							|  |  |  | 	header  *types.Header | 
					
						
							|  |  |  | 	statedb *state.StateDB | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-02 12:55:11 +02:00
										 |  |  | 	gasPool  *GasPool | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	txs      []*types.Transaction | 
					
						
							|  |  |  | 	receipts []*types.Receipt | 
					
						
							|  |  |  | 	uncles   []*types.Header | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	config *params.ChainConfig | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // SetCoinbase sets the coinbase of the generated block. | 
					
						
							|  |  |  | // It can be called at most once. | 
					
						
							|  |  |  | func (b *BlockGen) SetCoinbase(addr common.Address) { | 
					
						
							| 
									
										
										
										
											2015-09-02 12:55:11 +02:00
										 |  |  | 	if b.gasPool != nil { | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		if len(b.txs) > 0 { | 
					
						
							|  |  |  | 			panic("coinbase must be set before adding transactions") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		panic("coinbase can only be set once") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	b.header.Coinbase = addr | 
					
						
							| 
									
										
										
										
											2015-09-02 12:55:11 +02:00
										 |  |  | 	b.gasPool = new(GasPool).AddGas(b.header.GasLimit) | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // SetExtra sets the extra data field of the generated block. | 
					
						
							|  |  |  | func (b *BlockGen) SetExtra(data []byte) { | 
					
						
							|  |  |  | 	b.header.Extra = data | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // AddTx adds a transaction to the generated block. If no coinbase has | 
					
						
							|  |  |  | // been set, the block's coinbase is set to the zero address. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // AddTx panics if the transaction cannot be executed. In addition to | 
					
						
							|  |  |  | // the protocol-imposed limitations (gas limit, etc.), there are some | 
					
						
							|  |  |  | // further limitations on the content of transactions that can be | 
					
						
							|  |  |  | // added. Notably, contract code relying on the BLOCKHASH instruction | 
					
						
							|  |  |  | // will panic during execution. | 
					
						
							|  |  |  | func (b *BlockGen) AddTx(tx *types.Transaction) { | 
					
						
							| 
									
										
										
										
											2015-09-02 12:55:11 +02:00
										 |  |  | 	if b.gasPool == nil { | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		b.SetCoinbase(common.Address{}) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-01 00:11:24 +01:00
										 |  |  | 	b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs)) | 
					
						
							| 
									
										
										
										
											2017-01-05 11:52:10 +01:00
										 |  |  | 	receipt, _, err := ApplyTransaction(b.config, nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{}) | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		panic(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	b.txs = append(b.txs, tx) | 
					
						
							|  |  |  | 	b.receipts = append(b.receipts, receipt) | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 14:13:30 +01:00
										 |  |  | // Number returns the block number of the block being generated. | 
					
						
							|  |  |  | func (b *BlockGen) Number() *big.Int { | 
					
						
							|  |  |  | 	return new(big.Int).Set(b.header.Number) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-12 17:58:51 +02:00
										 |  |  | // AddUncheckedReceipts forcefully adds a receipts to the block without a | 
					
						
							|  |  |  | // backing transaction. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // AddUncheckedReceipts will cause consensus failures when used during real | 
					
						
							| 
									
										
										
										
											2016-03-15 11:08:18 -07:00
										 |  |  | // chain processing. This is best used in conjunction with raw block insertion. | 
					
						
							| 
									
										
										
										
											2015-10-12 17:58:51 +02:00
										 |  |  | func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) { | 
					
						
							| 
									
										
										
										
											2015-10-12 17:54:59 +02:00
										 |  |  | 	b.receipts = append(b.receipts, receipt) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // TxNonce returns the next valid transaction nonce for the | 
					
						
							|  |  |  | // account at addr. It panics if the account does not exist. | 
					
						
							|  |  |  | func (b *BlockGen) TxNonce(addr common.Address) uint64 { | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | 	if !b.statedb.Exist(addr) { | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		panic("account does not exist") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return b.statedb.GetNonce(addr) | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // AddUncle adds an uncle header to the generated block. | 
					
						
							|  |  |  | func (b *BlockGen) AddUncle(h *types.Header) { | 
					
						
							|  |  |  | 	b.uncles = append(b.uncles, h) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-16 12:41:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // PrevBlock returns a previously generated block by number. It panics if | 
					
						
							|  |  |  | // num is greater or equal to the number of the block being generated. | 
					
						
							|  |  |  | // For index -1, PrevBlock returns the parent block given to GenerateChain. | 
					
						
							|  |  |  | func (b *BlockGen) PrevBlock(index int) *types.Block { | 
					
						
							|  |  |  | 	if index >= b.i { | 
					
						
							|  |  |  | 		panic("block index out of range") | 
					
						
							| 
									
										
										
										
											2015-06-16 12:41:50 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	if index == -1 { | 
					
						
							|  |  |  | 		return b.parent | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return b.chain[index] | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-17 13:32:00 +03:00
										 |  |  | // OffsetTime modifies the time instance of a block, implicitly changing its | 
					
						
							|  |  |  | // associated difficulty. It's useful to test scenarios where forking is not | 
					
						
							|  |  |  | // tied to chain length directly. | 
					
						
							|  |  |  | func (b *BlockGen) OffsetTime(seconds int64) { | 
					
						
							|  |  |  | 	b.header.Time.Add(b.header.Time, new(big.Int).SetInt64(seconds)) | 
					
						
							|  |  |  | 	if b.header.Time.Cmp(b.parent.Header().Time) <= 0 { | 
					
						
							|  |  |  | 		panic("block time out of range") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-31 17:43:41 +02:00
										 |  |  | 	b.header.Difficulty = CalcDifficulty(MakeChainConfig(), b.header.Time.Uint64(), b.parent.Time().Uint64(), b.parent.Number(), b.parent.Difficulty()) | 
					
						
							| 
									
										
										
										
											2015-09-17 13:32:00 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // GenerateChain creates a chain of n blocks. The first block's | 
					
						
							|  |  |  | // parent will be the provided parent. db is used to store | 
					
						
							|  |  |  | // intermediate states and should contain the parent's state trie. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The generator function is called with a new block generator for | 
					
						
							|  |  |  | // every block. Any transactions and uncles added to the generator | 
					
						
							|  |  |  | // become part of the block. If gen is nil, the blocks will be empty | 
					
						
							|  |  |  | // and their coinbase will be the zero address. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Blocks created by GenerateChain do not contain valid proof of work | 
					
						
							| 
									
										
										
										
											2015-08-31 17:09:50 +02:00
										 |  |  | // values. Inserting them into BlockChain requires use of FakePow or | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | // a similar non-validating proof of work implementation. | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | func GenerateChain(config *params.ChainConfig, parent *types.Block, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { | 
					
						
							| 
									
										
										
										
											2015-09-30 19:23:31 +03:00
										 |  |  | 	blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n) | 
					
						
							| 
									
										
										
										
											2016-01-11 16:53:06 +02:00
										 |  |  | 	genblock := func(i int, h *types.Header, statedb *state.StateDB) (*types.Block, types.Receipts) { | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 		b := &BlockGen{parent: parent, i: i, chain: blocks, header: h, statedb: statedb, config: config} | 
					
						
							| 
									
										
										
										
											2016-07-14 18:17:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Mutate the state and block according to any hard-fork specs | 
					
						
							|  |  |  | 		if config == nil { | 
					
						
							|  |  |  | 			config = MakeChainConfig() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if daoBlock := config.DAOForkBlock; daoBlock != nil { | 
					
						
							|  |  |  | 			limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) | 
					
						
							|  |  |  | 			if h.Number.Cmp(daoBlock) >= 0 && h.Number.Cmp(limit) < 0 { | 
					
						
							|  |  |  | 				if config.DAOForkSupport { | 
					
						
							|  |  |  | 					h.Extra = common.CopyBytes(params.DAOForkBlockExtra) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(h.Number) == 0 { | 
					
						
							|  |  |  | 			ApplyDAOHardFork(statedb) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Execute any user modifications to the block and finalize it | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		if gen != nil { | 
					
						
							|  |  |  | 			gen(i, b) | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		AccumulateRewards(statedb, h, b.uncles) | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 		root, err := statedb.Commit(config.IsEIP158(h.Number)) | 
					
						
							| 
									
										
										
										
											2015-08-18 14:14:45 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			panic(fmt.Sprintf("state write error: %v", err)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		h.Root = root | 
					
						
							| 
									
										
										
										
											2015-09-30 19:23:31 +03:00
										 |  |  | 		return types.NewBlock(h, b.txs, b.uncles, b.receipts), b.receipts | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for i := 0; i < n; i++ { | 
					
						
							| 
									
										
										
										
											2016-01-11 16:53:06 +02:00
										 |  |  | 		statedb, err := state.New(parent.Root(), db) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			panic(err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 		header := makeHeader(config, parent, statedb) | 
					
						
							| 
									
										
										
										
											2016-01-11 16:53:06 +02:00
										 |  |  | 		block, receipt := genblock(i, header, statedb) | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 		blocks[i] = block | 
					
						
							| 
									
										
										
										
											2015-09-30 19:23:31 +03:00
										 |  |  | 		receipts[i] = receipt | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 		parent = block | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-30 19:23:31 +03:00
										 |  |  | 	return blocks, receipts | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | func makeHeader(config *params.ChainConfig, parent *types.Block, state *state.StateDB) *types.Header { | 
					
						
							| 
									
										
										
										
											2015-08-24 02:52:53 +02:00
										 |  |  | 	var time *big.Int | 
					
						
							|  |  |  | 	if parent.Time() == nil { | 
					
						
							|  |  |  | 		time = big.NewInt(10) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		time = new(big.Int).Add(parent.Time(), big.NewInt(10)) // block time is fixed at 10 seconds | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	return &types.Header{ | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 		Root:       state.IntermediateRoot(config.IsEIP158(parent.Number())), | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		ParentHash: parent.Hash(), | 
					
						
							|  |  |  | 		Coinbase:   parent.Coinbase(), | 
					
						
							| 
									
										
										
										
											2016-03-31 17:43:41 +02:00
										 |  |  | 		Difficulty: CalcDifficulty(MakeChainConfig(), time.Uint64(), new(big.Int).Sub(time, big.NewInt(10)).Uint64(), parent.Number(), parent.Difficulty()), | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		GasLimit:   CalcGasLimit(parent), | 
					
						
							|  |  |  | 		GasUsed:    new(big.Int), | 
					
						
							|  |  |  | 		Number:     new(big.Int).Add(parent.Number(), common.Big1), | 
					
						
							| 
									
										
										
										
											2015-08-24 02:52:53 +02:00
										 |  |  | 		Time:       time, | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | // newCanonical creates a chain database, and injects a deterministic canonical | 
					
						
							|  |  |  | // chain. Depending on the full flag, if creates either a full block chain or a | 
					
						
							|  |  |  | // header only chain. | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | func newCanonical(n int, full bool) (ethdb.Database, *BlockChain, error) { | 
					
						
							| 
									
										
										
										
											2016-03-15 11:08:18 -07:00
										 |  |  | 	// Create the new chain database | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | 	db, _ := ethdb.NewMemDatabase() | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	evmux := &event.TypeMux{} | 
					
						
							| 
									
										
										
										
											2015-07-10 14:29:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | 	// Initialize a fresh chain with only a genesis block | 
					
						
							| 
									
										
										
										
											2015-11-17 18:33:25 +02:00
										 |  |  | 	genesis, _ := WriteTestNetGenesisBlock(db) | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 11:19:50 +00:00
										 |  |  | 	blockchain, _ := NewBlockChain(db, MakeChainConfig(), FakePow{}, evmux, vm.Config{}) | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | 	// Create and inject the requested chain | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 	if n == 0 { | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 		return db, blockchain, nil | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if full { | 
					
						
							|  |  |  | 		// Full block-chain requested | 
					
						
							|  |  |  | 		blocks := makeBlockChain(genesis, n, db, canonicalSeed) | 
					
						
							|  |  |  | 		_, err := blockchain.InsertChain(blocks) | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 		return db, blockchain, err | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | 	// Header-only chain requested | 
					
						
							|  |  |  | 	headers := makeHeaderChain(genesis.Header(), n, db, canonicalSeed) | 
					
						
							| 
									
										
										
										
											2015-10-07 12:14:30 +03:00
										 |  |  | 	_, err := blockchain.InsertHeaderChain(headers, 1) | 
					
						
							| 
									
										
										
										
											2015-10-19 16:08:17 +02:00
										 |  |  | 	return db, blockchain, err | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | // makeHeaderChain creates a deterministic chain of headers rooted at parent. | 
					
						
							|  |  |  | func makeHeaderChain(parent *types.Header, n int, db ethdb.Database, seed int) []*types.Header { | 
					
						
							|  |  |  | 	blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, db, seed) | 
					
						
							|  |  |  | 	headers := make([]*types.Header, len(blocks)) | 
					
						
							|  |  |  | 	for i, block := range blocks { | 
					
						
							|  |  |  | 		headers[i] = block.Header() | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | 	return headers | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | // makeBlockChain creates a deterministic chain of blocks rooted at parent. | 
					
						
							|  |  |  | func makeBlockChain(parent *types.Block, n int, db ethdb.Database, seed int) []*types.Block { | 
					
						
							| 
									
										
										
										
											2016-10-20 13:36:29 +02:00
										 |  |  | 	blocks, _ := GenerateChain(params.TestChainConfig, parent, db, n, func(i int, b *BlockGen) { | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-09-30 19:23:31 +03:00
										 |  |  | 	return blocks | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | } |