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
|
// 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
|
// a new block, but the check only happens periodically, so it is
|
||||||
// possible a block was found and submitted in between.
|
// possible a block was found and submitted in between.
|
||||||
latestHash := m.g.blockManager.chain.BestSnapshot().Hash
|
latestHash := m.g.BestSnapshot().Hash
|
||||||
msgBlock := block.MsgBlock()
|
msgBlock := block.MsgBlock()
|
||||||
if !msgBlock.Header.PrevBlock.IsEqual(latestHash) {
|
if !msgBlock.Header.PrevBlock.IsEqual(latestHash) {
|
||||||
minrLog.Debugf("Block submitted via CPU miner with previous "+
|
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
|
// Process this block using the same rules as blocks coming from other
|
||||||
// nodes. This will in turn relay it to the network like normal.
|
// 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 {
|
if err != nil {
|
||||||
// Anything other than a rule violation is an unexpected error,
|
// Anything other than a rule violation is an unexpected error,
|
||||||
// so log that error as an internal error.
|
// so log that error as an internal error.
|
||||||
|
@ -222,7 +222,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32,
|
||||||
|
|
||||||
// Initial state.
|
// Initial state.
|
||||||
lastGenerated := time.Now()
|
lastGenerated := time.Now()
|
||||||
lastTxUpdate := m.g.txSource.LastUpdated()
|
lastTxUpdate := m.g.TxSource().LastUpdated()
|
||||||
hashesCompleted := uint64(0)
|
hashesCompleted := uint64(0)
|
||||||
|
|
||||||
// Note that the entire extra nonce range is iterated and the offset is
|
// 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
|
// The current block is stale if the best block
|
||||||
// has changed.
|
// has changed.
|
||||||
best := m.g.blockManager.chain.BestSnapshot()
|
best := m.g.BestSnapshot()
|
||||||
if !header.PrevBlock.IsEqual(best.Hash) {
|
if !header.PrevBlock.IsEqual(best.Hash) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, blockHeight int32,
|
||||||
// has been updated since the block template was
|
// has been updated since the block template was
|
||||||
// generated and it has been at least one
|
// generated and it has been at least one
|
||||||
// minute.
|
// minute.
|
||||||
if lastTxUpdate != m.g.txSource.LastUpdated() &&
|
if lastTxUpdate != m.g.TxSource().LastUpdated() &&
|
||||||
time.Now().After(lastGenerated.Add(time.Minute)) {
|
time.Now().After(lastGenerated.Add(time.Minute)) {
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
@ -327,8 +327,8 @@ out:
|
||||||
// this would otherwise end up building a new block template on
|
// this would otherwise end up building a new block template on
|
||||||
// a block that is in the process of becoming stale.
|
// a block that is in the process of becoming stale.
|
||||||
m.submitBlockLock.Lock()
|
m.submitBlockLock.Lock()
|
||||||
curHeight := m.g.blockManager.chain.BestSnapshot().Height
|
curHeight := m.g.BestSnapshot().Height
|
||||||
if curHeight != 0 && !m.g.blockManager.IsCurrent() {
|
if curHeight != 0 && !m.cfg.IsCurrent() {
|
||||||
m.submitBlockLock.Unlock()
|
m.submitBlockLock.Unlock()
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
continue
|
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
|
// be changing and this would otherwise end up building a new block
|
||||||
// template on a block that is in the process of becoming stale.
|
// template on a block that is in the process of becoming stale.
|
||||||
m.submitBlockLock.Lock()
|
m.submitBlockLock.Lock()
|
||||||
curHeight := m.g.blockManager.chain.BestSnapshot().Height
|
curHeight := m.g.BestSnapshot().Height
|
||||||
|
|
||||||
// Choose a payment address at random.
|
// Choose a payment address at random.
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
|
52
mining.go
52
mining.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/blockchain"
|
"github.com/btcsuite/btcd/blockchain"
|
||||||
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/mempool"
|
"github.com/btcsuite/btcd/mempool"
|
||||||
"github.com/btcsuite/btcd/mining"
|
"github.com/btcsuite/btcd/mining"
|
||||||
|
@ -312,10 +313,11 @@ func medianAdjustedTime(chainState *blockchain.BestState, timeSource blockchain.
|
||||||
// template is generated.
|
// template is generated.
|
||||||
type BlkTmplGenerator struct {
|
type BlkTmplGenerator struct {
|
||||||
policy *mining.Policy
|
policy *mining.Policy
|
||||||
|
chainParams *chaincfg.Params
|
||||||
txSource mining.TxSource
|
txSource mining.TxSource
|
||||||
sigCache *txscript.SigCache
|
chain *blockchain.BlockChain
|
||||||
blockManager *blockManager
|
|
||||||
timeSource blockchain.MedianTimeSource
|
timeSource blockchain.MedianTimeSource
|
||||||
|
sigCache *txscript.SigCache
|
||||||
}
|
}
|
||||||
|
|
||||||
// newBlkTmplGenerator returns a new block template generator for the given
|
// 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
|
// 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
|
// templates are built on top of the current best chain and adhere to the
|
||||||
// consensus rules.
|
// consensus rules.
|
||||||
func newBlkTmplGenerator(policy *mining.Policy, txSource mining.TxSource,
|
func newBlkTmplGenerator(policy *mining.Policy, params *chaincfg.Params,
|
||||||
timeSource blockchain.MedianTimeSource, sigCache *txscript.SigCache,
|
txSource mining.TxSource, chain *blockchain.BlockChain,
|
||||||
blockManager *blockManager) *BlkTmplGenerator {
|
timeSource blockchain.MedianTimeSource,
|
||||||
|
sigCache *txscript.SigCache) *BlkTmplGenerator {
|
||||||
|
|
||||||
return &BlkTmplGenerator{
|
return &BlkTmplGenerator{
|
||||||
policy: policy,
|
policy: policy,
|
||||||
|
chainParams: params,
|
||||||
txSource: txSource,
|
txSource: txSource,
|
||||||
sigCache: sigCache,
|
chain: chain,
|
||||||
blockManager: blockManager,
|
|
||||||
timeSource: timeSource,
|
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) {
|
func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress btcutil.Address) (*BlockTemplate, error) {
|
||||||
// Locals for faster access.
|
// Locals for faster access.
|
||||||
policy := g.policy
|
policy := g.policy
|
||||||
blockManager := g.blockManager
|
|
||||||
timeSource := g.timeSource
|
timeSource := g.timeSource
|
||||||
sigCache := g.sigCache
|
sigCache := g.sigCache
|
||||||
|
|
||||||
// Extend the most recently known best block.
|
// Extend the most recently known best block.
|
||||||
best := blockManager.chain.BestSnapshot()
|
best := g.chain.BestSnapshot()
|
||||||
prevHash := best.Hash
|
prevHash := best.Hash
|
||||||
nextBlockHeight := best.Height + 1
|
nextBlockHeight := best.Height + 1
|
||||||
|
|
||||||
|
@ -490,7 +493,7 @@ mempoolLoop:
|
||||||
// mempool since a transaction which depends on other
|
// mempool since a transaction which depends on other
|
||||||
// transactions in the mempool must come after those
|
// transactions in the mempool must come after those
|
||||||
// dependencies in the final generated block.
|
// dependencies in the final generated block.
|
||||||
utxos, err := blockManager.chain.FetchUtxoView(tx)
|
utxos, err := g.chain.FetchUtxoView(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
minrLog.Warnf("Unable to fetch utxo view for tx %s: "+
|
minrLog.Warnf("Unable to fetch utxo view for tx %s: "+
|
||||||
"%v", tx.Hash(), err)
|
"%v", tx.Hash(), err)
|
||||||
|
@ -723,7 +726,7 @@ mempoolLoop:
|
||||||
// is potentially adjusted to ensure it comes after the median time of
|
// is potentially adjusted to ensure it comes after the median time of
|
||||||
// the last several blocks per the chain consensus rules.
|
// the last several blocks per the chain consensus rules.
|
||||||
ts := medianAdjustedTime(best, timeSource)
|
ts := medianAdjustedTime(best, timeSource)
|
||||||
reqDifficulty, err := blockManager.chain.CalcNextRequiredDifficulty(ts)
|
reqDifficulty, err := g.chain.CalcNextRequiredDifficulty(ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -749,7 +752,7 @@ mempoolLoop:
|
||||||
// chain with no issues.
|
// chain with no issues.
|
||||||
block := btcutil.NewBlock(&msgBlock)
|
block := btcutil.NewBlock(&msgBlock)
|
||||||
block.SetHeight(nextBlockHeight)
|
block.SetHeight(nextBlockHeight)
|
||||||
if err := blockManager.chain.CheckConnectBlock(block); err != nil {
|
if err := g.chain.CheckConnectBlock(block); err != nil {
|
||||||
return nil, err
|
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 new timestamp is potentially adjusted to ensure it comes after
|
||||||
// the median time of the last several blocks per the chain consensus
|
// the median time of the last several blocks per the chain consensus
|
||||||
// rules.
|
// rules.
|
||||||
best := g.blockManager.chain.BestSnapshot()
|
newTime := medianAdjustedTime(g.chain.BestSnapshot(), g.timeSource)
|
||||||
newTimestamp := medianAdjustedTime(best, g.timeSource)
|
msgBlock.Header.Timestamp = newTime
|
||||||
msgBlock.Header.Timestamp = newTimestamp
|
|
||||||
|
|
||||||
// If running on a network that requires recalculating the difficulty,
|
// If running on a network that requires recalculating the difficulty,
|
||||||
// do so now.
|
// do so now.
|
||||||
if activeNetParams.ReduceMinDifficulty {
|
if activeNetParams.ReduceMinDifficulty {
|
||||||
chain := g.blockManager.chain
|
difficulty, err := g.chain.CalcNextRequiredDifficulty(newTime)
|
||||||
difficulty, err := chain.CalcNextRequiredDifficulty(newTimestamp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -822,3 +823,20 @@ func (g *BlkTmplGenerator) UpdateExtraNonce(msgBlock *wire.MsgBlock, blockHeight
|
||||||
msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1]
|
msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1]
|
||||||
return nil
|
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,
|
BlockPrioritySize: cfg.BlockPrioritySize,
|
||||||
TxMinFreeFee: cfg.minRelayTxFee,
|
TxMinFreeFee: cfg.minRelayTxFee,
|
||||||
}
|
}
|
||||||
blockTemplateGenerator := newBlkTmplGenerator(&policy, s.txMemPool,
|
blockTemplateGenerator := newBlkTmplGenerator(&policy, s.chainParams,
|
||||||
s.timeSource, s.sigCache, bm)
|
s.txMemPool, s.blockManager.chain, s.timeSource, s.sigCache)
|
||||||
s.cpuMiner = newCPUMiner(&cpuminerConfig{
|
s.cpuMiner = newCPUMiner(&cpuminerConfig{
|
||||||
ChainParams: chainParams,
|
ChainParams: chainParams,
|
||||||
BlockTemplateGenerator: blockTemplateGenerator,
|
BlockTemplateGenerator: blockTemplateGenerator,
|
||||||
|
|
Loading…
Reference in a new issue