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 }