diff --git a/cpuminer.go b/cpuminer.go index 9f03705f..9e07fbd6 100644 --- a/cpuminer.go +++ b/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()) diff --git a/mining.go b/mining.go index 39ba6291..b11fa2a1 100644 --- a/mining.go +++ b/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" @@ -311,11 +312,12 @@ func medianAdjustedTime(chainState *blockchain.BestState, timeSource blockchain. // See the NewBlockTemplate method for a detailed description of how the block // template is generated. type BlkTmplGenerator struct { - policy *mining.Policy - txSource mining.TxSource - sigCache *txscript.SigCache - blockManager *blockManager - timeSource blockchain.MedianTimeSource + policy *mining.Policy + chainParams *chaincfg.Params + txSource mining.TxSource + 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, - txSource: txSource, - sigCache: sigCache, - blockManager: blockManager, - timeSource: timeSource, + policy: policy, + chainParams: params, + txSource: txSource, + 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 +} diff --git a/server.go b/server.go index 537da016..cdb334b9 100644 --- a/server.go +++ b/server.go @@ -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,