github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/utilities/miner/unconfirmed.go (about)

     1  package miner
     2  
     3  import (
     4  	"container/ring"
     5  	"sync"
     6  
     7  	"github.com/neatlab/neatio/chain/core/types"
     8  	"github.com/neatlab/neatio/chain/log"
     9  	"github.com/neatlab/neatio/utilities/common"
    10  )
    11  
    12  type headerRetriever interface {
    13  	GetHeaderByNumber(number uint64) *types.Header
    14  }
    15  
    16  type unconfirmedBlock struct {
    17  	index uint64
    18  	hash  common.Hash
    19  }
    20  
    21  type unconfirmedBlocks struct {
    22  	chain  headerRetriever
    23  	depth  uint
    24  	blocks *ring.Ring
    25  	lock   sync.RWMutex
    26  	logger log.Logger
    27  }
    28  
    29  func newUnconfirmedBlocks(chain headerRetriever, depth uint, logger log.Logger) *unconfirmedBlocks {
    30  	return &unconfirmedBlocks{
    31  		chain:  chain,
    32  		depth:  depth,
    33  		logger: logger,
    34  	}
    35  }
    36  
    37  func (set *unconfirmedBlocks) Insert(index uint64, hash common.Hash) {
    38  
    39  	set.Shift(index)
    40  
    41  	item := ring.New(1)
    42  	item.Value = &unconfirmedBlock{
    43  		index: index,
    44  		hash:  hash,
    45  	}
    46  
    47  	set.lock.Lock()
    48  	defer set.lock.Unlock()
    49  
    50  	if set.blocks == nil {
    51  		set.blocks = item
    52  	} else {
    53  		set.blocks.Move(-1).Link(item)
    54  	}
    55  
    56  }
    57  
    58  func (set *unconfirmedBlocks) Shift(height uint64) {
    59  	set.lock.Lock()
    60  	defer set.lock.Unlock()
    61  
    62  	for set.blocks != nil {
    63  
    64  		next := set.blocks.Value.(*unconfirmedBlock)
    65  		if next.index+uint64(set.depth) > height {
    66  			break
    67  		}
    68  
    69  		header := set.chain.GetHeaderByNumber(next.index)
    70  		switch {
    71  		case header == nil:
    72  			set.logger.Warn("Failed to retrieve header of mined block", "number", next.index, "hash", next.hash)
    73  		case header.Hash() == next.hash:
    74  
    75  		default:
    76  			set.logger.Info("⑂ Block became a side fork", "number", next.index, "hash", next.hash)
    77  		}
    78  
    79  		if set.blocks.Value == set.blocks.Next().Value {
    80  			set.blocks = nil
    81  		} else {
    82  			set.blocks = set.blocks.Move(-1)
    83  			set.blocks.Unlink(1)
    84  			set.blocks = set.blocks.Move(1)
    85  		}
    86  	}
    87  }