8 log "github.com/sirupsen/logrus"
10 "github.com/bytom/account"
11 "github.com/bytom/mining"
12 "github.com/bytom/protocol"
13 "github.com/bytom/protocol/bc"
14 "github.com/bytom/protocol/bc/types"
17 const blockUpdateMS = 1000
19 // MiningPool is the support struct for p2p mine pool
20 type MiningPool struct {
25 accountManager *account.Manager
26 txPool *protocol.TxPool
27 newBlockCh chan *bc.Hash
30 // NewMiningPool will create a new MiningPool
31 func NewMiningPool(c *protocol.Chain, accountManager *account.Manager, txPool *protocol.TxPool, newBlockCh chan *bc.Hash) *MiningPool {
34 accountManager: accountManager,
36 newBlockCh: newBlockCh,
42 // blockUpdater is the goroutine for keep update mining block
43 func (m *MiningPool) blockUpdater() {
44 ticker := time.NewTicker(time.Millisecond * blockUpdateMS)
45 for _ = range ticker.C {
50 func (m *MiningPool) generateBlock() {
52 defer m.mutex.Unlock()
53 if m.block != nil && *m.chain.BestBlockHash() == m.block.PreviousBlockHash {
54 m.block.Timestamp = uint64(time.Now().Unix())
58 block, err := mining.NewBlockTemplate(m.chain, m.txPool, m.accountManager)
60 log.Errorf("miningpool: failed on create NewBlockTemplate: %v", err)
67 // GetWork will return a block header for p2p mining
68 func (m *MiningPool) GetWork() (*types.BlockHeader, error) {
71 defer m.mutex.RUnlock()
72 bh := m.block.BlockHeader
75 return nil, errors.New("no block is ready for mining")
78 // SubmitWork will try to submit the result to the blockchain
79 func (m *MiningPool) SubmitWork(bh *types.BlockHeader) error {
81 defer m.mutex.Unlock()
83 if m.block == nil || bh.PreviousBlockHash != m.block.PreviousBlockHash {
84 return errors.New("pending mining block has been changed")
87 m.block.Nonce = bh.Nonce
88 m.block.Timestamp = bh.Timestamp
89 isOrphan, err := m.chain.ProcessBlock(m.block)
95 log.Warning("SubmitWork is orphan")
98 blockHash := bh.Hash()
99 m.newBlockCh <- &blockHash