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
}
}
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
}
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
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
}
}
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 {
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
}
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.