go-ethereum/miner/fake_miner.go
2023-01-20 17:13:36 +05:30

241 lines
6.4 KiB
Go

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/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().GetCurrentValidators(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()
// Create Ethash config
chainDB, _, chainConfig := NewDBForFakes(t)
engine := NewFakeBor(t, chainDB, chainConfig, ethAPIMock, spanner, heimdallClientMock, contractMock)
// Create Ethereum backend
bc, err := core.NewBlockChain(chainDB, nil, chainConfig, 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 := core.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, 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 *core.TxPool
}
func NewMockBackend(bc *core.BlockChain, txPool *core.TxPool) *mockBackend {
return &mockBackend{
bc: bc,
txPool: txPool,
}
}
func (m *mockBackend) BlockChain() *core.BlockChain {
return m.bc
}
func (m *mockBackend) TxPool() *core.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.Block {
return types.NewBlock(&types.Header{
GasLimit: bc.gasLimit,
}, nil, nil, nil, trie.NewStackTrie(nil))
}
func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
return bc.CurrentBlock()
}
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 core.TxPoolConfig
ethashChainConfig *params.ChainConfig
cliqueChainConfig *params.ChainConfig
// Test accounts
testBankKey, _ = crypto.GenerateKey()
TestBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
testBankFunds = big.NewInt(1000000000000000000)
testUserKey, _ = crypto.GenerateKey()
testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey)
// Test transactions
pendingTxs []*types.Transaction
newTxs []*types.Transaction
testConfig = &Config{
Recommit: time.Second,
GasCeil: params.GenesisGasLimit,
}
)
func init() {
testTxPoolConfig = core.DefaultTxPoolConfig
testTxPoolConfig.Journal = ""
ethashChainConfig = new(params.ChainConfig)
*ethashChainConfig = *params.TestChainConfig
cliqueChainConfig = new(params.ChainConfig)
*cliqueChainConfig = *params.TestChainConfig
cliqueChainConfig.Clique = &params.CliqueConfig{
Period: 10,
Epoch: 30000,
}
}