2014-01-09 06:52:54 +01:00
|
|
|
// Copyright (c) 2013-2014 Conformal Systems LLC.
|
2013-07-18 16:49:28 +02:00
|
|
|
// Use of this source code is governed by an ISC
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package btcchain
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"github.com/conformal/btcwire"
|
|
|
|
"math/big"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// targetTimespan is the desired amount of time that should elapse
|
|
|
|
// before block difficulty requirement is examined to determine how
|
|
|
|
// it should be changed in order to maintain the desired block
|
|
|
|
// generation rate.
|
|
|
|
targetTimespan = time.Hour * 24 * 14
|
|
|
|
|
|
|
|
// targetSpacing is the desired amount of time to generate each block.
|
|
|
|
targetSpacing = time.Minute * 10
|
|
|
|
|
2014-02-07 23:23:11 +01:00
|
|
|
// BlocksPerRetarget is the number of blocks between each difficulty
|
2013-07-18 16:49:28 +02:00
|
|
|
// retarget. It is calculated based on the desired block generation
|
|
|
|
// rate.
|
2014-02-07 23:23:11 +01:00
|
|
|
BlocksPerRetarget = int64(targetTimespan / targetSpacing)
|
2013-07-18 16:49:28 +02:00
|
|
|
|
|
|
|
// retargetAdjustmentFactor is the adjustment factor used to limit
|
|
|
|
// the minimum and maximum amount of adjustment that can occur between
|
|
|
|
// difficulty retargets.
|
|
|
|
retargetAdjustmentFactor = 4
|
|
|
|
|
|
|
|
// minRetargetTimespan is the minimum amount of adjustment that can
|
|
|
|
// occur between difficulty retargets. It equates to 25% of the
|
|
|
|
// previous difficulty.
|
|
|
|
minRetargetTimespan = int64(targetTimespan / retargetAdjustmentFactor)
|
|
|
|
|
|
|
|
// maxRetargetTimespan is the maximum amount of adjustment that can
|
|
|
|
// occur between difficulty retargets. It equates to 400% of the
|
|
|
|
// previous difficulty.
|
|
|
|
maxRetargetTimespan = int64(targetTimespan * retargetAdjustmentFactor)
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// bigOne is 1 represented as a big.Int. It is defined here to avoid
|
|
|
|
// the overhead of creating it multiple times.
|
|
|
|
bigOne = big.NewInt(1)
|
|
|
|
|
|
|
|
// oneLsh256 is 1 shifted left 256 bits. It is defined here to avoid
|
|
|
|
// the overhead of creating it multiple times.
|
|
|
|
oneLsh256 = new(big.Int).Lsh(bigOne, 256)
|
|
|
|
)
|
|
|
|
|
|
|
|
// ShaHashToBig converts a btcwire.ShaHash into a big.Int that can be used to
|
|
|
|
// perform math comparisons.
|
|
|
|
func ShaHashToBig(hash *btcwire.ShaHash) *big.Int {
|
|
|
|
// A ShaHash is in little-endian, but the big package wants the bytes
|
|
|
|
// in big-endian. Reverse them. ShaHash.Bytes makes a copy, so it
|
|
|
|
// is safe to modify the returned buffer.
|
|
|
|
buf := hash.Bytes()
|
|
|
|
blen := len(buf)
|
|
|
|
for i := 0; i < blen/2; i++ {
|
|
|
|
buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
|
|
|
|
}
|
|
|
|
|
|
|
|
return new(big.Int).SetBytes(buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
// CompactToBig converts a compact representation of a whole number N to an
|
|
|
|
// unsigned 32-bit number. The representation is similar to IEEE754 floating
|
|
|
|
// point numbers.
|
|
|
|
//
|
|
|
|
// Like IEEE754 floating point, there are three basic components: the sign,
|
|
|
|
// the exponent, and the mantissa. They are broken out as follows:
|
|
|
|
//
|
|
|
|
// * the most significant 8 bits represent the unsigned base 256 exponent
|
|
|
|
// * bit 23 (the 24th bit) represents the sign bit
|
|
|
|
// * the least significant 23 bits represent the mantissa
|
|
|
|
//
|
|
|
|
// -------------------------------------------------
|
|
|
|
// | Exponent | Sign | Mantissa |
|
|
|
|
// -------------------------------------------------
|
|
|
|
// | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] |
|
|
|
|
// -------------------------------------------------
|
|
|
|
//
|
|
|
|
// The formula to calculate N is:
|
|
|
|
// N = (-1^sign) * mantissa * 256^(exponent-3)
|
|
|
|
//
|
|
|
|
// This compact form is only used in bitcoin to encode unsigned 256-bit numbers
|
|
|
|
// which represent difficulty targets, thus there really is not a need for a
|
|
|
|
// sign bit, but it is implemented here to stay consistent with bitcoind.
|
|
|
|
func CompactToBig(compact uint32) *big.Int {
|
|
|
|
// Extract the mantissa, sign bit, and exponent.
|
|
|
|
mantissa := compact & 0x007fffff
|
|
|
|
isNegative := compact&0x00800000 != 0
|
|
|
|
exponent := uint(compact >> 24)
|
|
|
|
|
|
|
|
// Since the base for the exponent is 256, the exponent can be treated
|
|
|
|
// as the number of bytes to represent the full 256-bit number. So,
|
|
|
|
// treat the exponent as the number of bytes and shift the mantissa
|
|
|
|
// right or left accordingly. This is equivalent to:
|
|
|
|
// N = mantissa * 256^(exponent-3)
|
|
|
|
var bn *big.Int
|
|
|
|
if exponent <= 3 {
|
|
|
|
mantissa >>= 8 * (3 - exponent)
|
|
|
|
bn = big.NewInt(int64(mantissa))
|
|
|
|
} else {
|
|
|
|
bn = big.NewInt(int64(mantissa))
|
|
|
|
bn.Lsh(bn, 8*(exponent-3))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make it negative if the sign bit is set.
|
|
|
|
if isNegative {
|
|
|
|
bn = bn.Neg(bn)
|
|
|
|
}
|
|
|
|
|
|
|
|
return bn
|
|
|
|
}
|
|
|
|
|
|
|
|
// BigToCompact converts a whole number N to a compact representation using
|
|
|
|
// an unsigned 32-bit number. The compact representation only provides 23 bits
|
|
|
|
// of precision, so values larger than (2^23 - 1) only encode the most
|
|
|
|
// significant digits of the number. See CompactToBig for details.
|
|
|
|
func BigToCompact(n *big.Int) uint32 {
|
|
|
|
// No need to do any work if it's zero.
|
|
|
|
if n.Sign() == 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// Since the base for the exponent is 256, the exponent can be treated
|
|
|
|
// as the number of bytes. So, shift the number right or left
|
|
|
|
// accordingly. This is equivalent to:
|
|
|
|
// mantissa = mantissa / 256^(exponent-3)
|
|
|
|
var mantissa uint32
|
|
|
|
exponent := uint(len(n.Bytes()))
|
|
|
|
if exponent <= 3 {
|
|
|
|
mantissa = uint32(n.Bits()[0])
|
|
|
|
mantissa <<= 8 * (3 - exponent)
|
|
|
|
} else {
|
|
|
|
// Use a copy to avoid modifying the caller's original number.
|
|
|
|
tn := new(big.Int).Set(n)
|
|
|
|
mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
// When the mantissa already has the sign bit set, the number is too
|
|
|
|
// large to fit into the available 23-bits, so divide the number by 256
|
|
|
|
// and increment the exponent accordingly.
|
|
|
|
if mantissa&0x00800000 != 0 {
|
|
|
|
mantissa >>= 8
|
|
|
|
exponent++
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pack the exponent, sign bit, and mantissa into an unsigned 32-bit
|
|
|
|
// int and return it.
|
|
|
|
compact := uint32(exponent<<24) | mantissa
|
|
|
|
if n.Sign() < 0 {
|
|
|
|
compact |= 0x00800000
|
|
|
|
}
|
|
|
|
return compact
|
|
|
|
}
|
|
|
|
|
2014-02-07 23:23:11 +01:00
|
|
|
// CalcWork calculates a work value from difficulty bits. Bitcoin increases
|
2013-07-18 16:49:28 +02:00
|
|
|
// the difficulty for generating a block by decreasing the value which the
|
|
|
|
// generated hash must be less than. This difficulty target is stored in each
|
|
|
|
// block header using a compact representation as described in the documenation
|
|
|
|
// for CompactToBig. The main chain is selected by choosing the chain that has
|
|
|
|
// the most proof of work (highest difficulty). Since a lower target difficulty
|
|
|
|
// value equates to higher actual difficulty, the work value which will be
|
|
|
|
// accumulated must be the inverse of the difficulty. Also, in order to avoid
|
2014-02-07 23:23:11 +01:00
|
|
|
// potential division by zero and really small floating point numbers, the
|
|
|
|
// result adds 1 to the denominator and multiplies the numerator by 2^256.
|
|
|
|
func CalcWork(bits uint32) *big.Int {
|
2013-07-31 19:57:54 +02:00
|
|
|
// Return a work value of zero if the passed difficulty bits represent
|
|
|
|
// a negative number. Note this should not happen in practice with valid
|
|
|
|
// blocks, but an invalid block could trigger it.
|
2013-07-18 16:49:28 +02:00
|
|
|
difficultyNum := CompactToBig(bits)
|
2013-07-31 19:57:54 +02:00
|
|
|
if difficultyNum.Sign() <= 0 {
|
|
|
|
return big.NewInt(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
// (1 << 256) / (difficultyNum + 1)
|
2013-07-18 16:49:28 +02:00
|
|
|
denominator := new(big.Int).Add(difficultyNum, bigOne)
|
2013-07-31 19:57:54 +02:00
|
|
|
return new(big.Int).Div(oneLsh256, denominator)
|
2013-07-18 16:49:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// calcEasiestDifficulty calculates the easiest possible difficulty that a block
|
|
|
|
// can have given starting difficulty bits and a duration. It is mainly used to
|
|
|
|
// verify that claimed proof of work by a block is sane as compared to a
|
|
|
|
// known good checkpoint.
|
2013-07-24 18:37:45 +02:00
|
|
|
func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 {
|
2013-07-18 16:49:28 +02:00
|
|
|
// Convert types used in the calculations below.
|
|
|
|
durationVal := int64(duration)
|
|
|
|
adjustmentFactor := big.NewInt(retargetAdjustmentFactor)
|
|
|
|
|
2013-07-24 23:43:39 +02:00
|
|
|
// The test network rules allow minimum difficulty blocks after more
|
|
|
|
// than twice the desired amount of time needed to generate a block has
|
|
|
|
// elapsed.
|
2014-05-26 17:27:50 +02:00
|
|
|
if b.netParams.ResetMinDifficulty {
|
2013-07-24 23:43:39 +02:00
|
|
|
if durationVal > int64(targetSpacing)*2 {
|
2014-05-26 17:27:50 +02:00
|
|
|
return b.netParams.PowLimitBits
|
2013-07-24 23:43:39 +02:00
|
|
|
}
|
|
|
|
}
|
2013-07-18 16:49:28 +02:00
|
|
|
|
|
|
|
// Since easier difficulty equates to higher numbers, the easiest
|
|
|
|
// difficulty for a given duration is the largest value possible given
|
|
|
|
// the number of retargets for the duration and starting difficulty
|
|
|
|
// multiplied by the max adjustment factor.
|
|
|
|
newTarget := CompactToBig(bits)
|
2014-05-26 17:27:50 +02:00
|
|
|
for durationVal > 0 && newTarget.Cmp(b.netParams.PowLimit) < 0 {
|
2013-07-18 16:49:28 +02:00
|
|
|
newTarget.Mul(newTarget, adjustmentFactor)
|
|
|
|
durationVal -= maxRetargetTimespan
|
|
|
|
}
|
|
|
|
|
|
|
|
// Limit new value to the proof of work limit.
|
2014-05-26 17:27:50 +02:00
|
|
|
if newTarget.Cmp(b.netParams.PowLimit) > 0 {
|
|
|
|
newTarget.Set(b.netParams.PowLimit)
|
2013-07-18 16:49:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return BigToCompact(newTarget)
|
|
|
|
}
|
|
|
|
|
2013-07-24 23:43:39 +02:00
|
|
|
// findPrevTestNetDifficulty returns the difficulty of the previous block which
|
|
|
|
// did not have the special testnet minimum difficulty rule applied.
|
|
|
|
func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, error) {
|
|
|
|
// Search backwards through the chain for the last block without
|
|
|
|
// the special rule applied.
|
|
|
|
iterNode := startNode
|
2014-05-26 17:27:50 +02:00
|
|
|
for iterNode != nil && iterNode.height%BlocksPerRetarget != 0 &&
|
|
|
|
iterNode.bits == b.netParams.PowLimitBits {
|
|
|
|
|
2013-07-24 23:43:39 +02:00
|
|
|
// Get the previous block node. This function is used over
|
|
|
|
// simply accessing iterNode.parent directly as it will
|
|
|
|
// dynamically create previous block nodes as needed. This
|
|
|
|
// helps allow only the pieces of the chain that are needed
|
|
|
|
// to remain in memory.
|
|
|
|
var err error
|
|
|
|
iterNode, err = b.getPrevNodeFromNode(iterNode)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("getPrevNodeFromNode: %v", err)
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the found difficulty or the minimum difficulty if no
|
|
|
|
// appropriate block was found.
|
2014-05-26 17:27:50 +02:00
|
|
|
lastBits := b.netParams.PowLimitBits
|
2013-07-24 23:43:39 +02:00
|
|
|
if iterNode != nil {
|
|
|
|
lastBits = iterNode.bits
|
|
|
|
}
|
|
|
|
return lastBits, nil
|
|
|
|
}
|
|
|
|
|
2013-07-18 16:49:28 +02:00
|
|
|
// calcNextRequiredDifficulty calculates the required difficulty for the block
|
|
|
|
// after the passed previous block node based on the difficulty retarget rules.
|
2014-03-02 19:17:36 +01:00
|
|
|
// 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) {
|
2013-07-18 16:49:28 +02:00
|
|
|
// Genesis block.
|
|
|
|
if lastNode == nil {
|
2014-05-26 17:27:50 +02:00
|
|
|
return b.netParams.PowLimitBits, nil
|
2013-07-18 16:49:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the previous block's difficulty requirements if this block
|
|
|
|
// is not at a difficulty retarget interval.
|
2014-02-07 23:23:11 +01:00
|
|
|
if (lastNode.height+1)%BlocksPerRetarget != 0 {
|
2013-07-24 23:43:39 +02:00
|
|
|
// The test network rules allow minimum difficulty blocks after
|
|
|
|
// more than twice the desired amount of time needed to generate
|
|
|
|
// a block has elapsed.
|
2014-05-26 17:27:50 +02:00
|
|
|
if b.netParams.ResetMinDifficulty {
|
2013-07-24 23:43:39 +02:00
|
|
|
// Return minimum difficulty when more than twice the
|
|
|
|
// desired amount of time needed to generate a block has
|
|
|
|
// elapsed.
|
|
|
|
allowMinTime := lastNode.timestamp.Add(targetSpacing * 2)
|
|
|
|
if newBlockTime.After(allowMinTime) {
|
2014-05-26 17:27:50 +02:00
|
|
|
return b.netParams.PowLimitBits, nil
|
2013-07-24 23:43:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// The block was mined within the desired timeframe, so
|
|
|
|
// return the difficulty for the last block which did
|
|
|
|
// not have the special minimum difficulty rule applied.
|
|
|
|
prevBits, err := b.findPrevTestNetDifficulty(lastNode)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return prevBits, nil
|
2014-05-26 17:27:50 +02:00
|
|
|
}
|
2013-07-24 23:43:39 +02:00
|
|
|
|
|
|
|
// For the main network (or any unrecognized networks), simply
|
2014-05-26 17:27:50 +02:00
|
|
|
// return the previous block's difficulty requirements.
|
|
|
|
return lastNode.bits, nil
|
2013-07-18 16:49:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get the block node at the previous retarget (targetTimespan days
|
|
|
|
// worth of blocks).
|
|
|
|
firstNode := lastNode
|
2014-02-07 23:23:11 +01:00
|
|
|
for i := int64(0); i < BlocksPerRetarget-1 && firstNode != nil; i++ {
|
2013-07-18 16:49:28 +02:00
|
|
|
// Get the previous block node. This function is used over
|
|
|
|
// simply accessing firstNode.parent directly as it will
|
|
|
|
// dynamically create previous block nodes as needed. This
|
|
|
|
// helps allow only the pieces of the chain that are needed
|
|
|
|
// to remain in memory.
|
|
|
|
var err error
|
|
|
|
firstNode, err = b.getPrevNodeFromNode(firstNode)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if firstNode == nil {
|
|
|
|
return 0, fmt.Errorf("unable to obtain previous retarget block")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Limit the amount of adjustment that can occur to the previous
|
|
|
|
// difficulty.
|
|
|
|
actualTimespan := lastNode.timestamp.UnixNano() - firstNode.timestamp.UnixNano()
|
|
|
|
adjustedTimespan := actualTimespan
|
|
|
|
if actualTimespan < minRetargetTimespan {
|
|
|
|
adjustedTimespan = minRetargetTimespan
|
|
|
|
} else if actualTimespan > maxRetargetTimespan {
|
|
|
|
adjustedTimespan = maxRetargetTimespan
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate new target difficulty as:
|
|
|
|
// currentDifficulty * (adjustedTimespan / targetTimespan)
|
|
|
|
// The result uses integer division which means it will be slightly
|
|
|
|
// rounded down. Bitcoind also uses integer division to calculate this
|
|
|
|
// result.
|
|
|
|
oldTarget := CompactToBig(lastNode.bits)
|
|
|
|
newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan))
|
|
|
|
newTarget.Div(newTarget, big.NewInt(int64(targetTimespan)))
|
|
|
|
|
|
|
|
// Limit new value to the proof of work limit.
|
2014-05-26 17:27:50 +02:00
|
|
|
if newTarget.Cmp(b.netParams.PowLimit) > 0 {
|
|
|
|
newTarget.Set(b.netParams.PowLimit)
|
2013-07-18 16:49:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Log new target difficulty and return it. The new target logging is
|
|
|
|
// intentionally converting the bits back to a number instead of using
|
|
|
|
// newTarget since conversion to the compact representation loses
|
|
|
|
// precision.
|
|
|
|
newTargetBits := BigToCompact(newTarget)
|
|
|
|
log.Debugf("Difficulty retarget at block height %d", lastNode.height+1)
|
|
|
|
log.Debugf("Old target %08x (%064x)", lastNode.bits, oldTarget)
|
|
|
|
log.Debugf("New target %08x (%064x)", newTargetBits, CompactToBig(newTargetBits))
|
|
|
|
log.Debugf("Actual timespan %v, adjusted timespan %v, target timespan %v",
|
|
|
|
time.Duration(actualTimespan), time.Duration(adjustedTimespan),
|
|
|
|
targetTimespan)
|
|
|
|
|
|
|
|
return newTargetBits, nil
|
|
|
|
}
|
2014-03-02 19:17:36 +01:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|