mining: Break dependency on block manager instance.
This modifies the block template generate for the mining code such that it takes chain instance and params instead of requiring a fully initialized blockManager instance. Also, in preparation for being able to more easily separate the code, it exposes and makes use of two new functions: - BestSnapshot which returns the state snapshot from the underlying chain instance - TxSource which returns the underlying transaction source This is a step towards being able to separate the mining code into its own package. No functional change.
This commit is contained in:
parent
671901486c
commit
660467259e
3 changed files with 51 additions and 33 deletions
16
cpuminer.go
16
cpuminer.go
|
@ -160,7 +160,7 @@ func (m *CPUMiner) submitBlock(block *btcutil.Block) bool {
|
|||
// detected and all work on the stale block is halted to start work on
|
||||
// a new block, but the check only happens periodically, so it is
|
||||
// possible a block was found and submitted in between.
|
||||
latestHash := m.g.blockManager.chain.BestSnapshot().Hash
|
||||
latestHash := m.g.BestSnapshot().Hash
|
||||
msgBlock := block.MsgBlock()
|
||||
if !msgBlock.Header.PrevBlock.IsEqual(latestHash) {
|
||||
minrLog.Debugf("Block submitted via CPU miner with previous "+
|
||||
|
@ -170,7 +170,7 @@ func (m *CPUMiner) submitBlock(block *btcutil.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.g.blockManager.ProcessBlock(block, blockchain.BFNone)
|
||||
isOrphan, err := m.cfg.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.
|
||||
|
@ -222,7 +222,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32,
|
|||
|
||||
// Initial state.
|
||||
lastGenerated := time.Now()
|
||||
lastTxUpdate := m.g.txSource.LastUpdated()
|
||||
lastTxUpdate := m.g.TxSource().LastUpdated()
|
||||
hashesCompleted := uint64(0)
|
||||
|
||||
// Note that the entire extra nonce range is iterated and the offset is
|
||||
|
@ -248,7 +248,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32,
|
|||
|
||||
// The current block is stale if the best block
|
||||
// has changed.
|
||||
best := m.g.blockManager.chain.BestSnapshot()
|
||||
best := m.g.BestSnapshot()
|
||||
if !header.PrevBlock.IsEqual(best.Hash) {
|
||||
return false
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32,
|
|||
// has been updated since the block template was
|
||||
// generated and it has been at least one
|
||||
// minute.
|
||||
if lastTxUpdate != m.g.txSource.LastUpdated() &&
|
||||
if lastTxUpdate != m.g.TxSource().LastUpdated() &&
|
||||
time.Now().After(lastGenerated.Add(time.Minute)) {
|
||||
|
||||
return false
|
||||
|
@ -327,8 +327,8 @@ out:
|
|||
// this would otherwise end up building a new block template on
|
||||
// a block that is in the process of becoming stale.
|
||||
m.submitBlockLock.Lock()
|
||||
curHeight := m.g.blockManager.chain.BestSnapshot().Height
|
||||
if curHeight != 0 && !m.g.blockManager.IsCurrent() {
|
||||
curHeight := m.g.BestSnapshot().Height
|
||||
if curHeight != 0 && !m.cfg.IsCurrent() {
|
||||
m.submitBlockLock.Unlock()
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
|
@ -594,7 +594,7 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) {
|
|||
// be changing and this would otherwise end up building a new block
|
||||
// template on a block that is in the process of becoming stale.
|
||||
m.submitBlockLock.Lock()
|
||||
curHeight := m.g.blockManager.chain.BestSnapshot().Height
|
||||
curHeight := m.g.BestSnapshot().Height
|
||||
|
||||
// Choose a payment address at random.
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
|
52
mining.go
52
mining.go
|
@ -10,6 +10,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/mempool"
|
||||
"github.com/btcsuite/btcd/mining"
|
||||
|
@ -312,10 +313,11 @@ func medianAdjustedTime(chainState *blockchain.BestState, timeSource blockchain.
|
|||
// template is generated.
|
||||
type BlkTmplGenerator struct {
|
||||
policy *mining.Policy
|
||||
chainParams *chaincfg.Params
|
||||
txSource mining.TxSource
|
||||
sigCache *txscript.SigCache
|
||||
blockManager *blockManager
|
||||
chain *blockchain.BlockChain
|
||||
timeSource blockchain.MedianTimeSource
|
||||
sigCache *txscript.SigCache
|
||||
}
|
||||
|
||||
// newBlkTmplGenerator returns a new block template generator for the given
|
||||
|
@ -324,16 +326,18 @@ type BlkTmplGenerator struct {
|
|||
// The additional state-related fields are required in order to ensure the
|
||||
// templates are built on top of the current best chain and adhere to the
|
||||
// consensus rules.
|
||||
func newBlkTmplGenerator(policy *mining.Policy, txSource mining.TxSource,
|
||||
timeSource blockchain.MedianTimeSource, sigCache *txscript.SigCache,
|
||||
blockManager *blockManager) *BlkTmplGenerator {
|
||||
func newBlkTmplGenerator(policy *mining.Policy, params *chaincfg.Params,
|
||||
txSource mining.TxSource, chain *blockchain.BlockChain,
|
||||
timeSource blockchain.MedianTimeSource,
|
||||
sigCache *txscript.SigCache) *BlkTmplGenerator {
|
||||
|
||||
return &BlkTmplGenerator{
|
||||
policy: policy,
|
||||
chainParams: params,
|
||||
txSource: txSource,
|
||||
sigCache: sigCache,
|
||||
blockManager: blockManager,
|
||||
chain: chain,
|
||||
timeSource: timeSource,
|
||||
sigCache: sigCache,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,12 +406,11 @@ func newBlkTmplGenerator(policy *mining.Policy, txSource mining.TxSource,
|
|||
func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*BlockTemplate, error) {
|
||||
// Locals for faster access.
|
||||
policy := g.policy
|
||||
blockManager := g.blockManager
|
||||
timeSource := g.timeSource
|
||||
sigCache := g.sigCache
|
||||
|
||||
// Extend the most recently known best block.
|
||||
best := blockManager.chain.BestSnapshot()
|
||||
best := g.chain.BestSnapshot()
|
||||
prevHash := best.Hash
|
||||
nextBlockHeight := best.Height + 1
|
||||
|
||||
|
@ -490,7 +493,7 @@ mempoolLoop:
|
|||
// mempool since a transaction which depends on other
|
||||
// transactions in the mempool must come after those
|
||||
// dependencies in the final generated block.
|
||||
utxos, err := blockManager.chain.FetchUtxoView(tx)
|
||||
utxos, err := g.chain.FetchUtxoView(tx)
|
||||
if err != nil {
|
||||
minrLog.Warnf("Unable to fetch utxo view for tx %s: "+
|
||||
"%v", tx.Hash(), err)
|
||||
|
@ -723,7 +726,7 @@ mempoolLoop:
|
|||
// is potentially adjusted to ensure it comes after the median time of
|
||||
// the last several blocks per the chain consensus rules.
|
||||
ts := medianAdjustedTime(best, timeSource)
|
||||
reqDifficulty, err := blockManager.chain.CalcNextRequiredDifficulty(ts)
|
||||
reqDifficulty, err := g.chain.CalcNextRequiredDifficulty(ts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -749,7 +752,7 @@ mempoolLoop:
|
|||
// chain with no issues.
|
||||
block := btcutil.NewBlock(&msgBlock)
|
||||
block.SetHeight(nextBlockHeight)
|
||||
if err := blockManager.chain.CheckConnectBlock(block); err != nil {
|
||||
if err := g.chain.CheckConnectBlock(block); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -777,15 +780,13 @@ func (g *BlkTmplGenerator) UpdateBlockTime(msgBlock *wire.MsgBlock) error {
|
|||
// The new timestamp is potentially adjusted to ensure it comes after
|
||||
// the median time of the last several blocks per the chain consensus
|
||||
// rules.
|
||||
best := g.blockManager.chain.BestSnapshot()
|
||||
newTimestamp := medianAdjustedTime(best, g.timeSource)
|
||||
msgBlock.Header.Timestamp = newTimestamp
|
||||
newTime := medianAdjustedTime(g.chain.BestSnapshot(), g.timeSource)
|
||||
msgBlock.Header.Timestamp = newTime
|
||||
|
||||
// If running on a network that requires recalculating the difficulty,
|
||||
// do so now.
|
||||
if activeNetParams.ReduceMinDifficulty {
|
||||
chain := g.blockManager.chain
|
||||
difficulty, err := chain.CalcNextRequiredDifficulty(newTimestamp)
|
||||
difficulty, err := g.chain.CalcNextRequiredDifficulty(newTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -822,3 +823,20 @@ func (g *BlkTmplGenerator) UpdateExtraNonce(msgBlock *wire.MsgBlock, blockHeight
|
|||
msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1]
|
||||
return nil
|
||||
}
|
||||
|
||||
// BestSnapshot returns information about the current best chain block and
|
||||
// related state as of the current point in time using the chain instance
|
||||
// associated with the block template generator. The returned state must be
|
||||
// treated as immutable since it is shared by all callers.
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (g *BlkTmplGenerator) BestSnapshot() *blockchain.BestState {
|
||||
return g.chain.BestSnapshot()
|
||||
}
|
||||
|
||||
// TxSource returns the associated transaction source.
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (g *BlkTmplGenerator) TxSource() mining.TxSource {
|
||||
return g.txSource
|
||||
}
|
||||
|
|
|
@ -2380,8 +2380,8 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
|||
BlockPrioritySize: cfg.BlockPrioritySize,
|
||||
TxMinFreeFee: cfg.minRelayTxFee,
|
||||
}
|
||||
blockTemplateGenerator := newBlkTmplGenerator(&policy, s.txMemPool,
|
||||
s.timeSource, s.sigCache, bm)
|
||||
blockTemplateGenerator := newBlkTmplGenerator(&policy, s.chainParams,
|
||||
s.txMemPool, s.blockManager.chain, s.timeSource, s.sigCache)
|
||||
s.cpuMiner = newCPUMiner(&cpuminerConfig{
|
||||
ChainParams: chainParams,
|
||||
BlockTemplateGenerator: blockTemplateGenerator,
|
||||
|
|
Loading…
Reference in a new issue