+// getPrevRoundVoteBlockHash return the previous round block hash by the given block header
+func (c *Chain) getPrevRoundVoteBlockHash(hash *bc.Hash) (*bc.Hash, error) {
+ if data, ok := c.prevRoundVoteBlockHashCache.Get(*hash); ok {
+ return data.(*bc.Hash), nil
+ }
+
+ header, err := c.store.GetBlockHeader(hash)
+ if err != nil {
+ return nil, errNotFoundBlockNode
+ }
+
+ if header.Height%consensus.ActiveNetParams.RoundVoteBlockNums == 0 {
+ c.prevRoundVoteBlockHashCache.Add(*hash, hash)
+ return hash, nil
+ }
+
+ if data, ok := c.prevRoundVoteBlockHashCache.Get(header.PreviousBlockHash); ok {
+ c.prevRoundVoteBlockHashCache.Add(*hash, data.(*bc.Hash))
+ return data.(*bc.Hash), nil
+ }
+
+ // loop find the prev round vote block hash
+ for header.Height%consensus.ActiveNetParams.RoundVoteBlockNums != 0 {
+ header, err = c.store.GetBlockHeader(&header.PreviousBlockHash)
+ if err != nil {
+ return nil, err
+ }
+ }
+ preRoundVoteBlockHash := header.Hash()
+ c.prevRoundVoteBlockHashCache.Add(*hash, &preRoundVoteBlockHash)
+ return &preRoundVoteBlockHash, nil
+}
+