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