agent.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package miner
  2. import (
  3. "github.com/ethereum/go-ethereum/core/types"
  4. "github.com/ethereum/go-ethereum/pow"
  5. )
  6. type CpuMiner struct {
  7. c chan *types.Block
  8. quit chan struct{}
  9. quitCurrentOp chan struct{}
  10. returnCh chan<- Work
  11. index int
  12. pow pow.PoW
  13. }
  14. func NewCpuMiner(index int, pow pow.PoW) *CpuMiner {
  15. miner := &CpuMiner{
  16. pow: pow,
  17. index: index,
  18. }
  19. return miner
  20. }
  21. func (self *CpuMiner) Work() chan<- *types.Block { return self.c }
  22. func (self *CpuMiner) Pow() pow.PoW { return self.pow }
  23. func (self *CpuMiner) SetWorkCh(ch chan<- Work) { self.returnCh = ch }
  24. func (self *CpuMiner) Stop() {
  25. close(self.quit)
  26. close(self.quitCurrentOp)
  27. }
  28. func (self *CpuMiner) Start() {
  29. self.quit = make(chan struct{})
  30. self.quitCurrentOp = make(chan struct{}, 1)
  31. self.c = make(chan *types.Block, 1)
  32. go self.update()
  33. }
  34. func (self *CpuMiner) update() {
  35. out:
  36. for {
  37. select {
  38. case block := <-self.c:
  39. self.quitCurrentOp <- struct{}{}
  40. go self.mine(block)
  41. case <-self.quit:
  42. break out
  43. }
  44. }
  45. done:
  46. // Empty channel
  47. for {
  48. select {
  49. case <-self.c:
  50. default:
  51. close(self.c)
  52. break done
  53. }
  54. }
  55. }
  56. func (self *CpuMiner) mine(block *types.Block) {
  57. minerlogger.Infof("(re)started agent[%d]. mining...\n", self.index)
  58. nonce := self.pow.Search(block, self.quitCurrentOp)
  59. if nonce != nil {
  60. self.returnCh <- Work{block.Number().Uint64(), nonce}
  61. }
  62. }