aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBojie Wu <bojie@dexon.org>2018-10-09 13:28:45 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-12 17:27:16 +0800
commitbc2cfaa5cec22740b0f61a09fc129235eadc2134 (patch)
tree69cd72cb25bf45aa2e9e019732ddca725b7be165
parent44ce26cb076c5852167c1ffc9eceff9148ee5477 (diff)
downloadgo-tangerine-bc2cfaa5cec22740b0f61a09fc129235eadc2134.tar
go-tangerine-bc2cfaa5cec22740b0f61a09fc129235eadc2134.tar.gz
go-tangerine-bc2cfaa5cec22740b0f61a09fc129235eadc2134.tar.bz2
go-tangerine-bc2cfaa5cec22740b0f61a09fc129235eadc2134.tar.lz
go-tangerine-bc2cfaa5cec22740b0f61a09fc129235eadc2134.tar.xz
go-tangerine-bc2cfaa5cec22740b0f61a09fc129235eadc2134.tar.zst
go-tangerine-bc2cfaa5cec22740b0f61a09fc129235eadc2134.zip
app: correct process pending block logic
-rw-r--r--core/blockchain.go237
-rw-r--r--dex/app.go67
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus-core/core/interfaces.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice.go3
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus-core/core/nonblocking.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go14
-rw-r--r--vendor/vendor.json32
7 files changed, 183 insertions, 174 deletions
diff --git a/core/blockchain.go b/core/blockchain.go
index 5393171f6..43e528a2d 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -33,6 +33,7 @@ import (
lru "github.com/hashicorp/golang-lru"
"github.com/dexon-foundation/dexon/common"
+ "github.com/dexon-foundation/dexon/common/math"
"github.com/dexon-foundation/dexon/common/mclock"
"github.com/dexon-foundation/dexon/common/prque"
"github.com/dexon-foundation/dexon/consensus"
@@ -1506,28 +1507,13 @@ func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (i
return 0, nil, nil, nil
}
-func (bc *BlockChain) InsertPendingBlocks(chain types.Blocks) (int, error) {
- n, events, logs, err := bc.insertPendingBlocks(chain)
+func (bc *BlockChain) ProcessPendingBlock(block *types.Block) (int, error) {
+ n, events, logs, err := bc.processPendingBlock(block)
bc.PostChainEvents(events, logs)
return n, err
}
-func (bc *BlockChain) insertPendingBlocks(chain types.Blocks) (int, []interface{}, []*types.Log, error) {
- // Sanity check that we have something meaningful to import
- if len(chain) == 0 {
- return 0, nil, nil, nil
- }
- // Do a sanity check that the provided chain is actually ordered and linked
- for i := 1; i < len(chain); i++ {
- if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() {
- // Chain broke ancestry, log a message (programming error) and skip insertion
- log.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(),
- "parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash())
-
- return 0, nil, nil, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, chain[i-1].NumberU64(),
- chain[i-1].Hash().Bytes()[:4], i, chain[i].NumberU64(), chain[i].Hash().Bytes()[:4], chain[i].ParentHash().Bytes()[:4])
- }
- }
+func (bc *BlockChain) processPendingBlock(block *types.Block) (int, []interface{}, []*types.Log, error) {
// Pre-checks passed, start the full block imports
bc.wg.Add(1)
defer bc.wg.Done()
@@ -1540,147 +1526,146 @@ func (bc *BlockChain) insertPendingBlocks(chain types.Blocks) (int, []interface{
// acquiring.
var (
stats = insertStats{startTime: mclock.Now()}
- events = make([]interface{}, 0, len(chain))
+ events = make([]interface{}, 0, 2)
lastCanon *types.Block
coalescedLogs []*types.Log
)
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
- senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain)
+ senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, block.Number()), []*types.Block{block})
- // Iterate over the blocks and insert when the verifier permits
- for i, block := range chain {
- if atomic.LoadInt32(&bc.procInterrupt) == 1 {
- log.Debug("Premature abort during blocks processing")
- break
- }
- bstart := time.Now()
+ if atomic.LoadInt32(&bc.procInterrupt) == 1 {
+ log.Debug("Premature abort during blocks processing")
+ return 0, nil, nil, fmt.Errorf("interrupt")
+ }
+ bstart := time.Now()
- currentBlock := bc.CurrentBlock()
- if block.Header().WitnessHeight > currentBlock.NumberU64() && block.Header().WitnessHeight != 0 {
- if bc.pendingBlocks[block.Header().WitnessHeight].block.Root() != block.Header().WitnessRoot {
- return i, nil, nil, fmt.Errorf("invalid witness root %s vs %s", bc.pendingBlocks[block.Header().WitnessHeight].block.Root().String(), block.Header().WitnessRoot.String())
- }
+ currentBlock := bc.CurrentBlock()
+ if block.Header().WitnessHeight > currentBlock.NumberU64() && block.Header().WitnessHeight != 0 {
+ if bc.pendingBlocks[block.Header().WitnessHeight].block.Root() != block.Header().WitnessRoot {
+ return 0, nil, nil, fmt.Errorf("invalid witness root %s vs %s", bc.pendingBlocks[block.Header().WitnessHeight].block.Root().String(), block.Header().WitnessRoot.String())
+ }
- if bc.pendingBlocks[block.Header().WitnessHeight].block.ReceiptHash() != block.Header().WitnessReceiptHash {
- return i, nil, nil, fmt.Errorf("invalid witness receipt hash %s vs %s", bc.pendingBlocks[block.Header().WitnessHeight].block.ReceiptHash().String(), block.Header().WitnessReceiptHash.String())
- }
+ if bc.pendingBlocks[block.Header().WitnessHeight].block.ReceiptHash() != block.Header().WitnessReceiptHash {
+ return 0, nil, nil, fmt.Errorf("invalid witness receipt hash %s vs %s", bc.pendingBlocks[block.Header().WitnessHeight].block.ReceiptHash().String(), block.Header().WitnessReceiptHash.String())
}
+ }
- var parentBlock *types.Block
- var pendingState *state.StateDB
- var err error
- parent, exist := bc.pendingBlocks[block.NumberU64()-1]
- if !exist {
- parentBlock = currentBlock
- if parentBlock.NumberU64() != block.NumberU64()-1 {
- return i, nil, nil, fmt.Errorf("parent block %d not exist", block.NumberU64()-1)
- }
- } else {
- parentBlock = parent.block
+ var parentBlock *types.Block
+ var pendingState *state.StateDB
+ var err error
+ parent, exist := bc.pendingBlocks[block.NumberU64()-1]
+ if !exist {
+ parentBlock = currentBlock
+ if parentBlock.NumberU64() != block.NumberU64()-1 {
+ return 0, nil, nil, fmt.Errorf("parent block %d not exist", block.NumberU64()-1)
}
- block.RawHeader().ParentHash = parentBlock.Hash()
- pendingState, err = state.New(parentBlock.Root(), bc.stateCache)
+ } else {
+ parentBlock = parent.block
+ }
+ block.RawHeader().ParentHash = parentBlock.Hash()
+ pendingState, err = state.New(parentBlock.Root(), bc.stateCache)
+ if err != nil {
+ return 0, nil, nil, err
+ }
+
+ var (
+ receipts types.Receipts
+ usedGas = new(uint64)
+ header = block.Header()
+ gp = new(GasPool).AddGas(math.MaxUint64)
+ )
+ // 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)
if err != nil {
- return i, events, coalescedLogs, err
+ return i, nil, nil, fmt.Errorf("apply transaction error: %v %d", err, tx.Nonce())
}
+ receipts = append(receipts, receipt)
+ log.Debug("Apply transaction", "tx.hash", tx.Hash(), "nonce", tx.Nonce(), "amount", tx.Value())
+ }
+ // 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)
+ if err != nil {
+ return 0, nil, nil, fmt.Errorf("finalize error: %v", err)
+ }
- var (
- receipts types.Receipts
- usedGas = new(uint64)
- header = block.Header()
- allLogs []*types.Log
- gp = new(GasPool).AddGas(block.GasLimit())
- )
- // 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)
- if err != nil {
- return i, nil, nil, fmt.Errorf("apply transaction error: %v %d", err, tx.Nonce())
- }
- receipts = append(receipts, receipt)
- allLogs = append(allLogs, receipt.Logs...)
- log.Debug("Apply transaction", "tx.hash", tx.Hash(), "nonce", tx.Nonce(), "amount", tx.Value())
- }
- // 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)
- if err != nil {
- return i, events, coalescedLogs, fmt.Errorf("finalize error: %v", err)
+ // Validate the state using the default validator
+ err = bc.Validator().ValidateState(block, nil, pendingState, receipts, *usedGas)
+ if err != nil {
+ bc.reportBlock(block, receipts, err)
+ return 0, nil, nil, fmt.Errorf("valiadte state error: %v", err)
+ }
+ proctime := time.Since(bstart)
+
+ // commit state to refresh stateCache
+ root, err := pendingState.Commit(true)
+ if err != nil {
+ return 0, nil, nil, fmt.Errorf("pendingState commit error: %v", err)
+ }
+ log.Info("Commit pending root", "hash", root)
+
+ // add into pending blocks
+ bc.pendingBlocks[block.NumberU64()] = struct {
+ block *types.Block
+ receipts types.Receipts
+ }{block: newPendingBlock, receipts: receipts}
+
+ // start insert available pending blocks into db
+ for pendingHeight := bc.CurrentBlock().NumberU64() + 1; pendingHeight <= block.Header().WitnessHeight; pendingHeight++ {
+ pendingIns, exist := bc.pendingBlocks[pendingHeight]
+ if !exist {
+ log.Error("Block has already inserted", "height", pendingHeight)
+ continue
}
- // Validate the state using the default validator
- err = bc.Validator().ValidateState(block, nil, pendingState, receipts, *usedGas)
+ s, err := state.New(pendingIns.block.Root(), bc.stateCache)
if err != nil {
- bc.reportBlock(block, receipts, err)
- return i, events, coalescedLogs, fmt.Errorf("valiadte state error: %v", err)
+ return 0, events, coalescedLogs, err
}
- proctime := time.Since(bstart)
- // commit state to refresh stateCache
- root, err := pendingState.Commit(true)
+ // Write the block to the chain and get the status.
+ log.Debug("Insert pending block", "height", pendingHeight)
+ status, err := bc.WriteBlockWithState(pendingIns.block, pendingIns.receipts, s)
if err != nil {
- return i, nil, nil, fmt.Errorf("pendingState commit error: %v", err)
+ return 0, events, coalescedLogs, fmt.Errorf("WriteBlockWithState error: %v", err)
}
- log.Info("Commit pending root", "hash", root)
- // add into pending blocks
- bc.pendingBlocks[block.NumberU64()] = struct {
- block *types.Block
- receipts types.Receipts
- }{block: newPendingBlock, receipts: receipts}
-
- // start insert available pending blocks into db
- for pendingHeight := bc.CurrentBlock().NumberU64() + 1; pendingHeight <= block.Header().WitnessHeight; pendingHeight++ {
- confirmedBlock, exist := bc.pendingBlocks[pendingHeight]
- if !exist {
- log.Error("Block has already inserted", "height", pendingHeight)
- continue
- }
-
- s, err := state.New(confirmedBlock.block.Root(), bc.stateCache)
- if err != nil {
- return i, events, coalescedLogs, 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)))
- // Write the block to the chain and get the status.
- log.Debug("Insert pending block", "height", pendingHeight)
- status, err := bc.WriteBlockWithState(confirmedBlock.block, confirmedBlock.receipts, s)
- if err != nil {
- return i, events, coalescedLogs, fmt.Errorf("WriteBlockWithState error: %v", err)
+ var allLogs []*types.Log
+ for _, r := range pendingIns.receipts {
+ allLogs = append(allLogs, r.Logs...)
}
+ coalescedLogs = append(coalescedLogs, allLogs...)
+ blockInsertTimer.UpdateSince(bstart)
+ events = append(events, ChainEvent{pendingIns.block, pendingIns.block.Hash(), allLogs})
+ lastCanon = pendingIns.block
- switch status {
- case CanonStatTy:
- log.Debug("Inserted new block", "number", block.Number(), "hash", block.Hash(), "uncles", len(block.Uncles()),
- "txs", len(block.Transactions()), "gas", block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart)))
-
- coalescedLogs = append(coalescedLogs, allLogs...)
- blockInsertTimer.UpdateSince(bstart)
- events = append(events, ChainEvent{confirmedBlock.block, confirmedBlock.block.Hash(), allLogs})
- lastCanon = confirmedBlock.block
-
- // Only count canonical blocks for GC processing time
- bc.gcproc += proctime
-
- case SideStatTy:
- return i, nil, nil, fmt.Errorf("insert pending block and fork found")
- }
+ // Only count canonical blocks for GC processing time
+ bc.gcproc += proctime
- delete(bc.pendingBlocks, pendingHeight)
+ case SideStatTy:
+ return 0, nil, nil, fmt.Errorf("insert pending block and fork found")
+ }
+ delete(bc.pendingBlocks, pendingHeight)
- stats.processed++
- stats.usedGas += *usedGas
+ stats.processed++
+ stats.usedGas += pendingIns.block.GasUsed()
- cache, _ := bc.stateCache.TrieDB().Size()
- stats.report(chain, i, cache)
- }
+ cache, _ := bc.stateCache.TrieDB().Size()
+ stats.report([]*types.Block{pendingIns.block}, 0, cache)
}
// 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})
}
+
return 0, events, coalescedLogs, nil
}
diff --git a/dex/app.go b/dex/app.go
index 7de2bdc86..577135dc0 100644
--- a/dex/app.go
+++ b/dex/app.go
@@ -129,7 +129,7 @@ func (d *DexconApp) PreparePayload(position coreTypes.Position) (payload []byte,
// check if chain block height is sequential
if chainLastHeight != position.Height-1 {
- log.Error("Check confirmed block height fail", "chain", position.ChainID, "height", position.Height-1)
+ log.Error("Check confirmed block height fail", "chain", position.ChainID, "height", position.Height-1, "cache height", chainLastHeight)
return nil, fmt.Errorf("check confirmed block height fail")
}
}
@@ -263,24 +263,33 @@ func (d *DexconApp) PrepareWitness(consensusHeight uint64) (witness coreTypes.Wi
}
// VerifyBlock verifies if the payloads are valid.
-func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
- d.insertMu.Lock()
- defer d.insertMu.Unlock()
-
+func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifyStatus {
var witnessData witnessData
err := rlp.Decode(bytes.NewReader(block.Witness.Data), &witnessData)
if err != nil {
log.Error("Witness rlp decode", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
- // check witness root exist
- _, err = d.blockchain.StateAt(witnessData.Root)
+ log.Info("Ready to verify witness block", "height", block.Witness.Height)
+
+ for i := 0; i < 3 && err != nil; i++ {
+ // check witness root exist
+ err = nil
+ _, err = d.blockchain.StateAt(witnessData.Root)
+ if err != nil {
+ log.Warn("Sleep 2 seconds and try again", "error", err)
+ time.Sleep(2 * time.Second)
+ }
+ }
if err != nil {
- log.Error("Get state root error", "err", err)
- return false
+ log.Error("Expect witness root not in stateDB", "err", err)
+ return coreTypes.VerifyRetryLater
}
+ d.insertMu.Lock()
+ defer d.insertMu.Unlock()
+
if block.Position.Height != 0 {
chainLastHeight, empty := d.blockchain.GetChainLastConfirmedHeight(block.Position.ChainID)
if empty {
@@ -288,14 +297,14 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
chainLastHeight, exist = d.chainHeight[block.Position.ChainID]
if !exist {
log.Error("Something wrong")
- return false
+ return coreTypes.VerifyInvalidBlock
}
}
// check if chain block height is sequential
if chainLastHeight != block.Position.Height-1 {
log.Error("Check confirmed block height fail", "chain", block.Position.ChainID, "height", block.Position.Height-1)
- return false
+ return coreTypes.VerifyRetryLater
}
}
@@ -305,13 +314,13 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
latestState, err = d.blockchain.State()
if err != nil {
log.Error("Get current state", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
} else {
latestState, err = d.blockchain.StateAt(d.blockchain.GetPendingBlockByHeight(d.lastPendingHeight).Root())
if err != nil {
log.Error("Get pending state", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
}
@@ -319,14 +328,14 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
err = rlp.Decode(bytes.NewReader(block.Payload), &transactions)
if err != nil {
log.Error("Payload rlp decode", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
// check if nonce is sequential and return first nonce of every address
addresses, err := d.validateNonce(transactions)
if err != nil {
log.Error("Get address nonce", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
// check all address nonce
@@ -335,7 +344,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
for address, firstNonce := range addresses {
if !d.checkChain(address, chainNums, chainID) {
log.Error("check chain fail", "address", address)
- return false
+ return coreTypes.VerifyInvalidBlock
}
var expectNonce uint64
@@ -343,7 +352,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
lastConfirmedNonce, empty, err := d.blockchain.GetLastNonceFromConfirmedBlocks(block.Position.ChainID, address)
if err != nil {
log.Error("Get last nonce from confirmed blocks", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
} else if empty {
// get expect nonce from latest state when confirmed block is empty
expectNonce = latestState.GetNonce(address)
@@ -353,7 +362,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
if expectNonce != firstNonce {
log.Error("Nonce check error", "expect", expectNonce, "firstNonce", firstNonce)
- return false
+ return coreTypes.VerifyInvalidBlock
}
}
@@ -370,14 +379,14 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
err := rlp.Decode(bytes.NewReader(block.Payload), &txs)
if err != nil {
log.Error("Decode confirmed block", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
for _, tx := range txs {
msg, err := tx.AsMessage(types.MakeSigner(d.blockchain.Config(), new(big.Int)))
if err != nil {
log.Error("Tx to message", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
balance, exist := addressesBalance[msg.From()]
@@ -387,7 +396,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
balance = new(big.Int).Sub(balance, msg.Value())
if balance.Cmp(big.NewInt(0)) <= 0 {
log.Error("Replay confirmed tx fail", "reason", "not enough balance")
- return false
+ return coreTypes.VerifyInvalidBlock
}
addressesBalance[msg.From()] = balance
}
@@ -401,37 +410,37 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) bool {
msg, err := tx.AsMessage(types.MakeSigner(d.blockchain.Config(), new(big.Int)))
if err != nil {
log.Error("Tx to message", "error", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
balance, _ := addressesBalance[msg.From()]
maxGasUsed := new(big.Int).Mul(new(big.Int).SetUint64(msg.Gas()), msg.GasPrice())
intrinsicGas, err := core.IntrinsicGas(msg.Data(), msg.To() == nil, true)
if err != nil {
log.Error("Calculate intrinsic gas fail", "err", err)
- return false
+ return coreTypes.VerifyInvalidBlock
}
if big.NewInt(int64(intrinsicGas)).Cmp(maxGasUsed) > 0 {
log.Error("Intrinsic gas is larger than (gas limit * gas price)", "intrinsic", intrinsicGas, "maxGasUsed", maxGasUsed)
- return false
+ return coreTypes.VerifyInvalidBlock
}
balance = new(big.Int).Sub(balance, maxGasUsed)
balance = new(big.Int).Sub(balance, msg.Value())
if balance.Cmp(big.NewInt(0)) < 0 {
log.Error("Tx fail", "reason", "not enough balance")
- return false
+ return coreTypes.VerifyInvalidBlock
}
blockGasUsed = new(big.Int).Add(blockGasUsed, new(big.Int).SetUint64(tx.Gas()))
if blockGasLimit.Cmp(blockGasUsed) < 0 {
log.Error("Reach block gas limit", "limit", blockGasLimit)
- return false
+ return coreTypes.VerifyInvalidBlock
}
addressesBalance[msg.From()] = balance
}
- return true
+ return coreTypes.VerifyOK
}
// BlockDelivered is called when a block is add to the compaction chain.
@@ -479,7 +488,7 @@ func (d *DexconApp) BlockDelivered(blockHash coreCommon.Hash, result coreTypes.F
Randomness: result.Randomness,
}, transactions, nil, nil)
- _, err = d.blockchain.InsertPendingBlocks([]*types.Block{newBlock})
+ _, err = d.blockchain.ProcessPendingBlock(newBlock)
if err != nil {
log.Error("Insert chain", "error", err)
panic(err)
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/interfaces.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/interfaces.go
index 7b985cf7a..2ba8e0d3a 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/interfaces.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/interfaces.go
@@ -35,7 +35,7 @@ type Application interface {
PrepareWitness(consensusHeight uint64) (types.Witness, error)
// VerifyBlock verifies if the block is valid.
- VerifyBlock(block *types.Block) bool
+ VerifyBlock(block *types.Block) types.BlockVerifyStatus
// BlockConfirmed is called when a block is confirmed and added to lattice.
BlockConfirmed(block types.Block)
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice.go
index 984203d7d..0357a8d99 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/lattice.go
@@ -136,7 +136,8 @@ func (s *Lattice) SanityCheck(b *types.Block, checkRelation bool) (err error) {
}
// Verify data in application layer.
s.logger.Debug("Calling Application.VerifyBlock", "block", b)
- if !s.app.VerifyBlock(b) {
+ // TODO(jimmy-dexon): handle types.VerifyRetryLater.
+ if s.app.VerifyBlock(b) == types.VerifyInvalidBlock {
err = ErrInvalidBlock
return err
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/nonblocking.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/nonblocking.go
index 675675b2f..36135fdd9 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/nonblocking.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/nonblocking.go
@@ -129,7 +129,7 @@ func (nb *nonBlocking) PrepareWitness(height uint64) (types.Witness, error) {
}
// VerifyBlock cannot be non-blocking.
-func (nb *nonBlocking) VerifyBlock(block *types.Block) bool {
+func (nb *nonBlocking) VerifyBlock(block *types.Block) types.BlockVerifyStatus {
return nb.app.VerifyBlock(block)
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go
index 9de467397..29b1c841f 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus-core/core/types/block.go
@@ -33,6 +33,20 @@ import (
"github.com/dexon-foundation/dexon-consensus-core/core/crypto"
)
+// BlockVerifyStatus is the return code for core.Application.VerifyBlock
+type BlockVerifyStatus int
+
+// Enums for return value of core.Application.VerifyBlock.
+const (
+ // VerifyOK: Block is verified.
+ VerifyOK BlockVerifyStatus = iota
+ // VerifyRetryLater: Block is unable to be verified at this moment.
+ // Try again later.
+ VerifyRetryLater
+ // VerifyInvalidBlock: Block is an invalid one.
+ VerifyInvalidBlock
+)
+
var (
// blockPool is the blocks cache to reuse allocated blocks.
blockPool = sync.Pool{
diff --git a/vendor/vendor.json b/vendor/vendor.json
index f2c472262..e0fd8cc5c 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -105,44 +105,44 @@
{
"checksumSHA1": "IKOLx0ZjJoT9x9zO/bVAXWcNXs8=",
"path": "github.com/dexon-foundation/dexon-consensus-core/common",
- "revision": "d6a321f8f3a67af251f2ab1f8a52f1aaab629387",
- "revisionTime": "2018-10-23T07:29:58Z"
+ "revision": "83c4f24de2aa8f13f6b97c06aa29f204b4fc2f8b",
+ "revisionTime": "2018-10-23T09:14:47Z"
},
{
- "checksumSHA1": "MALFN2XbuWHClEnqeZtgV8sIO5Y=",
+ "checksumSHA1": "rcPl7V6DiiKQCvkX/h6THwOAGoc=",
"path": "github.com/dexon-foundation/dexon-consensus-core/core",
- "revision": "d6a321f8f3a67af251f2ab1f8a52f1aaab629387",
- "revisionTime": "2018-10-23T07:29:58Z"
+ "revision": "83c4f24de2aa8f13f6b97c06aa29f204b4fc2f8b",
+ "revisionTime": "2018-10-23T09:14:47Z"
},
{
"checksumSHA1": "69/j3ROwzhdGPWKymJnGjaJ5QzY=",
"path": "github.com/dexon-foundation/dexon-consensus-core/core/blockdb",
- "revision": "d6a321f8f3a67af251f2ab1f8a52f1aaab629387",
- "revisionTime": "2018-10-23T07:29:58Z"
+ "revision": "83c4f24de2aa8f13f6b97c06aa29f204b4fc2f8b",
+ "revisionTime": "2018-10-23T09:14:47Z"
},
{
"checksumSHA1": "GXHmtn3UlUftllBXI+M8RBkilzY=",
"path": "github.com/dexon-foundation/dexon-consensus-core/core/crypto",
- "revision": "d6a321f8f3a67af251f2ab1f8a52f1aaab629387",
- "revisionTime": "2018-10-23T07:29:58Z"
+ "revision": "83c4f24de2aa8f13f6b97c06aa29f204b4fc2f8b",
+ "revisionTime": "2018-10-23T09:14:47Z"
},
{
"checksumSHA1": "sh19Kk6G7esEcBPC2QsaFF3V/Ds=",
"path": "github.com/dexon-foundation/dexon-consensus-core/core/crypto/dkg",
- "revision": "d6a321f8f3a67af251f2ab1f8a52f1aaab629387",
- "revisionTime": "2018-10-23T07:29:58Z"
+ "revision": "83c4f24de2aa8f13f6b97c06aa29f204b4fc2f8b",
+ "revisionTime": "2018-10-23T09:14:47Z"
},
{
"checksumSHA1": "priVCcv7H4LTooiN/1EUu8qFiSs=",
"path": "github.com/dexon-foundation/dexon-consensus-core/core/crypto/ecdsa",
- "revision": "d6a321f8f3a67af251f2ab1f8a52f1aaab629387",
- "revisionTime": "2018-10-23T07:29:58Z"
+ "revision": "83c4f24de2aa8f13f6b97c06aa29f204b4fc2f8b",
+ "revisionTime": "2018-10-23T09:14:47Z"
},
{
- "checksumSHA1": "ILGM5rnuCywK3Z6e6fs1ns9CUx0=",
+ "checksumSHA1": "dKIKJdmVmYKd1ihBAfEoOn6qeCc=",
"path": "github.com/dexon-foundation/dexon-consensus-core/core/types",
- "revision": "d6a321f8f3a67af251f2ab1f8a52f1aaab629387",
- "revisionTime": "2018-10-23T07:29:58Z"
+ "revision": "83c4f24de2aa8f13f6b97c06aa29f204b4fc2f8b",
+ "revisionTime": "2018-10-23T09:14:47Z"
},
{
"checksumSHA1": "TAkwduKZqLyimyTPPWIllZWYFuE=",