OSDN Git Service

accumulate vote (#103)
[bytom/vapor.git] / protocol / consensus_node_manager.go
index 51acca9..8f0cb7a 100644 (file)
@@ -254,24 +254,11 @@ 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 := voteResultMap[voteSeq]
-
-       if voteResult == nil {
-               voteResult, err = c.store.GetVoteResult(voteSeq)
-               if err != nil && err != ErrNotFoundVoteResult {
-                       return err
-               }
-       }
-
-       if voteResult == nil {
-               voteResult = &state.VoteResult{
-                       Seq:       voteSeq,
-                       NumOfVote: make(map[string]uint64),
-               }
+       voteResult, err := c.getVoteResult(voteResultMap, voteSeq)
+       if err != nil {
+               return err
        }
 
-       voteResultMap[voteSeq] = voteResult
-
        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")
@@ -308,6 +295,42 @@ 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) {
+       var err error
+       voteResult := voteResultMap[seq]
+       if voteResult == nil {
+               prevVoteResult := voteResultMap[seq - 1]
+               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
+               }
+       }
+
+       if voteResult == nil {
+               voteResult, err := c.store.GetVoteResult(seq - 1)
+               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")
+               }
+
+               voteResult.Finalized = false
+               voteResult.LastBlockHash = bc.Hash{}
+       }
+       voteResultMap[seq] = voteResult
+       return voteResult, nil
+}
+
 func (c *consensusNodeManager) detachBlock(voteResultMap map[uint64]*state.VoteResult, block *types.Block) error {
        voteSeq := block.Height / roundVoteBlockNums
        voteResult := voteResultMap[voteSeq]