github.com/ethereum/go-ethereum@v1.16.1/core/chain_makers.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/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/consensus" 25 "github.com/ethereum/go-ethereum/consensus/misc" 26 "github.com/ethereum/go-ethereum/consensus/misc/eip1559" 27 "github.com/ethereum/go-ethereum/consensus/misc/eip4844" 28 "github.com/ethereum/go-ethereum/core/rawdb" 29 "github.com/ethereum/go-ethereum/core/state" 30 "github.com/ethereum/go-ethereum/core/types" 31 "github.com/ethereum/go-ethereum/core/vm" 32 "github.com/ethereum/go-ethereum/ethdb" 33 "github.com/ethereum/go-ethereum/params" 34 "github.com/ethereum/go-ethereum/triedb" 35 "github.com/ethereum/go-verkle" 36 "github.com/holiman/uint256" 37 ) 38 39 // BlockGen creates blocks for testing. 40 // See GenerateChain for a detailed explanation. 41 type BlockGen struct { 42 i int 43 cm *chainMaker 44 parent *types.Block 45 header *types.Header 46 statedb *state.StateDB 47 48 gasPool *GasPool 49 txs []*types.Transaction 50 receipts []*types.Receipt 51 uncles []*types.Header 52 withdrawals []*types.Withdrawal 53 54 engine consensus.Engine 55 } 56 57 // SetCoinbase sets the coinbase of the generated block. 58 // It can be called at most once. 59 func (b *BlockGen) SetCoinbase(addr common.Address) { 60 if b.gasPool != nil { 61 if len(b.txs) > 0 { 62 panic("coinbase must be set before adding transactions") 63 } 64 panic("coinbase can only be set once") 65 } 66 b.header.Coinbase = addr 67 b.gasPool = new(GasPool).AddGas(b.header.GasLimit) 68 } 69 70 // SetExtra sets the extra data field of the generated block. 71 func (b *BlockGen) SetExtra(data []byte) { 72 b.header.Extra = data 73 } 74 75 // SetNonce sets the nonce field of the generated block. 76 func (b *BlockGen) SetNonce(nonce types.BlockNonce) { 77 b.header.Nonce = nonce 78 } 79 80 // SetDifficulty sets the difficulty field of the generated block. This method is 81 // useful for Clique tests where the difficulty does not depend on time. For the 82 // ethash tests, please use OffsetTime, which implicitly recalculates the diff. 83 func (b *BlockGen) SetDifficulty(diff *big.Int) { 84 b.header.Difficulty = diff 85 } 86 87 // SetPoS makes the header a PoS-header (0 difficulty) 88 func (b *BlockGen) SetPoS() { 89 b.header.Difficulty = new(big.Int) 90 } 91 92 // Difficulty returns the currently calculated difficulty of the block. 93 func (b *BlockGen) Difficulty() *big.Int { 94 return new(big.Int).Set(b.header.Difficulty) 95 } 96 97 // SetParentBeaconRoot sets the parent beacon root field of the generated 98 // block. 99 func (b *BlockGen) SetParentBeaconRoot(root common.Hash) { 100 b.header.ParentBeaconRoot = &root 101 blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase) 102 ProcessBeaconBlockRoot(root, vm.NewEVM(blockContext, b.statedb, b.cm.config, vm.Config{})) 103 } 104 105 // addTx adds a transaction to the generated block. If no coinbase has 106 // been set, the block's coinbase is set to the zero address. 107 // 108 // There are a few options can be passed as well in order to run some 109 // customized rules. 110 // - bc: enables the ability to query historical block hashes for BLOCKHASH 111 // - vmConfig: extends the flexibility for customizing evm rules, e.g. enable extra EIPs 112 func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transaction) { 113 if b.gasPool == nil { 114 b.SetCoinbase(common.Address{}) 115 } 116 var ( 117 blockContext = NewEVMBlockContext(b.header, bc, &b.header.Coinbase) 118 evm = vm.NewEVM(blockContext, b.statedb, b.cm.config, vmConfig) 119 ) 120 b.statedb.SetTxContext(tx.Hash(), len(b.txs)) 121 receipt, err := ApplyTransaction(evm, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed) 122 if err != nil { 123 panic(err) 124 } 125 // Merge the tx-local access event into the "block-local" one, in order to collect 126 // all values, so that the witness can be built. 127 if b.statedb.Database().TrieDB().IsVerkle() { 128 b.statedb.AccessEvents().Merge(evm.AccessEvents) 129 } 130 b.txs = append(b.txs, tx) 131 b.receipts = append(b.receipts, receipt) 132 if b.header.BlobGasUsed != nil { 133 *b.header.BlobGasUsed += receipt.BlobGasUsed 134 } 135 } 136 137 // AddTx adds a transaction to the generated block. If no coinbase has 138 // been set, the block's coinbase is set to the zero address. 139 // 140 // AddTx panics if the transaction cannot be executed. In addition to the protocol-imposed 141 // limitations (gas limit, etc.), there are some further limitations on the content of 142 // transactions that can be added. Notably, contract code relying on the BLOCKHASH 143 // instruction will panic during execution if it attempts to access a block number outside 144 // of the range created by GenerateChain. 145 func (b *BlockGen) AddTx(tx *types.Transaction) { 146 // Wrap the chain config in an empty BlockChain object to satisfy ChainContext. 147 bc := &BlockChain{chainConfig: b.cm.config} 148 b.addTx(bc, vm.Config{}, tx) 149 } 150 151 // AddTxWithChain adds a transaction to the generated block. If no coinbase has 152 // been set, the block's coinbase is set to the zero address. 153 // 154 // AddTxWithChain panics if the transaction cannot be executed. In addition to the 155 // protocol-imposed limitations (gas limit, etc.), there are some further limitations on 156 // the content of transactions that can be added. If contract code relies on the BLOCKHASH 157 // instruction, the block in chain will be returned. 158 func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) { 159 b.addTx(bc, vm.Config{}, tx) 160 } 161 162 // AddTxWithVMConfig adds a transaction to the generated block. If no coinbase has 163 // been set, the block's coinbase is set to the zero address. 164 // The evm interpreter can be customized with the provided vm config. 165 func (b *BlockGen) AddTxWithVMConfig(tx *types.Transaction, config vm.Config) { 166 b.addTx(nil, config, tx) 167 } 168 169 // GetBalance returns the balance of the given address at the generated block. 170 func (b *BlockGen) GetBalance(addr common.Address) *uint256.Int { 171 return b.statedb.GetBalance(addr) 172 } 173 174 // AddUncheckedTx forcefully adds a transaction to the block without any validation. 175 // 176 // AddUncheckedTx will cause consensus failures when used during real 177 // chain processing. This is best used in conjunction with raw block insertion. 178 func (b *BlockGen) AddUncheckedTx(tx *types.Transaction) { 179 b.txs = append(b.txs, tx) 180 } 181 182 // Number returns the block number of the block being generated. 183 func (b *BlockGen) Number() *big.Int { 184 return new(big.Int).Set(b.header.Number) 185 } 186 187 // Timestamp returns the timestamp of the block being generated. 188 func (b *BlockGen) Timestamp() uint64 { 189 return b.header.Time 190 } 191 192 // BaseFee returns the EIP-1559 base fee of the block being generated. 193 func (b *BlockGen) BaseFee() *big.Int { 194 return new(big.Int).Set(b.header.BaseFee) 195 } 196 197 // Gas returns the amount of gas left in the current block. 198 func (b *BlockGen) Gas() uint64 { 199 return b.header.GasLimit - b.header.GasUsed 200 } 201 202 // Signer returns a valid signer instance for the current block. 203 func (b *BlockGen) Signer() types.Signer { 204 return types.MakeSigner(b.cm.config, b.header.Number, b.header.Time) 205 } 206 207 // AddUncheckedReceipt forcefully adds a receipts to the block without a 208 // backing transaction. 209 // 210 // AddUncheckedReceipt will cause consensus failures when used during real 211 // chain processing. This is best used in conjunction with raw block insertion. 212 func (b *BlockGen) AddUncheckedReceipt(receipt *types.Receipt) { 213 b.receipts = append(b.receipts, receipt) 214 } 215 216 // TxNonce returns the next valid transaction nonce for the 217 // account at addr. It panics if the account does not exist. 218 func (b *BlockGen) TxNonce(addr common.Address) uint64 { 219 if !b.statedb.Exist(addr) { 220 panic("account does not exist") 221 } 222 return b.statedb.GetNonce(addr) 223 } 224 225 // AddUncle adds an uncle header to the generated block. 226 func (b *BlockGen) AddUncle(h *types.Header) { 227 // The uncle will have the same timestamp and auto-generated difficulty 228 h.Time = b.header.Time 229 230 var parent *types.Header 231 for i := b.i - 1; i >= 0; i-- { 232 if b.cm.chain[i].Hash() == h.ParentHash { 233 parent = b.cm.chain[i].Header() 234 break 235 } 236 } 237 h.Difficulty = b.engine.CalcDifficulty(b.cm, b.header.Time, parent) 238 239 // The gas limit and price should be derived from the parent 240 h.GasLimit = parent.GasLimit 241 if b.cm.config.IsLondon(h.Number) { 242 h.BaseFee = eip1559.CalcBaseFee(b.cm.config, parent) 243 if !b.cm.config.IsLondon(parent.Number) { 244 parentGasLimit := parent.GasLimit * b.cm.config.ElasticityMultiplier() 245 h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) 246 } 247 } 248 b.uncles = append(b.uncles, h) 249 } 250 251 // AddWithdrawal adds a withdrawal to the generated block. 252 // It returns the withdrawal index. 253 func (b *BlockGen) AddWithdrawal(w *types.Withdrawal) uint64 { 254 cpy := *w 255 cpy.Index = b.nextWithdrawalIndex() 256 b.withdrawals = append(b.withdrawals, &cpy) 257 return cpy.Index 258 } 259 260 // nextWithdrawalIndex computes the index of the next withdrawal. 261 func (b *BlockGen) nextWithdrawalIndex() uint64 { 262 if len(b.withdrawals) != 0 { 263 return b.withdrawals[len(b.withdrawals)-1].Index + 1 264 } 265 for i := b.i - 1; i >= 0; i-- { 266 if wd := b.cm.chain[i].Withdrawals(); len(wd) != 0 { 267 return wd[len(wd)-1].Index + 1 268 } 269 if i == 0 { 270 // Correctly set the index if no parent had withdrawals. 271 if wd := b.cm.bottom.Withdrawals(); len(wd) != 0 { 272 return wd[len(wd)-1].Index + 1 273 } 274 } 275 } 276 return 0 277 } 278 279 // PrevBlock returns a previously generated block by number. It panics if 280 // num is greater or equal to the number of the block being generated. 281 // For index -1, PrevBlock returns the parent block given to GenerateChain. 282 func (b *BlockGen) PrevBlock(index int) *types.Block { 283 if index >= b.i { 284 panic(fmt.Errorf("block index %d out of range (%d,%d)", index, -1, b.i)) 285 } 286 if index == -1 { 287 return b.cm.bottom 288 } 289 return b.cm.chain[index] 290 } 291 292 // OffsetTime modifies the time instance of a block, implicitly changing its 293 // associated difficulty. It's useful to test scenarios where forking is not 294 // tied to chain length directly. 295 func (b *BlockGen) OffsetTime(seconds int64) { 296 b.header.Time += uint64(seconds) 297 if b.header.Time <= b.cm.bottom.Header().Time { 298 panic("block time out of range") 299 } 300 b.header.Difficulty = b.engine.CalcDifficulty(b.cm, b.header.Time, b.parent.Header()) 301 } 302 303 // ConsensusLayerRequests returns the EIP-7685 requests which have accumulated so far. 304 func (b *BlockGen) ConsensusLayerRequests() [][]byte { 305 return b.collectRequests(true) 306 } 307 308 func (b *BlockGen) collectRequests(readonly bool) (requests [][]byte) { 309 statedb := b.statedb 310 if readonly { 311 // The system contracts clear themselves on a system-initiated read. 312 // When reading the requests mid-block, we don't want this behavior, so fork 313 // off the statedb before executing the system calls. 314 statedb = statedb.Copy() 315 } 316 317 if b.cm.config.IsPrague(b.header.Number, b.header.Time) { 318 requests = [][]byte{} 319 // EIP-6110 deposits 320 var blockLogs []*types.Log 321 for _, r := range b.receipts { 322 blockLogs = append(blockLogs, r.Logs...) 323 } 324 if err := ParseDepositLogs(&requests, blockLogs, b.cm.config); err != nil { 325 panic(fmt.Sprintf("failed to parse deposit log: %v", err)) 326 } 327 // create EVM for system calls 328 blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase) 329 evm := vm.NewEVM(blockContext, statedb, b.cm.config, vm.Config{}) 330 // EIP-7002 331 if err := ProcessWithdrawalQueue(&requests, evm); err != nil { 332 panic(fmt.Sprintf("could not process withdrawal requests: %v", err)) 333 } 334 // EIP-7251 335 if err := ProcessConsolidationQueue(&requests, evm); err != nil { 336 panic(fmt.Sprintf("could not process consolidation requests: %v", err)) 337 } 338 } 339 return requests 340 } 341 342 // GenerateChain creates a chain of n blocks. The first block's 343 // parent will be the provided parent. db is used to store 344 // intermediate states and should contain the parent's state trie. 345 // 346 // The generator function is called with a new block generator for 347 // every block. Any transactions and uncles added to the generator 348 // become part of the block. If gen is nil, the blocks will be empty 349 // and their coinbase will be the zero address. 350 // 351 // Blocks created by GenerateChain do not contain valid proof of work 352 // values. Inserting them into BlockChain requires use of FakePow or 353 // a similar non-validating proof of work implementation. 354 func GenerateChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { 355 if config == nil { 356 config = params.TestChainConfig 357 } 358 if engine == nil { 359 panic("nil consensus engine") 360 } 361 cm := newChainMaker(parent, config, engine) 362 363 genblock := func(i int, parent *types.Block, triedb *triedb.Database, statedb *state.StateDB) (*types.Block, types.Receipts) { 364 b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine} 365 b.header = cm.makeHeader(parent, statedb, b.engine) 366 367 // Set the difficulty for clique block. The chain maker doesn't have access 368 // to a chain, so the difficulty will be left unset (nil). Set it here to the 369 // correct value. 370 if b.header.Difficulty == nil { 371 if config.TerminalTotalDifficulty == nil { 372 // Clique chain 373 b.header.Difficulty = big.NewInt(2) 374 } else { 375 // Post-merge chain 376 b.header.Difficulty = big.NewInt(0) 377 } 378 } 379 380 // Mutate the state and block according to any hard-fork specs 381 if daoBlock := config.DAOForkBlock; daoBlock != nil { 382 limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) 383 if b.header.Number.Cmp(daoBlock) >= 0 && b.header.Number.Cmp(limit) < 0 { 384 if config.DAOForkSupport { 385 b.header.Extra = common.CopyBytes(params.DAOForkBlockExtra) 386 } 387 } 388 } 389 if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 { 390 misc.ApplyDAOHardFork(statedb) 391 } 392 393 if config.IsPrague(b.header.Number, b.header.Time) || config.IsVerkle(b.header.Number, b.header.Time) { 394 // EIP-2935 395 blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) 396 blockContext.Random = &common.Hash{} // enable post-merge instruction set 397 evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) 398 ProcessParentBlockHash(b.header.ParentHash, evm) 399 } 400 401 // Execute any user modifications to the block 402 if gen != nil { 403 gen(i, b) 404 } 405 406 requests := b.collectRequests(false) 407 if requests != nil { 408 reqHash := types.CalcRequestsHash(requests) 409 b.header.RequestsHash = &reqHash 410 } 411 412 body := types.Body{Transactions: b.txs, Uncles: b.uncles, Withdrawals: b.withdrawals} 413 block, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, &body, b.receipts) 414 if err != nil { 415 panic(err) 416 } 417 418 // Write state changes to db 419 root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number), config.IsCancun(b.header.Number, b.header.Time)) 420 if err != nil { 421 panic(fmt.Sprintf("state write error: %v", err)) 422 } 423 if err = triedb.Commit(root, false); err != nil { 424 panic(fmt.Sprintf("trie write error: %v", err)) 425 } 426 return block, b.receipts 427 } 428 429 // Forcibly use hash-based state scheme for retaining all nodes in disk. 430 triedb := triedb.NewDatabase(db, triedb.HashDefaults) 431 defer triedb.Close() 432 433 for i := 0; i < n; i++ { 434 statedb, err := state.New(parent.Root(), state.NewDatabase(triedb, nil)) 435 if err != nil { 436 panic(err) 437 } 438 block, receipts := genblock(i, parent, triedb, statedb) 439 440 // Post-process the receipts. 441 // Here we assign the final block hash and other info into the receipt. 442 // In order for DeriveFields to work, the transaction and receipt lists need to be 443 // of equal length. If AddUncheckedTx or AddUncheckedReceipt are used, there will be 444 // extra ones, so we just trim the lists here. 445 receiptsCount := len(receipts) 446 txs := block.Transactions() 447 if len(receipts) > len(txs) { 448 receipts = receipts[:len(txs)] 449 } else if len(receipts) < len(txs) { 450 txs = txs[:len(receipts)] 451 } 452 var blobGasPrice *big.Int 453 if block.ExcessBlobGas() != nil { 454 blobGasPrice = eip4844.CalcBlobFee(cm.config, block.Header()) 455 } 456 if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, txs); err != nil { 457 panic(err) 458 } 459 460 // Re-expand to ensure all receipts are returned. 461 receipts = receipts[:receiptsCount] 462 463 // Advance the chain. 464 cm.add(block, receipts) 465 parent = block 466 } 467 return cm.chain, cm.receipts 468 } 469 470 // GenerateChainWithGenesis is a wrapper of GenerateChain which will initialize 471 // genesis block to database first according to the provided genesis specification 472 // then generate chain on top. 473 func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts) { 474 db := rawdb.NewMemoryDatabase() 475 triedb := triedb.NewDatabase(db, triedb.HashDefaults) 476 defer triedb.Close() 477 _, err := genesis.Commit(db, triedb) 478 if err != nil { 479 panic(err) 480 } 481 blocks, receipts := GenerateChain(genesis.Config, genesis.ToBlock(), engine, db, n, gen) 482 return db, blocks, receipts 483 } 484 485 func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, trdb *triedb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { 486 if config == nil { 487 config = params.TestChainConfig 488 } 489 proofs := make([]*verkle.VerkleProof, 0, n) 490 keyvals := make([]verkle.StateDiff, 0, n) 491 cm := newChainMaker(parent, config, engine) 492 493 genblock := func(i int, parent *types.Block, triedb *triedb.Database, statedb *state.StateDB) (*types.Block, types.Receipts) { 494 b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine} 495 b.header = cm.makeHeader(parent, statedb, b.engine) 496 497 // TODO uncomment when proof generation is merged 498 // Save pre state for proof generation 499 // preState := statedb.Copy() 500 501 // EIP-2935 / 7709 502 blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) 503 blockContext.Random = &common.Hash{} // enable post-merge instruction set 504 evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) 505 ProcessParentBlockHash(b.header.ParentHash, evm) 506 507 // Execute any user modifications to the block. 508 if gen != nil { 509 gen(i, b) 510 } 511 512 requests := b.collectRequests(false) 513 if requests != nil { 514 reqHash := types.CalcRequestsHash(requests) 515 b.header.RequestsHash = &reqHash 516 } 517 518 body := &types.Body{ 519 Transactions: b.txs, 520 Uncles: b.uncles, 521 Withdrawals: b.withdrawals, 522 } 523 block, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, body, b.receipts) 524 if err != nil { 525 panic(err) 526 } 527 528 // Write state changes to DB. 529 root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number), config.IsCancun(b.header.Number, b.header.Time)) 530 if err != nil { 531 panic(fmt.Sprintf("state write error: %v", err)) 532 } 533 if err = triedb.Commit(root, false); err != nil { 534 panic(fmt.Sprintf("trie write error: %v", err)) 535 } 536 537 proofs = append(proofs, block.ExecutionWitness().VerkleProof) 538 keyvals = append(keyvals, block.ExecutionWitness().StateDiff) 539 540 return block, b.receipts 541 } 542 543 for i := 0; i < n; i++ { 544 statedb, err := state.New(parent.Root(), state.NewDatabase(trdb, nil)) 545 if err != nil { 546 panic(err) 547 } 548 block, receipts := genblock(i, parent, trdb, statedb) 549 550 // Post-process the receipts. 551 // Here we assign the final block hash and other info into the receipt. 552 // In order for DeriveFields to work, the transaction and receipt lists need to be 553 // of equal length. If AddUncheckedTx or AddUncheckedReceipt are used, there will be 554 // extra ones, so we just trim the lists here. 555 receiptsCount := len(receipts) 556 txs := block.Transactions() 557 if len(receipts) > len(txs) { 558 receipts = receipts[:len(txs)] 559 } else if len(receipts) < len(txs) { 560 txs = txs[:len(receipts)] 561 } 562 var blobGasPrice *big.Int 563 if block.ExcessBlobGas() != nil { 564 blobGasPrice = eip4844.CalcBlobFee(cm.config, block.Header()) 565 } 566 if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, txs); err != nil { 567 panic(err) 568 } 569 570 // Re-expand to ensure all receipts are returned. 571 receipts = receipts[:receiptsCount] 572 573 // Advance the chain. 574 cm.add(block, receipts) 575 parent = block 576 } 577 return cm.chain, cm.receipts, proofs, keyvals 578 } 579 580 func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (common.Hash, ethdb.Database, []*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { 581 db := rawdb.NewMemoryDatabase() 582 cacheConfig := DefaultConfig().WithStateScheme(rawdb.PathScheme) 583 cacheConfig.SnapshotLimit = 0 584 triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) 585 defer triedb.Close() 586 genesisBlock, err := genesis.Commit(db, triedb) 587 if err != nil { 588 panic(err) 589 } 590 blocks, receipts, proofs, keyvals := GenerateVerkleChain(genesis.Config, genesisBlock, engine, db, triedb, n, gen) 591 return genesisBlock.Hash(), db, blocks, receipts, proofs, keyvals 592 } 593 594 func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { 595 time := parent.Time() + 10 // block time is fixed at 10 seconds 596 parentHeader := parent.Header() 597 header := &types.Header{ 598 Root: state.IntermediateRoot(cm.config.IsEIP158(parent.Number())), 599 ParentHash: parent.Hash(), 600 Coinbase: parent.Coinbase(), 601 Difficulty: engine.CalcDifficulty(cm, time, parentHeader), 602 GasLimit: parent.GasLimit(), 603 Number: new(big.Int).Add(parent.Number(), common.Big1), 604 Time: time, 605 } 606 607 if cm.config.IsLondon(header.Number) { 608 header.BaseFee = eip1559.CalcBaseFee(cm.config, parentHeader) 609 if !cm.config.IsLondon(parent.Number()) { 610 parentGasLimit := parent.GasLimit() * cm.config.ElasticityMultiplier() 611 header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) 612 } 613 } 614 if cm.config.IsCancun(header.Number, header.Time) { 615 excessBlobGas := eip4844.CalcExcessBlobGas(cm.config, parentHeader, time) 616 header.ExcessBlobGas = &excessBlobGas 617 header.BlobGasUsed = new(uint64) 618 header.ParentBeaconRoot = new(common.Hash) 619 } 620 return header 621 } 622 623 // makeHeaderChain creates a deterministic chain of headers rooted at parent. 624 func makeHeaderChain(chainConfig *params.ChainConfig, parent *types.Header, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Header { 625 blocks := makeBlockChain(chainConfig, types.NewBlockWithHeader(parent), n, engine, db, seed) 626 headers := make([]*types.Header, len(blocks)) 627 for i, block := range blocks { 628 headers[i] = block.Header() 629 } 630 return headers 631 } 632 633 // makeHeaderChainWithGenesis creates a deterministic chain of headers from genesis. 634 func makeHeaderChainWithGenesis(genesis *Genesis, n int, engine consensus.Engine, seed int) (ethdb.Database, []*types.Header) { 635 db, blocks := makeBlockChainWithGenesis(genesis, n, engine, seed) 636 headers := make([]*types.Header, len(blocks)) 637 for i, block := range blocks { 638 headers[i] = block.Header() 639 } 640 return db, headers 641 } 642 643 // makeBlockChain creates a deterministic chain of blocks rooted at parent. 644 func makeBlockChain(chainConfig *params.ChainConfig, parent *types.Block, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Block { 645 blocks, _ := GenerateChain(chainConfig, parent, engine, db, n, func(i int, b *BlockGen) { 646 b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) 647 }) 648 return blocks 649 } 650 651 // makeBlockChainWithGenesis creates a deterministic chain of blocks from genesis 652 func makeBlockChainWithGenesis(genesis *Genesis, n int, engine consensus.Engine, seed int) (ethdb.Database, []*types.Block) { 653 db, blocks, _ := GenerateChainWithGenesis(genesis, engine, n, func(i int, b *BlockGen) { 654 b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) 655 }) 656 return db, blocks 657 } 658 659 // chainMaker contains the state of chain generation. 660 type chainMaker struct { 661 bottom *types.Block 662 engine consensus.Engine 663 config *params.ChainConfig 664 chain []*types.Block 665 chainByHash map[common.Hash]*types.Block 666 receipts []types.Receipts 667 } 668 669 func newChainMaker(bottom *types.Block, config *params.ChainConfig, engine consensus.Engine) *chainMaker { 670 return &chainMaker{ 671 bottom: bottom, 672 config: config, 673 engine: engine, 674 chainByHash: make(map[common.Hash]*types.Block), 675 } 676 } 677 678 func (cm *chainMaker) add(b *types.Block, r []*types.Receipt) { 679 cm.chain = append(cm.chain, b) 680 cm.chainByHash[b.Hash()] = b 681 cm.receipts = append(cm.receipts, r) 682 } 683 684 func (cm *chainMaker) blockByNumber(number uint64) *types.Block { 685 if number == cm.bottom.NumberU64() { 686 return cm.bottom 687 } 688 cur := cm.CurrentHeader().Number.Uint64() 689 lowest := cm.bottom.NumberU64() + 1 690 if number < lowest || number > cur { 691 return nil 692 } 693 return cm.chain[number-lowest] 694 } 695 696 // ChainReader/ChainContext implementation 697 698 // Config returns the chain configuration (for consensus.ChainReader). 699 func (cm *chainMaker) Config() *params.ChainConfig { 700 return cm.config 701 } 702 703 // Engine returns the consensus engine (for ChainContext). 704 func (cm *chainMaker) Engine() consensus.Engine { 705 return cm.engine 706 } 707 708 func (cm *chainMaker) CurrentHeader() *types.Header { 709 if len(cm.chain) == 0 { 710 return cm.bottom.Header() 711 } 712 return cm.chain[len(cm.chain)-1].Header() 713 } 714 715 func (cm *chainMaker) GetHeaderByNumber(number uint64) *types.Header { 716 b := cm.blockByNumber(number) 717 if b == nil { 718 return nil 719 } 720 return b.Header() 721 } 722 723 func (cm *chainMaker) GetHeaderByHash(hash common.Hash) *types.Header { 724 b := cm.chainByHash[hash] 725 if b == nil { 726 return nil 727 } 728 return b.Header() 729 } 730 731 func (cm *chainMaker) GetHeader(hash common.Hash, number uint64) *types.Header { 732 return cm.GetHeaderByNumber(number) 733 } 734 735 func (cm *chainMaker) GetBlock(hash common.Hash, number uint64) *types.Block { 736 return cm.blockByNumber(number) 737 }