github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/blockchain/difficulty.go (about)

     1  // Copyright (c) 2013-2016 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package blockchain
     7  
     8  import (
     9  	"math/big"
    10  	"time"
    11  
    12  	"github.com/BlockABC/godash/wire"
    13  )
    14  
    15  const (
    16  	// targetTimespan is the desired amount of time that should elapse
    17  	// before block difficulty requirement is examined to determine how
    18  	// it should be changed in order to maintain the desired block
    19  	// generation rate.
    20  	targetTimespan = time.Hour * 24 * 14
    21  
    22  	// targetSpacing is the desired amount of time to generate each block.
    23  	targetSpacing = time.Minute * 10
    24  
    25  	// BlocksPerRetarget is the number of blocks between each difficulty
    26  	// retarget.  It is calculated based on the desired block generation
    27  	// rate.
    28  	BlocksPerRetarget = int32(targetTimespan / targetSpacing)
    29  
    30  	// retargetAdjustmentFactor is the adjustment factor used to limit
    31  	// the minimum and maximum amount of adjustment that can occur between
    32  	// difficulty retargets.
    33  	retargetAdjustmentFactor = 4
    34  
    35  	// minRetargetTimespan is the minimum amount of adjustment that can
    36  	// occur between difficulty retargets.  It equates to 25% of the
    37  	// previous difficulty.
    38  	minRetargetTimespan = int64(targetTimespan / retargetAdjustmentFactor)
    39  
    40  	// maxRetargetTimespan is the maximum amount of adjustment that can
    41  	// occur between difficulty retargets.  It equates to 400% of the
    42  	// previous difficulty.
    43  	maxRetargetTimespan = int64(targetTimespan * retargetAdjustmentFactor)
    44  )
    45  
    46  var (
    47  	// bigOne is 1 represented as a big.Int.  It is defined here to avoid
    48  	// the overhead of creating it multiple times.
    49  	bigOne = big.NewInt(1)
    50  
    51  	// oneLsh256 is 1 shifted left 256 bits.  It is defined here to avoid
    52  	// the overhead of creating it multiple times.
    53  	oneLsh256 = new(big.Int).Lsh(bigOne, 256)
    54  )
    55  
    56  // ShaHashToBig converts a wire.ShaHash into a big.Int that can be used to
    57  // perform math comparisons.
    58  func ShaHashToBig(hash *wire.ShaHash) *big.Int {
    59  	// A ShaHash is in little-endian, but the big package wants the bytes
    60  	// in big-endian, so reverse them.
    61  	buf := *hash
    62  	blen := len(buf)
    63  	for i := 0; i < blen/2; i++ {
    64  		buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
    65  	}
    66  
    67  	return new(big.Int).SetBytes(buf[:])
    68  }
    69  
    70  // CompactToBig converts a compact representation of a whole number N to an
    71  // unsigned 32-bit number.  The representation is similar to IEEE754 floating
    72  // point numbers.
    73  //
    74  // Like IEEE754 floating point, there are three basic components: the sign,
    75  // the exponent, and the mantissa.  They are broken out as follows:
    76  //
    77  //	* the most significant 8 bits represent the unsigned base 256 exponent
    78  // 	* bit 23 (the 24th bit) represents the sign bit
    79  //	* the least significant 23 bits represent the mantissa
    80  //
    81  //	-------------------------------------------------
    82  //	|   Exponent     |    Sign    |    Mantissa     |
    83  //	-------------------------------------------------
    84  //	| 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] |
    85  //	-------------------------------------------------
    86  //
    87  // The formula to calculate N is:
    88  // 	N = (-1^sign) * mantissa * 256^(exponent-3)
    89  //
    90  // This compact form is only used in bitcoin to encode unsigned 256-bit numbers
    91  // which represent difficulty targets, thus there really is not a need for a
    92  // sign bit, but it is implemented here to stay consistent with bitcoind.
    93  func CompactToBig(compact uint32) *big.Int {
    94  	// Extract the mantissa, sign bit, and exponent.
    95  	mantissa := compact & 0x007fffff
    96  	isNegative := compact&0x00800000 != 0
    97  	exponent := uint(compact >> 24)
    98  
    99  	// Since the base for the exponent is 256, the exponent can be treated
   100  	// as the number of bytes to represent the full 256-bit number.  So,
   101  	// treat the exponent as the number of bytes and shift the mantissa
   102  	// right or left accordingly.  This is equivalent to:
   103  	// N = mantissa * 256^(exponent-3)
   104  	var bn *big.Int
   105  	if exponent <= 3 {
   106  		mantissa >>= 8 * (3 - exponent)
   107  		bn = big.NewInt(int64(mantissa))
   108  	} else {
   109  		bn = big.NewInt(int64(mantissa))
   110  		bn.Lsh(bn, 8*(exponent-3))
   111  	}
   112  
   113  	// Make it negative if the sign bit is set.
   114  	if isNegative {
   115  		bn = bn.Neg(bn)
   116  	}
   117  
   118  	return bn
   119  }
   120  
   121  // BigToCompact converts a whole number N to a compact representation using
   122  // an unsigned 32-bit number.  The compact representation only provides 23 bits
   123  // of precision, so values larger than (2^23 - 1) only encode the most
   124  // significant digits of the number.  See CompactToBig for details.
   125  func BigToCompact(n *big.Int) uint32 {
   126  	// No need to do any work if it's zero.
   127  	if n.Sign() == 0 {
   128  		return 0
   129  	}
   130  
   131  	// Since the base for the exponent is 256, the exponent can be treated
   132  	// as the number of bytes.  So, shift the number right or left
   133  	// accordingly.  This is equivalent to:
   134  	// mantissa = mantissa / 256^(exponent-3)
   135  	var mantissa uint32
   136  	exponent := uint(len(n.Bytes()))
   137  	if exponent <= 3 {
   138  		mantissa = uint32(n.Bits()[0])
   139  		mantissa <<= 8 * (3 - exponent)
   140  	} else {
   141  		// Use a copy to avoid modifying the caller's original number.
   142  		tn := new(big.Int).Set(n)
   143  		mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0])
   144  	}
   145  
   146  	// When the mantissa already has the sign bit set, the number is too
   147  	// large to fit into the available 23-bits, so divide the number by 256
   148  	// and increment the exponent accordingly.
   149  	if mantissa&0x00800000 != 0 {
   150  		mantissa >>= 8
   151  		exponent++
   152  	}
   153  
   154  	// Pack the exponent, sign bit, and mantissa into an unsigned 32-bit
   155  	// int and return it.
   156  	compact := uint32(exponent<<24) | mantissa
   157  	if n.Sign() < 0 {
   158  		compact |= 0x00800000
   159  	}
   160  	return compact
   161  }
   162  
   163  // CalcWork calculates a work value from difficulty bits.  Bitcoin increases
   164  // the difficulty for generating a block by decreasing the value which the
   165  // generated hash must be less than.  This difficulty target is stored in each
   166  // block header using a compact representation as described in the documentation
   167  // for CompactToBig.  The main chain is selected by choosing the chain that has
   168  // the most proof of work (highest difficulty).  Since a lower target difficulty
   169  // value equates to higher actual difficulty, the work value which will be
   170  // accumulated must be the inverse of the difficulty.  Also, in order to avoid
   171  // potential division by zero and really small floating point numbers, the
   172  // result adds 1 to the denominator and multiplies the numerator by 2^256.
   173  func CalcWork(bits uint32) *big.Int {
   174  	// Return a work value of zero if the passed difficulty bits represent
   175  	// a negative number. Note this should not happen in practice with valid
   176  	// blocks, but an invalid block could trigger it.
   177  	difficultyNum := CompactToBig(bits)
   178  	if difficultyNum.Sign() <= 0 {
   179  		return big.NewInt(0)
   180  	}
   181  
   182  	// (1 << 256) / (difficultyNum + 1)
   183  	denominator := new(big.Int).Add(difficultyNum, bigOne)
   184  	return new(big.Int).Div(oneLsh256, denominator)
   185  }
   186  
   187  // calcEasiestDifficulty calculates the easiest possible difficulty that a block
   188  // can have given starting difficulty bits and a duration.  It is mainly used to
   189  // verify that claimed proof of work by a block is sane as compared to a
   190  // known good checkpoint.
   191  func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 {
   192  	// Convert types used in the calculations below.
   193  	durationVal := int64(duration)
   194  	adjustmentFactor := big.NewInt(retargetAdjustmentFactor)
   195  
   196  	// The test network rules allow minimum difficulty blocks after more
   197  	// than twice the desired amount of time needed to generate a block has
   198  	// elapsed.
   199  	if b.chainParams.ResetMinDifficulty {
   200  		if durationVal > int64(targetSpacing)*2 {
   201  			return b.chainParams.PowLimitBits
   202  		}
   203  	}
   204  
   205  	// Since easier difficulty equates to higher numbers, the easiest
   206  	// difficulty for a given duration is the largest value possible given
   207  	// the number of retargets for the duration and starting difficulty
   208  	// multiplied by the max adjustment factor.
   209  	newTarget := CompactToBig(bits)
   210  	for durationVal > 0 && newTarget.Cmp(b.chainParams.PowLimit) < 0 {
   211  		newTarget.Mul(newTarget, adjustmentFactor)
   212  		durationVal -= maxRetargetTimespan
   213  	}
   214  
   215  	// Limit new value to the proof of work limit.
   216  	if newTarget.Cmp(b.chainParams.PowLimit) > 0 {
   217  		newTarget.Set(b.chainParams.PowLimit)
   218  	}
   219  
   220  	return BigToCompact(newTarget)
   221  }
   222  
   223  // findPrevTestNetDifficulty returns the difficulty of the previous block which
   224  // did not have the special testnet minimum difficulty rule applied.
   225  //
   226  // This function MUST be called with the chain state lock held (for writes).
   227  func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) (uint32, error) {
   228  	// Search backwards through the chain for the last block without
   229  	// the special rule applied.
   230  	iterNode := startNode
   231  	for iterNode != nil && iterNode.height%BlocksPerRetarget != 0 &&
   232  		iterNode.bits == b.chainParams.PowLimitBits {
   233  
   234  		// Get the previous block node.  This function is used over
   235  		// simply accessing iterNode.parent directly as it will
   236  		// dynamically create previous block nodes as needed.  This
   237  		// helps allow only the pieces of the chain that are needed
   238  		// to remain in memory.
   239  		var err error
   240  		iterNode, err = b.getPrevNodeFromNode(iterNode)
   241  		if err != nil {
   242  			log.Errorf("getPrevNodeFromNode: %v", err)
   243  			return 0, err
   244  		}
   245  	}
   246  
   247  	// Return the found difficulty or the minimum difficulty if no
   248  	// appropriate block was found.
   249  	lastBits := b.chainParams.PowLimitBits
   250  	if iterNode != nil {
   251  		lastBits = iterNode.bits
   252  	}
   253  	return lastBits, nil
   254  }
   255  
   256  // calcNextRequiredDifficulty calculates the required difficulty for the block
   257  // after the passed previous block node based on the difficulty retarget rules.
   258  // This function differs from the exported CalcNextRequiredDifficulty in that
   259  // the exported version uses the current best chain as the previous block node
   260  // while this function accepts any block node.
   261  //
   262  // This function MUST be called with the chain state lock held (for writes).
   263  func (b *BlockChain) calcNextRequiredDifficulty(lastNode *blockNode, newBlockTime time.Time) (uint32, error) {
   264  	// Genesis block.
   265  	if lastNode == nil {
   266  		return b.chainParams.PowLimitBits, nil
   267  	}
   268  
   269  	// Return the previous block's difficulty requirements if this block
   270  	// is not at a difficulty retarget interval.
   271  	if (lastNode.height+1)%BlocksPerRetarget != 0 {
   272  		// The test network rules allow minimum difficulty blocks after
   273  		// more than twice the desired amount of time needed to generate
   274  		// a block has elapsed.
   275  		if b.chainParams.ResetMinDifficulty {
   276  			// Return minimum difficulty when more than twice the
   277  			// desired amount of time needed to generate a block has
   278  			// elapsed.
   279  			allowMinTime := lastNode.timestamp.Add(targetSpacing * 2)
   280  			if newBlockTime.After(allowMinTime) {
   281  				return b.chainParams.PowLimitBits, nil
   282  			}
   283  
   284  			// The block was mined within the desired timeframe, so
   285  			// return the difficulty for the last block which did
   286  			// not have the special minimum difficulty rule applied.
   287  			prevBits, err := b.findPrevTestNetDifficulty(lastNode)
   288  			if err != nil {
   289  				return 0, err
   290  			}
   291  			return prevBits, nil
   292  		}
   293  
   294  		// For the main network (or any unrecognized networks), simply
   295  		// return the previous block's difficulty requirements.
   296  		return lastNode.bits, nil
   297  	}
   298  
   299  	// Get the block node at the previous retarget (targetTimespan days
   300  	// worth of blocks).
   301  	firstNode := lastNode
   302  	for i := int32(0); i < BlocksPerRetarget-1 && firstNode != nil; i++ {
   303  		// Get the previous block node.  This function is used over
   304  		// simply accessing firstNode.parent directly as it will
   305  		// dynamically create previous block nodes as needed.  This
   306  		// helps allow only the pieces of the chain that are needed
   307  		// to remain in memory.
   308  		var err error
   309  		firstNode, err = b.getPrevNodeFromNode(firstNode)
   310  		if err != nil {
   311  			return 0, err
   312  		}
   313  	}
   314  
   315  	if firstNode == nil {
   316  		return 0, AssertError("unable to obtain previous retarget block")
   317  	}
   318  
   319  	// Limit the amount of adjustment that can occur to the previous
   320  	// difficulty.
   321  	actualTimespan := lastNode.timestamp.UnixNano() - firstNode.timestamp.UnixNano()
   322  	adjustedTimespan := actualTimespan
   323  	if actualTimespan < minRetargetTimespan {
   324  		adjustedTimespan = minRetargetTimespan
   325  	} else if actualTimespan > maxRetargetTimespan {
   326  		adjustedTimespan = maxRetargetTimespan
   327  	}
   328  
   329  	// Calculate new target difficulty as:
   330  	//  currentDifficulty * (adjustedTimespan / targetTimespan)
   331  	// The result uses integer division which means it will be slightly
   332  	// rounded down.  Bitcoind also uses integer division to calculate this
   333  	// result.
   334  	oldTarget := CompactToBig(lastNode.bits)
   335  	newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan))
   336  	newTarget.Div(newTarget, big.NewInt(int64(targetTimespan)))
   337  
   338  	// Limit new value to the proof of work limit.
   339  	if newTarget.Cmp(b.chainParams.PowLimit) > 0 {
   340  		newTarget.Set(b.chainParams.PowLimit)
   341  	}
   342  
   343  	// Log new target difficulty and return it.  The new target logging is
   344  	// intentionally converting the bits back to a number instead of using
   345  	// newTarget since conversion to the compact representation loses
   346  	// precision.
   347  	newTargetBits := BigToCompact(newTarget)
   348  	log.Debugf("Difficulty retarget at block height %d", lastNode.height+1)
   349  	log.Debugf("Old target %08x (%064x)", lastNode.bits, oldTarget)
   350  	log.Debugf("New target %08x (%064x)", newTargetBits, CompactToBig(newTargetBits))
   351  	log.Debugf("Actual timespan %v, adjusted timespan %v, target timespan %v",
   352  		time.Duration(actualTimespan), time.Duration(adjustedTimespan),
   353  		targetTimespan)
   354  
   355  	return newTargetBits, nil
   356  }
   357  
   358  // CalcNextRequiredDifficulty calculates the required difficulty for the block
   359  // after the end of the current best chain based on the difficulty retarget
   360  // rules.
   361  //
   362  // This function is safe for concurrent access.
   363  func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error) {
   364  	b.chainLock.Lock()
   365  	difficulty, err := b.calcNextRequiredDifficulty(b.bestNode, timestamp)
   366  	b.chainLock.Unlock()
   367  	return difficulty, err
   368  }