aboutsummaryrefslogtreecommitdiffstats
path: root/miner/worker_test.go
diff options
context:
space:
mode:
authorgary rong <garyrong0905@gmail.com>2018-08-14 23:34:33 +0800
committerPéter Szilágyi <peterke@gmail.com>2018-08-14 23:34:33 +0800
commita1783d169732dd34aa8c7d68f411ce741c1a5015 (patch)
tree14e12ac6077667789c0fe5bd1166fdc534528d73 /miner/worker_test.go
parente0e0e53401e93733d921338b6d794162c40a7883 (diff)
downloaddexon-a1783d169732dd34aa8c7d68f411ce741c1a5015.tar
dexon-a1783d169732dd34aa8c7d68f411ce741c1a5015.tar.gz
dexon-a1783d169732dd34aa8c7d68f411ce741c1a5015.tar.bz2
dexon-a1783d169732dd34aa8c7d68f411ce741c1a5015.tar.lz
dexon-a1783d169732dd34aa8c7d68f411ce741c1a5015.tar.xz
dexon-a1783d169732dd34aa8c7d68f411ce741c1a5015.tar.zst
dexon-a1783d169732dd34aa8c7d68f411ce741c1a5015.zip
miner: move agent logic to worker (#17351)
* miner: move agent logic to worker * miner: polish * core: persist block before reorg
Diffstat (limited to 'miner/worker_test.go')
-rw-r--r--miner/worker_test.go212
1 files changed, 212 insertions, 0 deletions
diff --git a/miner/worker_test.go b/miner/worker_test.go
new file mode 100644
index 000000000..5823a608e
--- /dev/null
+++ b/miner/worker_test.go
@@ -0,0 +1,212 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package miner
+
+import (
+ "math/big"
+ "testing"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus"
+ "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/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"
+)
+
+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)
+
+ acc1Key, _ = crypto.GenerateKey()
+ acc1Addr = crypto.PubkeyToAddress(acc1Key.PublicKey)
+
+ // Test transactions
+ pendingTxs []*types.Transaction
+ newTxs []*types.Transaction
+)
+
+func init() {
+ testTxPoolConfig = core.DefaultTxPoolConfig
+ testTxPoolConfig.Journal = ""
+ ethashChainConfig = params.TestChainConfig
+ cliqueChainConfig = params.TestChainConfig
+ cliqueChainConfig.Clique = &params.CliqueConfig{
+ Period: 1,
+ Epoch: 30000,
+ }
+ tx1, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), types.HomesteadSigner{}, testBankKey)
+ pendingTxs = append(pendingTxs, tx1)
+ tx2, _ := types.SignTx(types.NewTransaction(1, acc1Addr, big.NewInt(1000), params.TxGas, nil, nil), types.HomesteadSigner{}, testBankKey)
+ 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
+ testTxFeed event.Feed
+}
+
+func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) *testWorkerBackend {
+ var (
+ db = ethdb.NewMemDatabase()
+ gspec = core.Genesis{
+ Config: chainConfig,
+ Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
+ }
+ )
+
+ switch engine.(type) {
+ case *clique.Clique:
+ gspec.ExtraData = make([]byte, 32+common.AddressLength+65)
+ copy(gspec.ExtraData[32:], testBankAddress[:])
+ case *ethash.Ethash:
+ default:
+ t.Fatal("unexpect consensus engine type")
+ }
+ gspec.MustCommit(db)
+
+ chain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{})
+ txpool := core.NewTxPool(testTxPoolConfig, chainConfig, chain)
+
+ return &testWorkerBackend{
+ db: db,
+ chain: chain,
+ txPool: txpool,
+ }
+}
+
+func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
+func (b *testWorkerBackend) TxPool() *core.TxPool { return b.txPool }
+func (b *testWorkerBackend) PostChainEvents(events []interface{}) {
+ b.chain.PostChainEvents(events, nil)
+}
+
+func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) (*worker, *testWorkerBackend) {
+ backend := newTestWorkerBackend(t, chainConfig, engine)
+ backend.txPool.AddLocals(pendingTxs)
+ w := newWorker(chainConfig, engine, backend, new(event.TypeMux))
+ w.setEtherbase(testBankAddress)
+ return w, backend
+}
+
+func TestPendingStateAndBlockEthash(t *testing.T) {
+ testPendingStateAndBlock(t, ethashChainConfig, ethash.NewFaker())
+}
+func TestPendingStateAndBlockClique(t *testing.T) {
+ testPendingStateAndBlock(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, ethdb.NewMemDatabase()))
+}
+
+func testPendingStateAndBlock(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
+ defer engine.Close()
+
+ w, b := newTestWorker(t, chainConfig, engine)
+ defer w.close()
+
+ // Ensure snapshot has been updated.
+ time.Sleep(100 * time.Millisecond)
+ block, state := w.pending()
+ if block.NumberU64() != 1 {
+ t.Errorf("block number mismatch, has %d, want %d", block.NumberU64(), 1)
+ }
+ if balance := state.GetBalance(acc1Addr); balance.Cmp(big.NewInt(1000)) != 0 {
+ t.Errorf("account balance mismatch, has %d, want %d", balance, 1000)
+ }
+ b.txPool.AddLocals(newTxs)
+ // Ensure the new tx events has been processed
+ time.Sleep(100 * time.Millisecond)
+ block, state = w.pending()
+ if balance := state.GetBalance(acc1Addr); balance.Cmp(big.NewInt(2000)) != 0 {
+ t.Errorf("account balance mismatch, has %d, want %d", balance, 2000)
+ }
+}
+
+func TestEmptyWorkEthash(t *testing.T) {
+ testEmptyWork(t, ethashChainConfig, ethash.NewFaker())
+}
+func TestEmptyWorkClique(t *testing.T) {
+ testEmptyWork(t, cliqueChainConfig, clique.New(cliqueChainConfig.Clique, ethdb.NewMemDatabase()))
+}
+
+func testEmptyWork(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine) {
+ defer engine.Close()
+
+ w, _ := newTestWorker(t, chainConfig, engine)
+ defer w.close()
+
+ var (
+ taskCh = make(chan struct{}, 2)
+ taskIndex int
+ )
+
+ checkEqual := func(t *testing.T, task *task, index int) {
+ receiptLen, balance := 0, big.NewInt(0)
+ if index == 1 {
+ receiptLen, balance = 1, big.NewInt(1000)
+ }
+ if len(task.receipts) != receiptLen {
+ t.Errorf("receipt number mismatch has %d, want %d", len(task.receipts), receiptLen)
+ }
+ if task.state.GetBalance(acc1Addr).Cmp(balance) != 0 {
+ t.Errorf("account balance mismatch has %d, want %d", task.state.GetBalance(acc1Addr), balance)
+ }
+ }
+
+ w.newTaskHook = func(task *task) {
+ if task.block.NumberU64() == 1 {
+ checkEqual(t, task, taskIndex)
+ taskIndex += 1
+ taskCh <- struct{}{}
+ }
+ }
+ w.fullTaskInterval = func() {
+ time.Sleep(100 * time.Millisecond)
+ }
+
+ // Ensure worker has finished initialization
+ for {
+ b := w.pendingBlock()
+ if b != nil && b.NumberU64() == 1 {
+ break
+ }
+ }
+
+ w.start()
+ for i := 0; i < 2; i += 1 {
+ to := time.NewTimer(time.Second)
+ select {
+ case <-taskCh:
+ case <-to.C:
+ t.Error("new task timeout")
+ }
+ }
+}