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