github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/utilities/miner/agent.go (about) 1 package miner 2 3 import ( 4 "sync" 5 6 "sync/atomic" 7 8 "github.com/neatio-net/neatio/chain/consensus" 9 ntcTypes "github.com/neatio-net/neatio/chain/consensus/neatcon/types" 10 "github.com/neatio-net/neatio/chain/core/types" 11 "github.com/neatio-net/neatio/chain/log" 12 ) 13 14 type CpuAgent struct { 15 mu sync.Mutex 16 17 workCh chan *Work 18 stop chan struct{} 19 quitCurrentOp chan struct{} 20 returnCh chan<- *Result 21 22 chain consensus.ChainReader 23 engine consensus.Engine 24 25 isMining int32 26 27 logger log.Logger 28 } 29 30 func NewCpuAgent(chain consensus.ChainReader, engine consensus.Engine, logger log.Logger) *CpuAgent { 31 miner := &CpuAgent{ 32 chain: chain, 33 engine: engine, 34 stop: make(chan struct{}, 1), 35 workCh: make(chan *Work, 1), 36 logger: logger, 37 } 38 return miner 39 } 40 41 func (self *CpuAgent) Work() chan<- *Work { return self.workCh } 42 func (self *CpuAgent) SetReturnCh(ch chan<- *Result) { self.returnCh = ch } 43 44 func (self *CpuAgent) Stop() { 45 if !atomic.CompareAndSwapInt32(&self.isMining, 1, 0) { 46 return 47 } 48 self.stop <- struct{}{} 49 done: 50 51 for { 52 select { 53 case <-self.workCh: 54 default: 55 break done 56 } 57 } 58 } 59 60 func (self *CpuAgent) Start() { 61 if !atomic.CompareAndSwapInt32(&self.isMining, 0, 1) { 62 return 63 } 64 go self.update() 65 } 66 67 func (self *CpuAgent) update() { 68 out: 69 for { 70 select { 71 case work := <-self.workCh: 72 self.mu.Lock() 73 if self.quitCurrentOp != nil { 74 close(self.quitCurrentOp) 75 } 76 self.quitCurrentOp = make(chan struct{}) 77 go self.mine(work, self.quitCurrentOp) 78 self.mu.Unlock() 79 case <-self.stop: 80 self.mu.Lock() 81 if self.quitCurrentOp != nil { 82 close(self.quitCurrentOp) 83 self.quitCurrentOp = nil 84 } 85 self.mu.Unlock() 86 break out 87 } 88 } 89 } 90 91 func (self *CpuAgent) mine(work *Work, stop <-chan struct{}) { 92 if result, err := self.engine.Seal(self.chain, work.Block, stop); result != nil { 93 switch result := result.(type) { 94 case *types.Block: 95 self.logger.Info("Successfully minted new block.") 96 self.returnCh <- &Result{Work: work, Block: result} 97 case *ntcTypes.IntermediateBlockResult: 98 99 self.returnCh <- &Result{Intermediate: result} 100 } 101 102 } else { 103 if err != nil { 104 self.logger.Warn("Block sealing failed", "err", err) 105 } 106 // self.logger.Warn("Block sealing aborted") 107 self.returnCh <- nil 108 } 109 }