github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/utilities/miner/unconfirmed.go (about) 1 package miner 2 3 import ( 4 "container/ring" 5 "sync" 6 7 "github.com/neatio-net/neatio/chain/core/types" 8 "github.com/neatio-net/neatio/chain/log" 9 "github.com/neatio-net/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 }