github.com/ethereum/go-ethereum@v1.16.1/miner/miner_test.go (about) 1 // Copyright 2020 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 miner implements Ethereum block creation and mining. 18 package miner 19 20 import ( 21 "math/big" 22 "sync" 23 "testing" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/consensus/clique" 27 "github.com/ethereum/go-ethereum/core" 28 "github.com/ethereum/go-ethereum/core/rawdb" 29 "github.com/ethereum/go-ethereum/core/state" 30 "github.com/ethereum/go-ethereum/core/txpool" 31 "github.com/ethereum/go-ethereum/core/txpool/legacypool" 32 "github.com/ethereum/go-ethereum/core/types" 33 "github.com/ethereum/go-ethereum/crypto" 34 "github.com/ethereum/go-ethereum/event" 35 "github.com/ethereum/go-ethereum/params" 36 "github.com/ethereum/go-ethereum/trie" 37 "github.com/ethereum/go-ethereum/triedb" 38 ) 39 40 type mockBackend struct { 41 bc *core.BlockChain 42 txPool *txpool.TxPool 43 } 44 45 func NewMockBackend(bc *core.BlockChain, txPool *txpool.TxPool) *mockBackend { 46 return &mockBackend{ 47 bc: bc, 48 txPool: txPool, 49 } 50 } 51 52 func (m *mockBackend) BlockChain() *core.BlockChain { 53 return m.bc 54 } 55 56 func (m *mockBackend) TxPool() *txpool.TxPool { 57 return m.txPool 58 } 59 60 type testBlockChain struct { 61 root common.Hash 62 config *params.ChainConfig 63 statedb *state.StateDB 64 gasLimit uint64 65 chainHeadFeed *event.Feed 66 } 67 68 func (bc *testBlockChain) Config() *params.ChainConfig { 69 return bc.config 70 } 71 72 func (bc *testBlockChain) CurrentBlock() *types.Header { 73 return &types.Header{ 74 Number: new(big.Int), 75 GasLimit: bc.gasLimit, 76 } 77 } 78 79 func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { 80 return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil)) 81 } 82 83 func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { 84 return bc.statedb, nil 85 } 86 87 func (bc *testBlockChain) HasState(root common.Hash) bool { 88 return bc.root == root 89 } 90 91 func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { 92 return bc.chainHeadFeed.Subscribe(ch) 93 } 94 95 func TestBuildPendingBlocks(t *testing.T) { 96 miner := createMiner(t) 97 var wg sync.WaitGroup 98 wg.Add(1) 99 go func() { 100 defer wg.Done() 101 block, _, _ := miner.Pending() 102 if block == nil { 103 t.Error("Pending failed") 104 } 105 }() 106 wg.Wait() 107 } 108 109 func minerTestGenesisBlock(period uint64, gasLimit uint64, faucet common.Address) *core.Genesis { 110 config := *params.AllCliqueProtocolChanges 111 config.Clique = ¶ms.CliqueConfig{ 112 Period: period, 113 Epoch: config.Clique.Epoch, 114 } 115 116 // Assemble and return the genesis with the precompiles and faucet pre-funded 117 return &core.Genesis{ 118 Config: &config, 119 ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...), 120 GasLimit: gasLimit, 121 BaseFee: big.NewInt(params.InitialBaseFee), 122 Difficulty: big.NewInt(1), 123 Alloc: map[common.Address]types.Account{ 124 common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover 125 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 126 common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD 127 common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity 128 common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp 129 common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd 130 common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul 131 common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing 132 common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b 133 faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, 134 }, 135 } 136 } 137 138 func createMiner(t *testing.T) *Miner { 139 // Create Ethash config 140 config := Config{ 141 PendingFeeRecipient: common.HexToAddress("123456789"), 142 } 143 // Create chainConfig 144 chainDB := rawdb.NewMemoryDatabase() 145 triedb := triedb.NewDatabase(chainDB, nil) 146 genesis := minerTestGenesisBlock(15, 11_500_000, common.HexToAddress("12345")) 147 chainConfig, _, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis) 148 if err != nil { 149 t.Fatalf("can't create new chain config: %v", err) 150 } 151 // Create consensus engine 152 engine := clique.New(chainConfig.Clique, chainDB) 153 // Create Ethereum backend 154 bc, err := core.NewBlockChain(chainDB, genesis, engine, nil) 155 if err != nil { 156 t.Fatalf("can't create new chain %v", err) 157 } 158 statedb, _ := state.New(bc.Genesis().Root(), bc.StateCache()) 159 blockchain := &testBlockChain{bc.Genesis().Root(), chainConfig, statedb, 10000000, new(event.Feed)} 160 161 pool := legacypool.New(testTxPoolConfig, blockchain) 162 txpool, _ := txpool.New(testTxPoolConfig.PriceLimit, blockchain, []txpool.SubPool{pool}) 163 164 // Create Miner 165 backend := NewMockBackend(bc, txpool) 166 miner := New(backend, config, engine) 167 return miner 168 }