aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbojie <bojie@dexon.org>2019-01-14 20:42:15 +0800
committerWei-Ning Huang <w@dexon.org>2019-04-09 21:32:56 +0800
commit2155bbd85373a8527e3b565f4316bc4f1517650a (patch)
tree2f64cbc5a6810aa496524c7509a4998847526123
parent3fcb8b6825b3c62c9890a5ca59594f1503e66893 (diff)
downloaddexon-2155bbd85373a8527e3b565f4316bc4f1517650a.tar.gz
dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.tar.zst
dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.zip
app: remove pending block logic (#149)
-rw-r--r--core/block_validator.go7
-rw-r--r--core/blockchain.go331
-rw-r--r--core/blockchain_test.go38
-rw-r--r--core/events.go2
-rw-r--r--core/tx_pool.go77
-rw-r--r--core/tx_pool_test.go38
-rw-r--r--dex/api_backend.go6
-rw-r--r--dex/app.go72
-rw-r--r--dex/app_test.go224
-rw-r--r--dex/backend.go2
-rw-r--r--eth/backend.go2
-rw-r--r--indexer/blockchain.go5
-rw-r--r--les/handler_test.go2
-rw-r--r--miner/worker_test.go2
14 files changed, 342 insertions, 466 deletions
diff --git a/core/block_validator.go b/core/block_validator.go
index 660bd09f8..c6038381f 100644
--- a/core/block_validator.go
+++ b/core/block_validator.go
@@ -102,12 +102,9 @@ func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *stat
}
func (v *BlockValidator) ValidateWitnessData(height uint64, data types.WitnessData) error {
- b := v.bc.GetPendingBlockByNumber(height)
+ b := v.bc.GetBlockByNumber(height)
if b == nil {
- b = v.bc.GetBlockByNumber(height)
- if b == nil {
- return fmt.Errorf("can not find block %v either pending or confirmed block", height)
- }
+ return fmt.Errorf("can not find block %v either pending or confirmed block", height)
}
if b.Root() != data.Root {
diff --git a/core/blockchain.go b/core/blockchain.go
index 089f1c2fa..6aee356d2 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -105,15 +105,14 @@ type BlockChain struct {
triegc *prque.Prque // Priority queue mapping block numbers to tries to gc
gcproc time.Duration // Accumulates canonical block processing for trie dumping
- hc *HeaderChain
- rmLogsFeed event.Feed
- chainFeed event.Feed
- chainSideFeed event.Feed
- chainHeadFeed event.Feed
- blockConfirmedFeed event.Feed
- logsFeed event.Feed
- scope event.SubscriptionScope
- genesisBlock *types.Block
+ hc *HeaderChain
+ rmLogsFeed event.Feed
+ chainFeed event.Feed
+ chainSideFeed event.Feed
+ chainHeadFeed event.Feed
+ logsFeed event.Feed
+ scope event.SubscriptionScope
+ genesisBlock *types.Block
mu sync.RWMutex // global mutex for locking chain operations
chainmu sync.RWMutex // blockchain insertion lock
@@ -154,14 +153,6 @@ type BlockChain struct {
addressCost map[uint32]map[common.Address]*big.Int
addressCounter map[uint32]map[common.Address]uint64
chainLastHeight sync.Map
-
- pendingBlockMu sync.RWMutex
- lastPendingHeight uint64
- pendingBlocks map[uint64]struct {
- block *types.Block
- receipts types.Receipts
- proctime time.Duration
- }
}
// NewBlockChain returns a fully initialised block chain using information
@@ -183,25 +174,20 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
badBlocks, _ := lru.New(badBlockLimit)
bc := &BlockChain{
- chainConfig: chainConfig,
- cacheConfig: cacheConfig,
- db: db,
- triegc: prque.New(nil),
- stateCache: state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit),
- quit: make(chan struct{}),
- bodyCache: bodyCache,
- bodyRLPCache: bodyRLPCache,
- receiptsCache: receiptsCache,
- blockCache: blockCache,
- futureBlocks: futureBlocks,
- engine: engine,
- vmConfig: vmConfig,
- badBlocks: badBlocks,
- pendingBlocks: make(map[uint64]struct {
- block *types.Block
- receipts types.Receipts
- proctime time.Duration
- }),
+ chainConfig: chainConfig,
+ cacheConfig: cacheConfig,
+ db: db,
+ triegc: prque.New(nil),
+ stateCache: state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit),
+ quit: make(chan struct{}),
+ bodyCache: bodyCache,
+ bodyRLPCache: bodyRLPCache,
+ receiptsCache: receiptsCache,
+ blockCache: blockCache,
+ futureBlocks: futureBlocks,
+ engine: engine,
+ vmConfig: vmConfig,
+ badBlocks: badBlocks,
confirmedBlocks: make(map[uint32]map[coreCommon.Hash]*blockInfo),
addressNonce: make(map[uint32]map[common.Address]uint64),
addressCost: make(map[uint32]map[common.Address]*big.Int),
@@ -1764,6 +1750,16 @@ func (bc *BlockChain) insertDexonChain(chain types.Blocks) (int, []interface{},
}
proctime := time.Since(bstart)
+ chainBlock := bc.GetBlockByNumber(block.NumberU64())
+ if chainBlock != nil {
+ if chainBlock.Hash() != block.Hash() {
+ return i, nil, nil, fmt.Errorf("block %v exist but hash is not equal: exist %v expect %v", block.NumberU64(),
+ chainBlock.Hash(), block.Hash())
+ }
+
+ continue
+ }
+
// Write the block to the chain and get the status.
status, err := bc.WriteBlockWithState(block, receipts, state)
if err != nil {
@@ -1814,13 +1810,13 @@ func (bc *BlockChain) VerifyDexonHeader(header *types.Header) error {
return bc.hc.verifyTSig(header, bc.verifierCache)
}
-func (bc *BlockChain) ProcessPendingBlock(block *types.Block, witness *coreTypes.Witness) (*common.Hash, error) {
- n, events, logs, err := bc.processPendingBlock(block, witness)
+func (bc *BlockChain) ProcessBlock(block *types.Block, witness *coreTypes.Witness) (*common.Hash, error) {
+ root, events, logs, err := bc.processBlock(block, witness)
bc.PostChainEvents(events, logs)
- return n, err
+ return root, err
}
-func (bc *BlockChain) processPendingBlock(
+func (bc *BlockChain) processBlock(
block *types.Block, witness *coreTypes.Witness) (*common.Hash, []interface{}, []*types.Log, error) {
// Pre-checks passed, start the full block imports
bc.wg.Add(1)
@@ -1835,7 +1831,6 @@ func (bc *BlockChain) processPendingBlock(
var (
stats = insertStats{startTime: mclock.Now()}
events = make([]interface{}, 0, 2)
- lastCanon *types.Block
coalescedLogs []*types.Log
)
@@ -1858,28 +1853,23 @@ func (bc *BlockChain) processPendingBlock(
)
var parentBlock *types.Block
- var pendingState *state.StateDB
+ var currentState *state.StateDB
var err error
- parent, exist := bc.pendingBlocks[block.NumberU64()-1]
- if !exist {
- parentBlock = bc.GetBlockByNumber(block.NumberU64() - 1)
- if parentBlock == nil {
- return nil, nil, nil, fmt.Errorf("parent block %d not exist", block.NumberU64()-1)
- }
- } else {
- parentBlock = parent.block
+ parentBlock = bc.GetBlockByNumber(block.NumberU64() - 1)
+ if parentBlock == nil {
+ return nil, nil, nil, fmt.Errorf("parent block %d not exist", block.NumberU64()-1)
}
header.ParentHash = parentBlock.Hash()
- pendingState, err = state.New(parentBlock.Root(), bc.stateCache)
+ currentState, err = state.New(parentBlock.Root(), bc.stateCache)
if err != nil {
return nil, nil, nil, err
}
// Iterate over and process the individual transactions.
for i, tx := range block.Transactions() {
- pendingState.Prepare(tx.Hash(), block.Hash(), i)
- receipt, _, err := ApplyTransaction(bc.chainConfig, bc, nil, gp, pendingState, header, tx, usedGas, bc.vmConfig)
+ currentState.Prepare(tx.Hash(), block.Hash(), i)
+ receipt, _, err := ApplyTransaction(bc.chainConfig, bc, nil, gp, currentState, header, tx, usedGas, bc.vmConfig)
if err != nil {
return nil, nil, nil, fmt.Errorf("apply transaction error: %v %d", err, tx.Nonce())
}
@@ -1888,189 +1878,148 @@ func (bc *BlockChain) processPendingBlock(
}
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
header.GasUsed = *usedGas
- newPendingBlock, err := bc.engine.Finalize(bc, header, pendingState, block.Transactions(), block.Uncles(), receipts)
+ newBlock, err := bc.engine.Finalize(bc, header, currentState, block.Transactions(), block.Uncles(), receipts)
+ root := newBlock.Root()
if err != nil {
return nil, nil, nil, fmt.Errorf("finalize error: %v", err)
}
- if _, ok := bc.GetRoundHeight(newPendingBlock.Round()); !ok {
- bc.storeRoundHeight(newPendingBlock.Round(), newPendingBlock.NumberU64())
+ if _, ok := bc.GetRoundHeight(newBlock.Round()); !ok {
+ bc.storeRoundHeight(newBlock.Round(), newBlock.NumberU64())
}
-
proctime := time.Since(bstart)
- // Commit state to refresh stateCache.
- _, err = pendingState.Commit(true)
- if err != nil {
- return nil, nil, nil, fmt.Errorf("pendingState commit error: %v", err)
- }
-
- // Add into pending blocks.
- bc.addPendingBlock(newPendingBlock, receipts, proctime)
- events = append(events, BlockConfirmedEvent{newPendingBlock})
-
- log.Debug("Inserted pending block", "height", newPendingBlock.Number(), "hash", newPendingBlock.Hash())
-
- // Start insert available pending blocks into db
- for pendingHeight := bc.CurrentBlock().NumberU64() + 1; pendingHeight <= witness.Height; pendingHeight++ {
- if atomic.LoadInt32(&bc.procInterrupt) == 1 {
- log.Debug("Premature abort during blocks processing")
- return nil, nil, nil, fmt.Errorf("interrupt")
- }
-
- pendingIns, exist := bc.pendingBlocks[pendingHeight]
- if !exist {
- log.Error("Block has already inserted", "height", pendingHeight)
- continue
+ chainBlock := bc.GetBlockByNumber(newBlock.NumberU64())
+ if chainBlock != nil {
+ if chainBlock.Hash() != newBlock.Hash() {
+ return nil, nil, nil, fmt.Errorf("block %v exist but hash is not equal: exist %v expect %v", newBlock.NumberU64(),
+ chainBlock.Hash(), newBlock.Hash())
}
- s, err := state.New(pendingIns.block.Root(), bc.stateCache)
- if err != nil {
- return nil, events, coalescedLogs, err
- }
+ return &root, nil, nil, nil
+ }
- // Write the block to the chain and get the status.
- insertTime := time.Now()
- status, err := bc.WriteBlockWithState(pendingIns.block, pendingIns.receipts, s)
- if err != nil {
- return nil, events, coalescedLogs, fmt.Errorf("WriteBlockWithState error: %v", err)
- }
+ // Write the block to the chain and get the status.
+ status, err := bc.WriteBlockWithState(newBlock, receipts, currentState)
+ if err != nil {
+ return nil, events, coalescedLogs, fmt.Errorf("WriteBlockWithState error: %v", err)
+ }
- switch status {
- case CanonStatTy:
- log.Debug("Inserted new block", "number", pendingIns.block.Number(), "hash", pendingIns.block.Hash(),
- "uncles", len(pendingIns.block.Uncles()), "txs", len(pendingIns.block.Transactions()),
- "gas", pendingIns.block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart)))
+ switch status {
+ case CanonStatTy:
+ log.Debug("Inserted new block", "number", newBlock.Number(), "hash", newBlock.Hash(),
+ "uncles", len(newBlock.Uncles()), "txs", len(newBlock.Transactions()),
+ "gas", newBlock.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart)))
- var allLogs []*types.Log
- for _, r := range pendingIns.receipts {
- allLogs = append(allLogs, r.Logs...)
- }
- coalescedLogs = append(coalescedLogs, allLogs...)
- blockInsertTimer.UpdateSince(insertTime)
- events = append(events, ChainEvent{pendingIns.block, pendingIns.block.Hash(), allLogs})
- lastCanon = pendingIns.block
+ var allLogs []*types.Log
+ for _, r := range receipts {
+ allLogs = append(allLogs, r.Logs...)
+ }
+ coalescedLogs = append(coalescedLogs, allLogs...)
+ blockInsertTimer.UpdateSince(bstart)
+ events = append(events, ChainEvent{newBlock, newBlock.Hash(), allLogs}, ChainHeadEvent{newBlock})
- // Only count canonical blocks for GC processing time
- bc.gcproc += pendingIns.proctime
+ // Only count canonical blocks for GC processing time
+ bc.gcproc += proctime
- case SideStatTy:
- return nil, nil, nil, fmt.Errorf("insert pending block and fork found")
- }
- bc.removePendingBlock(pendingHeight)
+ case SideStatTy:
+ return nil, nil, nil, fmt.Errorf("insert pending block and fork found")
+ }
- stats.processed++
- stats.usedGas += pendingIns.block.GasUsed()
+ stats.processed++
+ stats.usedGas += newBlock.GasUsed()
- cache, _ := bc.stateCache.TrieDB().Size()
- stats.report([]*types.Block{pendingIns.block}, 0, cache)
+ cache, _ := bc.stateCache.TrieDB().Size()
+ stats.report([]*types.Block{newBlock}, 0, cache)
- if pendingHeight == witness.Height {
- err = bc.updateLastRoundNumber(pendingIns.block.Round())
- if err != nil {
- return nil, nil, nil, err
- }
- }
- }
- // Append a single chain head event if we've progressed the chain
- if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
- events = append(events, ChainHeadEvent{lastCanon})
+ err = bc.updateLastRoundNumber(newBlock.Round())
+ if err != nil {
+ return nil, nil, nil, err
}
- root := newPendingBlock.Root()
return &root, events, coalescedLogs, nil
}
-func (bc *BlockChain) ProcessEmptyBlock(block *types.Block) error {
+func (bc *BlockChain) ProcessEmptyBlock(block *types.Block) (*common.Hash, error) {
bstart := time.Now()
+ var stats = insertStats{startTime: mclock.Now()}
var header = block.Header()
var parentBlock *types.Block
- var pendingState *state.StateDB
+ var currentState *state.StateDB
var err error
- parent, exist := bc.pendingBlocks[block.NumberU64()-1]
- if !exist {
- parentBlock = bc.GetBlockByNumber(block.NumberU64() - 1)
- if parentBlock == nil {
- return fmt.Errorf("parent block %d not exist", block.NumberU64()-1)
- }
- } else {
- parentBlock = parent.block
+
+ parentBlock = bc.GetBlockByNumber(block.NumberU64() - 1)
+ if parentBlock == nil {
+ return nil, fmt.Errorf("parent block %d not exist", block.NumberU64()-1)
}
- pendingState, err = state.New(parentBlock.Root(), bc.stateCache)
+ currentState, err = state.New(parentBlock.Root(), bc.stateCache)
if err != nil {
- return err
+ return nil, err
}
header.ParentHash = parentBlock.Hash()
header.GasUsed = 0
- header.Root = pendingState.IntermediateRoot(true)
+ header.Root = currentState.IntermediateRoot(true)
if header.Root != parentBlock.Root() {
- return fmt.Errorf("empty block state root must same as parent")
+ return nil, fmt.Errorf("empty block state root must same as parent")
}
- newPendingBlock := types.NewBlock(header, nil, nil, nil)
- if _, ok := bc.GetRoundHeight(newPendingBlock.Round()); !ok {
- bc.storeRoundHeight(newPendingBlock.Round(), newPendingBlock.NumberU64())
+ newBlock := types.NewBlock(header, nil, nil, nil)
+ root := newBlock.Root()
+ if _, ok := bc.GetRoundHeight(newBlock.Round()); !ok {
+ bc.storeRoundHeight(newBlock.Round(), newBlock.NumberU64())
}
+ if _, ok := bc.GetRoundHeight(newBlock.Round()); !ok {
+ bc.storeRoundHeight(newBlock.Round(), newBlock.NumberU64())
+ }
proctime := time.Since(bstart)
- bc.addPendingBlock(newPendingBlock, nil, proctime)
- bc.PostChainEvents([]interface{}{BlockConfirmedEvent{newPendingBlock}}, nil)
- return nil
-}
-
-func (bc *BlockChain) removePendingBlock(height uint64) {
- bc.pendingBlockMu.Lock()
- defer bc.pendingBlockMu.Unlock()
-
- delete(bc.pendingBlocks, height)
-}
-
-func (bc *BlockChain) addPendingBlock(block *types.Block, receipts types.Receipts, proctime time.Duration) {
- bc.pendingBlockMu.Lock()
- defer bc.pendingBlockMu.Unlock()
-
- bc.pendingBlocks[block.NumberU64()] = struct {
- block *types.Block
- receipts types.Receipts
- proctime time.Duration
- }{block: block, receipts: receipts, proctime: proctime}
- bc.lastPendingHeight = block.NumberU64()
-}
+ chainBlock := bc.GetBlockByNumber(newBlock.NumberU64())
+ if chainBlock != nil {
+ if chainBlock.Hash() != newBlock.Hash() {
+ return nil, fmt.Errorf("block %v exist but hash is not equal: exist %v expect %v", newBlock.NumberU64(),
+ chainBlock.Hash(), newBlock.Hash())
+ }
-func (bc *BlockChain) GetPendingHeight() uint64 {
- bc.pendingBlockMu.RLock()
- defer bc.pendingBlockMu.RUnlock()
+ return &root, nil
+ }
- return bc.lastPendingHeight
-}
+ // Write the block to the chain and get the status.
+ status, err := bc.WriteBlockWithState(newBlock, nil, currentState)
+ if err != nil {
+ return nil, fmt.Errorf("WriteBlockWithState error: %v", err)
+ }
-func (bc *BlockChain) PendingBlock() *types.Block {
- bc.pendingBlockMu.RLock()
- defer bc.pendingBlockMu.RUnlock()
+ switch status {
+ case CanonStatTy:
+ log.Debug("Inserted new block", "number", newBlock.Number(), "hash", newBlock.Hash(),
+ "uncles", len(newBlock.Uncles()), "txs", len(newBlock.Transactions()),
+ "gas", newBlock.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart)))
+ blockInsertTimer.UpdateSince(bstart)
+ // Only count canonical blocks for GC processing time
+ bc.gcproc += proctime
- return bc.pendingBlocks[bc.lastPendingHeight].block
-}
+ case SideStatTy:
+ return nil, fmt.Errorf("insert pending block and fork found")
+ }
-func (bc *BlockChain) GetPendingBlockByNumber(number uint64) *types.Block {
- bc.pendingBlockMu.RLock()
- defer bc.pendingBlockMu.RUnlock()
+ stats.processed++
+ stats.usedGas += newBlock.GasUsed()
- return bc.pendingBlocks[number].block
-}
+ cache, _ := bc.stateCache.TrieDB().Size()
+ stats.report([]*types.Block{newBlock}, 0, cache)
-func (bc *BlockChain) GetPending() (*types.Block, *state.StateDB) {
- block := bc.PendingBlock()
- if block == nil {
- block = bc.CurrentBlock()
- }
- s, err := state.New(block.Header().Root, bc.stateCache)
+ err = bc.updateLastRoundNumber(newBlock.Round())
if err != nil {
- panic(err)
+ return nil, err
}
- return block, s
+
+ bc.PostChainEvents([]interface{}{ChainEvent{newBlock, newBlock.Hash(), nil},
+ ChainHeadEvent{newBlock}}, nil)
+
+ return &root, nil
}
// GetGovStateByHash extracts the governance contract's state from state trie
@@ -2253,9 +2202,6 @@ func (bc *BlockChain) PostChainEvents(events []interface{}, logs []*types.Log) {
case ChainHeadEvent:
bc.chainHeadFeed.Send(ev)
- case BlockConfirmedEvent:
- bc.blockConfirmedFeed.Send(ev)
-
case ChainSideEvent:
bc.chainSideFeed.Send(ev)
}
@@ -2475,11 +2421,6 @@ func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Su
return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
}
-// SubscribeBlockConfirmedEvent registers a subscription of ChainHeadEvent.
-func (bc *BlockChain) SubscribeBlockConfirmedEvent(ch chan<- BlockConfirmedEvent) event.Subscription {
- return bc.scope.Track(bc.blockConfirmedFeed.Subscribe(ch))
-}
-
// SubscribeChainSideEvent registers a subscription of ChainSideEvent.
func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index a902f0032..45eb191f2 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -1626,7 +1626,7 @@ func (d *dexconTest) Finalize(chain consensus.ChainReader, header *types.Header,
return types.NewBlock(header, txs, uncles, receipts), nil
}
-func TestProcessPendingBlock(t *testing.T) {
+func TestProcessBlock(t *testing.T) {
db := ethdb.NewMemDatabase()
key, err := crypto.GenerateKey()
@@ -1672,8 +1672,8 @@ func TestProcessPendingBlock(t *testing.T) {
}
} else {
witnessData := types.WitnessData{
- Root: chain.pendingBlocks[uint64(i)].block.Root(),
- ReceiptHash: chain.pendingBlocks[uint64(i)].block.ReceiptHash(),
+ Root: chain.CurrentBlock().Root(),
+ ReceiptHash: chain.CurrentBlock().ReceiptHash(),
}
witnessDataBytes, err = rlp.EncodeToBytes(&witnessData)
if err != nil {
@@ -1689,7 +1689,7 @@ func TestProcessPendingBlock(t *testing.T) {
t.Fatalf("sign tx error: %v", err)
}
- _, err = chain.ProcessPendingBlock(types.NewBlock(&types.Header{
+ _, err = chain.ProcessBlock(types.NewBlock(&types.Header{
Number: new(big.Int).SetUint64(uint64(i) + 1),
Time: uint64(time.Now().UnixNano() / 1000000),
GasLimit: 10000,
@@ -1703,13 +1703,13 @@ func TestProcessPendingBlock(t *testing.T) {
t.Fatalf("process pending block error: %v", err)
}
- if chain.CurrentBlock().NumberU64() != uint64(i) {
- t.Fatalf("expect current height %v but %v", uint64(i), chain.CurrentBlock().NumberU64())
+ if chain.CurrentBlock().NumberU64() != uint64(i+1) {
+ t.Fatalf("expect current height %v but %v", uint64(i+1), chain.CurrentBlock().NumberU64())
}
}
// Witness rlp decode fail.
- _, err = chain.ProcessPendingBlock(types.NewBlock(&types.Header{
+ _, err = chain.ProcessBlock(types.NewBlock(&types.Header{
Number: new(big.Int).SetUint64(processNum + 1),
Time: uint64(time.Now().UnixNano() / 1000000),
GasLimit: 10000,
@@ -1724,14 +1724,14 @@ func TestProcessPendingBlock(t *testing.T) {
// Validate witness fail with unknown block.
witnessData := types.WitnessData{
- Root: chain.pendingBlocks[processNum].block.Root(),
- ReceiptHash: chain.pendingBlocks[processNum].block.ReceiptHash(),
+ Root: chain.CurrentBlock().Root(),
+ ReceiptHash: chain.CurrentBlock().ReceiptHash(),
}
witnessDataBytes, err := rlp.EncodeToBytes(&witnessData)
if err != nil {
t.Fatalf("rlp encode fail: %v", err)
}
- _, err = chain.ProcessPendingBlock(types.NewBlock(&types.Header{
+ _, err = chain.ProcessBlock(types.NewBlock(&types.Header{
Number: new(big.Int).SetUint64(processNum + 1),
Time: uint64(time.Now().UnixNano() / 1000000),
GasLimit: 10000,
@@ -1747,14 +1747,14 @@ func TestProcessPendingBlock(t *testing.T) {
// Validate witness fail with unexpected root.
witnessData = types.WitnessData{
- Root: chain.pendingBlocks[processNum].block.Root(),
- ReceiptHash: chain.pendingBlocks[processNum].block.ReceiptHash(),
+ Root: chain.CurrentBlock().Root(),
+ ReceiptHash: chain.CurrentBlock().ReceiptHash(),
}
witnessDataBytes, err = rlp.EncodeToBytes(&witnessData)
if err != nil {
t.Fatalf("rlp encode fail: %v", err)
}
- _, err = chain.ProcessPendingBlock(types.NewBlock(&types.Header{
+ _, err = chain.ProcessBlock(types.NewBlock(&types.Header{
Number: new(big.Int).SetUint64(processNum + 1),
Time: uint64(time.Now().UnixNano() / 1000000),
GasLimit: 10000,
@@ -1770,8 +1770,8 @@ func TestProcessPendingBlock(t *testing.T) {
// Apply transaction fail with insufficient fund.
witnessData = types.WitnessData{
- Root: chain.pendingBlocks[processNum].block.Root(),
- ReceiptHash: chain.pendingBlocks[processNum].block.ReceiptHash(),
+ Root: chain.CurrentBlock().Root(),
+ ReceiptHash: chain.CurrentBlock().ReceiptHash(),
}
witnessDataBytes, err = rlp.EncodeToBytes(&witnessData)
if err != nil {
@@ -1786,7 +1786,7 @@ func TestProcessPendingBlock(t *testing.T) {
t.Fatalf("sign tx error: %v", err)
}
- _, err = chain.ProcessPendingBlock(types.NewBlock(&types.Header{
+ _, err = chain.ProcessBlock(types.NewBlock(&types.Header{
Number: new(big.Int).SetUint64(processNum + 1),
Time: uint64(time.Now().UnixNano() / 1000000),
GasLimit: 10000,
@@ -1802,8 +1802,8 @@ func TestProcessPendingBlock(t *testing.T) {
// Apply transaction fail with nonce too height.
witnessData = types.WitnessData{
- Root: chain.pendingBlocks[processNum].block.Root(),
- ReceiptHash: chain.pendingBlocks[processNum].block.ReceiptHash(),
+ Root: chain.CurrentBlock().Root(),
+ ReceiptHash: chain.CurrentBlock().ReceiptHash(),
}
witnessDataBytes, err = rlp.EncodeToBytes(&witnessData)
if err != nil {
@@ -1818,7 +1818,7 @@ func TestProcessPendingBlock(t *testing.T) {
t.Fatalf("sign tx error: %v", err)
}
- _, err = chain.ProcessPendingBlock(types.NewBlock(&types.Header{
+ _, err = chain.ProcessBlock(types.NewBlock(&types.Header{
Number: new(big.Int).SetUint64(processNum + 1),
Time: uint64(time.Now().UnixNano() / 1000000),
GasLimit: 10000,
diff --git a/core/events.go b/core/events.go
index e174e8aad..c2cabafd3 100644
--- a/core/events.go
+++ b/core/events.go
@@ -50,8 +50,6 @@ type ChainSideEvent struct {
type ChainHeadEvent struct{ Block *types.Block }
-type BlockConfirmedEvent struct{ Block *types.Block }
-
type NewNotarySetEvent struct {
Round uint64
Pubkeys map[string]struct{} // pubkeys in hex format
diff --git a/core/tx_pool.go b/core/tx_pool.go
index 546ef0a99..871b50be1 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -37,9 +37,6 @@ import (
const (
// chainHeadChanSize is the size of channel listening to ChainHeadEvent.
chainHeadChanSize = 10
-
- // blockConfirmedChanSize is the size of channel listening to BlockConfirmedEvent.
- blockConfirmedChanSize = 10
)
var (
@@ -121,7 +118,6 @@ type blockChain interface {
StateAt(root common.Hash) (*state.StateDB, error)
SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
- SubscribeBlockConfirmedEvent(ch chan<- BlockConfirmedEvent) event.Subscription
}
// TxPoolConfig are the configuration parameters of the transaction pool.
@@ -206,18 +202,16 @@ func (config *TxPoolConfig) sanitize() TxPoolConfig {
// current state) and future transactions. Transactions move between those
// two states over time as they are received and processed.
type TxPool struct {
- config TxPoolConfig
- chainconfig *params.ChainConfig
- chain blockChain
- gasPrice *big.Int
- txFeed event.Feed
- scope event.SubscriptionScope
- chainHeadCh chan ChainHeadEvent
- chainHeadSub event.Subscription
- blockConfirmedCh chan BlockConfirmedEvent
- blockConfirmedSub event.Subscription
- signer types.Signer
- mu sync.RWMutex
+ config TxPoolConfig
+ chainconfig *params.ChainConfig
+ chain blockChain
+ gasPrice *big.Int
+ txFeed event.Feed
+ scope event.SubscriptionScope
+ chainHeadCh chan ChainHeadEvent
+ chainHeadSub event.Subscription
+ signer types.Signer
+ mu sync.RWMutex
currentState *state.StateDB // Current state in the blockchain head
pendingState *state.ManagedState // Pending state tracking virtual nonces
@@ -234,30 +228,27 @@ type TxPool struct {
wg sync.WaitGroup // for shutdown sync
- homestead bool
- isBlockProposer bool
+ homestead bool
}
// NewTxPool creates a new transaction pool to gather, sort and filter inbound
// transactions from the network.
-func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain, isBlockProposer bool) *TxPool {
+func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool {
// Sanitize the input to ensure no vulnerable gas prices are set
config = (&config).sanitize()
// Create the transaction pool with its initial settings
pool := &TxPool{
- config: config,
- chainconfig: chainconfig,
- chain: chain,
- signer: types.NewEIP155Signer(chainconfig.ChainID),
- pending: make(map[common.Address]*txList),
- queue: make(map[common.Address]*txList),
- beats: make(map[common.Address]time.Time),
- all: newTxLookup(),
- chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize),
- blockConfirmedCh: make(chan BlockConfirmedEvent, blockConfirmedChanSize),
- gasPrice: new(big.Int).SetUint64(config.PriceLimit),
- isBlockProposer: isBlockProposer,
+ config: config,
+ chainconfig: chainconfig,
+ chain: chain,
+ signer: types.NewEIP155Signer(chainconfig.ChainID),
+ pending: make(map[common.Address]*txList),
+ queue: make(map[common.Address]*txList),
+ beats: make(map[common.Address]time.Time),
+ all: newTxLookup(),
+ chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize),
+ gasPrice: new(big.Int).SetUint64(config.PriceLimit),
}
pool.locals = newAccountSet(pool.signer)
for _, addr := range config.Locals {
@@ -279,7 +270,6 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block
}
}
// Subscribe events from blockchain
- pool.blockConfirmedSub = pool.chain.SubscribeBlockConfirmedEvent(pool.blockConfirmedCh)
pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh)
// Start the event loop and return
@@ -315,9 +305,6 @@ func (pool *TxPool) loop() {
select {
// Handle ChainHeadEvent
case ev := <-pool.chainHeadCh:
- if pool.isBlockProposer {
- break
- }
if ev.Block != nil {
pool.mu.Lock()
if pool.chainconfig.IsHomestead(ev.Block.Number()) {
@@ -331,24 +318,6 @@ func (pool *TxPool) loop() {
// Be unsubscribed due to system stopped
case <-pool.chainHeadSub.Err():
return
- // Handle BlockConfirmedEvent
- case ev := <-pool.blockConfirmedCh:
- if !pool.isBlockProposer {
- break
- }
- if ev.Block != nil {
- pool.mu.Lock()
- if pool.chainconfig.IsHomestead(ev.Block.Number()) {
- pool.homestead = true
- }
- pool.reset(head.Header(), ev.Block.Header())
- head = ev.Block
-
- pool.mu.Unlock()
- }
- // Be unsubscribed due to system stopped
- case <-pool.blockConfirmedSub.Err():
- return
// Handle stats reporting ticks
case <-report.C:
@@ -439,7 +408,7 @@ func (pool *TxPool) Stop() {
pool.scope.Close()
// Unsubscribe subscriptions registered from blockchain
- pool.blockConfirmedSub.Unsubscribe()
+ pool.chainHeadSub.Unsubscribe()
pool.wg.Wait()
if pool.journal != nil {
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index dc664eedd..96151850d 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -69,10 +69,6 @@ func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) even
return bc.chainHeadFeed.Subscribe(ch)
}
-func (bc *testBlockChain) SubscribeBlockConfirmedEvent(ch chan<- BlockConfirmedEvent) event.Subscription {
- return bc.blockConfirmedFeed.Subscribe(ch)
-}
-
func transaction(nonce uint64, gaslimit uint64, key *ecdsa.PrivateKey) *types.Transaction {
return pricedTransaction(nonce, gaslimit, big.NewInt(1), key)
}
@@ -87,7 +83,7 @@ func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed), new(event.Feed)}
key, _ := crypto.GenerateKey()
- pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
return pool, key
}
@@ -197,7 +193,7 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
tx0 := transaction(0, 100000, key)
tx1 := transaction(1, 100000, key)
- pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop()
nonce := pool.State().GetNonce(address)
@@ -562,7 +558,7 @@ func TestTransactionPostponing(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed), new(event.Feed)}
- pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop()
// Create two test accounts to produce different gap profiles with
@@ -781,7 +777,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
config.NoLocals = nolocals
config.GlobalQueue = config.AccountQueue*3 - 1 // reduce the queue limits to shorten test time (-1 to make it non divisible)
- pool := NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(config, params.TestChainConfig, blockchain)
defer pool.Stop()
// Create a number of test accounts and fund them (last one will be the local)
@@ -869,7 +865,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
config.Lifetime = time.Second
config.NoLocals = nolocals
- pool := NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(config, params.TestChainConfig, blockchain)
defer pool.Stop()
// Create two test accounts to ensure remotes expire but locals do not
@@ -1022,7 +1018,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) {
config := testTxPoolConfig
config.GlobalSlots = config.AccountSlots * 10
- pool := NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(config, params.TestChainConfig, blockchain)
defer pool.Stop()
// Create a number of test accounts and fund them
@@ -1070,7 +1066,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
config.AccountQueue = 2
config.GlobalSlots = 8
- pool := NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(config, params.TestChainConfig, blockchain)
defer pool.Stop()
// Create a number of test accounts and fund them
@@ -1102,7 +1098,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
config := testTxPoolConfig
config.GlobalSlots = 1
- pool := NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(config, params.TestChainConfig, blockchain)
defer pool.Stop()
// Create a number of test accounts and fund them
@@ -1147,7 +1143,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed), new(event.Feed)}
- pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop()
// Keep track of transaction events to ensure all executables get announced
@@ -1268,7 +1264,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed), new(event.Feed)}
- pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop()
// Create a number of test accounts and fund them
@@ -1334,7 +1330,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
config.GlobalSlots = 2
config.GlobalQueue = 2
- pool := NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(config, params.TestChainConfig, blockchain)
defer pool.Stop()
// Keep track of transaction events to ensure all executables get announced
@@ -1442,7 +1438,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
config.AccountQueue = 1024
config.GlobalQueue = 0
- pool := NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(config, params.TestChainConfig, blockchain)
defer pool.Stop()
// Keep track of transaction events to ensure all executables get announced
@@ -1504,7 +1500,7 @@ func TestTransactionReplacement(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed), new(event.Feed)}
- pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop()
// Keep track of transaction events to ensure all executables get announced
@@ -1603,7 +1599,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
config.Journal = journal
config.Rejournal = time.Second
- pool := NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(config, params.TestChainConfig, blockchain)
// Create two test accounts to ensure remotes expire but locals do not
local, _ := crypto.GenerateKey()
@@ -1640,7 +1636,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
blockchain = &testBlockChain{statedb, 1000000, new(event.Feed), new(event.Feed)}
- pool = NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool = NewTxPool(config, params.TestChainConfig, blockchain)
pending, queued = pool.Stats()
if queued != 0 {
@@ -1666,7 +1662,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
blockchain = &testBlockChain{statedb, 1000000, new(event.Feed), new(event.Feed)}
- pool = NewTxPool(config, params.TestChainConfig, blockchain, false)
+ pool = NewTxPool(config, params.TestChainConfig, blockchain)
pending, queued = pool.Stats()
if pending != 0 {
@@ -1696,7 +1692,7 @@ func TestTransactionStatusCheck(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
blockchain := &testBlockChain{statedb, 1000000, new(event.Feed), new(event.Feed)}
- pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain, false)
+ pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
defer pool.Stop()
// Create the test accounts to check various transaction statuses with
diff --git a/dex/api_backend.go b/dex/api_backend.go
index 80fe1e39b..957f4d886 100644
--- a/dex/api_backend.go
+++ b/dex/api_backend.go
@@ -60,7 +60,7 @@ func (b *DexAPIBackend) SetHead(number uint64) {
func (b *DexAPIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
// Otherwise resolve and return the block
- if blockNr == rpc.LatestBlockNumber {
+ if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber {
return b.dex.blockchain.CurrentBlock().Header(), nil
}
return b.dex.blockchain.GetHeaderByNumber(uint64(blockNr)), nil
@@ -79,10 +79,6 @@ func (b *DexAPIBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb
}
func (b *DexAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
- if blockNr == rpc.PendingBlockNumber {
- block, state := b.dex.BlockChain().GetPending()
- return state, block.Header(), nil
- }
header, err := b.HeaderByNumber(ctx, blockNr)
if header == nil || err != nil {
return nil, nil, err
diff --git a/dex/app.go b/dex/app.go
index b1a0b4548..c40371254 100644
--- a/dex/app.go
+++ b/dex/app.go
@@ -49,6 +49,7 @@ type DexconApp struct {
scope event.SubscriptionScope
chainLocks sync.Map
+ chainRoot sync.Map
}
func NewDexconApp(txPool *core.TxPool, blockchain *core.BlockChain, gov *DexconGovernance,
@@ -202,8 +203,16 @@ func (d *DexconApp) preparePayload(ctx context.Context, position coreTypes.Posit
}
}
- b, latestState := d.blockchain.GetPending()
- log.Debug("Prepare payload", "chain", position.ChainID, "height", position.Height, "state", b.Root().String())
+ root, exist := d.chainRoot.Load(position.ChainID)
+ if !exist {
+ return nil, nil
+ }
+
+ currentState, err := d.blockchain.StateAt(*root.(*common.Hash))
+ if err != nil {
+ return nil, err
+ }
+ log.Debug("Prepare payload", "chain", position.ChainID, "height", position.Height)
txsMap, err := d.txPool.Pending()
if err != nil {
@@ -228,7 +237,7 @@ addressMap:
continue
}
- balance := latestState.GetBalance(address)
+ balance := currentState.GetBalance(address)
cost, exist := d.blockchain.GetCostInConfirmedBlocks(position.ChainID, address)
if exist {
balance = new(big.Int).Sub(balance, cost)
@@ -237,7 +246,7 @@ addressMap:
var expectNonce uint64
lastConfirmedNonce, exist := d.blockchain.GetLastNonceInConfirmedBlocks(position.ChainID, address)
if !exist {
- expectNonce = latestState.GetNonce(address)
+ expectNonce = currentState.GetNonce(address)
} else {
expectNonce = lastConfirmedNonce + 1
}
@@ -249,7 +258,8 @@ addressMap:
firstNonce := txs[0].Nonce()
startIndex := int(expectNonce - firstNonce)
- for i := startIndex; i < len(txs); i++ {
+ // Warning: the pending tx will also affect by syncing, so startIndex maybe negative
+ for i := startIndex; i >= 0 && i < len(txs); i++ {
tx := txs[i]
intrGas, err := core.IntrinsicGas(tx.Data(), tx.To() == nil, true)
if err != nil {
@@ -282,15 +292,12 @@ addressMap:
// PrepareWitness will return the witness data no lower than consensusHeight.
func (d *DexconApp) PrepareWitness(consensusHeight uint64) (witness coreTypes.Witness, err error) {
var witnessBlock *types.Block
- lastPendingHeight := d.blockchain.GetPendingHeight()
- if lastPendingHeight == 0 && consensusHeight == 0 {
+ if d.blockchain.CurrentBlock().NumberU64() >= consensusHeight {
witnessBlock = d.blockchain.CurrentBlock()
- } else if lastPendingHeight >= consensusHeight {
- witnessBlock = d.blockchain.PendingBlock()
} else {
- log.Error("last pending height too low", "lastPendingHeight", lastPendingHeight,
+ log.Error("Current height too low", "lastPendingHeight", d.blockchain.CurrentBlock().NumberU64(),
"consensusHeight", consensusHeight)
- return witness, fmt.Errorf("last pending height < consensus height")
+ return witness, fmt.Errorf("current height < consensus height")
}
witnessData, err := rlp.EncodeToBytes(&types.WitnessData{
@@ -312,23 +319,20 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
var witnessData types.WitnessData
err := rlp.DecodeBytes(block.Witness.Data, &witnessData)
if err != nil {
- log.Error("failed to RLP decode witness data", "error", err)
+ log.Error("Failed to RLP decode witness data", "error", err)
return coreTypes.VerifyInvalidBlock
}
// Validate witness height.
- if d.blockchain.GetPendingHeight() < block.Witness.Height {
- log.Debug("Pending height < witness height")
+ if d.blockchain.CurrentBlock().NumberU64() < block.Witness.Height {
+ log.Debug("Current height < witness height")
return coreTypes.VerifyRetryLater
}
- b := d.blockchain.GetPendingBlockByNumber(block.Witness.Height)
+ b := d.blockchain.GetBlockByNumber(block.Witness.Height)
if b == nil {
- b = d.blockchain.GetBlockByNumber(block.Witness.Height)
- if b == nil {
- log.Error("Can not get block by height %v", block.Witness.Height)
- return coreTypes.VerifyInvalidBlock
- }
+ log.Error("Can not get block by height %v", block.Witness.Height)
+ return coreTypes.VerifyInvalidBlock
}
if b.Root() != witnessData.Root {
@@ -381,10 +385,18 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
}
}
- // Get latest pending state.
- b, latestState := d.blockchain.GetPending()
- log.Debug("Verify block", "chain", block.Position.ChainID, "height", block.Position.Height, "state",
- b.Root().String())
+ // Get latest state with current chain.
+ root, exist := d.chainRoot.Load(block.Position.ChainID)
+ if !exist {
+ return coreTypes.VerifyRetryLater
+ }
+
+ currentState, err := d.blockchain.StateAt(*root.(*common.Hash))
+ log.Debug("Verify block", "chain", block.Position.ChainID, "height", block.Position.Height)
+ if err != nil {
+ log.Debug("Invalid state root", "root", *root.(*common.Hash), "err", err)
+ return coreTypes.VerifyInvalidBlock
+ }
var transactions types.Transactions
if len(block.Payload) == 0 {
@@ -423,7 +435,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
if exist {
expectNonce = lastConfirmedNonce + 1
} else {
- expectNonce = latestState.GetNonce(address)
+ expectNonce = currentState.GetNonce(address)
}
if expectNonce != firstNonce {
@@ -437,9 +449,9 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
for address := range addressNonce {
cost, exist := d.blockchain.GetCostInConfirmedBlocks(block.Position.ChainID, address)
if exist {
- addressesBalance[address] = new(big.Int).Sub(latestState.GetBalance(address), cost)
+ addressesBalance[address] = new(big.Int).Sub(currentState.GetBalance(address), cost)
} else {
- addressesBalance[address] = latestState.GetBalance(address)
+ addressesBalance[address] = currentState.GetBalance(address)
}
}
@@ -518,19 +530,21 @@ func (d *DexconApp) BlockDelivered(
}, txs, nil, nil)
h := d.blockchain.CurrentBlock().NumberU64() + 1
+ var root *common.Hash
if block.IsEmpty() {
- err = d.blockchain.ProcessEmptyBlock(newBlock)
+ root, err = d.blockchain.ProcessEmptyBlock(newBlock)
if err != nil {
log.Error("Failed to process empty block", "error", err)
panic(err)
}
} else {
- _, err = d.blockchain.ProcessPendingBlock(newBlock, &block.Witness)
+ root, err = d.blockchain.ProcessBlock(newBlock, &block.Witness)
if err != nil {
log.Error("Failed to process pending block", "error", err)
panic(err)
}
}
+ d.chainRoot.Store(chainID, root)
d.blockchain.RemoveConfirmedBlock(chainID, blockHash)
diff --git a/dex/app_test.go b/dex/app_test.go
index c79dbc42c..7d665a0af 100644
--- a/dex/app_test.go
+++ b/dex/app_test.go
@@ -26,12 +26,12 @@ import (
func TestPreparePayload(t *testing.T) {
key, err := crypto.GenerateKey()
if err != nil {
- t.Errorf("hex to ecdsa error: %v", err)
+ t.Fatalf("hex to ecdsa error: %v", err)
}
dex, err := newTestDexonWithGenesis(key)
if err != nil {
- t.Errorf("new test dexon error: %v", err)
+ t.Fatalf("new test dexon error: %v", err)
}
signer := types.NewEIP155Signer(dex.chainConfig.ChainID)
@@ -40,7 +40,7 @@ func TestPreparePayload(t *testing.T) {
for i := 0; i < 5; i++ {
tx, err := addTx(dex, i, signer, key)
if err != nil {
- t.Errorf("add tx error: %v", err)
+ t.Fatalf("add tx error: %v", err)
}
expectTx = append(expectTx, tx)
}
@@ -48,7 +48,7 @@ func TestPreparePayload(t *testing.T) {
// This transaction will not be included.
_, err = addTx(dex, 100, signer, key)
if err != nil {
- t.Errorf("add tx error: %v", err)
+ t.Fatalf("add tx error: %v", err)
}
chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(),
@@ -56,39 +56,41 @@ func TestPreparePayload(t *testing.T) {
var chainNum uint32
for chainNum = 0; chainNum < dex.chainConfig.Dexcon.NumChains; chainNum++ {
+ root := dex.blockchain.CurrentBlock().Root()
+ dex.app.chainRoot.Store(chainNum, &root)
payload, err := dex.app.PreparePayload(coreTypes.Position{ChainID: chainNum})
if err != nil {
- t.Errorf("prepare payload error: %v", err)
+ t.Fatalf("prepare payload error: %v", err)
}
var transactions types.Transactions
err = rlp.DecodeBytes(payload, &transactions)
if err != nil {
- t.Errorf("rlp decode error: %v", err)
+ t.Fatalf("rlp decode error: %v", err)
}
// Only one chain id allow prepare transactions.
if chainID.Uint64() == uint64(chainNum) && len(transactions) != 5 {
- t.Errorf("incorrect transaction num expect %v but %v", 5, len(transactions))
+ t.Fatalf("incorrect transaction num expect %v but %v", 5, len(transactions))
} else if chainID.Uint64() != uint64(chainNum) && len(transactions) != 0 {
- t.Errorf("expect empty slice but %v", len(transactions))
+ t.Fatalf("expect empty slice but %v", len(transactions))
}
for i, tx := range transactions {
if expectTx[i].Gas() != tx.Gas() {
- t.Errorf("unexpected gas expect %v but %v", expectTx[i].Gas(), tx.Gas())
+ t.Fatalf("unexpected gas expect %v but %v", expectTx[i].Gas(), tx.Gas())
}
if expectTx[i].Hash() != tx.Hash() {
- t.Errorf("unexpected hash expect %v but %v", expectTx[i].Hash(), tx.Hash())
+ t.Fatalf("unexpected hash expect %v but %v", expectTx[i].Hash(), tx.Hash())
}
if expectTx[i].Nonce() != tx.Nonce() {
- t.Errorf("unexpected nonce expect %v but %v", expectTx[i].Nonce(), tx.Nonce())
+ t.Fatalf("unexpected nonce expect %v but %v", expectTx[i].Nonce(), tx.Nonce())
}
if expectTx[i].GasPrice().Uint64() != tx.GasPrice().Uint64() {
- t.Errorf("unexpected gas price expect %v but %v",
+ t.Fatalf("unexpected gas price expect %v but %v",
expectTx[i].GasPrice().Uint64(), tx.GasPrice().Uint64())
}
}
@@ -98,41 +100,41 @@ func TestPreparePayload(t *testing.T) {
func TestPrepareWitness(t *testing.T) {
key, err := crypto.GenerateKey()
if err != nil {
- t.Errorf("hex to ecdsa error: %v", err)
+ t.Fatalf("hex to ecdsa error: %v", err)
}
dex, err := newTestDexonWithGenesis(key)
if err != nil {
- t.Errorf("new test dexon error: %v", err)
+ t.Fatalf("new test dexon error: %v", err)
}
currentBlock := dex.blockchain.CurrentBlock()
witness, err := dex.app.PrepareWitness(0)
if err != nil {
- t.Errorf("prepare witness error: %v", err)
+ t.Fatalf("prepare witness error: %v", err)
}
if witness.Height != currentBlock.NumberU64() {
- t.Errorf("unexpeted witness height %v", witness.Height)
+ t.Fatalf("unexpeted witness height %v", witness.Height)
}
var witnessData types.WitnessData
err = rlp.DecodeBytes(witness.Data, &witnessData)
if err != nil {
- t.Errorf("rlp decode error: %v", err)
+ t.Fatalf("rlp decode error: %v", err)
}
if witnessData.Root != currentBlock.Root() {
- t.Errorf("expect root %v but %v", currentBlock.Root(), witnessData.Root)
+ t.Fatalf("expect root %v but %v", currentBlock.Root(), witnessData.Root)
}
if witnessData.ReceiptHash != currentBlock.ReceiptHash() {
- t.Errorf("expect receipt hash %v but %v", currentBlock.ReceiptHash(), witnessData.ReceiptHash)
+ t.Fatalf("expect receipt hash %v but %v", currentBlock.ReceiptHash(), witnessData.ReceiptHash)
}
if _, err := dex.app.PrepareWitness(999); err == nil {
- t.Errorf("it must be get error from prepare")
+ t.Fatalf("it must be get error from prepare")
} else {
t.Logf("Nice error: %v", err)
}
@@ -141,20 +143,26 @@ func TestPrepareWitness(t *testing.T) {
func TestVerifyBlock(t *testing.T) {
key, err := crypto.GenerateKey()
if err != nil {
- t.Errorf("hex to ecdsa error: %v", err)
+ t.Fatalf("hex to ecdsa error: %v", err)
}
dex, err := newTestDexonWithGenesis(key)
if err != nil {
- t.Errorf("new test dexon error: %v", err)
+ t.Fatalf("new test dexon error: %v", err)
}
- // Prepare first confirmed block.
- prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 0)
-
chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(),
big.NewInt(int64(dex.chainConfig.Dexcon.NumChains)))
+ root := dex.blockchain.CurrentBlock().Root()
+ dex.app.chainRoot.Store(uint32(chainID.Uint64()), &root)
+
+ // Prepare first confirmed block.
+ _, err = prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 0)
+ if err != nil {
+ t.Fatalf("prepare confirmed blocks error: %v", err)
+ }
+
// Prepare normal block.
block := &coreTypes.Block{}
block.Hash = coreCommon.NewRandomHash()
@@ -163,13 +171,13 @@ func TestVerifyBlock(t *testing.T) {
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 100)
if err != nil {
- t.Errorf("prepare data error: %v", err)
+ t.Fatalf("prepare data error: %v", err)
}
// Expect ok.
status := dex.app.VerifyBlock(block)
if status != coreTypes.VerifyOK {
- t.Errorf("verify fail: %v", status)
+ t.Fatalf("verify fail: %v", status)
}
// Prepare invalid nonce tx.
@@ -180,13 +188,13 @@ func TestVerifyBlock(t *testing.T) {
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 1, 100)
if err != nil {
- t.Errorf("prepare data error: %v", err)
+ t.Fatalf("prepare data error: %v", err)
}
// Expect invalid block.
status = dex.app.VerifyBlock(block)
if status != coreTypes.VerifyInvalidBlock {
- t.Errorf("verify fail: %v", status)
+ t.Fatalf("verify fail: %v", status)
}
// Prepare invalid block height.
@@ -197,13 +205,13 @@ func TestVerifyBlock(t *testing.T) {
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 100)
if err != nil {
- t.Errorf("prepare data error: %v", err)
+ t.Fatalf("prepare data error: %v", err)
}
// Expect retry later.
status = dex.app.VerifyBlock(block)
if status != coreTypes.VerifyRetryLater {
- t.Errorf("verify fail expect retry later but get %v", status)
+ t.Fatalf("verify fail expect retry later but get %v", status)
}
// Prepare reach block limit.
@@ -214,13 +222,13 @@ func TestVerifyBlock(t *testing.T) {
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 10000)
if err != nil {
- t.Errorf("prepare data error: %v", err)
+ t.Fatalf("prepare data error: %v", err)
}
// Expect invalid block.
status = dex.app.VerifyBlock(block)
if status != coreTypes.VerifyInvalidBlock {
- t.Errorf("verify fail expect invalid block but get %v", status)
+ t.Fatalf("verify fail expect invalid block but get %v", status)
}
// Prepare insufficient funds.
@@ -231,7 +239,7 @@ func TestVerifyBlock(t *testing.T) {
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
_, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0)
if err != nil {
- t.Errorf("prepare data error: %v", err)
+ t.Fatalf("prepare data error: %v", err)
}
signer := types.NewEIP155Signer(dex.chainConfig.ChainID)
@@ -255,7 +263,7 @@ func TestVerifyBlock(t *testing.T) {
// expect invalid block
status = dex.app.VerifyBlock(block)
if status != coreTypes.VerifyInvalidBlock {
- t.Errorf("verify fail expect invalid block but get %v", status)
+ t.Fatalf("verify fail expect invalid block but get %v", status)
}
// Prepare invalid intrinsic gas.
@@ -266,7 +274,7 @@ func TestVerifyBlock(t *testing.T) {
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
_, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0)
if err != nil {
- t.Errorf("prepare data error: %v", err)
+ t.Fatalf("prepare data error: %v", err)
}
signer = types.NewEIP155Signer(dex.chainConfig.ChainID)
@@ -290,7 +298,7 @@ func TestVerifyBlock(t *testing.T) {
// Expect invalid block.
status = dex.app.VerifyBlock(block)
if status != coreTypes.VerifyInvalidBlock {
- t.Errorf("verify fail expect invalid block but get %v", status)
+ t.Fatalf("verify fail expect invalid block but get %v", status)
}
// Prepare invalid transactions with nonce.
@@ -301,7 +309,7 @@ func TestVerifyBlock(t *testing.T) {
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
_, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0)
if err != nil {
- t.Errorf("prepare data error: %v", err)
+ t.Fatalf("prepare data error: %v", err)
}
signer = types.NewEIP155Signer(dex.chainConfig.ChainID)
@@ -338,24 +346,27 @@ func TestVerifyBlock(t *testing.T) {
// Expect invalid block.
status = dex.app.VerifyBlock(block)
if status != coreTypes.VerifyInvalidBlock {
- t.Errorf("verify fail expect invalid block but get %v", status)
+ t.Fatalf("verify fail expect invalid block but get %v", status)
}
}
func TestBlockConfirmed(t *testing.T) {
key, err := crypto.GenerateKey()
if err != nil {
- t.Errorf("hex to ecdsa error: %v", err)
+ t.Fatalf("hex to ecdsa error: %v", err)
}
dex, err := newTestDexonWithGenesis(key)
if err != nil {
- t.Errorf("new test dexon error: %v", err)
+ t.Fatalf("new test dexon error: %v", err)
}
chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(),
big.NewInt(int64(dex.chainConfig.Dexcon.NumChains)))
+ root := dex.blockchain.CurrentBlock().Root()
+ dex.app.chainRoot.Store(uint32(chainID.Uint64()), &root)
+
var (
expectCost big.Int
expectNonce uint64
@@ -368,7 +379,7 @@ func TestBlockConfirmed(t *testing.T) {
}
payload, witness, cost, nonce, err := prepareData(dex, key, startNonce, 50)
if err != nil {
- t.Errorf("prepare data error: %v", err)
+ t.Fatalf("prepare data error: %v", err)
}
expectCost.Add(&expectCost, &cost)
expectNonce = nonce
@@ -388,33 +399,39 @@ func TestBlockConfirmed(t *testing.T) {
crypto.PubkeyToAddress(key.PublicKey))
if info.Counter != expectCounter {
- t.Errorf("expect address counter is %v but %v", expectCounter, info.Counter)
+ t.Fatalf("expect address counter is %v but %v", expectCounter, info.Counter)
}
if info.Cost.Cmp(&expectCost) != 0 {
- t.Errorf("expect address cost is %v but %v", expectCost.Uint64(), info.Cost.Uint64())
+ t.Fatalf("expect address cost is %v but %v", expectCost.Uint64(), info.Cost.Uint64())
}
if info.Nonce != expectNonce {
- t.Errorf("expect address nonce is %v but %v", expectNonce, info.Nonce)
+ t.Fatalf("expect address nonce is %v but %v", expectNonce, info.Nonce)
}
}
func TestBlockDelivered(t *testing.T) {
key, err := crypto.GenerateKey()
if err != nil {
- t.Errorf("hex to ecdsa error: %v", err)
+ t.Fatalf("hex to ecdsa error: %v", err)
}
dex, err := newTestDexonWithGenesis(key)
if err != nil {
- t.Errorf("new test dexon error: %v", err)
+ t.Fatalf("new test dexon error: %v", err)
}
+ chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(),
+ big.NewInt(int64(dex.chainConfig.Dexcon.NumChains)))
+
+ root := dex.blockchain.CurrentBlock().Root()
+ dex.app.chainRoot.Store(uint32(chainID.Uint64()), &root)
+
address := crypto.PubkeyToAddress(key.PublicKey)
firstBlocksInfo, err := prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 50)
if err != nil {
- t.Errorf("preapare confirmed block error: %v", err)
+ t.Fatalf("preapare confirmed block error: %v", err)
}
dex.app.BlockDelivered(firstBlocksInfo[0].Block.Hash, firstBlocksInfo[0].Block.Position,
@@ -423,72 +440,48 @@ func TestBlockDelivered(t *testing.T) {
Height: 1,
})
- _, pendingState := dex.blockchain.GetPending()
- currentBlock := dex.blockchain.CurrentBlock()
- if currentBlock.NumberU64() != 0 {
- t.Errorf("unexpected current block number %v", currentBlock.NumberU64())
- }
-
- pendingNonce := pendingState.GetNonce(address)
- if pendingNonce != firstBlocksInfo[0].Nonce+1 {
- t.Errorf("unexpected pending state nonce %v", pendingNonce)
- }
-
- balance := pendingState.GetBalance(address)
- if new(big.Int).Add(balance, &firstBlocksInfo[0].Cost).Cmp(big.NewInt(50000000000000000)) != 0 {
- t.Errorf("unexpected pending state balance %v", balance)
- }
-
- // prepare second block to witness first block
- secondBlocksInfo, err := prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 25)
+ currentState, err := dex.blockchain.State()
if err != nil {
- t.Errorf("preapare confirmed block error: %v", err)
+ t.Fatalf("get state error: %v", err)
}
-
- dex.app.BlockDelivered(secondBlocksInfo[0].Block.Hash, secondBlocksInfo[0].Block.Position,
- coreTypes.FinalizationResult{
- Timestamp: time.Now(),
- Height: 2,
- })
-
- // second block witness first block, so current block number should be 1
- currentBlock = dex.blockchain.CurrentBlock()
+ currentBlock := dex.blockchain.CurrentBlock()
if currentBlock.NumberU64() != 1 {
- t.Errorf("unexpected current block number %v", currentBlock.NumberU64())
- }
-
- currentState, err := dex.blockchain.State()
- if err != nil {
- t.Errorf("current state error: %v", err)
+ t.Fatalf("unexpected current block number %v", currentBlock.NumberU64())
}
currentNonce := currentState.GetNonce(address)
if currentNonce != firstBlocksInfo[0].Nonce+1 {
- t.Errorf("unexpected current state nonce %v", currentNonce)
+ t.Fatalf("unexpected pending state nonce %v", currentNonce)
}
- balance = currentState.GetBalance(address)
+ balance := currentState.GetBalance(address)
if new(big.Int).Add(balance, &firstBlocksInfo[0].Cost).Cmp(big.NewInt(50000000000000000)) != 0 {
- t.Errorf("unexpected current state balance %v", balance)
+ t.Fatalf("unexpected pending state balance %v", balance)
}
}
func TestNumChainsChange(t *testing.T) {
key, err := crypto.GenerateKey()
if err != nil {
- t.Errorf("hex to ecdsa error: %v", err)
+ t.Fatalf("hex to ecdsa error: %v", err)
}
params.TestnetChainConfig.Dexcon.Owner = crypto.PubkeyToAddress(key.PublicKey)
dex, err := newTestDexonWithGenesis(key)
if err != nil {
- t.Errorf("new test dexon error: %v", err)
+ t.Fatalf("new test dexon error: %v", err)
}
+ chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(),
+ big.NewInt(int64(dex.chainConfig.Dexcon.NumChains)))
+
+ root := dex.blockchain.CurrentBlock().Root()
+ dex.app.chainRoot.Store(uint32(chainID.Uint64()), &root)
+
abiObject, err := abi.JSON(strings.NewReader(vm.GovernanceABIJSON))
if err != nil {
- t.Errorf("get abi object fail: %v", err)
+ t.Fatalf("get abi object fail: %v", err)
}
// Update config in round 1 and height 1.
@@ -511,12 +504,12 @@ func TestNumChainsChange(t *testing.T) {
big.NewInt(1000),
[]*big.Int{big.NewInt(1), big.NewInt(1), big.NewInt(1)})
if err != nil {
- t.Errorf("updateConfiguration abiObject pack error: %v", err)
+ t.Fatalf("updateConfiguration abiObject pack error: %v", err)
}
block, err := prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{input}, 1)
if err != nil {
- t.Errorf("prepare block error: %v", err)
+ t.Fatalf("prepare block error: %v", err)
}
dex.app.BlockDelivered(block.Hash, block.Position,
coreTypes.FinalizationResult{
@@ -527,12 +520,12 @@ func TestNumChainsChange(t *testing.T) {
// Snapshot round on round 1 and height 2.
input, err = abiObject.Pack("snapshotRound", big.NewInt(1), big.NewInt(1))
if err != nil {
- t.Errorf("abiObject pack error: %v", err)
+ t.Fatalf("abiObject pack error: %v", err)
}
block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{input}, 1)
if err != nil {
- t.Errorf("prepare block error: %v", err)
+ t.Fatalf("prepare block error: %v", err)
}
dex.app.BlockDelivered(block.Hash, block.Position,
coreTypes.FinalizationResult{
@@ -543,7 +536,7 @@ func TestNumChainsChange(t *testing.T) {
// Make round 1 height 2 block write into chain.
block, err = prepareConfirmedBlockWithTxAndData(dex, key, nil, 1)
if err != nil {
- t.Errorf("prepare block error: %v", err)
+ t.Fatalf("prepare block error: %v", err)
}
dex.app.BlockDelivered(block.Hash, block.Position,
coreTypes.FinalizationResult{
@@ -554,10 +547,10 @@ func TestNumChainsChange(t *testing.T) {
// Round 2 will keep prepare tx as usual.
block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{{1}}, 2)
if err != nil {
- t.Errorf("prepare block error: %v", err)
+ t.Fatalf("prepare block error: %v", err)
}
if block.Payload == nil {
- t.Errorf("payload should not be nil")
+ t.Fatalf("payload should not be nil")
}
dex.app.BlockDelivered(block.Hash, block.Position,
coreTypes.FinalizationResult{
@@ -568,16 +561,16 @@ func TestNumChainsChange(t *testing.T) {
// It will prepare empty payload until witness any block in round 3.
block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{{1}}, 3)
if err != nil {
- t.Errorf("prepare block error: %v", err)
+ t.Fatalf("prepare block error: %v", err)
}
if block.Payload != nil {
- t.Errorf("payload should be nil but %v", block.Payload)
+ t.Fatalf("payload should be nil but %v", block.Payload)
}
// Test non-empty payload.
block.Payload = []byte{1}
if status := dex.app.VerifyBlock(block); status != coreTypes.VerifyInvalidBlock {
- t.Errorf("unexpected verify status %v", status)
+ t.Fatalf("unexpected verify status %v", status)
}
block.Payload = nil
@@ -587,62 +580,39 @@ func TestNumChainsChange(t *testing.T) {
Height: 5,
})
- // Still empty payload because round 3 is not witness yet.
- // This block just for witness round 3 height 5.
- block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{{1}}, 3)
- if err != nil {
- t.Errorf("prepare block error: %v", err)
- }
- if block.Payload != nil {
- t.Errorf("payload should be nil but %v", block.Payload)
- }
-
- // Test non-empty payload.
- block.Payload = []byte{1}
- if status := dex.app.VerifyBlock(block); status != coreTypes.VerifyInvalidBlock {
- t.Errorf("unexpected verify status %v", status)
- }
- block.Payload = nil
-
- dex.app.BlockDelivered(block.Hash, block.Position,
- coreTypes.FinalizationResult{
- Timestamp: time.Now(),
- Height: 6,
- })
-
// Empty block in round 3 has been delivered.
// Now can prepare payload as usual.
block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{{1}}, 3)
if err != nil {
- t.Errorf("prepare block error: %v", err)
+ t.Fatalf("prepare block error: %v", err)
}
if block.Payload == nil {
- t.Errorf("payload should not be nil")
+ t.Fatalf("payload should not be nil")
}
dex.app.BlockDelivered(block.Hash, block.Position,
coreTypes.FinalizationResult{
Timestamp: time.Now(),
- Height: 7,
+ Height: 6,
})
}
func BenchmarkBlockDeliveredFlow(b *testing.B) {
key, err := crypto.GenerateKey()
if err != nil {
- b.Errorf("hex to ecdsa error: %v", err)
+ b.Fatalf("hex to ecdsa error: %v", err)
return
}
dex, err := newTestDexonWithGenesis(key)
if err != nil {
- b.Errorf("new test dexon error: %v", err)
+ b.Fatalf("new test dexon error: %v", err)
}
b.ResetTimer()
for i := 1; i <= b.N; i++ {
blocksInfo, err := prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 100)
if err != nil {
- b.Errorf("preapare confirmed block error: %v", err)
+ b.Fatalf("preapare confirmed block error: %v", err)
return
}
diff --git a/dex/backend.go b/dex/backend.go
index c75fdfa29..a000d5fbc 100644
--- a/dex/backend.go
+++ b/dex/backend.go
@@ -146,7 +146,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Dexon, error) {
if config.TxPool.Journal != "" {
config.TxPool.Journal = ctx.ResolvePath(config.TxPool.Journal)
}
- dex.txPool = core.NewTxPool(config.TxPool, dex.chainConfig, dex.blockchain, config.BlockProposerEnabled)
+ dex.txPool = core.NewTxPool(config.TxPool, dex.chainConfig, dex.blockchain)
dex.APIBackend = &DexAPIBackend{dex, nil}
gpoParams := config.GPO
diff --git a/eth/backend.go b/eth/backend.go
index 90cfa1a9a..f75f2e521 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -173,7 +173,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if config.TxPool.Journal != "" {
config.TxPool.Journal = ctx.ResolvePath(config.TxPool.Journal)
}
- eth.txPool = core.NewTxPool(config.TxPool, eth.chainConfig, eth.blockchain, false)
+ eth.txPool = core.NewTxPool(config.TxPool, eth.chainConfig, eth.blockchain)
if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, config.Whitelist); err != nil {
return nil, err
diff --git a/indexer/blockchain.go b/indexer/blockchain.go
index f41c05a15..f3275f882 100644
--- a/indexer/blockchain.go
+++ b/indexer/blockchain.go
@@ -51,9 +51,6 @@ type ReadOnlyBlockChain interface {
GetHeaderByHash(common.Hash) *types.Header
GetHeaderByNumber(number uint64) *types.Header
GetLastNonceInConfirmedBlocks(uint32, common.Address) (uint64, bool)
- GetPending() (*types.Block, *state.StateDB)
- GetPendingBlockByNumber(uint64) *types.Block
- GetPendingHeight() uint64
GetReceiptsByHash(common.Hash) types.Receipts
GetRoundHeight(uint64) (uint64, bool)
GetTd(common.Hash, uint64) *big.Int
@@ -64,10 +61,8 @@ type ReadOnlyBlockChain interface {
HasBlockAndState(common.Hash, uint64) bool
HasHeader(common.Hash, uint64) bool
HasState(common.Hash) bool
- PendingBlock() *types.Block
State() (*state.StateDB, error)
StateAt(root common.Hash) (*state.StateDB, error)
- SubscribeBlockConfirmedEvent(chan<- core.BlockConfirmedEvent) event.Subscription
SubscribeChainEvent(chan<- core.ChainEvent) event.Subscription
SubscribeChainHeadEvent(chan<- core.ChainHeadEvent) event.Subscription
SubscribeChainSideEvent(chan<- core.ChainSideEvent) event.Subscription
diff --git a/les/handler_test.go b/les/handler_test.go
index eece82a28..30bf382f1 100644
--- a/les/handler_test.go
+++ b/les/handler_test.go
@@ -498,7 +498,7 @@ func TestTransactionStatusLes2(t *testing.T) {
chain := pm.blockchain.(*core.BlockChain)
config := core.DefaultTxPoolConfig
config.Journal = ""
- txpool := core.NewTxPool(config, params.TestChainConfig, chain, false)
+ txpool := core.NewTxPool(config, params.TestChainConfig, chain)
pm.txpool = txpool
peer, _ := newTestPeer(t, "peer", 2, pm, true)
defer peer.close()
diff --git a/miner/worker_test.go b/miner/worker_test.go
index eb25e27f2..a3468e551 100644
--- a/miner/worker_test.go
+++ b/miner/worker_test.go
@@ -97,7 +97,7 @@ func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine
genesis := gspec.MustCommit(db)
chain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil)
- txpool := core.NewTxPool(testTxPoolConfig, chainConfig, chain, false)
+ txpool := core.NewTxPool(testTxPoolConfig, chainConfig, chain)
// Generate a small n-block chain and an uncle block for it
if n > 0 {