agent.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. justStarted := true
  36. out:
  37. for {
  38. select {
  39. case block := <-self.c:
  40. if justStarted {
  41. justStarted = true
  42. } else {
  43. self.quitCurrentOp <- struct{}{}
  44. }
  45. go self.mine(block)
  46. case <-self.quit:
  47. break out
  48. }
  49. }
  50. done:
  51. // Empty channel
  52. for {
  53. select {
  54. case <-self.c:
  55. default:
  56. close(self.c)
  57. break done
  58. }
  59. }
  60. }
  61. func (self *CpuMiner) mine(block *types.Block) {
  62. minerlogger.Infof("(re)started agent[%d]. mining...\n", self.index)
  63. nonce, mixDigest, seedHash := self.pow.Search(block, self.quitCurrentOp)
  64. if nonce != 0 {
  65. self.returnCh <- Work{block.Number().Uint64(), nonce, mixDigest, seedHash}
  66. }
  67. }