github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/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/dashpay/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 }