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 }