Skip to content

Commit

Permalink
multi: add cpuminerConfig.
Browse files Browse the repository at this point in the history
Port of upstream commit 6719014.
  • Loading branch information
dnldd committed Sep 7, 2018
1 parent c9e3928 commit c3fd242
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 16 deletions.
60 changes: 45 additions & 15 deletions cpuminer.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,31 @@ var (
littleEndian = binary.LittleEndian
)

// cpuminerConfig is a descriptor containing the cpu miner configuration.
type cpuminerConfig struct {
// TmplGenerator identifies the instance to use in order to
// generate block templates that the miner will attempt to solve.
TmplGenerator *BlkTmplGenerator
// ProcessBlock defines the function to call with any solved blocks.
// It typically must run the provided block through the same set of
// rules and handling as any other block coming from the network.
ProcessBlock func(*dcrutil.Block, blockchain.BehaviorFlags) (bool, error)
// ConnectedCount defines the function to use to obtain how many other
// peers the server is connected to. This is used by the automatic
// persistent mining routine to determine whether or it should attempt
// mining. This is useful because there is no point in mining when not
// connected to any peers since there would no be anyone to send any
// found blocks to.
ConnectedCount func() int32
// IsCurrent defines the function to use to obtain whether or not the
// block chain is current. This is used by the automatic persistent
// mining routine to determine whether or it should attempt mining.
// This is useful because there is no point in mining if the chain is
// not current since any solved blocks would be on a side chain and and
// up orphaned anyways.
IsCurrent func() bool
}

// CPUMiner provides facilities for solving blocks (mining) using the CPU in
// a concurrency-safe manner. It consists of two main goroutines -- a speed
// monitor and a controller for worker goroutines which generate and solve
Expand All @@ -64,8 +89,7 @@ var (
// system which is typically sufficient.
type CPUMiner struct {
sync.Mutex
g *BlkTmplGenerator
server *server
cfg cpuminerConfig
numWorkers uint32
started bool
discreteMining bool
Expand Down Expand Up @@ -138,7 +162,8 @@ func (m *CPUMiner) submitBlock(block *dcrutil.Block) bool {

// Process this block using the same rules as blocks coming from other
// nodes. This will in turn relay it to the network like normal.
isOrphan, err := m.server.blockManager.ProcessBlock(block, blockchain.BFNone)
isOrphan, err := m.cfg.TmplGenerator.blockManager.
ProcessBlock(block, blockchain.BFNone)
if err != nil {
// Anything other than a rule violation is an unexpected error,
// so log that error as an internal error.
Expand All @@ -151,7 +176,8 @@ func (m *CPUMiner) submitBlock(block *dcrutil.Block) bool {
// Occasionally errors are given out for timing errors with
// ReduceMinDifficulty and high block works that is above
// the target. Feed these to debug.
if m.server.chainParams.ReduceMinDifficulty &&
if m.cfg.TmplGenerator.blockManager.server.chainParams.
ReduceMinDifficulty &&
rErr.ErrorCode == blockchain.ErrHighHash {
minrLog.Debugf("Block submitted via CPU miner rejected "+
"because of ReduceMinDifficulty time sync failure: %v",
Expand Down Expand Up @@ -206,7 +232,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, ticker *time.Ticker, quit

// Initial state.
lastGenerated := time.Now()
lastTxUpdate := m.g.txSource.LastUpdated()
lastTxUpdate := m.cfg.TmplGenerator.txSource.LastUpdated()
hashesCompleted := uint64(0)

// Note that the entire extra nonce range is iterated and the offset is
Expand All @@ -233,14 +259,16 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, ticker *time.Ticker, quit
// has been updated since the block template was
// generated and it has been at least 3 seconds,
// or if it's been one minute.
if (lastTxUpdate != m.g.txSource.LastUpdated() &&
if (lastTxUpdate !=
m.cfg.TmplGenerator.txSource.LastUpdated() &&
time.Now().After(lastGenerated.Add(3*time.Second))) ||
time.Now().After(lastGenerated.Add(60*time.Second)) {

return false
}

err = UpdateBlockTime(msgBlock, m.server.blockManager)
err = UpdateBlockTime(msgBlock,
m.cfg.TmplGenerator.blockManager)
if err != nil {
minrLog.Warnf("CPU miner unable to update block template "+
"time: %v", err)
Expand Down Expand Up @@ -304,7 +332,8 @@ out:
// Hacks to make dcr work with Decred PoC (simnet only)
// TODO Remove before production.
if cfg.SimNet {
curHeight := m.server.blockManager.chain.BestSnapshot().Height
curHeight := m.cfg.TmplGenerator.blockManager.chain.
BestSnapshot().Height

if curHeight == 1 {
time.Sleep(5500 * time.Millisecond) // let wallet reconn
Expand All @@ -322,7 +351,7 @@ out:
// Create a new block template using the available transactions
// in the memory pool as a source of transactions to potentially
// include in the block.
template, err := m.g.NewBlockTemplate(payToAddr)
template, err := m.cfg.TmplGenerator.NewBlockTemplate(payToAddr)
m.submitBlockLock.Unlock()
if err != nil {
errStr := fmt.Sprintf("Failed to create new block "+
Expand Down Expand Up @@ -547,10 +576,12 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) {
m.Lock()

// Respond with an error if there's virtually 0 chance of CPU-mining a block.
if !m.server.chainParams.GenerateSupported {
if !m.cfg.TmplGenerator.blockManager.server.chainParams.
GenerateSupported {
m.Unlock()
return nil, errors.New("no support for `generate` on the current " +
"network, " + m.server.chainParams.Net.String() +
"network, " + m.cfg.TmplGenerator.blockManager.server.
chainParams.Net.String() +
", as it's unlikely to be possible to CPU-mine a block.")
}

Expand Down Expand Up @@ -601,7 +632,7 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) {
// Create a new block template using the available transactions
// in the memory pool as a source of transactions to potentially
// include in the block.
template, err := m.g.NewBlockTemplate(payToAddr)
template, err := m.cfg.TmplGenerator.NewBlockTemplate(payToAddr)
m.submitBlockLock.Unlock()
if err != nil {
errStr := fmt.Sprintf("Failed to create new block "+
Expand Down Expand Up @@ -642,10 +673,9 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) {
// newCPUMiner returns a new instance of a CPU miner for the provided server.
// Use Start to begin the mining process. See the documentation for CPUMiner
// type for more details.
func newCPUMiner(generator *BlkTmplGenerator, s *server) *CPUMiner {
func newCPUMiner(cfg *cpuminerConfig) *CPUMiner {
return &CPUMiner{
g: generator,
server: s,
cfg: *cfg,
numWorkers: defaultNumWorkers,
updateNumWorkers: make(chan struct{}),
queryHashesPerSec: make(chan float64),
Expand Down
7 changes: 6 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2518,7 +2518,12 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
}
blockTemplateGenerator := newBlkTmplGenerator(&policy, s.txMemPool, bm,
s.timeSource)
s.cpuMiner = newCPUMiner(blockTemplateGenerator, &s)
s.cpuMiner = newCPUMiner(&cpuminerConfig{
TmplGenerator: blockTemplateGenerator,
ProcessBlock: bm.ProcessBlock,
ConnectedCount: s.ConnectedCount,
IsCurrent: bm.IsCurrent,
})

// Only setup a function to return new addresses to connect to when
// not running in connect-only mode. The simulation network is always
Expand Down

0 comments on commit c3fd242

Please sign in to comment.