func (c *consensusNodeManager) getPrevRoundVoteLastBlock(blockNode *state.BlockNode) (*state.BlockNode, error) {
prevVoteRoundLastBlockHeight := blockNode.Height/roundVoteBlockNums*roundVoteBlockNums - 1
- lastBlockNode := c.blockIndex.NodeByHeightInSameChain(&blockNode.Hash, prevVoteRoundLastBlockHeight)
- if blockNode == nil {
+ lastBlockNode := blockNode.GetParent(prevVoteRoundLastBlockHeight)
+ if lastBlockNode == nil {
return nil, errNotFoundBlockNode
}
return lastBlockNode, nil
}
}
- var attachBlocks []*types.Block
- var detachBlocks []*types.Block
+ var attachNodes []*state.BlockNode
+ var detachNodes []*state.BlockNode
for forkChainNode.Hash != mainChainNode.Hash && forkChainNode.Height >= (voteResult.Seq-1)*roundVoteBlockNums {
- attachBlock, err := c.store.GetBlock(&forkChainNode.Hash)
- if err != nil {
- return err
- }
-
- attachBlocks = append([]*types.Block{attachBlock}, attachBlocks...)
+ attachNodes = append([]*state.BlockNode{forkChainNode}, attachNodes...)
forkChainNode = forkChainNode.Parent
if mainChainNode != nil && forkChainNode.Height == mainChainNode.Height {
- detachBlock, err := c.store.GetBlock(&mainChainNode.Hash)
- if err != nil {
- return err
- }
-
- detachBlocks = append(detachBlocks, detachBlock)
+ detachNodes = append(detachNodes, mainChainNode)
mainChainNode = mainChainNode.Parent
}
}
- for _, block := range detachBlocks {
+ for _, node := range detachNodes {
+ block, err := c.store.GetBlock(&node.Hash)
+ if err != nil {
+ return err
+ }
+
if err := c.detachBlock(map[uint64]*state.VoteResult{voteResult.Seq: voteResult}, block); err != nil {
return err
}
}
- for _, block := range attachBlocks {
+ for _, node := range attachNodes {
+ block, err := c.store.GetBlock(&node.Hash)
+ if err != nil {
+ return err
+ }
+
if err := c.applyBlock(map[uint64]*state.VoteResult{voteResult.Seq: voteResult}, block); err != nil {
return err
}
return timestamps[len(timestamps)/2]
}
+// GetParent return the node of specified height
+// And the node satisfies the same chain as current node
+// Height of current node must greater than height parameter
+func (node *BlockNode) GetParent(height uint64) *BlockNode {
+ prevBlockNode := node
+ for prevBlockNode != nil && prevBlockNode.Height != height {
+ if prevBlockNode.Height < height {
+ return nil
+ }
+ prevBlockNode = prevBlockNode.Parent
+ }
+ return prevBlockNode
+}
+
// BlockIndex is the struct for help chain trace block chain as tree
type BlockIndex struct {
sync.RWMutex
return bi.index[*hash]
}
-// NodeByHeightInSameChain return the node of specified height
-// And the node satisfies the same chain as the node that specifies the hash
-// Height of the block of the specified node hash must greater than height parameter
-func (bi *BlockIndex) NodeByHeightInSameChain(nodeHash *bc.Hash, height uint64) *BlockNode {
- bi.RLock()
- defer bi.RUnlock()
-
- blockNode := bi.index[*nodeHash]
- prevBlockNode := blockNode
- for prevBlockNode != nil && prevBlockNode.Height != height {
- if prevBlockNode.Height < height {
- return nil
- }
- prevBlockNode = bi.index[prevBlockNode.Parent.Hash]
- }
- return prevBlockNode
-}
-
func (bi *BlockIndex) BestNode() *BlockNode {
bi.RLock()
defer bi.RUnlock()