-
Notifications
You must be signed in to change notification settings - Fork 147
/
miner.go
144 lines (119 loc) · 3.78 KB
/
miner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright (c) 2018 The MATRIX Authors
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php
// Package miner implements Matrix block creation and mining.
package miner
import (
"errors"
"fmt"
"sync/atomic"
"github.com/MatrixAINetwork/go-matrix/params/manparams"
"github.com/MatrixAINetwork/go-matrix/common"
"github.com/MatrixAINetwork/go-matrix/consensus"
"github.com/MatrixAINetwork/go-matrix/core"
"github.com/MatrixAINetwork/go-matrix/core/state"
"github.com/MatrixAINetwork/go-matrix/core/types"
"github.com/MatrixAINetwork/go-matrix/event"
"github.com/MatrixAINetwork/go-matrix/log"
"github.com/MatrixAINetwork/go-matrix/msgsend"
"github.com/MatrixAINetwork/go-matrix/params"
)
const (
ModuleWork = "Miner_Work"
ModuleMiner = "Miner"
)
var (
invalidParameter = errors.New("Parameter is invalid!")
currentNotMiner = errors.New("Current Not Miner")
smallThanCurrentHeightt = errors.New("Small than current height")
LimitBroadcastRole = errors.New("change Broadcast to others")
currentRoleIsNotBroadcast = errors.New("current Role Is Not Broadcast")
difficultyIsZero = errors.New("difficulty Is Zero")
)
// Miner creates blocks and searches for proof-of-work values.
type Miner struct {
mux *event.TypeMux
worker *worker
coinbase common.Address
bc *core.BlockChain
canStart int32 // can start indicates whether we can start the mining operation
shouldStart int32 // should start indicates whether we should start after sync
}
func (s *Miner) Getworker() *worker { return s.worker }
func New(bc *core.BlockChain, config *params.ChainConfig, mux *event.TypeMux, hd *msgsend.HD) (*Miner, error) {
miner := &Miner{
mux: mux,
bc: bc,
canStart: 1,
}
var err error
miner.worker, err = newWorker(config, bc, mux, hd)
if err != nil {
log.ERROR(ModuleMiner, "创建work", "失败")
return miner, err
}
miner.Register(NewCpuAgent(bc))
//go miner.update()
log.INFO(ModuleMiner, "创建miner", "成功")
return miner, nil
}
//Start
func (self *Miner) Start() {
atomic.StoreInt32(&self.shouldStart, 1)
if atomic.LoadInt32(&self.canStart) == 0 {
log.Info("Network syncing, will start miner afterwards")
return
}
}
func (self *Miner) Stop() {
// todo:
self.worker.Stop()
atomic.StoreInt32(&self.shouldStart, 0)
}
func (self *Miner) Register(agent Agent) {
if self.Mining() {
agent.Start()
}
self.worker.Register(agent)
}
func (self *Miner) Unregister(agent Agent) {
self.worker.Unregister(agent)
}
func (self *Miner) Mining() bool {
return atomic.LoadInt32(&self.Getworker().mining) > 0
}
func (self *Miner) HashRate() (tot int64) {
if pow, ok := self.bc.Engine([]byte(manparams.VersionAlpha)).(consensus.PoW); ok {
tot += int64(pow.Hashrate())
}
// do we care this might race? is it worth we're rewriting some
// aspects of the worker/locking up agents so we can get an accurate
// hashrate?
for agent := range self.worker.agents {
if _, ok := agent.(*CpuAgent); !ok {
tot += agent.GetHashRate()
}
}
return
}
func (self *Miner) SetExtra(extra []byte) error {
if uint64(len(extra)) > params.MaximumExtraDataSize {
return fmt.Errorf("Extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize)
}
self.worker.setExtra(extra)
return nil
}
// Pending returns the currently pending block and associated state.
func (self *Miner) Pending() (*types.Block, *state.StateDBManage) {
return self.worker.pending()
}
/*
// PendingBlock returns the currently pending block.
//
// Note, to access both the pending block and the pending state
// simultaneously, please use Pending(), as the pending state can
// change between multiple method calls
*/
func (self *Miner) PendingBlock() *types.Block {
return self.worker.pendingBlock()
}