From: muscle_boy Date: Fri, 31 May 2019 07:16:25 +0000 (+0800) Subject: Accumulate vote (#104) X-Git-Tag: v1.0.5~208^2~87 X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=commitdiff_plain;h=c79cd2eac9b58794d852e494f572992b377edcdf Accumulate vote (#104) * accumulate vote * bug fix * fix ci --- diff --git a/protocol/bbft.go b/protocol/bbft.go index 987397fa..dbdfe4da 100644 --- a/protocol/bbft.go +++ b/protocol/bbft.go @@ -253,3 +253,8 @@ func (b *bbft) updateBlockSignature(block *types.Block, nodeOrder uint64, signat return b.consensusNodeManager.store.SaveBlock(block, txStatus) } + +// SetBlockIndex set the block index field +func (b *bbft) SetBlockIndex(blockIndex *state.BlockIndex) { + b.consensusNodeManager.blockIndex = blockIndex +} diff --git a/protocol/consensus_node_manager.go b/protocol/consensus_node_manager.go index 8f0cb7a7..a4754d88 100644 --- a/protocol/consensus_node_manager.go +++ b/protocol/consensus_node_manager.go @@ -93,12 +93,17 @@ func (c *consensusNodeManager) nextLeaderTimeRange(pubkey []byte, bestBlockHash return 0, 0, errNotFoundBlockNode } - consensusNode, err := c.getConsensusNode(&bestBlockNode.Parent.Hash, hex.EncodeToString(pubkey)) + parentHash := bestBlockNode.Hash + if bestBlockNode.Height > 0 { + parentHash = bestBlockNode.Parent.Hash + } + + consensusNode, err := c.getConsensusNode(&parentHash, hex.EncodeToString(pubkey)) if err != nil { return 0, 0, err } - prevRoundLastBlock, err := c.getPrevRoundVoteLastBlock(&bestBlockNode.Parent.Hash) + prevRoundLastBlock, err := c.getPrevRoundVoteLastBlock(&parentHash) if err != nil { return 0, 0, err } @@ -253,8 +258,7 @@ func (c *consensusNodeManager) reorganizeVoteResult(voteResult *state.VoteResult } func (c *consensusNodeManager) applyBlock(voteResultMap map[uint64]*state.VoteResult, block *types.Block) (err error) { - voteSeq := block.Height / roundVoteBlockNums - voteResult, err := c.getVoteResult(voteResultMap, voteSeq) + voteResult, err := c.getVoteResult(voteResultMap, block.Height) if err != nil { return err } @@ -295,19 +299,30 @@ func (c *consensusNodeManager) applyBlock(voteResultMap map[uint64]*state.VoteRe return nil } -func (c *consensusNodeManager) getVoteResult(voteResultMap map[uint64]*state.VoteResult, seq uint64) (*state.VoteResult, error) { +func (c *consensusNodeManager) getVoteResult(voteResultMap map[uint64]*state.VoteResult, blockHeight uint64) (*state.VoteResult, error) { var err error + seq := blockHeight / roundVoteBlockNums voteResult := voteResultMap[seq] - if voteResult == nil { - prevVoteResult := voteResultMap[seq - 1] - voteResult = &state.VoteResult { - Seq: seq, - NumOfVote: prevVoteResult.NumOfVote, + if blockHeight == 0 { + voteResult = &state.VoteResult{ + Seq: seq, + NumOfVote: make(map[string]uint64), Finalized: false, } } if voteResult == nil { + prevVoteResult := voteResultMap[seq-1] + if prevVoteResult != nil { + voteResult = &state.VoteResult{ + Seq: seq, + NumOfVote: prevVoteResult.NumOfVote, + Finalized: false, + } + } + } + + if voteResult == nil { voteResult, err = c.store.GetVoteResult(seq) if err != nil && err != ErrNotFoundVoteResult { return nil, err @@ -319,14 +334,22 @@ func (c *consensusNodeManager) getVoteResult(voteResultMap map[uint64]*state.Vot if err != nil && err != ErrNotFoundVoteResult { return nil, err } - // previous round voting must have finalized - if !voteResult.Finalized { - return nil, errors.New("previous round voting has not finalized") + + if voteResult != nil { + // previous round voting must have finalized + if !voteResult.Finalized { + return nil, errors.New("previous round voting has not finalized") + } + + voteResult.Finalized = false + voteResult.LastBlockHash = bc.Hash{} } + } - voteResult.Finalized = false - voteResult.LastBlockHash = bc.Hash{} + if voteResult == nil { + return nil, errors.New("fail to get vote result") } + voteResultMap[seq] = voteResult return voteResult, nil } diff --git a/protocol/protocol.go b/protocol/protocol.go index 0f4026bd..1331d7f9 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -38,6 +38,7 @@ func NewChain(store Store, txPool *TxPool, eventDispatcher *event.Dispatcher) (* } c.cond.L = new(sync.Mutex) + c.bbft = newBbft(store, nil, c.orphanManage, eventDispatcher) storeStatus := store.GetStoreStatus() if storeStatus == nil { if err := c.initChainStatus(); err != nil { @@ -54,7 +55,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) + c.bbft.SetBlockIndex(c.index) go c.blockProcesser() return c, nil } @@ -78,12 +79,17 @@ func (c *Chain) initChainStatus() error { return err } + voteResultMap := make(map[uint64]*state.VoteResult) + if err := c.bbft.ApplyBlock(voteResultMap, genesisBlock); err != nil { + return err + } + node, err := state.NewBlockNode(&genesisBlock.BlockHeader, nil) if err != nil { return err } - return c.store.SaveChainStatus(node, node, utxoView, map[uint64]*state.VoteResult{}) + return c.store.SaveChainStatus(node, node, utxoView, voteResultMap) } // BestBlockHeight returns the current height of the blockchain.