mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
Mining benchmark (#439)
* mining benchmark * mining benchmark * prepare for enabling fork tests * linters * logs
This commit is contained in:
parent
5f69302b3a
commit
f28f384b72
5 changed files with 355 additions and 219 deletions
|
|
@ -29,7 +29,6 @@ import (
|
||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus/bor"
|
"github.com/ethereum/go-ethereum/consensus/bor"
|
||||||
"github.com/ethereum/go-ethereum/consensus/bor/api"
|
"github.com/ethereum/go-ethereum/consensus/bor/api"
|
||||||
|
|
@ -1788,6 +1787,8 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
}
|
}
|
||||||
defer db.Close() // Might double close, should be fine
|
defer db.Close() // Might double close, should be fine
|
||||||
|
|
||||||
|
chainConfig := params.BorUnittestChainConfig
|
||||||
|
|
||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
defer ctrl.Finish()
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
|
@ -1798,7 +1799,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
spanner.EXPECT().GetCurrentValidators(gomock.Any(), gomock.Any()).Return([]*valset.Validator{
|
spanner.EXPECT().GetCurrentValidators(gomock.Any(), gomock.Any()).Return([]*valset.Validator{
|
||||||
{
|
{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Address: common.Address{0x1},
|
Address: miner.TestBankAddress,
|
||||||
VotingPower: 100,
|
VotingPower: 100,
|
||||||
ProposerPriority: 0,
|
ProposerPriority: 0,
|
||||||
},
|
},
|
||||||
|
|
@ -1809,44 +1810,15 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
|
|
||||||
contractMock := bor.NewMockGenesisContract(ctrl)
|
contractMock := bor.NewMockGenesisContract(ctrl)
|
||||||
|
|
||||||
// Initialize a fresh chain
|
engine := miner.NewFakeBor(t, db, chainConfig, ethAPIMock, spanner, heimdallClientMock, contractMock)
|
||||||
var (
|
|
||||||
gspec = &core.Genesis{
|
|
||||||
Config: params.BorUnittestChainConfig,
|
|
||||||
BaseFee: big.NewInt(params.InitialBaseFee),
|
|
||||||
}
|
|
||||||
config = &core.CacheConfig{
|
|
||||||
TrieCleanLimit: 256,
|
|
||||||
TrieDirtyLimit: 256,
|
|
||||||
TrieTimeLimit: 5 * time.Minute,
|
|
||||||
SnapshotLimit: 0, // Disable snapshot by default
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
engine := miner.NewFakeBor(t, db, params.BorUnittestChainConfig, ethAPIMock, spanner, heimdallClientMock, contractMock)
|
|
||||||
defer engine.Close()
|
defer engine.Close()
|
||||||
|
|
||||||
engineBorInternal, ok := engine.(*bor.Bor)
|
chainConfig.LondonBlock = big.NewInt(0)
|
||||||
if ok {
|
|
||||||
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
|
|
||||||
copy(gspec.ExtraData[32:32+common.AddressLength], testAddress1.Bytes())
|
|
||||||
|
|
||||||
engineBorInternal.Authorize(testAddress1, func(account accounts.Account, s string, data []byte) ([]byte, error) {
|
_, back, closeFn := miner.NewTestWorker(t, chainConfig, engine, db, 0)
|
||||||
return crypto.Sign(crypto.Keccak256(data), testKey1)
|
defer closeFn()
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
genesis := gspec.MustCommit(db)
|
genesis := back.BlockChain().Genesis()
|
||||||
|
|
||||||
if snapshots {
|
|
||||||
config.SnapshotLimit = 256
|
|
||||||
config.SnapshotWait = true
|
|
||||||
}
|
|
||||||
|
|
||||||
chain, err := core.NewBlockChain(db, config, params.BorUnittestChainConfig, engine, vm.Config{}, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to create chain: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If sidechain blocks are needed, make a light chain and import it
|
// If sidechain blocks are needed, make a light chain and import it
|
||||||
var sideblocks types.Blocks
|
var sideblocks types.Blocks
|
||||||
|
|
@ -1855,55 +1827,59 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
b.SetCoinbase(testAddress1)
|
b.SetCoinbase(testAddress1)
|
||||||
|
|
||||||
if bor.IsSprintStart(b.Number().Uint64(), params.BorUnittestChainConfig.Bor.Sprint) {
|
if bor.IsSprintStart(b.Number().Uint64(), params.BorUnittestChainConfig.Bor.Sprint) {
|
||||||
b.SetExtra(gspec.ExtraData)
|
b.SetExtra(back.Genesis.ExtraData)
|
||||||
} else {
|
} else {
|
||||||
b.SetExtra(make([]byte, 32+crypto.SignatureLength))
|
b.SetExtra(make([]byte, 32+crypto.SignatureLength))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if _, err := chain.InsertChain(sideblocks); err != nil {
|
if _, err := back.BlockChain().InsertChain(sideblocks); err != nil {
|
||||||
t.Fatalf("Failed to import side chain: %v", err)
|
t.Fatalf("Failed to import side chain: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canonblocks, _ := core.GenerateChain(params.BorUnittestChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), tt.canonicalBlocks, func(i int, b *core.BlockGen) {
|
canonblocks, _ := core.GenerateChain(params.BorUnittestChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), tt.canonicalBlocks, func(i int, b *core.BlockGen) {
|
||||||
b.SetCoinbase(common.Address{0x02})
|
b.SetCoinbase(miner.TestBankAddress)
|
||||||
b.SetDifficulty(big.NewInt(1000000))
|
b.SetDifficulty(big.NewInt(1000000))
|
||||||
|
|
||||||
if bor.IsSprintStart(b.Number().Uint64(), params.BorUnittestChainConfig.Bor.Sprint) {
|
if bor.IsSprintStart(b.Number().Uint64(), params.BorUnittestChainConfig.Bor.Sprint) {
|
||||||
b.SetExtra(gspec.ExtraData)
|
b.SetExtra(back.Genesis.ExtraData)
|
||||||
} else {
|
} else {
|
||||||
b.SetExtra(make([]byte, 32+crypto.SignatureLength))
|
b.SetExtra(make([]byte, 32+crypto.SignatureLength))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if _, err := chain.InsertChain(canonblocks[:tt.commitBlock]); err != nil {
|
if _, err := back.BlockChain().InsertChain(canonblocks[:tt.commitBlock]); err != nil {
|
||||||
t.Fatalf("Failed to import canonical chain start: %v", err)
|
t.Fatalf("Failed to import canonical chain start: %v", err)
|
||||||
}
|
}
|
||||||
if tt.commitBlock > 0 {
|
if tt.commitBlock > 0 {
|
||||||
err = chain.StateCache().TrieDB().Commit(canonblocks[tt.commitBlock-1].Root(), true, nil)
|
err = back.BlockChain().StateCache().TrieDB().Commit(canonblocks[tt.commitBlock-1].Root(), true, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("on trieDB.Commit", err)
|
t.Fatal("on trieDB.Commit", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if snapshots {
|
if snapshots {
|
||||||
if err := chain.Snaps().Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil {
|
if err := back.BlockChain().Snaps().Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil {
|
||||||
t.Fatalf("Failed to flatten snapshots: %v", err)
|
t.Fatalf("Failed to flatten snapshots: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, err := chain.InsertChain(canonblocks[tt.commitBlock:]); err != nil {
|
|
||||||
|
if _, err := back.BlockChain().InsertChain(canonblocks[tt.commitBlock:]); err != nil {
|
||||||
t.Fatalf("Failed to import canonical chain tail: %v", err)
|
t.Fatalf("Failed to import canonical chain tail: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force run a freeze cycle
|
// Force run a freeze cycle
|
||||||
type freezer interface {
|
type freezer interface {
|
||||||
Freeze(threshold uint64) error
|
Freeze(threshold uint64) error
|
||||||
Ancients() (uint64, error)
|
Ancients() (uint64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
db.(freezer).Freeze(tt.freezeThreshold)
|
db.(freezer).Freeze(tt.freezeThreshold)
|
||||||
|
|
||||||
// Set the simulated pivot block
|
// Set the simulated pivot block
|
||||||
if tt.pivotBlock != nil {
|
if tt.pivotBlock != nil {
|
||||||
rawdb.WriteLastPivotNumber(db, *tt.pivotBlock)
|
rawdb.WriteLastPivotNumber(db, *tt.pivotBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull the plug on the database, simulating a hard crash
|
// Pull the plug on the database, simulating a hard crash
|
||||||
db.Close()
|
db.Close()
|
||||||
|
|
||||||
|
|
@ -1912,12 +1888,14 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to reopen persistent database: %v", err)
|
t.Fatalf("Failed to reopen persistent database: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
newChain, err := core.NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
|
newChain, err := core.NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to recreate chain: %v", err)
|
t.Fatalf("Failed to recreate chain: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer newChain.Stop()
|
defer newChain.Stop()
|
||||||
|
|
||||||
// Iterate over all the remaining blocks and ensure there are no gaps
|
// Iterate over all the remaining blocks and ensure there are no gaps
|
||||||
|
|
@ -1929,12 +1907,15 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
|
||||||
if head := newChain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader {
|
if head := newChain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader {
|
||||||
t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader)
|
t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := newChain.CurrentFastBlock(); head.NumberU64() != tt.expHeadFastBlock {
|
if head := newChain.CurrentFastBlock(); head.NumberU64() != tt.expHeadFastBlock {
|
||||||
t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadFastBlock)
|
t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadFastBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
if head := newChain.CurrentBlock(); head.NumberU64() != tt.expHeadBlock {
|
if head := newChain.CurrentBlock(); head.NumberU64() != tt.expHeadBlock {
|
||||||
t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadBlock)
|
t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
if frozen, err := db.(freezer).Ancients(); err != nil {
|
if frozen, err := db.(freezer).Ancients(); err != nil {
|
||||||
t.Errorf("Failed to retrieve ancient count: %v\n", err)
|
t.Errorf("Failed to retrieve ancient count: %v\n", err)
|
||||||
} else if int(frozen) != tt.expFrozen {
|
} else if int(frozen) != tt.expFrozen {
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,12 @@ func createBorMiner(t *testing.T, ethAPIMock api.Caller, spanner bor.Spanner, he
|
||||||
return miner, mux, cleanup
|
return miner, mux, cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDBForFakes(t *testing.T) (ethdb.Database, *core.Genesis, *params.ChainConfig) {
|
type TensingObject interface {
|
||||||
|
Helper()
|
||||||
|
Fatalf(format string, args ...any)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDBForFakes(t TensingObject) (ethdb.Database, *core.Genesis, *params.ChainConfig) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
memdb := memorydb.New()
|
memdb := memorydb.New()
|
||||||
|
|
@ -137,7 +142,7 @@ func NewDBForFakes(t *testing.T) (ethdb.Database, *core.Genesis, *params.ChainCo
|
||||||
return chainDB, genesis, chainConfig
|
return chainDB, genesis, chainConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFakeBor(t *testing.T, chainDB ethdb.Database, chainConfig *params.ChainConfig, ethAPIMock api.Caller, spanner bor.Spanner, heimdallClientMock bor.IHeimdallClient, contractMock bor.GenesisContract) consensus.Engine {
|
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()
|
t.Helper()
|
||||||
|
|
||||||
if chainConfig.Bor == nil {
|
if chainConfig.Bor == nil {
|
||||||
|
|
@ -203,7 +208,7 @@ var (
|
||||||
|
|
||||||
// Test accounts
|
// Test accounts
|
||||||
testBankKey, _ = crypto.GenerateKey()
|
testBankKey, _ = crypto.GenerateKey()
|
||||||
testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
|
TestBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
|
||||||
testBankFunds = big.NewInt(1000000000000000000)
|
testBankFunds = big.NewInt(1000000000000000000)
|
||||||
|
|
||||||
testUserKey, _ = crypto.GenerateKey()
|
testUserKey, _ = crypto.GenerateKey()
|
||||||
|
|
|
||||||
182
miner/test_backend.go
Normal file
182
miner/test_backend.go
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
package miner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
|
"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/clique"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
"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/event"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// testCode is the testing contract binary code which will initialises some
|
||||||
|
// variables in constructor
|
||||||
|
testCode = "0x60806040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0060005534801561003457600080fd5b5060fc806100436000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80630c4dae8814603757806398a213cf146053575b600080fd5b603d607e565b6040518082815260200191505060405180910390f35b607c60048036036020811015606757600080fd5b81019080803590602001909291905050506084565b005b60005481565b806000819055507fe9e44f9f7da8c559de847a3232b57364adc0354f15a2cd8dc636d54396f9587a6000546040518082815260200191505060405180910390a15056fea265627a7a723058208ae31d9424f2d0bc2a3da1a5dd659db2d71ec322a17db8f87e19e209e3a1ff4a64736f6c634300050a0032"
|
||||||
|
|
||||||
|
// testGas is the gas required for contract deployment.
|
||||||
|
testGas = 144109
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
signer := types.LatestSigner(params.TestChainConfig)
|
||||||
|
|
||||||
|
tx1 := types.MustSignNewTx(testBankKey, signer, &types.AccessListTx{
|
||||||
|
ChainID: params.TestChainConfig.ChainID,
|
||||||
|
Nonce: 0,
|
||||||
|
To: &testUserAddress,
|
||||||
|
Value: big.NewInt(1000),
|
||||||
|
Gas: params.TxGas,
|
||||||
|
GasPrice: big.NewInt(params.InitialBaseFee),
|
||||||
|
})
|
||||||
|
|
||||||
|
pendingTxs = append(pendingTxs, tx1)
|
||||||
|
|
||||||
|
tx2 := types.MustSignNewTx(testBankKey, signer, &types.LegacyTx{
|
||||||
|
Nonce: 1,
|
||||||
|
To: &testUserAddress,
|
||||||
|
Value: big.NewInt(1000),
|
||||||
|
Gas: params.TxGas,
|
||||||
|
GasPrice: big.NewInt(params.InitialBaseFee),
|
||||||
|
})
|
||||||
|
|
||||||
|
newTxs = append(newTxs, tx2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// testWorkerBackend implements worker.Backend interfaces and wraps all information needed during the testing.
|
||||||
|
type testWorkerBackend struct {
|
||||||
|
DB ethdb.Database
|
||||||
|
txPool *core.TxPool
|
||||||
|
chain *core.BlockChain
|
||||||
|
Genesis *core.Genesis
|
||||||
|
uncleBlock *types.Block
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTestWorkerBackend(t TensingObject, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, n int) *testWorkerBackend {
|
||||||
|
var gspec = core.Genesis{
|
||||||
|
Config: chainConfig,
|
||||||
|
Alloc: core.GenesisAlloc{TestBankAddress: {Balance: testBankFunds}},
|
||||||
|
GasLimit: 30_000_000,
|
||||||
|
}
|
||||||
|
|
||||||
|
switch e := engine.(type) {
|
||||||
|
case *bor.Bor:
|
||||||
|
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
|
||||||
|
copy(gspec.ExtraData[32:32+common.AddressLength], TestBankAddress.Bytes())
|
||||||
|
e.Authorize(TestBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
|
||||||
|
return crypto.Sign(crypto.Keccak256(data), testBankKey)
|
||||||
|
})
|
||||||
|
case *clique.Clique:
|
||||||
|
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
|
||||||
|
copy(gspec.ExtraData[32:32+common.AddressLength], TestBankAddress.Bytes())
|
||||||
|
e.Authorize(TestBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
|
||||||
|
return crypto.Sign(crypto.Keccak256(data), testBankKey)
|
||||||
|
})
|
||||||
|
case *ethash.Ethash:
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected consensus engine type: %T", engine)
|
||||||
|
}
|
||||||
|
|
||||||
|
genesis := gspec.MustCommit(db)
|
||||||
|
|
||||||
|
chain, _ := core.NewBlockChain(db, &core.CacheConfig{TrieDirtyDisabled: true}, gspec.Config, engine, vm.Config{}, nil, nil)
|
||||||
|
txpool := core.NewTxPool(testTxPoolConfig, chainConfig, chain)
|
||||||
|
|
||||||
|
// Generate a small n-block chain and an uncle block for it
|
||||||
|
if n > 0 {
|
||||||
|
blocks, _ := core.GenerateChain(chainConfig, genesis, engine, db, n, func(i int, gen *core.BlockGen) {
|
||||||
|
gen.SetCoinbase(TestBankAddress)
|
||||||
|
})
|
||||||
|
if _, err := chain.InsertChain(blocks); err != nil {
|
||||||
|
t.Fatalf("failed to insert origin chain: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parent := genesis
|
||||||
|
if n > 0 {
|
||||||
|
parent = chain.GetBlockByHash(chain.CurrentBlock().ParentHash())
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks, _ := core.GenerateChain(chainConfig, parent, engine, db, 1, func(i int, gen *core.BlockGen) {
|
||||||
|
gen.SetCoinbase(testUserAddress)
|
||||||
|
})
|
||||||
|
|
||||||
|
return &testWorkerBackend{
|
||||||
|
DB: db,
|
||||||
|
chain: chain,
|
||||||
|
txPool: txpool,
|
||||||
|
Genesis: &gspec,
|
||||||
|
uncleBlock: blocks[0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
|
||||||
|
func (b *testWorkerBackend) TxPool() *core.TxPool { return b.txPool }
|
||||||
|
func (b *testWorkerBackend) StateAtBlock(block *types.Block, reexec uint64, base *state.StateDB, checkLive bool, preferDisk bool) (statedb *state.StateDB, err error) {
|
||||||
|
return nil, errors.New("not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *testWorkerBackend) newRandomUncle() (*types.Block, error) {
|
||||||
|
var parent *types.Block
|
||||||
|
|
||||||
|
cur := b.chain.CurrentBlock()
|
||||||
|
|
||||||
|
if cur.NumberU64() == 0 {
|
||||||
|
parent = b.chain.Genesis()
|
||||||
|
} else {
|
||||||
|
parent = b.chain.GetBlockByHash(b.chain.CurrentBlock().ParentHash())
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
blocks, _ := core.GenerateChain(b.chain.Config(), parent, b.chain.Engine(), b.DB, 1, func(i int, gen *core.BlockGen) {
|
||||||
|
var addr = make([]byte, common.AddressLength)
|
||||||
|
|
||||||
|
_, err = rand.Read(addr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
gen.SetCoinbase(common.BytesToAddress(addr))
|
||||||
|
})
|
||||||
|
|
||||||
|
return blocks[0], err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction {
|
||||||
|
var tx *types.Transaction
|
||||||
|
|
||||||
|
gasPrice := big.NewInt(10 * params.InitialBaseFee)
|
||||||
|
|
||||||
|
if creation {
|
||||||
|
tx, _ = types.SignTx(types.NewContractCreation(b.txPool.Nonce(TestBankAddress), big.NewInt(0), testGas, gasPrice, common.FromHex(testCode)), types.HomesteadSigner{}, testBankKey)
|
||||||
|
} else {
|
||||||
|
tx, _ = types.SignTx(types.NewTransaction(b.txPool.Nonce(TestBankAddress), testUserAddress, big.NewInt(1000), params.TxGas, gasPrice, nil), types.HomesteadSigner{}, testBankKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestWorker(t TensingObject, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, blocks int) (*worker, *testWorkerBackend, func()) {
|
||||||
|
backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks)
|
||||||
|
backend.txPool.AddLocals(pendingTxs)
|
||||||
|
|
||||||
|
//nolint:staticcheck
|
||||||
|
w := newWorker(testConfig, chainConfig, engine, backend, new(event.TypeMux), nil, false)
|
||||||
|
|
||||||
|
w.setEtherbase(TestBankAddress)
|
||||||
|
|
||||||
|
return w, backend, w.close
|
||||||
|
}
|
||||||
|
|
@ -248,6 +248,7 @@ type worker struct {
|
||||||
resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval.
|
resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:staticcheck
|
||||||
func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(header *types.Header) bool, init bool) *worker {
|
func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(header *types.Header) bool, init bool) *worker {
|
||||||
worker := &worker{
|
worker := &worker{
|
||||||
config: config,
|
config: config,
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,13 @@
|
||||||
package miner
|
package miner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/consensus/bor"
|
"github.com/ethereum/go-ethereum/consensus/bor"
|
||||||
|
|
@ -36,169 +33,12 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"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/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/tests/bor/mocks"
|
"github.com/ethereum/go-ethereum/tests/bor/mocks"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// testCode is the testing contract binary code which will initialises some
|
|
||||||
// variables in constructor
|
|
||||||
testCode = "0x60806040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0060005534801561003457600080fd5b5060fc806100436000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80630c4dae8814603757806398a213cf146053575b600080fd5b603d607e565b6040518082815260200191505060405180910390f35b607c60048036036020811015606757600080fd5b81019080803590602001909291905050506084565b005b60005481565b806000819055507fe9e44f9f7da8c559de847a3232b57364adc0354f15a2cd8dc636d54396f9587a6000546040518082815260200191505060405180910390a15056fea265627a7a723058208ae31d9424f2d0bc2a3da1a5dd659db2d71ec322a17db8f87e19e209e3a1ff4a64736f6c634300050a0032"
|
|
||||||
|
|
||||||
// testGas is the gas required for contract deployment.
|
|
||||||
testGas = 144109
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
signer := types.LatestSigner(params.TestChainConfig)
|
|
||||||
|
|
||||||
tx1 := types.MustSignNewTx(testBankKey, signer, &types.AccessListTx{
|
|
||||||
ChainID: params.TestChainConfig.ChainID,
|
|
||||||
Nonce: 0,
|
|
||||||
To: &testUserAddress,
|
|
||||||
Value: big.NewInt(1000),
|
|
||||||
Gas: params.TxGas,
|
|
||||||
GasPrice: big.NewInt(params.InitialBaseFee),
|
|
||||||
})
|
|
||||||
|
|
||||||
pendingTxs = append(pendingTxs, tx1)
|
|
||||||
|
|
||||||
tx2 := types.MustSignNewTx(testBankKey, signer, &types.LegacyTx{
|
|
||||||
Nonce: 1,
|
|
||||||
To: &testUserAddress,
|
|
||||||
Value: big.NewInt(1000),
|
|
||||||
Gas: params.TxGas,
|
|
||||||
GasPrice: big.NewInt(params.InitialBaseFee),
|
|
||||||
})
|
|
||||||
|
|
||||||
newTxs = append(newTxs, tx2)
|
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
}
|
|
||||||
|
|
||||||
// testWorkerBackend implements worker.Backend interfaces and wraps all information needed during the testing.
|
|
||||||
type testWorkerBackend struct {
|
|
||||||
db ethdb.Database
|
|
||||||
txPool *core.TxPool
|
|
||||||
chain *core.BlockChain
|
|
||||||
testTxFeed event.Feed
|
|
||||||
genesis *core.Genesis
|
|
||||||
uncleBlock *types.Block
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, n int) *testWorkerBackend {
|
|
||||||
var gspec = core.Genesis{
|
|
||||||
Config: chainConfig,
|
|
||||||
Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
|
|
||||||
}
|
|
||||||
|
|
||||||
switch e := engine.(type) {
|
|
||||||
case *bor.Bor:
|
|
||||||
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
|
|
||||||
copy(gspec.ExtraData[32:32+common.AddressLength], testBankAddress.Bytes())
|
|
||||||
e.Authorize(testBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
|
|
||||||
return crypto.Sign(crypto.Keccak256(data), testBankKey)
|
|
||||||
})
|
|
||||||
case *clique.Clique:
|
|
||||||
gspec.ExtraData = make([]byte, 32+common.AddressLength+crypto.SignatureLength)
|
|
||||||
copy(gspec.ExtraData[32:32+common.AddressLength], testBankAddress.Bytes())
|
|
||||||
e.Authorize(testBankAddress, func(account accounts.Account, s string, data []byte) ([]byte, error) {
|
|
||||||
return crypto.Sign(crypto.Keccak256(data), testBankKey)
|
|
||||||
})
|
|
||||||
case *ethash.Ethash:
|
|
||||||
default:
|
|
||||||
t.Fatalf("unexpected consensus engine type: %T", engine)
|
|
||||||
}
|
|
||||||
|
|
||||||
genesis := gspec.MustCommit(db)
|
|
||||||
|
|
||||||
chain, _ := core.NewBlockChain(db, &core.CacheConfig{TrieDirtyDisabled: true}, gspec.Config, engine, vm.Config{}, nil, nil)
|
|
||||||
txpool := core.NewTxPool(testTxPoolConfig, chainConfig, chain)
|
|
||||||
|
|
||||||
// Generate a small n-block chain and an uncle block for it
|
|
||||||
if n > 0 {
|
|
||||||
blocks, _ := core.GenerateChain(chainConfig, genesis, engine, db, n, func(i int, gen *core.BlockGen) {
|
|
||||||
gen.SetCoinbase(testBankAddress)
|
|
||||||
})
|
|
||||||
if _, err := chain.InsertChain(blocks); err != nil {
|
|
||||||
t.Fatalf("failed to insert origin chain: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parent := genesis
|
|
||||||
if n > 0 {
|
|
||||||
parent = chain.GetBlockByHash(chain.CurrentBlock().ParentHash())
|
|
||||||
}
|
|
||||||
|
|
||||||
blocks, _ := core.GenerateChain(chainConfig, parent, engine, db, 1, func(i int, gen *core.BlockGen) {
|
|
||||||
gen.SetCoinbase(testUserAddress)
|
|
||||||
})
|
|
||||||
|
|
||||||
return &testWorkerBackend{
|
|
||||||
db: db,
|
|
||||||
chain: chain,
|
|
||||||
txPool: txpool,
|
|
||||||
genesis: &gspec,
|
|
||||||
uncleBlock: blocks[0],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
|
|
||||||
func (b *testWorkerBackend) TxPool() *core.TxPool { return b.txPool }
|
|
||||||
func (b *testWorkerBackend) StateAtBlock(block *types.Block, reexec uint64, base *state.StateDB, checkLive bool, preferDisk bool) (statedb *state.StateDB, err error) {
|
|
||||||
return nil, errors.New("not supported")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *testWorkerBackend) newRandomUncle() *types.Block {
|
|
||||||
var parent *types.Block
|
|
||||||
|
|
||||||
cur := b.chain.CurrentBlock()
|
|
||||||
|
|
||||||
if cur.NumberU64() == 0 {
|
|
||||||
parent = b.chain.Genesis()
|
|
||||||
} else {
|
|
||||||
parent = b.chain.GetBlockByHash(b.chain.CurrentBlock().ParentHash())
|
|
||||||
}
|
|
||||||
|
|
||||||
blocks, _ := core.GenerateChain(b.chain.Config(), parent, b.chain.Engine(), b.db, 1, func(i int, gen *core.BlockGen) {
|
|
||||||
var addr = make([]byte, common.AddressLength)
|
|
||||||
|
|
||||||
rand.Read(addr)
|
|
||||||
gen.SetCoinbase(common.BytesToAddress(addr))
|
|
||||||
})
|
|
||||||
|
|
||||||
return blocks[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *testWorkerBackend) newRandomTx(creation bool) *types.Transaction {
|
|
||||||
var tx *types.Transaction
|
|
||||||
|
|
||||||
gasPrice := big.NewInt(10 * params.InitialBaseFee)
|
|
||||||
|
|
||||||
if creation {
|
|
||||||
tx, _ = types.SignTx(types.NewContractCreation(b.txPool.Nonce(testBankAddress), big.NewInt(0), testGas, gasPrice, common.FromHex(testCode)), types.HomesteadSigner{}, testBankKey)
|
|
||||||
} else {
|
|
||||||
tx, _ = types.SignTx(types.NewTransaction(b.txPool.Nonce(testBankAddress), testUserAddress, big.NewInt(1000), params.TxGas, gasPrice, nil), types.HomesteadSigner{}, testBankKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tx
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, db ethdb.Database, blocks int) (*worker, *testWorkerBackend) {
|
|
||||||
backend := newTestWorkerBackend(t, chainConfig, engine, db, blocks)
|
|
||||||
backend.txPool.AddLocals(pendingTxs)
|
|
||||||
w := newWorker(testConfig, chainConfig, engine, backend, new(event.TypeMux), nil, false)
|
|
||||||
w.setEtherbase(testBankAddress)
|
|
||||||
|
|
||||||
return w, backend
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGenerateBlockAndImportEthash(t *testing.T) {
|
func TestGenerateBlockAndImportEthash(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
@ -238,7 +78,7 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool, isBor bool) {
|
||||||
spanner.EXPECT().GetCurrentValidators(gomock.Any(), gomock.Any()).Return([]*valset.Validator{
|
spanner.EXPECT().GetCurrentValidators(gomock.Any(), gomock.Any()).Return([]*valset.Validator{
|
||||||
{
|
{
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Address: testBankAddress,
|
Address: TestBankAddress,
|
||||||
VotingPower: 100,
|
VotingPower: 100,
|
||||||
ProposerPriority: 0,
|
ProposerPriority: 0,
|
||||||
},
|
},
|
||||||
|
|
@ -267,12 +107,12 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool, isBor bool) {
|
||||||
|
|
||||||
chainConfig.LondonBlock = big.NewInt(0)
|
chainConfig.LondonBlock = big.NewInt(0)
|
||||||
|
|
||||||
w, b := newTestWorker(t, chainConfig, engine, db, 0)
|
w, b, _ := NewTestWorker(t, chainConfig, engine, db, 0)
|
||||||
defer w.close()
|
defer w.close()
|
||||||
|
|
||||||
// This test chain imports the mined blocks.
|
// This test chain imports the mined blocks.
|
||||||
db2 := rawdb.NewMemoryDatabase()
|
db2 := rawdb.NewMemoryDatabase()
|
||||||
b.genesis.MustCommit(db2)
|
b.Genesis.MustCommit(db2)
|
||||||
|
|
||||||
chain, _ := core.NewBlockChain(db2, nil, b.chain.Config(), engine, vm.Config{}, nil, nil)
|
chain, _ := core.NewBlockChain(db2, nil, b.chain.Config(), engine, vm.Config{}, nil, nil)
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
@ -289,11 +129,35 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool, isBor bool) {
|
||||||
// Start mining!
|
// Start mining!
|
||||||
w.start()
|
w.start()
|
||||||
|
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
uncle *types.Block
|
||||||
|
)
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
b.txPool.AddLocal(b.newRandomTx(true))
|
err = b.txPool.AddLocal(b.newRandomTx(true))
|
||||||
b.txPool.AddLocal(b.newRandomTx(false))
|
if err != nil {
|
||||||
w.postSideBlock(core.ChainSideEvent{Block: b.newRandomUncle()})
|
t.Fatal("while adding a local transaction", err)
|
||||||
w.postSideBlock(core.ChainSideEvent{Block: b.newRandomUncle()})
|
}
|
||||||
|
|
||||||
|
err = b.txPool.AddLocal(b.newRandomTx(false))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("while adding a remote transaction", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
uncle, err = b.newRandomUncle()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("while making an uncle block", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.postSideBlock(core.ChainSideEvent{Block: uncle})
|
||||||
|
|
||||||
|
uncle, err = b.newRandomUncle()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("while making an uncle block", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.postSideBlock(core.ChainSideEvent{Block: uncle})
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case ev := <-sub.Chan():
|
case ev := <-sub.Chan():
|
||||||
|
|
@ -317,7 +181,7 @@ func TestEmptyWorkClique(t *testing.T) {
|
||||||
func testEmptyWork(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
|
func testEmptyWork(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
|
||||||
defer engine.Close()
|
defer engine.Close()
|
||||||
|
|
||||||
w, _ := newTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
|
w, _, _ := NewTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
|
||||||
defer w.close()
|
defer w.close()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -371,7 +235,7 @@ func TestStreamUncleBlock(t *testing.T) {
|
||||||
ethash := ethash.NewFaker()
|
ethash := ethash.NewFaker()
|
||||||
defer ethash.Close()
|
defer ethash.Close()
|
||||||
|
|
||||||
w, b := newTestWorker(t, ethashChainConfig, ethash, rawdb.NewMemoryDatabase(), 1)
|
w, b, _ := NewTestWorker(t, ethashChainConfig, ethash, rawdb.NewMemoryDatabase(), 1)
|
||||||
defer w.close()
|
defer w.close()
|
||||||
|
|
||||||
var taskCh = make(chan struct{})
|
var taskCh = make(chan struct{})
|
||||||
|
|
@ -433,7 +297,7 @@ func TestRegenerateMiningBlockClique(t *testing.T) {
|
||||||
func testRegenerateMiningBlock(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
|
func testRegenerateMiningBlock(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
|
||||||
defer engine.Close()
|
defer engine.Close()
|
||||||
|
|
||||||
w, b := newTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
|
w, b, _ := NewTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
|
||||||
defer w.close()
|
defer w.close()
|
||||||
|
|
||||||
var taskCh = make(chan struct{}, 3)
|
var taskCh = make(chan struct{}, 3)
|
||||||
|
|
@ -504,7 +368,7 @@ func TestAdjustIntervalClique(t *testing.T) {
|
||||||
func testAdjustInterval(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
|
func testAdjustInterval(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
|
||||||
defer engine.Close()
|
defer engine.Close()
|
||||||
|
|
||||||
w, _ := newTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
|
w, _, _ := NewTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
|
||||||
defer w.close()
|
defer w.close()
|
||||||
|
|
||||||
w.skipSealHook = func(task *task) bool {
|
w.skipSealHook = func(task *task) bool {
|
||||||
|
|
@ -612,7 +476,7 @@ func TestGetSealingWorkPostMerge(t *testing.T) {
|
||||||
func testGetSealingWork(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, postMerge bool) {
|
func testGetSealingWork(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, postMerge bool) {
|
||||||
defer engine.Close()
|
defer engine.Close()
|
||||||
|
|
||||||
w, b := newTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
|
w, b, _ := NewTestWorker(t, chainConfig, engine, rawdb.NewMemoryDatabase(), 0)
|
||||||
defer w.close()
|
defer w.close()
|
||||||
|
|
||||||
w.setExtra([]byte{0x01, 0x02})
|
w.setExtra([]byte{0x01, 0x02})
|
||||||
|
|
@ -747,3 +611,106 @@ func testGetSealingWork(t *testing.T, chainConfig *params.ChainConfig, engine co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkBorMining(b *testing.B) {
|
||||||
|
chainConfig := params.BorUnittestChainConfig
|
||||||
|
|
||||||
|
ctrl := gomock.NewController(b)
|
||||||
|
defer ctrl.Finish()
|
||||||
|
|
||||||
|
ethAPIMock := api.NewMockCaller(ctrl)
|
||||||
|
ethAPIMock.EXPECT().Call(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
|
||||||
|
|
||||||
|
spanner := bor.NewMockSpanner(ctrl)
|
||||||
|
spanner.EXPECT().GetCurrentValidators(gomock.Any(), gomock.Any()).Return([]*valset.Validator{
|
||||||
|
{
|
||||||
|
ID: 0,
|
||||||
|
Address: TestBankAddress,
|
||||||
|
VotingPower: 100,
|
||||||
|
ProposerPriority: 0,
|
||||||
|
},
|
||||||
|
}, nil).AnyTimes()
|
||||||
|
|
||||||
|
heimdallClientMock := mocks.NewMockIHeimdallClient(ctrl)
|
||||||
|
heimdallClientMock.EXPECT().Close().Times(1)
|
||||||
|
|
||||||
|
contractMock := bor.NewMockGenesisContract(ctrl)
|
||||||
|
|
||||||
|
db, _, _ := NewDBForFakes(b)
|
||||||
|
|
||||||
|
engine := NewFakeBor(b, db, chainConfig, ethAPIMock, spanner, heimdallClientMock, contractMock)
|
||||||
|
defer engine.Close()
|
||||||
|
|
||||||
|
chainConfig.LondonBlock = big.NewInt(0)
|
||||||
|
|
||||||
|
w, back, _ := NewTestWorker(b, chainConfig, engine, db, 0)
|
||||||
|
defer w.close()
|
||||||
|
|
||||||
|
// This test chain imports the mined blocks.
|
||||||
|
db2 := rawdb.NewMemoryDatabase()
|
||||||
|
back.Genesis.MustCommit(db2)
|
||||||
|
|
||||||
|
chain, _ := core.NewBlockChain(db2, nil, back.chain.Config(), engine, vm.Config{}, nil, nil)
|
||||||
|
defer chain.Stop()
|
||||||
|
|
||||||
|
// Ignore empty commit here for less noise.
|
||||||
|
w.skipSealHook = func(task *task) bool {
|
||||||
|
return len(task.receipts) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// fulfill tx pool
|
||||||
|
const (
|
||||||
|
totalGas = testGas + params.TxGas
|
||||||
|
totalBlocks = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
txInBlock := int(back.Genesis.GasLimit/totalGas) + 1
|
||||||
|
|
||||||
|
// a bit risky
|
||||||
|
for i := 0; i < 2*totalBlocks*txInBlock; i++ {
|
||||||
|
err = back.txPool.AddLocal(back.newRandomTx(true))
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal("while adding a local transaction", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = back.txPool.AddLocal(back.newRandomTx(false))
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal("while adding a remote transaction", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for mined blocks.
|
||||||
|
sub := w.mux.Subscribe(core.NewMinedBlockEvent{})
|
||||||
|
defer sub.Unsubscribe()
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
prev := uint64(time.Now().Unix())
|
||||||
|
|
||||||
|
// Start mining!
|
||||||
|
w.start()
|
||||||
|
|
||||||
|
blockPeriod, ok := back.Genesis.Config.Bor.Period["0"]
|
||||||
|
if !ok {
|
||||||
|
blockPeriod = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < totalBlocks; i++ {
|
||||||
|
select {
|
||||||
|
case ev := <-sub.Chan():
|
||||||
|
block := ev.Data.(core.NewMinedBlockEvent).Block
|
||||||
|
|
||||||
|
if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
|
||||||
|
b.Fatalf("failed to insert new mined block %d: %v", block.NumberU64(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Log("block", block.NumberU64(), "time", block.Time()-prev, "txs", block.Transactions().Len(), "gasUsed", block.GasUsed(), "gasLimit", block.GasLimit())
|
||||||
|
|
||||||
|
prev = block.Time()
|
||||||
|
case <-time.After(time.Duration(blockPeriod) * time.Second):
|
||||||
|
b.Fatalf("timeout")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue