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 = &params.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  }