8 log "github.com/sirupsen/logrus"
10 "github.com/vapor/account"
11 "github.com/vapor/protocol"
12 "github.com/vapor/protocol/bc"
13 "github.com/vapor/protocol/bc/types"
20 type submitBlockMsg struct {
21 blockHeader *types.BlockHeader
25 // MiningPool is the support struct for p2p mine pool
26 type MiningPool struct {
29 submitCh chan *submitBlockMsg
32 accountManager *account.Manager
33 txPool *protocol.TxPool
34 newBlockCh chan *bc.Hash
37 // NewMiningPool will create a new MiningPool
38 func NewMiningPool(c *protocol.Chain, accountManager *account.Manager, txPool *protocol.TxPool, newBlockCh chan *bc.Hash) *MiningPool {
40 submitCh: make(chan *submitBlockMsg, maxSubmitChSize),
42 accountManager: accountManager,
44 newBlockCh: newBlockCh,
51 // blockUpdater is the goroutine for keep update mining block
52 func (m *MiningPool) blockUpdater() {
55 case <-m.chain.BlockWaiter(m.chain.BestBlockHeight() + 1):
58 case submitMsg := <-m.submitCh:
59 err := m.submitWork(submitMsg.blockHeader)
63 submitMsg.reply <- err
68 // generateBlock generates a block template to mine
69 func (m *MiningPool) generateBlock() {
73 // GetWork will return a block header for p2p mining
74 func (m *MiningPool) GetWork() (*types.BlockHeader, error) {
77 defer m.mutex.RUnlock()
79 m.block.BlockHeader.Timestamp = uint64(time.Now().Unix())
80 bh := m.block.BlockHeader
83 return nil, errors.New("no block is ready for mining")
86 // SubmitWork will try to submit the result to the blockchain
87 func (m *MiningPool) SubmitWork(bh *types.BlockHeader) error {
88 reply := make(chan error, 1)
89 m.submitCh <- &submitBlockMsg{blockHeader: bh, reply: reply}
92 log.WithFields(log.Fields{"err": err, "height": bh.Height}).Warning("submitWork failed")
97 func (m *MiningPool) submitWork(bh *types.BlockHeader) error {
99 defer m.mutex.Unlock()
101 if m.block == nil || bh.PreviousBlockHash != m.block.PreviousBlockHash {
102 return errors.New("pending mining block has been changed")
105 //m.block.Nonce = bh.Nonce
106 m.block.Timestamp = bh.Timestamp
107 isOrphan, err := m.chain.ProcessBlock(m.block)
112 return errors.New("submit result is orphan")
115 blockHash := bh.Hash()
116 m.newBlockCh <- &blockHash