github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/btcutil/blockchain/difficulty.go (about)

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