| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 	"github.com/ethereum/go-ethereum/consensus" | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/consensus/misc" | 
					
						
							| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											2016-07-14 18:17:03 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/params" | 
					
						
							| 
									
										
										
										
											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 { | 
					
						
							| 
									
										
										
										
											2018-11-07 15:07:43 +01:00
										 |  |  | 	i       int | 
					
						
							|  |  |  | 	parent  *types.Block | 
					
						
							|  |  |  | 	chain   []*types.Block | 
					
						
							|  |  |  | 	header  *types.Header | 
					
						
							|  |  |  | 	statedb *state.StateDB | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 	engine consensus.Engine | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-10 17:12:39 +03:00
										 |  |  | // SetNonce sets the nonce field of the generated block. | 
					
						
							|  |  |  | func (b *BlockGen) SetNonce(nonce types.BlockNonce) { | 
					
						
							|  |  |  | 	b.header.Nonce = nonce | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2018-01-29 18:47:08 +08:00
										 |  |  | 	b.AddTxWithChain(nil, tx) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // AddTxWithChain adds a transaction to the generated block. If no coinbase has | 
					
						
							|  |  |  | // been set, the block's coinbase is set to the zero address. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // AddTxWithChain 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. If contract code relies on the BLOCKHASH instruction, | 
					
						
							|  |  |  | // the block in chain will be returned. | 
					
						
							|  |  |  | func (b *BlockGen) AddTxWithChain(bc *BlockChain, 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{}) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-01 22:36:51 +01:00
										 |  |  | 	b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) | 
					
						
							| 
									
										
										
										
											2018-01-29 18:47:08 +08:00
										 |  |  | 	receipt, _, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, 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) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-11 09:55:48 +08:00
										 |  |  | // AddUncheckedReceipt forcefully adds a receipts to the block without a | 
					
						
							| 
									
										
										
										
											2015-10-12 17:58:51 +02:00
										 |  |  | // backing transaction. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2017-05-11 09:55:48 +08:00
										 |  |  | // AddUncheckedReceipt 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 { | 
					
						
							| 
									
										
										
										
											2018-11-07 15:07:43 +01:00
										 |  |  | 		panic(fmt.Errorf("block index %d out of range (%d,%d)", index, -1, b.i)) | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2019-04-02 22:28:48 +02:00
										 |  |  | 	b.header.Time += uint64(seconds) | 
					
						
							|  |  |  | 	if b.header.Time <= b.parent.Header().Time { | 
					
						
							| 
									
										
										
										
											2015-09-17 13:32:00 +03:00
										 |  |  | 		panic("block time out of range") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-07 15:07:43 +01:00
										 |  |  | 	chainreader := &fakeChainReader{config: b.config} | 
					
						
							| 
									
										
										
										
											2019-04-02 22:28:48 +02:00
										 |  |  | 	b.header.Difficulty = b.engine.CalcDifficulty(chainreader, b.header.Time, b.parent.Header()) | 
					
						
							| 
									
										
										
										
											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. | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | func GenerateChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { | 
					
						
							| 
									
										
										
										
											2017-03-02 14:03:33 +01:00
										 |  |  | 	if config == nil { | 
					
						
							|  |  |  | 		config = params.TestChainConfig | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-30 19:23:31 +03:00
										 |  |  | 	blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n) | 
					
						
							| 
									
										
										
										
											2018-11-07 15:07:43 +01:00
										 |  |  | 	chainreader := &fakeChainReader{config: config} | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 	genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) { | 
					
						
							| 
									
										
										
										
											2018-11-07 15:07:43 +01:00
										 |  |  | 		b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine} | 
					
						
							| 
									
										
										
										
											2019-02-08 11:11:31 +02:00
										 |  |  | 		b.header = makeHeader(chainreader, parent, statedb, b.engine) | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-14 18:17:03 +03:00
										 |  |  | 		// Mutate the state and block according to any hard-fork specs | 
					
						
							|  |  |  | 		if daoBlock := config.DAOForkBlock; daoBlock != nil { | 
					
						
							|  |  |  | 			limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 			if b.header.Number.Cmp(daoBlock) >= 0 && b.header.Number.Cmp(limit) < 0 { | 
					
						
							| 
									
										
										
										
											2016-07-14 18:17:03 +03:00
										 |  |  | 				if config.DAOForkSupport { | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 					b.header.Extra = common.CopyBytes(params.DAOForkBlockExtra) | 
					
						
							| 
									
										
										
										
											2016-07-14 18:17:03 +03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 		if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 { | 
					
						
							| 
									
										
										
										
											2017-04-05 01:16:29 +03:00
										 |  |  | 			misc.ApplyDAOHardFork(statedb) | 
					
						
							| 
									
										
										
										
											2016-07-14 18:17:03 +03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-10 17:12:39 +03:00
										 |  |  | 		// Execute any user modifications to the block | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		if gen != nil { | 
					
						
							|  |  |  | 			gen(i, b) | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 		if b.engine != nil { | 
					
						
							| 
									
										
										
										
											2018-09-10 17:12:39 +03:00
										 |  |  | 			// Finalize and seal the block | 
					
						
							| 
									
										
										
										
											2018-11-07 15:07:43 +01:00
										 |  |  | 			block, _ := b.engine.Finalize(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts) | 
					
						
							| 
									
										
										
										
											2018-09-10 17:12:39 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 			// Write state changes to db | 
					
						
							| 
									
										
										
										
											2018-02-05 18:40:32 +02:00
										 |  |  | 			root, err := statedb.Commit(config.IsEIP158(b.header.Number)) | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				panic(fmt.Sprintf("state write error: %v", err)) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-02-05 18:40:32 +02:00
										 |  |  | 			if err := statedb.Database().TrieDB().Commit(root, false); err != nil { | 
					
						
							|  |  |  | 				panic(fmt.Sprintf("trie write error: %v", err)) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 			return block, b.receipts | 
					
						
							| 
									
										
										
										
											2015-08-18 14:14:45 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 		return nil, nil | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	for i := 0; i < n; i++ { | 
					
						
							| 
									
										
										
										
											2017-06-27 15:57:06 +02:00
										 |  |  | 		statedb, err := state.New(parent.Root(), state.NewDatabase(db)) | 
					
						
							| 
									
										
										
										
											2016-01-11 16:53:06 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			panic(err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 		block, receipt := genblock(i, parent, 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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { | 
					
						
							| 
									
										
										
										
											2019-04-02 22:28:48 +02:00
										 |  |  | 	var time uint64 | 
					
						
							|  |  |  | 	if parent.Time() == 0 { | 
					
						
							|  |  |  | 		time = 10 | 
					
						
							| 
									
										
										
										
											2015-08-24 02:52:53 +02:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2019-04-02 22:28:48 +02:00
										 |  |  | 		time = parent.Time() + 10 // block time is fixed at 10 seconds | 
					
						
							| 
									
										
										
										
											2015-08-24 02:52:53 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-01 22:36:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 	return &types.Header{ | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | 		Root:       state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())), | 
					
						
							| 
									
										
										
										
											2015-06-19 01:57:16 +02:00
										 |  |  | 		ParentHash: parent.Hash(), | 
					
						
							|  |  |  | 		Coinbase:   parent.Coinbase(), | 
					
						
							| 
									
										
										
										
											2019-04-02 22:28:48 +02:00
										 |  |  | 		Difficulty: engine.CalcDifficulty(chain, time, &types.Header{ | 
					
						
							| 
									
										
										
										
											2017-02-01 22:36:51 +01:00
										 |  |  | 			Number:     parent.Number(), | 
					
						
							| 
									
										
										
										
											2019-04-02 22:28:48 +02:00
										 |  |  | 			Time:       time - 10, | 
					
						
							| 
									
										
										
										
											2017-02-01 22:36:51 +01:00
										 |  |  | 			Difficulty: parent.Difficulty(), | 
					
						
							| 
									
										
										
										
											2017-06-29 13:13:00 +03:00
										 |  |  | 			UncleHash:  parent.UncleHash(), | 
					
						
							| 
									
										
										
										
											2017-02-01 22:36:51 +01:00
										 |  |  | 		}), | 
					
						
							| 
									
										
										
										
											2018-08-29 12:21:12 +03:00
										 |  |  | 		GasLimit: CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit()), | 
					
						
							| 
									
										
										
										
											2017-02-01 22:36:51 +01:00
										 |  |  | 		Number:   new(big.Int).Add(parent.Number(), common.Big1), | 
					
						
							|  |  |  | 		Time:     time, | 
					
						
							| 
									
										
										
										
											2015-02-27 16:05:03 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | // makeHeaderChain creates a deterministic chain of headers rooted at parent. | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | func makeHeaderChain(parent *types.Header, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Header { | 
					
						
							|  |  |  | 	blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed) | 
					
						
							| 
									
										
										
										
											2015-09-21 15:36:29 +03:00
										 |  |  | 	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. | 
					
						
							| 
									
										
										
										
											2017-12-22 20:37:50 +08:00
										 |  |  | func makeBlockChain(parent *types.Block, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Block { | 
					
						
							|  |  |  | 	blocks, _ := GenerateChain(params.TestChainConfig, parent, engine, 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
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-11-07 15:07:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | type fakeChainReader struct { | 
					
						
							|  |  |  | 	config  *params.ChainConfig | 
					
						
							|  |  |  | 	genesis *types.Block | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Config returns the chain configuration. | 
					
						
							|  |  |  | func (cr *fakeChainReader) Config() *params.ChainConfig { | 
					
						
							|  |  |  | 	return cr.config | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (cr *fakeChainReader) CurrentHeader() *types.Header                            { return nil } | 
					
						
							|  |  |  | func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *types.Header           { return nil } | 
					
						
							|  |  |  | func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *types.Header          { return nil } | 
					
						
							|  |  |  | func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *types.Header { return nil } | 
					
						
							|  |  |  | func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *types.Block   { return nil } |