github.com/btcsuite/btcd@v0.24.0/blockchain/difficulty.go (about) 1 // Copyright (c) 2013-2017 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/btcsuite/btcd/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 // 57 // N = (-1^sign) * mantissa * 256^(exponent-3) 58 // 59 // This compact form is only used in bitcoin to encode unsigned 256-bit numbers 60 // which represent difficulty targets, thus there really is not a need for a 61 // sign bit, but it is implemented here to stay consistent with bitcoind. 62 func CompactToBig(compact uint32) *big.Int { 63 // Extract the mantissa, sign bit, and exponent. 64 mantissa := compact & 0x007fffff 65 isNegative := compact&0x00800000 != 0 66 exponent := uint(compact >> 24) 67 68 // Since the base for the exponent is 256, the exponent can be treated 69 // as the number of bytes to represent the full 256-bit number. So, 70 // treat the exponent as the number of bytes and shift the mantissa 71 // right or left accordingly. This is equivalent to: 72 // N = mantissa * 256^(exponent-3) 73 var bn *big.Int 74 if exponent <= 3 { 75 mantissa >>= 8 * (3 - exponent) 76 bn = big.NewInt(int64(mantissa)) 77 } else { 78 bn = big.NewInt(int64(mantissa)) 79 bn.Lsh(bn, 8*(exponent-3)) 80 } 81 82 // Make it negative if the sign bit is set. 83 if isNegative { 84 bn = bn.Neg(bn) 85 } 86 87 return bn 88 } 89 90 // BigToCompact converts a whole number N to a compact representation using 91 // an unsigned 32-bit number. The compact representation only provides 23 bits 92 // of precision, so values larger than (2^23 - 1) only encode the most 93 // significant digits of the number. See CompactToBig for details. 94 func BigToCompact(n *big.Int) uint32 { 95 // No need to do any work if it's zero. 96 if n.Sign() == 0 { 97 return 0 98 } 99 100 // Since the base for the exponent is 256, the exponent can be treated 101 // as the number of bytes. So, shift the number right or left 102 // accordingly. This is equivalent to: 103 // mantissa = mantissa / 256^(exponent-3) 104 var mantissa uint32 105 exponent := uint(len(n.Bytes())) 106 if exponent <= 3 { 107 mantissa = uint32(n.Bits()[0]) 108 mantissa <<= 8 * (3 - exponent) 109 } else { 110 // Use a copy to avoid modifying the caller's original number. 111 tn := new(big.Int).Set(n) 112 mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0]) 113 } 114 115 // When the mantissa already has the sign bit set, the number is too 116 // large to fit into the available 23-bits, so divide the number by 256 117 // and increment the exponent accordingly. 118 if mantissa&0x00800000 != 0 { 119 mantissa >>= 8 120 exponent++ 121 } 122 123 // Pack the exponent, sign bit, and mantissa into an unsigned 32-bit 124 // int and return it. 125 compact := uint32(exponent<<24) | mantissa 126 if n.Sign() < 0 { 127 compact |= 0x00800000 128 } 129 return compact 130 } 131 132 // CalcWork calculates a work value from difficulty bits. Bitcoin increases 133 // the difficulty for generating a block by decreasing the value which the 134 // generated hash must be less than. This difficulty target is stored in each 135 // block header using a compact representation as described in the documentation 136 // for CompactToBig. The main chain is selected by choosing the chain that has 137 // the most proof of work (highest difficulty). Since a lower target difficulty 138 // value equates to higher actual difficulty, the work value which will be 139 // accumulated must be the inverse of the difficulty. Also, in order to avoid 140 // potential division by zero and really small floating point numbers, the 141 // result adds 1 to the denominator and multiplies the numerator by 2^256. 142 func CalcWork(bits uint32) *big.Int { 143 // Return a work value of zero if the passed difficulty bits represent 144 // a negative number. Note this should not happen in practice with valid 145 // blocks, but an invalid block could trigger it. 146 difficultyNum := CompactToBig(bits) 147 if difficultyNum.Sign() <= 0 { 148 return big.NewInt(0) 149 } 150 151 // (1 << 256) / (difficultyNum + 1) 152 denominator := new(big.Int).Add(difficultyNum, bigOne) 153 return new(big.Int).Div(oneLsh256, denominator) 154 } 155 156 // calcEasiestDifficulty calculates the easiest possible difficulty that a block 157 // can have given starting difficulty bits and a duration. It is mainly used to 158 // verify that claimed proof of work by a block is sane as compared to a 159 // known good checkpoint. 160 func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { 161 // Convert types used in the calculations below. 162 durationVal := int64(duration / time.Second) 163 adjustmentFactor := big.NewInt(b.chainParams.RetargetAdjustmentFactor) 164 165 // The test network rules allow minimum difficulty blocks after more 166 // than twice the desired amount of time needed to generate a block has 167 // elapsed. 168 if b.chainParams.ReduceMinDifficulty { 169 reductionTime := int64(b.chainParams.MinDiffReductionTime / 170 time.Second) 171 if durationVal > reductionTime { 172 return b.chainParams.PowLimitBits 173 } 174 } 175 176 // Since easier difficulty equates to higher numbers, the easiest 177 // difficulty for a given duration is the largest value possible given 178 // the number of retargets for the duration and starting difficulty 179 // multiplied by the max adjustment factor. 180 newTarget := CompactToBig(bits) 181 for durationVal > 0 && newTarget.Cmp(b.chainParams.PowLimit) < 0 { 182 newTarget.Mul(newTarget, adjustmentFactor) 183 durationVal -= b.maxRetargetTimespan 184 } 185 186 // Limit new value to the proof of work limit. 187 if newTarget.Cmp(b.chainParams.PowLimit) > 0 { 188 newTarget.Set(b.chainParams.PowLimit) 189 } 190 191 return BigToCompact(newTarget) 192 } 193 194 // findPrevTestNetDifficulty returns the difficulty of the previous block which 195 // did not have the special testnet minimum difficulty rule applied. 196 func findPrevTestNetDifficulty(startNode HeaderCtx, c ChainCtx) uint32 { 197 // Search backwards through the chain for the last block without 198 // the special rule applied. 199 iterNode := startNode 200 for iterNode != nil && iterNode.Height()%c.BlocksPerRetarget() != 0 && 201 iterNode.Bits() == c.ChainParams().PowLimitBits { 202 203 iterNode = iterNode.Parent() 204 } 205 206 // Return the found difficulty or the minimum difficulty if no 207 // appropriate block was found. 208 lastBits := c.ChainParams().PowLimitBits 209 if iterNode != nil { 210 lastBits = iterNode.Bits() 211 } 212 return lastBits 213 } 214 215 // calcNextRequiredDifficulty calculates the required difficulty for the block 216 // after the passed previous HeaderCtx based on the difficulty retarget rules. 217 // This function differs from the exported CalcNextRequiredDifficulty in that 218 // the exported version uses the current best chain as the previous HeaderCtx 219 // while this function accepts any block node. This function accepts a ChainCtx 220 // parameter that gives the necessary difficulty context variables. 221 func calcNextRequiredDifficulty(lastNode HeaderCtx, newBlockTime time.Time, 222 c ChainCtx) (uint32, error) { 223 224 // Emulate the same behavior as Bitcoin Core that for regtest there is 225 // no difficulty retargeting. 226 if c.ChainParams().PoWNoRetargeting { 227 return c.ChainParams().PowLimitBits, nil 228 } 229 230 // Genesis block. 231 if lastNode == nil { 232 return c.ChainParams().PowLimitBits, nil 233 } 234 235 // Return the previous block's difficulty requirements if this block 236 // is not at a difficulty retarget interval. 237 if (lastNode.Height()+1)%c.BlocksPerRetarget() != 0 { 238 // For networks that support it, allow special reduction of the 239 // required difficulty once too much time has elapsed without 240 // mining a block. 241 if c.ChainParams().ReduceMinDifficulty { 242 // Return minimum difficulty when more than the desired 243 // amount of time has elapsed without mining a block. 244 reductionTime := int64(c.ChainParams().MinDiffReductionTime / 245 time.Second) 246 allowMinTime := lastNode.Timestamp() + reductionTime 247 if newBlockTime.Unix() > allowMinTime { 248 return c.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 return findPrevTestNetDifficulty(lastNode, c), nil 255 } 256 257 // For the main network (or any unrecognized networks), simply 258 // return the previous block's difficulty requirements. 259 return lastNode.Bits(), nil 260 } 261 262 // Get the block node at the previous retarget (targetTimespan days 263 // worth of blocks). 264 firstNode := lastNode.RelativeAncestorCtx(c.BlocksPerRetarget() - 1) 265 if firstNode == nil { 266 return 0, AssertError("unable to obtain previous retarget block") 267 } 268 269 // Limit the amount of adjustment that can occur to the previous 270 // difficulty. 271 actualTimespan := lastNode.Timestamp() - firstNode.Timestamp() 272 adjustedTimespan := actualTimespan 273 if actualTimespan < c.MinRetargetTimespan() { 274 adjustedTimespan = c.MinRetargetTimespan() 275 } else if actualTimespan > c.MaxRetargetTimespan() { 276 adjustedTimespan = c.MaxRetargetTimespan() 277 } 278 279 // Calculate new target difficulty as: 280 // currentDifficulty * (adjustedTimespan / targetTimespan) 281 // The result uses integer division which means it will be slightly 282 // rounded down. Bitcoind also uses integer division to calculate this 283 // result. 284 oldTarget := CompactToBig(lastNode.Bits()) 285 newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan)) 286 targetTimeSpan := int64(c.ChainParams().TargetTimespan / time.Second) 287 newTarget.Div(newTarget, big.NewInt(targetTimeSpan)) 288 289 // Limit new value to the proof of work limit. 290 if newTarget.Cmp(c.ChainParams().PowLimit) > 0 { 291 newTarget.Set(c.ChainParams().PowLimit) 292 } 293 294 // Log new target difficulty and return it. The new target logging is 295 // intentionally converting the bits back to a number instead of using 296 // newTarget since conversion to the compact representation loses 297 // precision. 298 newTargetBits := BigToCompact(newTarget) 299 log.Debugf("Difficulty retarget at block height %d", lastNode.Height()+1) 300 log.Debugf("Old target %08x (%064x)", lastNode.Bits(), oldTarget) 301 log.Debugf("New target %08x (%064x)", newTargetBits, CompactToBig(newTargetBits)) 302 log.Debugf("Actual timespan %v, adjusted timespan %v, target timespan %v", 303 time.Duration(actualTimespan)*time.Second, 304 time.Duration(adjustedTimespan)*time.Second, 305 c.ChainParams().TargetTimespan) 306 307 return newTargetBits, nil 308 } 309 310 // CalcNextRequiredDifficulty calculates the required difficulty for the block 311 // after the end of the current best chain based on the difficulty retarget 312 // rules. 313 // 314 // This function is safe for concurrent access. 315 func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error) { 316 b.chainLock.Lock() 317 difficulty, err := calcNextRequiredDifficulty(b.bestChain.Tip(), timestamp, b) 318 b.chainLock.Unlock() 319 return difficulty, err 320 }