package miner import ( "errors" "math/big" "testing" "time" "github.com/golang/mock/gomock" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/bor" "github.com/ethereum/go-ethereum/consensus/bor/api" "github.com/ethereum/go-ethereum/consensus/bor/valset" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/tests/bor/mocks" "github.com/ethereum/go-ethereum/trie" ) type DefaultBorMiner struct { Miner *Miner Mux *event.TypeMux //nolint:staticcheck Cleanup func(skipMiner bool) Ctrl *gomock.Controller EthAPIMock api.Caller HeimdallClientMock bor.IHeimdallClient ContractMock bor.GenesisContract } func NewBorDefaultMiner(t *testing.T) *DefaultBorMiner { t.Helper() ctrl := gomock.NewController(t) ethAPI := api.NewMockCaller(ctrl) ethAPI.EXPECT().Call(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() spanner := bor.NewMockSpanner(ctrl) spanner.EXPECT().GetCurrentValidatorsByHash(gomock.Any(), gomock.Any(), gomock.Any()).Return([]*valset.Validator{ { ID: 0, Address: common.Address{0x1}, VotingPower: 100, ProposerPriority: 0, }, }, nil).AnyTimes() heimdallClient := mocks.NewMockIHeimdallClient(ctrl) heimdallClient.EXPECT().Close().Times(1) genesisContracts := bor.NewMockGenesisContract(ctrl) miner, mux, cleanup := createBorMiner(t, ethAPI, spanner, heimdallClient, genesisContracts) return &DefaultBorMiner{ Miner: miner, Mux: mux, Cleanup: cleanup, Ctrl: ctrl, EthAPIMock: ethAPI, HeimdallClientMock: heimdallClient, ContractMock: genesisContracts, } } //nolint:staticcheck func createBorMiner(t *testing.T, ethAPIMock api.Caller, spanner bor.Spanner, heimdallClientMock bor.IHeimdallClient, contractMock bor.GenesisContract) (*Miner, *event.TypeMux, func(skipMiner bool)) { t.Helper() // addr0 := common.Address{0x1} // genspec := &core.Genesis{ // Alloc: map[common.Address]core.GenesisAccount{ // addr0: { // Balance: big.NewInt(0), // Code: []byte{0x1, 0x1}, // }, // }, // } // Create Ethash config chainDB, genspec, chainConfig := NewDBForFakes(t) engine := NewFakeBor(t, chainDB, chainConfig, ethAPIMock, spanner, heimdallClientMock, contractMock) // Create Ethereum backend bc, err := core.NewBlockChain(chainDB, nil, genspec, nil, engine, vm.Config{}, nil, nil, nil) if err != nil { t.Fatalf("can't create new chain %v", err) } statedb, _ := state.New(common.Hash{}, state.NewDatabase(chainDB), nil) blockchain := &testBlockChain{statedb, 10000000, new(event.Feed)} pool := txpool.NewTxPool(testTxPoolConfig, chainConfig, blockchain) backend := NewMockBackend(bc, pool) // Create event Mux mux := new(event.TypeMux) config := Config{ Etherbase: common.HexToAddress("123456789"), } // Create Miner miner := New(backend, &config, chainConfig, mux, engine, nil) cleanup := func(skipMiner bool) { bc.Stop() engine.Close() pool.Stop() if !skipMiner { miner.Close() } } return miner, mux, cleanup } type TensingObject interface { Helper() Fatalf(format string, args ...any) } func NewDBForFakes(t TensingObject) (ethdb.Database, *core.Genesis, *params.ChainConfig) { t.Helper() memdb := memorydb.New() chainDB := rawdb.NewDatabase(memdb) genesis := core.DeveloperGenesisBlock(2, 11_500_000, common.HexToAddress("12345")) chainConfig, _, err := core.SetupGenesisBlock(chainDB, trie.NewDatabase(chainDB), genesis) if err != nil { t.Fatalf("can't create new chain config: %v", err) } chainConfig.Bor.Period = map[string]uint64{ "0": 1, } chainConfig.Bor.Sprint = map[string]uint64{ "0": 64, } return chainDB, genesis, chainConfig } func NewFakeBor(t TensingObject, chainDB ethdb.Database, chainConfig *params.ChainConfig, ethAPIMock api.Caller, spanner bor.Spanner, heimdallClientMock bor.IHeimdallClient, contractMock bor.GenesisContract) consensus.Engine { t.Helper() if chainConfig.Bor == nil { chainConfig.Bor = params.BorUnittestChainConfig.Bor } return bor.New(chainConfig, chainDB, ethAPIMock, spanner, heimdallClientMock, contractMock, false) } type mockBackend struct { bc *core.BlockChain txPool *txpool.TxPool } func NewMockBackend(bc *core.BlockChain, txPool *txpool.TxPool) *mockBackend { return &mockBackend{ bc: bc, txPool: txPool, } } func (m *mockBackend) BlockChain() *core.BlockChain { return m.bc } func (m *mockBackend) TxPool() *txpool.TxPool { return m.txPool } func (m *mockBackend) StateAtBlock(block *types.Block, reexec uint64, base *state.StateDB, checkLive bool, preferDisk bool) (statedb *state.StateDB, err error) { return nil, errors.New("not supported") } type testBlockChain struct { statedb *state.StateDB gasLimit uint64 chainHeadFeed *event.Feed } func (bc *testBlockChain) CurrentBlock() *types.Header { return &types.Header{ GasLimit: bc.gasLimit, Number: new(big.Int), } } func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { return types.NewBlock(bc.CurrentBlock(), nil, nil, nil, trie.NewStackTrie(nil)) } func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { return bc.statedb, nil } func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { return bc.chainHeadFeed.Subscribe(ch) } var ( // Test chain configurations testTxPoolConfig txpool.Config ethashChainConfig *params.ChainConfig cliqueChainConfig *params.ChainConfig // Test accounts testBankKey, _ = crypto.GenerateKey() TestBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) testBankFunds = big.NewInt(9000000000000000000) testUserKey, _ = crypto.GenerateKey() testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey) // Test transactions pendingTxs []*types.Transaction newTxs []*types.Transaction testConfig = &Config{ Recommit: time.Second, GasCeil: params.GenesisGasLimit, CommitInterruptFlag: true, } ) func init() { testTxPoolConfig = txpool.DefaultConfig testTxPoolConfig.Journal = "" ethashChainConfig = new(params.ChainConfig) *ethashChainConfig = *params.TestChainConfig cliqueChainConfig = new(params.ChainConfig) *cliqueChainConfig = *params.TestChainConfig cliqueChainConfig.Clique = ¶ms.CliqueConfig{ Period: 10, Epoch: 30000, } }