From e7c3686fa6506c1762ae88fff9cdc33dadfa0bcd Mon Sep 17 00:00:00 2001 From: muscle_boy Date: Fri, 31 May 2019 10:40:28 +0800 Subject: [PATCH] fix next leader time (#98) * fix next leader time * launch * fix verify block signature --- event/event.go | 1 + netsync/consensusmgr/handle.go | 1 + proposal/blockproposer/blockproposer.go | 2 +- proposal/proposal.go | 5 ++- protocol/bbft.go | 70 +++++++++++++++--------------- protocol/bbft_test.go | 22 ++-------- protocol/block.go | 29 ++++++++----- protocol/consensus_node_manager.go | 76 +++++++++++++++++---------------- protocol/protocol.go | 1 + test/bench_blockchain_test.go | 2 +- test/performance/mining_test.go | 3 +- 11 files changed, 104 insertions(+), 108 deletions(-) diff --git a/event/event.go b/event/event.go index 9ce4d413..8b08ee52 100644 --- a/event/event.go +++ b/event/event.go @@ -30,6 +30,7 @@ type NewProposedBlockEvent struct{ Block types.Block } type BlockSignatureEvent struct { BlockHash bc.Hash Signature []byte + XPub [64]byte } //NewBlockProposeEvent block propose event which needs to broadcast. diff --git a/netsync/consensusmgr/handle.go b/netsync/consensusmgr/handle.go index f3823e05..ec8d3fa6 100644 --- a/netsync/consensusmgr/handle.go +++ b/netsync/consensusmgr/handle.go @@ -47,6 +47,7 @@ type Manager struct { func NewManager(sw Switch, chain Chain, dispatcher *event.Dispatcher, peers *peers.PeerSet) *Manager { manager := &Manager{ sw: sw, + chain: chain, peers: peers, blockFetcher: newBlockFetcher(chain, peers), eventDispatcher: dispatcher, diff --git a/proposal/blockproposer/blockproposer.go b/proposal/blockproposer/blockproposer.go index 2bff4313..3ef5d213 100644 --- a/proposal/blockproposer/blockproposer.go +++ b/proposal/blockproposer/blockproposer.go @@ -70,7 +70,7 @@ out: count := 0 for now = timeStart; now < timeEnd && count < protocol.BlockNumEachNode; now = uint64(time.Now().UnixNano() / 1e6) { - block, err := proposal.NewBlockTemplate(b.chain, b.txPool, b.accountManager) + block, err := proposal.NewBlockTemplate(b.chain, b.txPool, b.accountManager, now) if err != nil { log.Errorf("failed on create NewBlockTemplate: %v", err) } else { diff --git a/proposal/proposal.go b/proposal/proposal.go index 364d9ffc..e451148b 100644 --- a/proposal/proposal.go +++ b/proposal/proposal.go @@ -69,7 +69,7 @@ func createCoinbaseTx(accountManager *account.Manager, amount uint64, blockHeigh } // NewBlockTemplate returns a new block template that is ready to be solved -func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager *account.Manager) (b *types.Block, err error) { +func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager *account.Manager, timestamp uint64) (b *types.Block, err error) { view := state.NewUtxoViewpoint() txStatus := bc.NewTransactionStatus() if err := txStatus.SetStatus(0, false); err != nil { @@ -89,8 +89,9 @@ func NewBlockTemplate(c *protocol.Chain, txPool *protocol.TxPool, accountManager Version: 1, Height: nextBlockHeight, PreviousBlockHash: preBlockHash, - Timestamp: uint64(time.Now().UnixNano() / int64(time.Millisecond)), + Timestamp: timestamp, BlockCommitment: types.BlockCommitment{}, + BlockWitness: types.BlockWitness{Witness: make([][]byte, protocol.NumOfConsensusNode)}, }, } bcBlock := &bc.Block{BlockHeader: &bc.BlockHeader{Height: nextBlockHeight}} diff --git a/protocol/bbft.go b/protocol/bbft.go index ee38f682..9d4de080 100644 --- a/protocol/bbft.go +++ b/protocol/bbft.go @@ -14,6 +14,7 @@ import ( "github.com/vapor/protocol/bc" "github.com/vapor/protocol/bc/types" "github.com/vapor/protocol/state" + "github.com/vapor/crypto/ed25519/chainkd" ) const ( @@ -42,22 +43,13 @@ func newBbft(store Store, blockIndex *state.BlockIndex, orphanManage *OrphanMana } } -// IsConsensusPubkey determine whether a public key is a consensus node at a specified height -func (b *bbft) IsConsensusPubkey(blockHash *bc.Hash, pubkey []byte) (bool, error) { - node, err := b.consensusNodeManager.getConsensusNode(blockHash, hex.EncodeToString(pubkey)) - if err != nil && err != errNotFoundConsensusNode { - return false, err - } - return node != nil, nil -} - func (b *bbft) isIrreversible(block *types.Block) bool { signNum, err := b.validateSign(block) if err != nil { return false } - return signNum > (numOfConsensusNode * 2 / 3) + return signNum > (NumOfConsensusNode * 2 / 3) } // NextLeaderTime returns the start time of the specified public key as the next leader node @@ -74,15 +66,23 @@ func (b *bbft) DetachBlock(voteResultMap map[uint64]*state.VoteResult, block *ty } // ProcessBlockSignature process the received block signature messages -// return once a block become irreversible, whether it's height greater than best block height -// if so, the chain module must update status -func (b *bbft) ProcessBlockSignature(signature, pubkey []byte, blockHeight uint64, blockHash *bc.Hash) (bool, error) { - consensusNode, err := b.consensusNodeManager.getConsensusNode(blockHash, hex.EncodeToString(pubkey)) +// return whether a block become irreversible, if so, the chain module must update status +func (b *bbft) ProcessBlockSignature(signature []byte, xPub [64]byte, blockHeight uint64, blockHash *bc.Hash) (bool, error) { + block, err := b.consensusNodeManager.store.GetBlock(blockHash) + if err != nil { + // block is not exist, save the signature + key := fmt.Sprintf("%s:%s", blockHash.String(), hex.EncodeToString(xPub[:])) + b.signatureCache.Add(key, signature) + return false, err + } + + consensusNode, err := b.consensusNodeManager.getConsensusNode(&block.PreviousBlockHash, hex.EncodeToString(xPub[:])) if err != nil { return false, err } - if !ed25519.Verify(ed25519.PublicKey(pubkey), blockHash.Bytes(), signature) { + + if chainkd.XPub(xPub).Verify(blockHash.Bytes(), signature) { return false, errInvalidSignature } @@ -92,7 +92,7 @@ func (b *bbft) ProcessBlockSignature(signature, pubkey []byte, blockHeight uint6 } if isDoubleSign { - log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "pubkey": pubkey}).Warn("the consensus node double sign the same height of different block") + log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "xPub": hex.EncodeToString(xPub[:])}).Warn("the consensus node double sign the same height of different block") return false, errDoubleSignBlock } @@ -102,19 +102,11 @@ func (b *bbft) ProcessBlockSignature(signature, pubkey []byte, blockHeight uint6 return false, nil } - block, err := b.consensusNodeManager.store.GetBlock(blockHash) - if err != nil { - // block is not exist, save the signature - key := fmt.Sprintf("%s:%s", blockHash.String(), hex.EncodeToString(pubkey)) - b.signatureCache.Add(key, signature) - return false, err - } - if err := b.updateBlockSignature(block, consensusNode.order, signature); err != nil { return false, err } - return b.isIrreversible(block) && blockHeight > b.consensusNodeManager.blockIndex.BestNode().Height, nil + return b.isIrreversible(block), nil } // ValidateBlock verify whether the block is valid @@ -135,40 +127,44 @@ func (b *bbft) ValidateBlock(block *types.Block) error { // if the block has not the signature of blocker, it will return error func (b *bbft) validateSign(block *types.Block) (uint64, error) { var correctSignNum uint64 - blockHash := block.Hash() - consensusNodeMap, err := b.consensusNodeManager.getConsensusNodesByVoteResult(&blockHash) + consensusNodeMap, err := b.consensusNodeManager.getConsensusNodesByVoteResult(&block.PreviousBlockHash) if err != nil { return 0, err } hasBlockerSign := false - for pubkey, node := range consensusNodeMap { + for pubKey, node := range consensusNodeMap { if len(block.Witness) <= int(node.order) { continue } blockHash := block.Hash() if block.Witness[node.order] == nil { - key := fmt.Sprintf("%s:%s", blockHash.String(), pubkey) + key := fmt.Sprintf("%s:%s", blockHash.String(), pubKey) signature, ok := b.signatureCache.Get(key) if ok { block.Witness[node.order] = signature.([]byte) } } - if ed25519.Verify(ed25519.PublicKey(pubkey), blockHash.Bytes(), block.Witness[node.order]) { + pubKeyBytes, err := hex.DecodeString(pubKey) + if err != nil { + return 0, err + } + + if ed25519.Verify(ed25519.PublicKey(pubKeyBytes[:32]), blockHash.Bytes(), block.Witness[node.order]) { isDoubleSign, err := b.checkDoubleSign(node.order, block.Height, block.Hash()) if err != nil { return 0, err } if isDoubleSign { - log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "pubkey": pubkey}).Warn("the consensus node double sign the same height of different block") + log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "pubKey": pubKey}).Warn("the consensus node double sign the same height of different block") // Consensus node is signed twice with the same block height, discard the signature block.Witness[node.order] = nil } else { correctSignNum++ - isBlocker, err := b.consensusNodeManager.isBlocker(&blockHash, pubkey) + isBlocker, err := b.consensusNodeManager.isBlocker(block, pubKey) if err != nil { return 0, err } @@ -214,8 +210,7 @@ func (b *bbft) checkDoubleSign(nodeOrder, blockHeight uint64, blockHash bc.Hash) func (b *bbft) SignBlock(block *types.Block) ([]byte, error) { xprv := config.CommonConfig.PrivateKey() xpub := [64]byte(xprv.XPub()) - blockHash := block.Hash() - node, err := b.consensusNodeManager.getConsensusNode(&blockHash, hex.EncodeToString(xpub[:])) + node, err := b.consensusNodeManager.getConsensusNode(&block.PreviousBlockHash, hex.EncodeToString(xpub[:])) if err != nil && err != errNotFoundConsensusNode { return nil, err } @@ -224,8 +219,11 @@ func (b *bbft) SignBlock(block *types.Block) ([]byte, error) { return nil, nil } - signature := xprv.Sign(block.Hash().Bytes()) - block.Witness[node.order] = signature + signature := block.Witness[node.order] + if len(signature) == 0 { + signature = xprv.Sign(block.Hash().Bytes()) + block.Witness[node.order] = signature + } return signature, nil } diff --git a/protocol/bbft_test.go b/protocol/bbft_test.go index 2a1c98c7..fb6d0d38 100644 --- a/protocol/bbft_test.go +++ b/protocol/bbft_test.go @@ -8,7 +8,6 @@ func TestNextLeaderTime(t *testing.T) { cases := []struct { desc string startTime uint64 - endTime uint64 now uint64 nodeOrder uint64 wantError error @@ -17,7 +16,6 @@ func TestNextLeaderTime(t *testing.T) { { desc: "normal case", startTime: 1557906284061, - endTime: 1557906784061, now: 1557906534061, nodeOrder: 1, wantError: nil, @@ -26,7 +24,6 @@ func TestNextLeaderTime(t *testing.T) { { desc: "best block height equals to start block height", startTime: 1557906284061, - endTime: 1557906784061, now: 1557906284061, nodeOrder: 0, wantError: nil, @@ -35,43 +32,30 @@ func TestNextLeaderTime(t *testing.T) { { desc: "best block height equals to start block height", startTime: 1557906284061, - endTime: 1557906784061, now: 1557906284061, nodeOrder: 1, wantError: nil, wantNextLeaderTime: 1557906284061 + BlockNumEachNode*BlockTimeInterval, }, { - desc: "has no chance product block in this round of voting", - startTime: 1557906284061, - endTime: 1557906784061, - now: 1557906781561, - nodeOrder: 1, - wantError: errHasNoChanceProductBlock, - wantNextLeaderTime: 0, - }, - { desc: "the node is producting block", startTime: 1557906284061, - endTime: 1557906784061, now: 1557906284561, nodeOrder: 0, wantError: nil, - wantNextLeaderTime: 1557906284061, + wantNextLeaderTime: 1557906315561, }, { desc: "the node is producting block", startTime: 1557906284061, - endTime: 1557906784061, now: 1557906317561, nodeOrder: 1, wantError: nil, - wantNextLeaderTime: 1557906284061 + 66*BlockTimeInterval, + wantNextLeaderTime: 1557906348561, }, { desc: "first round, must exclude genesis block", startTime: 1557906284061, - endTime: 1557906783561, now: 1557906286561, nodeOrder: 3, wantError: nil, @@ -80,7 +64,7 @@ func TestNextLeaderTime(t *testing.T) { } for i, c := range cases { - nextLeaderTimestamp, err := nextLeaderTimeHelper(c.startTime, c.endTime, c.now, c.nodeOrder) + nextLeaderTimestamp, err := nextLeaderTimeHelper(c.startTime, c.now, c.nodeOrder) if err != c.wantError { t.Fatalf("case #%d (%s) want error:%v, got error:%v", i, c.desc, c.wantError, err) } diff --git a/protocol/block.go b/protocol/block.go index cfb94174..1b1b304d 100644 --- a/protocol/block.go +++ b/protocol/block.go @@ -5,6 +5,7 @@ import ( "github.com/vapor/errors" "github.com/vapor/event" + "github.com/vapor/config" "github.com/vapor/protocol/bc" "github.com/vapor/protocol/bc/types" "github.com/vapor/protocol/state" @@ -187,7 +188,8 @@ func (c *Chain) saveBlock(block *types.Block) error { } parent := c.index.GetNode(&block.PreviousBlockHash) - if err := validation.ValidateBlock(types.MapBlock(block), parent); err != nil { + bcBlock := types.MapBlock(block) + if err := validation.ValidateBlock(bcBlock, parent); err != nil { return errors.Sub(ErrBadBlock, err) } @@ -196,13 +198,6 @@ func (c *Chain) saveBlock(block *types.Block) error { return errors.Sub(ErrBadBlock, err) } - if len(signature) != 0 { - if err := c.bbft.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: block.Hash(), Signature: signature}); err != nil { - return err - } - } - - bcBlock := types.MapBlock(block) if err := c.store.SaveBlock(block, bcBlock.TransactionStatus); err != nil { return err } @@ -214,6 +209,13 @@ func (c *Chain) saveBlock(block *types.Block) error { } c.index.AddNode(node) + + if len(signature) != 0 { + xPub := config.CommonConfig.PrivateKey().XPub() + if err := c.bbft.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: block.Hash(), Signature: signature, XPub: xPub}); err != nil { + return err + } + } return nil } @@ -306,13 +308,18 @@ func (c *Chain) processBlock(block *types.Block) (bool, error) { return false, nil } -func (c *Chain) ProcessBlockSignature(signature, pubkey []byte, blockHeight uint64, blockHash *bc.Hash) error { - isBestIrreversible, err := c.bbft.ProcessBlockSignature(signature, pubkey, blockHeight, blockHash) +func (c *Chain) ProcessBlockSignature(signature, pubKey []byte, blockHeight uint64, blockHash *bc.Hash) error { + var xPub [64]byte + for i := 0; i < 64; i++ { + xPub[i] = pubKey[i] + } + + isIrreversible, err := c.bbft.ProcessBlockSignature(signature, xPub, blockHeight, blockHash) if err != nil { return err } - if isBestIrreversible { + if isIrreversible && blockHeight > c.bestIrreversibleNode.Height { bestIrreversibleNode := c.index.GetNode(blockHash) if err := c.store.SaveChainNodeStatus(c.bestNode, bestIrreversibleNode); err != nil { return err diff --git a/protocol/consensus_node_manager.go b/protocol/consensus_node_manager.go index 62fc3ad9..e90ee3c2 100644 --- a/protocol/consensus_node_manager.go +++ b/protocol/consensus_node_manager.go @@ -14,7 +14,7 @@ import ( ) const ( - numOfConsensusNode = 21 + NumOfConsensusNode = 21 roundVoteBlockNums = 1000 // BlockTimeInterval indicate product one block per 500 milliseconds @@ -24,7 +24,6 @@ const ( ) var ( - errHasNoChanceProductBlock = errors.New("the node has no chance to product a block in this round of voting") errNotFoundConsensusNode = errors.New("can not found consensus node") errNotFoundBlockNode = errors.New("can not find block node") ) @@ -53,8 +52,8 @@ func newConsensusNodeManager(store Store, blockIndex *state.BlockIndex) *consens } } -func (c *consensusNodeManager) getConsensusNode(blockHash *bc.Hash, pubkey string) (*consensusNode, error) { - consensusNodeMap, err := c.getConsensusNodesByVoteResult(blockHash) +func (c *consensusNodeManager) getConsensusNode(prevBlockHash *bc.Hash, pubkey string) (*consensusNode, error) { + consensusNodeMap, err := c.getConsensusNodesByVoteResult(prevBlockHash) if err != nil { return nil, err } @@ -66,13 +65,8 @@ func (c *consensusNodeManager) getConsensusNode(blockHash *bc.Hash, pubkey strin return node, nil } -func (c *consensusNodeManager) isBlocker(blockHash *bc.Hash, pubkey string) (bool, error) { - blockNode := c.blockIndex.GetNode(blockHash) - if blockNode == nil { - return false, errNotFoundBlockNode - } - - consensusNode, err := c.getConsensusNode(blockHash, pubkey) +func (c *consensusNodeManager) isBlocker(block *types.Block, pubKey string) (bool, error) { + consensusNode, err := c.getConsensusNode(&block.PreviousBlockHash, pubKey) if err != nil && err != errNotFoundConsensusNode { return false, err } @@ -81,16 +75,16 @@ func (c *consensusNodeManager) isBlocker(blockHash *bc.Hash, pubkey string) (boo return false, nil } - prevVoteRoundLastBlock, err := c.getPrevRoundVoteLastBlock(blockNode) + prevVoteRoundLastBlock, err := c.getPrevRoundVoteLastBlock(&block.PreviousBlockHash) if err != nil { return false, err } startTimestamp := prevVoteRoundLastBlock.Timestamp + BlockTimeInterval - begin := getLastBlockTimeInTimeRange(startTimestamp, blockNode.Timestamp, consensusNode.order) + begin := getLastBlockTimeInTimeRange(startTimestamp, block.Timestamp, consensusNode.order) end := begin + BlockNumEachNode*BlockTimeInterval - return blockNode.Timestamp >= begin && blockNode.Timestamp < end, nil + return block.Timestamp >= begin && block.Timestamp < end, nil } func (c *consensusNodeManager) nextLeaderTimeRange(pubkey []byte, bestBlockHash *bc.Hash) (uint64, uint64, error) { @@ -99,20 +93,19 @@ func (c *consensusNodeManager) nextLeaderTimeRange(pubkey []byte, bestBlockHash return 0, 0, errNotFoundBlockNode } - consensusNode, err := c.getConsensusNode(bestBlockHash, hex.EncodeToString(pubkey)) + consensusNode, err := c.getConsensusNode(&bestBlockNode.Parent.Hash, hex.EncodeToString(pubkey)) if err != nil { return 0, 0, err } - prevRoundLastBlock, err := c.getPrevRoundVoteLastBlock(bestBlockNode) + prevRoundLastBlock, err := c.getPrevRoundVoteLastBlock(&bestBlockNode.Parent.Hash) if err != nil { - return 0, 0, nil + return 0, 0, err } startTime := prevRoundLastBlock.Timestamp + BlockTimeInterval - endTime := startTime + roundVoteBlockNums*BlockTimeInterval - nextLeaderTime, err := nextLeaderTimeHelper(startTime, endTime, uint64(time.Now().UnixNano()/1e6), consensusNode.order) + nextLeaderTime, err := nextLeaderTimeHelper(startTime, uint64(time.Now().UnixNano()/1e6), consensusNode.order) if err != nil { return 0, 0, err } @@ -120,15 +113,12 @@ func (c *consensusNodeManager) nextLeaderTimeRange(pubkey []byte, bestBlockHash return nextLeaderTime, nextLeaderTime + BlockNumEachNode*BlockTimeInterval, nil } -func nextLeaderTimeHelper(startTime, endTime, now, nodeOrder uint64) (uint64, error) { +func nextLeaderTimeHelper(startTime, now, nodeOrder uint64) (uint64, error) { nextLeaderTimestamp := getLastBlockTimeInTimeRange(startTime, now, nodeOrder) - roundBlockTime := uint64(BlockNumEachNode * numOfConsensusNode * BlockTimeInterval) + roundBlockTime := uint64(BlockNumEachNode * NumOfConsensusNode * BlockTimeInterval) - if int64(now-nextLeaderTimestamp) >= BlockNumEachNode*BlockTimeInterval { + if now > nextLeaderTimestamp { nextLeaderTimestamp += roundBlockTime - if nextLeaderTimestamp >= endTime { - return 0, errHasNoChanceProductBlock - } } return nextLeaderTimestamp, nil @@ -136,29 +126,41 @@ func nextLeaderTimeHelper(startTime, endTime, now, nodeOrder uint64) (uint64, er func getLastBlockTimeInTimeRange(startTimestamp, endTimestamp, order uint64) uint64 { // One round of product block time for all consensus nodes - roundBlockTime := uint64(BlockNumEachNode * numOfConsensusNode * BlockTimeInterval) + roundBlockTime := uint64(BlockNumEachNode * NumOfConsensusNode * BlockTimeInterval) // The start time of the last round of product block lastRoundStartTime := startTimestamp + (endTimestamp-startTimestamp)/roundBlockTime*roundBlockTime // The time of product block of the consensus in last round return lastRoundStartTime + order*(BlockNumEachNode*BlockTimeInterval) } -func (c *consensusNodeManager) getPrevRoundVoteLastBlock(blockNode *state.BlockNode) (*state.BlockNode, error) { - prevVoteRoundLastBlockHeight := blockNode.Height/roundVoteBlockNums*roundVoteBlockNums - 1 - lastBlockNode := blockNode.GetParent(prevVoteRoundLastBlockHeight) +func (c *consensusNodeManager) getPrevRoundVoteLastBlock(prevBlockHash *bc.Hash) (*state.BlockNode, error) { + prevBlockNode := c.blockIndex.GetNode(prevBlockHash) + if prevBlockNode == nil { + return nil, errNotFoundBlockNode + } + + blockHeight := prevBlockNode.Height + 1 + + prevVoteRoundLastBlockHeight := blockHeight/roundVoteBlockNums*roundVoteBlockNums - 1 + // first round + if blockHeight / roundVoteBlockNums == 0 { + prevVoteRoundLastBlockHeight = 0 + } + + lastBlockNode := prevBlockNode.GetParent(prevVoteRoundLastBlockHeight) if lastBlockNode == nil { return nil, errNotFoundBlockNode } return lastBlockNode, nil } -func (c *consensusNodeManager) getConsensusNodesByVoteResult(blockHash *bc.Hash) (map[string]*consensusNode, error) { - blockNode := c.blockIndex.GetNode(blockHash) - if blockNode == nil { +func (c *consensusNodeManager) getConsensusNodesByVoteResult(prevBlockHash *bc.Hash) (map[string]*consensusNode, error) { + prevBlockNode := c.blockIndex.GetNode(prevBlockHash) + if prevBlockNode == nil { return nil, errNotFoundBlockNode } - seq := blockNode.Height / roundVoteBlockNums + seq := (prevBlockNode.Height + 1) / roundVoteBlockNums if seq == 0 { return initVoteResult(), nil } @@ -173,7 +175,7 @@ func (c *consensusNodeManager) getConsensusNodesByVoteResult(blockHash *bc.Hash) } } - lastBlockNode, err := c.getPrevRoundVoteLastBlock(blockNode) + lastBlockNode, err := c.getPrevRoundVoteLastBlock(prevBlockHash) if err != nil { return nil, err } @@ -195,7 +197,7 @@ func (c *consensusNodeManager) getConsensusNodesByVoteResult(blockHash *bc.Hash) sort.Sort(consensusNodeSlice(nodes)) result := make(map[string]*consensusNode) - for i := 0; i < numOfConsensusNode; i++ { + for i := 0; i < NumOfConsensusNode; i++ { node := nodes[i] node.order = uint64(i) result[node.pubkey] = node @@ -265,13 +267,13 @@ func (c *consensusNodeManager) applyBlock(voteResultMap map[uint64]*state.VoteRe voteResult = &state.VoteResult{ Seq: voteSeq, NumOfVote: make(map[string]uint64), - LastBlockHash: block.Hash(), } } voteResultMap[voteSeq] = voteResult - if voteResult.LastBlockHash != block.PreviousBlockHash { + emptyHash := bc.Hash{} + if voteResult.LastBlockHash != emptyHash && voteResult.LastBlockHash != block.PreviousBlockHash { return errors.New("bbft append block error, the block parent hash is not equals last block hash of vote result") } diff --git a/protocol/protocol.go b/protocol/protocol.go index 183f95a3..0f4026bd 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -52,6 +52,7 @@ func NewChain(store Store, txPool *TxPool, eventDispatcher *event.Dispatcher) (* } c.bestNode = c.index.GetNode(storeStatus.Hash) + c.bestIrreversibleNode = c.index.GetNode(storeStatus.IrreversibleHash) c.index.SetMainChain(c.bestNode) c.bbft = newBbft(store, c.index, c.orphanManage, eventDispatcher) go c.blockProcesser() diff --git a/test/bench_blockchain_test.go b/test/bench_blockchain_test.go index dad704be..0d548feb 100644 --- a/test/bench_blockchain_test.go +++ b/test/bench_blockchain_test.go @@ -159,7 +159,7 @@ func InsertChain(chain *protocol.Chain, txPool *protocol.TxPool, txs []*types.Tx } } - block, err := proposal.NewBlockTemplate(chain, txPool, nil) + block, err := proposal.NewBlockTemplate(chain, txPool, nil, uint64(time.Now().UnixNano() / 1e6)) if err != nil { return err } diff --git a/test/performance/mining_test.go b/test/performance/mining_test.go index c7a606e0..87390082 100644 --- a/test/performance/mining_test.go +++ b/test/performance/mining_test.go @@ -3,6 +3,7 @@ package performance import ( "os" "testing" + "time" "github.com/vapor/account" dbm "github.com/vapor/database/leveldb" @@ -23,6 +24,6 @@ func BenchmarkNewBlockTpl(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - proposal.NewBlockTemplate(chain, txPool, accountManager) + proposal.NewBlockTemplate(chain, txPool, accountManager, uint64(time.Now().UnixNano() / 1e6)) } } -- 2.11.0