Export CalcNextRequiredDifficutly function.

This commit exports a new variant of the existing internal
calcNextRequiredDifficulty function which calculates and returns the next
required difficulty for a block after the end of the current best chain
based on the difficulty retarget rules.

In order to support the exported function the internal one was slightly
modified to accept the block timestamp instead of an entire block since
the timestamp is all that is needed and the caller of the exported
function might next have a full block yet.
This commit is contained in:
Dave Collins 2014-03-02 12:17:36 -06:00
parent b59a15d07e
commit b041971ca8
2 changed files with 15 additions and 4 deletions

View file

@ -39,7 +39,8 @@ func (b *BlockChain) maybeAcceptBlock(block *btcutil.Block, fastAdd bool) error
// Ensure the difficulty specified in the block header matches // Ensure the difficulty specified in the block header matches
// the calculated difficulty based on the previous block and // the calculated difficulty based on the previous block and
// difficulty retarget rules. // difficulty retarget rules.
expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode, block) expectedDifficulty, err := b.calcNextRequiredDifficulty(prevNode,
block.MsgBlock().Header.Timestamp)
if err != nil { if err != nil {
return err return err
} }

View file

@ -6,7 +6,6 @@ package btcchain
import ( import (
"fmt" "fmt"
"github.com/conformal/btcutil"
"github.com/conformal/btcwire" "github.com/conformal/btcwire"
"math/big" "math/big"
"time" "time"
@ -260,7 +259,10 @@ func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, er
// calcNextRequiredDifficulty calculates the required difficulty for the block // calcNextRequiredDifficulty calculates the required difficulty for the block
// after the passed previous block node based on the difficulty retarget rules. // after the passed previous block node based on the difficulty retarget rules.
func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcutil.Block) (uint32, error) { // This function differs from the exported CalcNextRequiredDifficulty in that
// the exported version uses the current best chain as the previous block node
// while this function accepts any block node.
func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTime time.Time) (uint32, error) {
// Choose the correct proof of work limit for the active network. // Choose the correct proof of work limit for the active network.
powLimit := b.chainParams().PowLimit powLimit := b.chainParams().PowLimit
powLimitBits := b.chainParams().PowLimitBits powLimitBits := b.chainParams().PowLimitBits
@ -284,7 +286,6 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcu
// Return minimum difficulty when more than twice the // Return minimum difficulty when more than twice the
// desired amount of time needed to generate a block has // desired amount of time needed to generate a block has
// elapsed. // elapsed.
newBlockTime := block.MsgBlock().Header.Timestamp
allowMinTime := lastNode.timestamp.Add(targetSpacing * 2) allowMinTime := lastNode.timestamp.Add(targetSpacing * 2)
if newBlockTime.After(allowMinTime) { if newBlockTime.After(allowMinTime) {
return powLimitBits, nil return powLimitBits, nil
@ -367,3 +368,12 @@ func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, block *btcu
return newTargetBits, nil return newTargetBits, nil
} }
// CalcNextRequiredDifficulty calculates the required difficulty for the block
// after the end of the current best chain based on the difficulty retarget
// rules.
//
// This function is NOT safe for concurrent access.
func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error) {
return b.calcNextRequiredDifficulty(b.bestChain, timestamp)
}