github.com/decred/dcrd/blockchain@v1.2.1/difficulty.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Copyright (c) 2015-2018 The Decred 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 "fmt" 10 "math/big" 11 "time" 12 13 "github.com/decred/dcrd/blockchain/standalone" 14 "github.com/decred/dcrd/chaincfg" 15 "github.com/decred/dcrd/chaincfg/chainhash" 16 "github.com/decred/dcrd/wire" 17 ) 18 19 var ( 20 // bigZero is 0 represented as a big.Int. It is defined here to avoid 21 // the overhead of creating it multiple times. 22 bigZero = big.NewInt(0) 23 24 // bigOne is 1 represented as a big.Int. It is defined here to avoid 25 // the overhead of creating it multiple times. 26 bigOne = big.NewInt(1) 27 28 // oneLsh256 is 1 shifted left 256 bits. It is defined here to avoid 29 // the overhead of creating it multiple times. 30 oneLsh256 = new(big.Int).Lsh(bigOne, 256) 31 ) 32 33 // HashToBig converts a chainhash.Hash into a big.Int that can be used to 34 // perform math comparisons. 35 // 36 // Deprecated: Use standalone.HashToBig instead. 37 func HashToBig(hash *chainhash.Hash) *big.Int { 38 return standalone.HashToBig(hash) 39 } 40 41 // CompactToBig converts a compact representation of a whole number N to an 42 // unsigned 32-bit number. The representation is similar to IEEE754 floating 43 // point numbers. 44 // 45 // Like IEEE754 floating point, there are three basic components: the sign, 46 // the exponent, and the mantissa. They are broken out as follows: 47 // 48 // * the most significant 8 bits represent the unsigned base 256 exponent 49 // * bit 23 (the 24th bit) represents the sign bit 50 // * the least significant 23 bits represent the mantissa 51 // 52 // ------------------------------------------------- 53 // | Exponent | Sign | Mantissa | 54 // ------------------------------------------------- 55 // | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | 56 // ------------------------------------------------- 57 // 58 // The formula to calculate N is: 59 // N = (-1^sign) * mantissa * 256^(exponent-3) 60 // 61 // This compact form is only used in Decred 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 // 65 // Deprecated: Use standalone.CompactToBig instead. 66 func CompactToBig(compact uint32) *big.Int { 67 return standalone.CompactToBig(compact) 68 } 69 70 // BigToCompact converts a whole number N to a compact representation using 71 // an unsigned 32-bit number. The compact representation only provides 23 bits 72 // of precision, so values larger than (2^23 - 1) only encode the most 73 // significant digits of the number. See CompactToBig for details. 74 // 75 // Deprecated: Use standalone.BigToCompact instead. 76 func BigToCompact(n *big.Int) uint32 { 77 return standalone.BigToCompact(n) 78 } 79 80 // CalcWork calculates a work value from difficulty bits. Decred increases 81 // the difficulty for generating a block by decreasing the value which the 82 // generated hash must be less than. This difficulty target is stored in each 83 // block header using a compact representation as described in the documentation 84 // for CompactToBig. The main chain is selected by choosing the chain that has 85 // the most proof of work (highest difficulty). Since a lower target difficulty 86 // value equates to higher actual difficulty, the work value which will be 87 // accumulated must be the inverse of the difficulty. Also, in order to avoid 88 // potential division by zero and really small floating point numbers, the 89 // result adds 1 to the denominator and multiplies the numerator by 2^256. 90 // 91 // Deprecated: Use standalone.CalcWork instead. 92 func CalcWork(bits uint32) *big.Int { 93 return standalone.CalcWork(bits) 94 } 95 96 // calcEasiestDifficulty calculates the easiest possible difficulty that a block 97 // can have given starting difficulty bits and a duration. It is mainly used to 98 // verify that claimed proof of work by a block is sane as compared to a 99 // known good checkpoint. 100 func (b *BlockChain) calcEasiestDifficulty(bits uint32, duration time.Duration) uint32 { 101 // Convert types used in the calculations below. 102 durationVal := int64(duration) 103 adjustmentFactor := big.NewInt(b.chainParams.RetargetAdjustmentFactor) 104 maxRetargetTimespan := int64(b.chainParams.TargetTimespan) * 105 b.chainParams.RetargetAdjustmentFactor 106 107 // The test network rules allow minimum difficulty blocks once too much 108 // time has elapsed without mining a block. 109 if b.chainParams.ReduceMinDifficulty { 110 if durationVal > int64(b.chainParams.MinDiffReductionTime) { 111 return b.chainParams.PowLimitBits 112 } 113 } 114 115 // Since easier difficulty equates to higher numbers, the easiest 116 // difficulty for a given duration is the largest value possible given 117 // the number of retargets for the duration and starting difficulty 118 // multiplied by the max adjustment factor. 119 newTarget := standalone.CompactToBig(bits) 120 for durationVal > 0 && newTarget.Cmp(b.chainParams.PowLimit) < 0 { 121 newTarget.Mul(newTarget, adjustmentFactor) 122 durationVal -= maxRetargetTimespan 123 } 124 125 // Limit new value to the proof of work limit. 126 if newTarget.Cmp(b.chainParams.PowLimit) > 0 { 127 newTarget.Set(b.chainParams.PowLimit) 128 } 129 130 return standalone.BigToCompact(newTarget) 131 } 132 133 // findPrevTestNetDifficulty returns the difficulty of the previous block which 134 // did not have the special testnet minimum difficulty rule applied. 135 // 136 // This function MUST be called with the chain state lock held (for writes). 137 func (b *BlockChain) findPrevTestNetDifficulty(startNode *blockNode) uint32 { 138 // Search backwards through the chain for the last block without 139 // the special rule applied. 140 blocksPerRetarget := b.chainParams.WorkDiffWindowSize * 141 b.chainParams.WorkDiffWindows 142 iterNode := startNode 143 for iterNode != nil && iterNode.height%blocksPerRetarget != 0 && 144 iterNode.bits == b.chainParams.PowLimitBits { 145 146 iterNode = iterNode.parent 147 } 148 149 // Return the found difficulty or the minimum difficulty if no 150 // appropriate block was found. 151 lastBits := b.chainParams.PowLimitBits 152 if iterNode != nil { 153 lastBits = iterNode.bits 154 } 155 return lastBits 156 } 157 158 // calcNextRequiredDifficulty calculates the required difficulty for the block 159 // after the passed previous block node based on the difficulty retarget rules. 160 // This function differs from the exported CalcNextRequiredDifficulty in that 161 // the exported version uses the current best chain as the previous block node 162 // while this function accepts any block node. 163 func (b *BlockChain) calcNextRequiredDifficulty(curNode *blockNode, newBlockTime time.Time) (uint32, error) { 164 // Get the old difficulty; if we aren't at a block height where it changes, 165 // just return this. 166 oldDiff := curNode.bits 167 oldDiffBig := standalone.CompactToBig(curNode.bits) 168 169 // We're not at a retarget point, return the oldDiff. 170 if (curNode.height+1)%b.chainParams.WorkDiffWindowSize != 0 { 171 // For networks that support it, allow special reduction of the 172 // required difficulty once too much time has elapsed without 173 // mining a block. 174 if b.chainParams.ReduceMinDifficulty { 175 // Return minimum difficulty when more than the desired 176 // amount of time has elapsed without mining a block. 177 reductionTime := int64(b.chainParams.MinDiffReductionTime / 178 time.Second) 179 allowMinTime := curNode.timestamp + reductionTime 180 if newBlockTime.Unix() > allowMinTime { 181 return b.chainParams.PowLimitBits, nil 182 } 183 184 // The block was mined within the desired timeframe, so 185 // return the difficulty for the last block which did 186 // not have the special minimum difficulty rule applied. 187 return b.findPrevTestNetDifficulty(curNode), nil 188 } 189 190 return oldDiff, nil 191 } 192 193 // Declare some useful variables. 194 RAFBig := big.NewInt(b.chainParams.RetargetAdjustmentFactor) 195 nextDiffBigMin := standalone.CompactToBig(curNode.bits) 196 nextDiffBigMin.Div(nextDiffBigMin, RAFBig) 197 nextDiffBigMax := standalone.CompactToBig(curNode.bits) 198 nextDiffBigMax.Mul(nextDiffBigMax, RAFBig) 199 200 alpha := b.chainParams.WorkDiffAlpha 201 202 // Number of nodes to traverse while calculating difficulty. 203 nodesToTraverse := (b.chainParams.WorkDiffWindowSize * 204 b.chainParams.WorkDiffWindows) 205 206 // Initialize bigInt slice for the percentage changes for each window period 207 // above or below the target. 208 windowChanges := make([]*big.Int, b.chainParams.WorkDiffWindows) 209 210 // Regress through all of the previous blocks and store the percent changes 211 // per window period; use bigInts to emulate 64.32 bit fixed point. 212 var olderTime, windowPeriod int64 213 var weights uint64 214 oldNode := curNode 215 recentTime := curNode.timestamp 216 217 for i := int64(0); ; i++ { 218 // Store and reset after reaching the end of every window period. 219 if i%b.chainParams.WorkDiffWindowSize == 0 && i != 0 { 220 olderTime = oldNode.timestamp 221 timeDifference := recentTime - olderTime 222 223 // Just assume we're at the target (no change) if we've 224 // gone all the way back to the genesis block. 225 if oldNode.height == 0 { 226 timeDifference = int64(b.chainParams.TargetTimespan / 227 time.Second) 228 } 229 230 timeDifBig := big.NewInt(timeDifference) 231 timeDifBig.Lsh(timeDifBig, 32) // Add padding 232 targetTemp := big.NewInt(int64(b.chainParams.TargetTimespan / 233 time.Second)) 234 235 windowAdjusted := targetTemp.Div(timeDifBig, targetTemp) 236 237 // Weight it exponentially. Be aware that this could at some point 238 // overflow if alpha or the number of blocks used is really large. 239 windowAdjusted = windowAdjusted.Lsh(windowAdjusted, 240 uint((b.chainParams.WorkDiffWindows-windowPeriod)*alpha)) 241 242 // Sum up all the different weights incrementally. 243 weights += 1 << uint64((b.chainParams.WorkDiffWindows-windowPeriod)* 244 alpha) 245 246 // Store it in the slice. 247 windowChanges[windowPeriod] = windowAdjusted 248 249 windowPeriod++ 250 251 recentTime = olderTime 252 } 253 254 if i == nodesToTraverse { 255 break // Exit for loop when we hit the end. 256 } 257 258 // Get the previous node while staying at the genesis block as 259 // needed. 260 if oldNode.parent != nil { 261 oldNode = oldNode.parent 262 } 263 } 264 265 // Sum up the weighted window periods. 266 weightedSum := big.NewInt(0) 267 for i := int64(0); i < b.chainParams.WorkDiffWindows; i++ { 268 weightedSum.Add(weightedSum, windowChanges[i]) 269 } 270 271 // Divide by the sum of all weights. 272 weightsBig := big.NewInt(int64(weights)) 273 weightedSumDiv := weightedSum.Div(weightedSum, weightsBig) 274 275 // Multiply by the old diff. 276 nextDiffBig := weightedSumDiv.Mul(weightedSumDiv, oldDiffBig) 277 278 // Right shift to restore the original padding (restore non-fixed point). 279 nextDiffBig = nextDiffBig.Rsh(nextDiffBig, 32) 280 281 // Check to see if we're over the limits for the maximum allowable retarget; 282 // if we are, return the maximum or minimum except in the case that oldDiff 283 // is zero. 284 if oldDiffBig.Cmp(bigZero) == 0 { // This should never really happen, 285 nextDiffBig.Set(nextDiffBig) // but in case it does... 286 } else if nextDiffBig.Cmp(bigZero) == 0 { 287 nextDiffBig.Set(b.chainParams.PowLimit) 288 } else if nextDiffBig.Cmp(nextDiffBigMax) == 1 { 289 nextDiffBig.Set(nextDiffBigMax) 290 } else if nextDiffBig.Cmp(nextDiffBigMin) == -1 { 291 nextDiffBig.Set(nextDiffBigMin) 292 } 293 294 // Limit new value to the proof of work limit. 295 if nextDiffBig.Cmp(b.chainParams.PowLimit) > 0 { 296 nextDiffBig.Set(b.chainParams.PowLimit) 297 } 298 299 // Log new target difficulty and return it. The new target logging is 300 // intentionally converting the bits back to a number instead of using 301 // newTarget since conversion to the compact representation loses 302 // precision. 303 nextDiffBits := standalone.BigToCompact(nextDiffBig) 304 log.Debugf("Difficulty retarget at block height %d", curNode.height+1) 305 log.Debugf("Old target %08x (%064x)", curNode.bits, oldDiffBig) 306 log.Debugf("New target %08x (%064x)", nextDiffBits, standalone.CompactToBig( 307 nextDiffBits)) 308 309 return nextDiffBits, nil 310 } 311 312 // CalcNextRequiredDiffFromNode calculates the required difficulty for the block 313 // given with the passed hash along with the given timestamp. 314 // 315 // This function is NOT safe for concurrent access. 316 func (b *BlockChain) CalcNextRequiredDiffFromNode(hash *chainhash.Hash, timestamp time.Time) (uint32, error) { 317 node := b.index.LookupNode(hash) 318 if node == nil { 319 return 0, fmt.Errorf("block %s is not known", hash) 320 } 321 322 return b.calcNextRequiredDifficulty(node, timestamp) 323 } 324 325 // CalcNextRequiredDifficulty calculates the required difficulty for the block 326 // after the end of the current best chain based on the difficulty retarget 327 // rules. 328 // 329 // This function is safe for concurrent access. 330 func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error) { 331 b.chainLock.Lock() 332 difficulty, err := b.calcNextRequiredDifficulty(b.bestChain.Tip(), timestamp) 333 b.chainLock.Unlock() 334 return difficulty, err 335 } 336 337 // mergeDifficulty takes an original stake difficulty and two new, scaled 338 // stake difficulties, merges the new difficulties, and outputs a new 339 // merged stake difficulty. 340 func mergeDifficulty(oldDiff int64, newDiff1 int64, newDiff2 int64) int64 { 341 newDiff1Big := big.NewInt(newDiff1) 342 newDiff2Big := big.NewInt(newDiff2) 343 newDiff2Big.Lsh(newDiff2Big, 32) 344 345 oldDiffBig := big.NewInt(oldDiff) 346 oldDiffBigLSH := big.NewInt(oldDiff) 347 oldDiffBigLSH.Lsh(oldDiffBig, 32) 348 349 newDiff1Big.Div(oldDiffBigLSH, newDiff1Big) 350 newDiff2Big.Div(newDiff2Big, oldDiffBig) 351 352 // Combine the two changes in difficulty. 353 summedChange := big.NewInt(0) 354 summedChange.Set(newDiff2Big) 355 summedChange.Lsh(summedChange, 32) 356 summedChange.Div(summedChange, newDiff1Big) 357 summedChange.Mul(summedChange, oldDiffBig) 358 summedChange.Rsh(summedChange, 32) 359 360 return summedChange.Int64() 361 } 362 363 // calcNextRequiredStakeDifficultyV1 calculates the required stake difficulty 364 // for the block after the passed previous block node based on exponentially 365 // weighted averages. 366 // 367 // NOTE: This is the original stake difficulty algorithm that was used at Decred 368 // launch. 369 // 370 // This function MUST be called with the chain state lock held (for writes). 371 func (b *BlockChain) calcNextRequiredStakeDifficultyV1(curNode *blockNode) (int64, error) { 372 alpha := b.chainParams.StakeDiffAlpha 373 stakeDiffStartHeight := int64(b.chainParams.CoinbaseMaturity) + 374 1 375 maxRetarget := b.chainParams.RetargetAdjustmentFactor 376 TicketPoolWeight := int64(b.chainParams.TicketPoolSizeWeight) 377 378 // Number of nodes to traverse while calculating difficulty. 379 nodesToTraverse := (b.chainParams.StakeDiffWindowSize * 380 b.chainParams.StakeDiffWindows) 381 382 // Genesis block. Block at height 1 has these parameters. 383 // Additionally, if we're before the time when people generally begin 384 // purchasing tickets, just use the MinimumStakeDiff. 385 // This is sort of sloppy and coded with the hopes that generally by 386 // stakeDiffStartHeight people will be submitting lots of SStx over the 387 // past nodesToTraverse many nodes. It should be okay with the default 388 // Decred parameters, but might do weird things if you use custom 389 // parameters. 390 if curNode == nil || 391 curNode.height < stakeDiffStartHeight { 392 return b.chainParams.MinimumStakeDiff, nil 393 } 394 395 // Get the old difficulty; if we aren't at a block height where it changes, 396 // just return this. 397 oldDiff := curNode.sbits 398 if (curNode.height+1)%b.chainParams.StakeDiffWindowSize != 0 { 399 return oldDiff, nil 400 } 401 402 // The target size of the ticketPool in live tickets. Recast these as int64 403 // to avoid possible overflows for large sizes of either variable in 404 // params. 405 targetForTicketPool := int64(b.chainParams.TicketsPerBlock) * 406 int64(b.chainParams.TicketPoolSize) 407 408 // Initialize bigInt slice for the percentage changes for each window period 409 // above or below the target. 410 windowChanges := make([]*big.Int, b.chainParams.StakeDiffWindows) 411 412 // Regress through all of the previous blocks and store the percent changes 413 // per window period; use bigInts to emulate 64.32 bit fixed point. 414 oldNode := curNode 415 windowPeriod := int64(0) 416 weights := uint64(0) 417 418 for i := int64(0); ; i++ { 419 // Store and reset after reaching the end of every window period. 420 if (i+1)%b.chainParams.StakeDiffWindowSize == 0 { 421 // First adjust based on ticketPoolSize. Skew the difference 422 // in ticketPoolSize by max adjustment factor to help 423 // weight ticket pool size versus tickets per block. 424 poolSizeSkew := (int64(oldNode.poolSize)- 425 targetForTicketPool)*TicketPoolWeight + targetForTicketPool 426 427 // Don't let this be negative or zero. 428 if poolSizeSkew <= 0 { 429 poolSizeSkew = 1 430 } 431 432 curPoolSizeTemp := big.NewInt(poolSizeSkew) 433 curPoolSizeTemp.Lsh(curPoolSizeTemp, 32) // Add padding 434 targetTemp := big.NewInt(targetForTicketPool) 435 436 windowAdjusted := curPoolSizeTemp.Div(curPoolSizeTemp, targetTemp) 437 438 // Weight it exponentially. Be aware that this could at some point 439 // overflow if alpha or the number of blocks used is really large. 440 windowAdjusted = windowAdjusted.Lsh(windowAdjusted, 441 uint((b.chainParams.StakeDiffWindows-windowPeriod)*alpha)) 442 443 // Sum up all the different weights incrementally. 444 weights += 1 << uint64((b.chainParams.StakeDiffWindows-windowPeriod)* 445 alpha) 446 447 // Store it in the slice. 448 windowChanges[windowPeriod] = windowAdjusted 449 450 // windowFreshStake = 0 451 windowPeriod++ 452 } 453 454 if (i + 1) == nodesToTraverse { 455 break // Exit for loop when we hit the end. 456 } 457 458 // Get the previous node while staying at the genesis block as 459 // needed. 460 if oldNode.parent != nil { 461 oldNode = oldNode.parent 462 } 463 } 464 465 // Sum up the weighted window periods. 466 weightedSum := big.NewInt(0) 467 for i := int64(0); i < b.chainParams.StakeDiffWindows; i++ { 468 weightedSum.Add(weightedSum, windowChanges[i]) 469 } 470 471 // Divide by the sum of all weights. 472 weightsBig := big.NewInt(int64(weights)) 473 weightedSumDiv := weightedSum.Div(weightedSum, weightsBig) 474 475 // Multiply by the old stake diff. 476 oldDiffBig := big.NewInt(oldDiff) 477 nextDiffBig := weightedSumDiv.Mul(weightedSumDiv, oldDiffBig) 478 479 // Right shift to restore the original padding (restore non-fixed point). 480 nextDiffBig = nextDiffBig.Rsh(nextDiffBig, 32) 481 nextDiffTicketPool := nextDiffBig.Int64() 482 483 // Check to see if we're over the limits for the maximum allowable retarget; 484 // if we are, return the maximum or minimum except in the case that oldDiff 485 // is zero. 486 if oldDiff == 0 { // This should never really happen, but in case it does... 487 return nextDiffTicketPool, nil 488 } else if nextDiffTicketPool == 0 { 489 nextDiffTicketPool = oldDiff / maxRetarget 490 } else if (nextDiffTicketPool / oldDiff) > (maxRetarget - 1) { 491 nextDiffTicketPool = oldDiff * maxRetarget 492 } else if (oldDiff / nextDiffTicketPool) > (maxRetarget - 1) { 493 nextDiffTicketPool = oldDiff / maxRetarget 494 } 495 496 // The target number of new SStx per block for any given window period. 497 targetForWindow := b.chainParams.StakeDiffWindowSize * 498 int64(b.chainParams.TicketsPerBlock) 499 500 // Regress through all of the previous blocks and store the percent changes 501 // per window period; use bigInts to emulate 64.32 bit fixed point. 502 oldNode = curNode 503 windowFreshStake := int64(0) 504 windowPeriod = int64(0) 505 weights = uint64(0) 506 507 for i := int64(0); ; i++ { 508 // Add the fresh stake into the store for this window period. 509 windowFreshStake += int64(oldNode.freshStake) 510 511 // Store and reset after reaching the end of every window period. 512 if (i+1)%b.chainParams.StakeDiffWindowSize == 0 { 513 // Don't let fresh stake be zero. 514 if windowFreshStake <= 0 { 515 windowFreshStake = 1 516 } 517 518 freshTemp := big.NewInt(windowFreshStake) 519 freshTemp.Lsh(freshTemp, 32) // Add padding 520 targetTemp := big.NewInt(targetForWindow) 521 522 // Get the percentage change. 523 windowAdjusted := freshTemp.Div(freshTemp, targetTemp) 524 525 // Weight it exponentially. Be aware that this could at some point 526 // overflow if alpha or the number of blocks used is really large. 527 windowAdjusted = windowAdjusted.Lsh(windowAdjusted, 528 uint((b.chainParams.StakeDiffWindows-windowPeriod)*alpha)) 529 530 // Sum up all the different weights incrementally. 531 weights += 1 << 532 uint64((b.chainParams.StakeDiffWindows-windowPeriod)*alpha) 533 534 // Store it in the slice. 535 windowChanges[windowPeriod] = windowAdjusted 536 537 windowFreshStake = 0 538 windowPeriod++ 539 } 540 541 if (i + 1) == nodesToTraverse { 542 break // Exit for loop when we hit the end. 543 } 544 545 // Get the previous node while staying at the genesis block as 546 // needed. 547 if oldNode.parent != nil { 548 oldNode = oldNode.parent 549 } 550 } 551 552 // Sum up the weighted window periods. 553 weightedSum = big.NewInt(0) 554 for i := int64(0); i < b.chainParams.StakeDiffWindows; i++ { 555 weightedSum.Add(weightedSum, windowChanges[i]) 556 } 557 558 // Divide by the sum of all weights. 559 weightsBig = big.NewInt(int64(weights)) 560 weightedSumDiv = weightedSum.Div(weightedSum, weightsBig) 561 562 // Multiply by the old stake diff. 563 oldDiffBig = big.NewInt(oldDiff) 564 nextDiffBig = weightedSumDiv.Mul(weightedSumDiv, oldDiffBig) 565 566 // Right shift to restore the original padding (restore non-fixed point). 567 nextDiffBig = nextDiffBig.Rsh(nextDiffBig, 32) 568 nextDiffFreshStake := nextDiffBig.Int64() 569 570 // Check to see if we're over the limits for the maximum allowable retarget; 571 // if we are, return the maximum or minimum except in the case that oldDiff 572 // is zero. 573 if oldDiff == 0 { // This should never really happen, but in case it does... 574 return nextDiffFreshStake, nil 575 } else if nextDiffFreshStake == 0 { 576 nextDiffFreshStake = oldDiff / maxRetarget 577 } else if (nextDiffFreshStake / oldDiff) > (maxRetarget - 1) { 578 nextDiffFreshStake = oldDiff * maxRetarget 579 } else if (oldDiff / nextDiffFreshStake) > (maxRetarget - 1) { 580 nextDiffFreshStake = oldDiff / maxRetarget 581 } 582 583 // Average the two differences using scaled multiplication. 584 nextDiff := mergeDifficulty(oldDiff, nextDiffTicketPool, nextDiffFreshStake) 585 586 // Check to see if we're over the limits for the maximum allowable retarget; 587 // if we are, return the maximum or minimum except in the case that oldDiff 588 // is zero. 589 if oldDiff == 0 { // This should never really happen, but in case it does... 590 return oldDiff, nil 591 } else if nextDiff == 0 { 592 nextDiff = oldDiff / maxRetarget 593 } else if (nextDiff / oldDiff) > (maxRetarget - 1) { 594 nextDiff = oldDiff * maxRetarget 595 } else if (oldDiff / nextDiff) > (maxRetarget - 1) { 596 nextDiff = oldDiff / maxRetarget 597 } 598 599 // If the next diff is below the network minimum, set the required stake 600 // difficulty to the minimum. 601 if nextDiff < b.chainParams.MinimumStakeDiff { 602 return b.chainParams.MinimumStakeDiff, nil 603 } 604 605 return nextDiff, nil 606 } 607 608 // estimateSupply returns an estimate of the coin supply for the provided block 609 // height. This is primarily used in the stake difficulty algorithm and relies 610 // on an estimate to simplify the necessary calculations. The actual total 611 // coin supply as of a given block height depends on many factors such as the 612 // number of votes included in every prior block (not including all votes 613 // reduces the subsidy) and whether or not any of the prior blocks have been 614 // invalidated by stakeholders thereby removing the PoW subsidy for them. 615 // 616 // This function is safe for concurrent access. 617 func estimateSupply(params *chaincfg.Params, height int64) int64 { 618 if height <= 0 { 619 return 0 620 } 621 622 // Estimate the supply by calculating the full block subsidy for each 623 // reduction interval and multiplying it the number of blocks in the 624 // interval then adding the subsidy produced by number of blocks in the 625 // current interval. 626 supply := params.BlockOneSubsidy() 627 reductions := height / params.SubsidyReductionInterval 628 subsidy := params.BaseSubsidy 629 for i := int64(0); i < reductions; i++ { 630 supply += params.SubsidyReductionInterval * subsidy 631 632 subsidy *= params.MulSubsidy 633 subsidy /= params.DivSubsidy 634 } 635 supply += (1 + height%params.SubsidyReductionInterval) * subsidy 636 637 // Blocks 0 and 1 have special subsidy amounts that have already been 638 // added above, so remove what their subsidies would have normally been 639 // which were also added above. 640 supply -= params.BaseSubsidy * 2 641 642 return supply 643 } 644 645 // sumPurchasedTickets returns the sum of the number of tickets purchased in the 646 // most recent specified number of blocks from the point of view of the passed 647 // node. 648 func (b *BlockChain) sumPurchasedTickets(startNode *blockNode, numToSum int64) int64 { 649 var numPurchased int64 650 for node, numTraversed := startNode, int64(0); node != nil && 651 numTraversed < numToSum; numTraversed++ { 652 653 numPurchased += int64(node.freshStake) 654 node = node.parent 655 } 656 657 return numPurchased 658 } 659 660 // calcNextStakeDiffV2 calculates the next stake difficulty for the given set 661 // of parameters using the algorithm defined in DCP0001. 662 // 663 // This function contains the heart of the algorithm and thus is separated for 664 // use in both the actual stake difficulty calculation as well as estimation. 665 // 666 // The caller must perform all of the necessary chain traversal in order to 667 // get the current difficulty, previous retarget interval's pool size plus 668 // its immature tickets, as well as the current pool size plus immature tickets. 669 // 670 // This function is safe for concurrent access. 671 func calcNextStakeDiffV2(params *chaincfg.Params, nextHeight, curDiff, prevPoolSizeAll, curPoolSizeAll int64) int64 { 672 // Shorter version of various parameter for convenience. 673 votesPerBlock := int64(params.TicketsPerBlock) 674 ticketPoolSize := int64(params.TicketPoolSize) 675 ticketMaturity := int64(params.TicketMaturity) 676 677 // Calculate the difficulty by multiplying the old stake difficulty 678 // with two ratios that represent a force to counteract the relative 679 // change in the pool size (Fc) and a restorative force to push the pool 680 // size towards the target value (Fr). 681 // 682 // Per DCP0001, the generalized equation is: 683 // 684 // nextDiff = min(max(curDiff * Fc * Fr, Slb), Sub) 685 // 686 // The detailed form expands to: 687 // 688 // curPoolSizeAll curPoolSizeAll 689 // nextDiff = curDiff * --------------- * ----------------- 690 // prevPoolSizeAll targetPoolSizeAll 691 // 692 // Slb = b.chainParams.MinimumStakeDiff 693 // 694 // estimatedTotalSupply 695 // Sub = ------------------------------- 696 // targetPoolSize / votesPerBlock 697 // 698 // In order to avoid the need to perform floating point math which could 699 // be problematic across languages due to uncertainty in floating point 700 // math libs, this is further simplified to integer math as follows: 701 // 702 // curDiff * curPoolSizeAll^2 703 // nextDiff = ----------------------------------- 704 // prevPoolSizeAll * targetPoolSizeAll 705 // 706 // Further, the Sub parameter must calculate the denomitor first using 707 // integer math. 708 targetPoolSizeAll := votesPerBlock * (ticketPoolSize + ticketMaturity) 709 curPoolSizeAllBig := big.NewInt(curPoolSizeAll) 710 nextDiffBig := big.NewInt(curDiff) 711 nextDiffBig.Mul(nextDiffBig, curPoolSizeAllBig) 712 nextDiffBig.Mul(nextDiffBig, curPoolSizeAllBig) 713 nextDiffBig.Div(nextDiffBig, big.NewInt(prevPoolSizeAll)) 714 nextDiffBig.Div(nextDiffBig, big.NewInt(targetPoolSizeAll)) 715 716 // Limit the new stake difficulty between the minimum allowed stake 717 // difficulty and a maximum value that is relative to the total supply. 718 // 719 // NOTE: This is intentionally using integer math to prevent any 720 // potential issues due to uncertainty in floating point math libs. The 721 // ticketPoolSize parameter already contains the result of 722 // (targetPoolSize / votesPerBlock). 723 nextDiff := nextDiffBig.Int64() 724 estimatedSupply := estimateSupply(params, nextHeight) 725 maximumStakeDiff := estimatedSupply / ticketPoolSize 726 if nextDiff > maximumStakeDiff { 727 nextDiff = maximumStakeDiff 728 } 729 if nextDiff < params.MinimumStakeDiff { 730 nextDiff = params.MinimumStakeDiff 731 } 732 return nextDiff 733 } 734 735 // calcNextRequiredStakeDifficultyV2 calculates the required stake difficulty 736 // for the block after the passed previous block node based on the algorithm 737 // defined in DCP0001. 738 // 739 // This function MUST be called with the chain state lock held (for writes). 740 func (b *BlockChain) calcNextRequiredStakeDifficultyV2(curNode *blockNode) (int64, error) { 741 // Stake difficulty before any tickets could possibly be purchased is 742 // the minimum value. 743 nextHeight := int64(0) 744 if curNode != nil { 745 nextHeight = curNode.height + 1 746 } 747 stakeDiffStartHeight := int64(b.chainParams.CoinbaseMaturity) + 1 748 if nextHeight < stakeDiffStartHeight { 749 return b.chainParams.MinimumStakeDiff, nil 750 } 751 752 // Return the previous block's difficulty requirements if the next block 753 // is not at a difficulty retarget interval. 754 intervalSize := b.chainParams.StakeDiffWindowSize 755 curDiff := curNode.sbits 756 if nextHeight%intervalSize != 0 { 757 return curDiff, nil 758 } 759 760 // Get the pool size and number of tickets that were immature at the 761 // previous retarget interval. 762 // 763 // NOTE: Since the stake difficulty must be calculated based on existing 764 // blocks, it is always calculated for the block after a given block, so 765 // the information for the previous retarget interval must be retrieved 766 // relative to the block just before it to coincide with how it was 767 // originally calculated. 768 var prevPoolSize int64 769 prevRetargetHeight := nextHeight - intervalSize - 1 770 prevRetargetNode := curNode.Ancestor(prevRetargetHeight) 771 if prevRetargetNode != nil { 772 prevPoolSize = int64(prevRetargetNode.poolSize) 773 } 774 ticketMaturity := int64(b.chainParams.TicketMaturity) 775 prevImmatureTickets := b.sumPurchasedTickets(prevRetargetNode, 776 ticketMaturity) 777 778 // Return the existing ticket price for the first few intervals to avoid 779 // division by zero and encourage initial pool population. 780 prevPoolSizeAll := prevPoolSize + prevImmatureTickets 781 if prevPoolSizeAll == 0 { 782 return curDiff, nil 783 } 784 785 // Count the number of currently immature tickets. 786 immatureTickets := b.sumPurchasedTickets(curNode, ticketMaturity) 787 788 // Calculate and return the final next required difficulty. 789 curPoolSizeAll := int64(curNode.poolSize) + immatureTickets 790 return calcNextStakeDiffV2(b.chainParams, nextHeight, curDiff, 791 prevPoolSizeAll, curPoolSizeAll), nil 792 } 793 794 // calcNextRequiredStakeDifficulty calculates the required stake difficulty for 795 // the block after the passed previous block node based on the active stake 796 // difficulty retarget rules. 797 // 798 // This function differs from the exported CalcNextRequiredDifficulty in that 799 // the exported version uses the current best chain as the previous block node 800 // while this function accepts any block node. 801 // 802 // This function MUST be called with the chain state lock held (for writes). 803 func (b *BlockChain) calcNextRequiredStakeDifficulty(curNode *blockNode) (int64, error) { 804 // Determine the correct deployment version for the new stake difficulty 805 // algorithm consensus vote or treat it as active when voting is not enabled 806 // for the current network. 807 const deploymentID = chaincfg.VoteIDSDiffAlgorithm 808 deploymentVer, ok := b.deploymentVers[deploymentID] 809 if !ok { 810 return b.calcNextRequiredStakeDifficultyV2(curNode) 811 } 812 813 // Use the new stake difficulty algorithm if the stake vote for the new 814 // algorithm agenda is active. 815 // 816 // NOTE: The choice field of the return threshold state is not examined 817 // here because there is only one possible choice that can be active 818 // for the agenda, which is yes, so there is no need to check it. 819 state, err := b.deploymentState(curNode, deploymentVer, deploymentID) 820 if err != nil { 821 return 0, err 822 } 823 if state.State == ThresholdActive { 824 return b.calcNextRequiredStakeDifficultyV2(curNode) 825 } 826 827 // Use the old stake difficulty algorithm in any other case. 828 return b.calcNextRequiredStakeDifficultyV1(curNode) 829 } 830 831 // CalcNextRequiredStakeDifficulty calculates the required stake difficulty for 832 // the block after the end of the current best chain based on the active stake 833 // difficulty retarget rules. 834 // 835 // This function is safe for concurrent access. 836 func (b *BlockChain) CalcNextRequiredStakeDifficulty() (int64, error) { 837 b.chainLock.Lock() 838 nextDiff, err := b.calcNextRequiredStakeDifficulty(b.bestChain.Tip()) 839 b.chainLock.Unlock() 840 return nextDiff, err 841 } 842 843 // estimateNextStakeDifficultyV1 estimates the next stake difficulty by 844 // pretending the provided number of tickets will be purchased in the remainder 845 // of the interval unless the flag to use max tickets is set in which case it 846 // will use the max possible number of tickets that can be purchased in the 847 // remainder of the interval. 848 // 849 // NOTE: This uses the original stake difficulty algorithm that was used at 850 // Decred launch. 851 // 852 // This function MUST be called with the chain state lock held (for writes). 853 func (b *BlockChain) estimateNextStakeDifficultyV1(curNode *blockNode, ticketsInWindow int64, useMaxTickets bool) (int64, error) { 854 alpha := b.chainParams.StakeDiffAlpha 855 stakeDiffStartHeight := int64(b.chainParams.CoinbaseMaturity) + 856 1 857 maxRetarget := b.chainParams.RetargetAdjustmentFactor 858 TicketPoolWeight := int64(b.chainParams.TicketPoolSizeWeight) 859 860 // Number of nodes to traverse while calculating difficulty. 861 nodesToTraverse := (b.chainParams.StakeDiffWindowSize * 862 b.chainParams.StakeDiffWindows) 863 864 // Genesis block. Block at height 1 has these parameters. 865 if curNode == nil || 866 curNode.height < stakeDiffStartHeight { 867 return b.chainParams.MinimumStakeDiff, nil 868 } 869 870 // Create a fake blockchain on top of the current best node with 871 // the number of freshly purchased tickets as indicated by the 872 // user. 873 oldDiff := curNode.sbits 874 topNode := curNode 875 if (curNode.height+1)%b.chainParams.StakeDiffWindowSize != 0 { 876 nextAdjHeight := ((curNode.height / 877 b.chainParams.StakeDiffWindowSize) + 1) * 878 b.chainParams.StakeDiffWindowSize 879 maxTickets := (nextAdjHeight - curNode.height) * 880 int64(b.chainParams.MaxFreshStakePerBlock) 881 882 // If the user has indicated that the automatically 883 // calculated maximum amount of tickets should be 884 // used, plug that in here. 885 if useMaxTickets { 886 ticketsInWindow = maxTickets 887 } 888 889 // Double check to make sure there isn't too much. 890 if ticketsInWindow > maxTickets { 891 return 0, fmt.Errorf("too much fresh stake to be used "+ 892 "in evaluation requested; max %v, got %v", maxTickets, 893 ticketsInWindow) 894 } 895 896 // Insert all the tickets into bogus nodes that will be 897 // used to calculate the next difficulty below. 898 ticketsToInsert := ticketsInWindow 899 for i := curNode.height + 1; i < nextAdjHeight; i++ { 900 var emptyHeader wire.BlockHeader 901 emptyHeader.Height = uint32(i) 902 903 // User a constant pool size for estimate, since 904 // this has much less fluctuation than freshStake. 905 // TODO Use a better pool size estimate? 906 emptyHeader.PoolSize = curNode.poolSize 907 908 // Insert the fake fresh stake into each block, 909 // decrementing the amount we need to use each 910 // time until we hit 0. 911 freshStake := b.chainParams.MaxFreshStakePerBlock 912 if int64(freshStake) > ticketsToInsert { 913 freshStake = uint8(ticketsToInsert) 914 ticketsToInsert -= ticketsToInsert 915 } else { 916 ticketsToInsert -= int64(b.chainParams.MaxFreshStakePerBlock) 917 } 918 emptyHeader.FreshStake = freshStake 919 920 // Connect the header. 921 emptyHeader.PrevBlock = topNode.hash 922 923 thisNode := newBlockNode(&emptyHeader, topNode) 924 topNode = thisNode 925 } 926 } 927 928 // The target size of the ticketPool in live tickets. Recast these as int64 929 // to avoid possible overflows for large sizes of either variable in 930 // params. 931 targetForTicketPool := int64(b.chainParams.TicketsPerBlock) * 932 int64(b.chainParams.TicketPoolSize) 933 934 // Initialize bigInt slice for the percentage changes for each window period 935 // above or below the target. 936 windowChanges := make([]*big.Int, b.chainParams.StakeDiffWindows) 937 938 // Regress through all of the previous blocks and store the percent changes 939 // per window period; use bigInts to emulate 64.32 bit fixed point. 940 oldNode := topNode 941 windowPeriod := int64(0) 942 weights := uint64(0) 943 944 for i := int64(0); ; i++ { 945 // Store and reset after reaching the end of every window period. 946 if (i+1)%b.chainParams.StakeDiffWindowSize == 0 { 947 // First adjust based on ticketPoolSize. Skew the difference 948 // in ticketPoolSize by max adjustment factor to help 949 // weight ticket pool size versus tickets per block. 950 poolSizeSkew := (int64(oldNode.poolSize)- 951 targetForTicketPool)*TicketPoolWeight + targetForTicketPool 952 953 // Don't let this be negative or zero. 954 if poolSizeSkew <= 0 { 955 poolSizeSkew = 1 956 } 957 958 curPoolSizeTemp := big.NewInt(poolSizeSkew) 959 curPoolSizeTemp.Lsh(curPoolSizeTemp, 32) // Add padding 960 targetTemp := big.NewInt(targetForTicketPool) 961 962 windowAdjusted := curPoolSizeTemp.Div(curPoolSizeTemp, targetTemp) 963 964 // Weight it exponentially. Be aware that this could at some point 965 // overflow if alpha or the number of blocks used is really large. 966 windowAdjusted = windowAdjusted.Lsh(windowAdjusted, 967 uint((b.chainParams.StakeDiffWindows-windowPeriod)*alpha)) 968 969 // Sum up all the different weights incrementally. 970 weights += 1 << uint64((b.chainParams.StakeDiffWindows-windowPeriod)* 971 alpha) 972 973 // Store it in the slice. 974 windowChanges[windowPeriod] = windowAdjusted 975 976 // windowFreshStake = 0 977 windowPeriod++ 978 } 979 980 if (i + 1) == nodesToTraverse { 981 break // Exit for loop when we hit the end. 982 } 983 984 // Get the previous node while staying at the genesis block as 985 // needed. 986 if oldNode.parent != nil { 987 oldNode = oldNode.parent 988 } 989 } 990 991 // Sum up the weighted window periods. 992 weightedSum := big.NewInt(0) 993 for i := int64(0); i < b.chainParams.StakeDiffWindows; i++ { 994 weightedSum.Add(weightedSum, windowChanges[i]) 995 } 996 997 // Divide by the sum of all weights. 998 weightsBig := big.NewInt(int64(weights)) 999 weightedSumDiv := weightedSum.Div(weightedSum, weightsBig) 1000 1001 // Multiply by the old stake diff. 1002 oldDiffBig := big.NewInt(oldDiff) 1003 nextDiffBig := weightedSumDiv.Mul(weightedSumDiv, oldDiffBig) 1004 1005 // Right shift to restore the original padding (restore non-fixed point). 1006 nextDiffBig = nextDiffBig.Rsh(nextDiffBig, 32) 1007 nextDiffTicketPool := nextDiffBig.Int64() 1008 1009 // Check to see if we're over the limits for the maximum allowable retarget; 1010 // if we are, return the maximum or minimum except in the case that oldDiff 1011 // is zero. 1012 if oldDiff == 0 { // This should never really happen, but in case it does... 1013 return nextDiffTicketPool, nil 1014 } else if nextDiffTicketPool == 0 { 1015 nextDiffTicketPool = oldDiff / maxRetarget 1016 } else if (nextDiffTicketPool / oldDiff) > (maxRetarget - 1) { 1017 nextDiffTicketPool = oldDiff * maxRetarget 1018 } else if (oldDiff / nextDiffTicketPool) > (maxRetarget - 1) { 1019 nextDiffTicketPool = oldDiff / maxRetarget 1020 } 1021 1022 // The target number of new SStx per block for any given window period. 1023 targetForWindow := b.chainParams.StakeDiffWindowSize * 1024 int64(b.chainParams.TicketsPerBlock) 1025 1026 // Regress through all of the previous blocks and store the percent changes 1027 // per window period; use bigInts to emulate 64.32 bit fixed point. 1028 oldNode = topNode 1029 windowFreshStake := int64(0) 1030 windowPeriod = int64(0) 1031 weights = uint64(0) 1032 1033 for i := int64(0); ; i++ { 1034 // Add the fresh stake into the store for this window period. 1035 windowFreshStake += int64(oldNode.freshStake) 1036 1037 // Store and reset after reaching the end of every window period. 1038 if (i+1)%b.chainParams.StakeDiffWindowSize == 0 { 1039 // Don't let fresh stake be zero. 1040 if windowFreshStake <= 0 { 1041 windowFreshStake = 1 1042 } 1043 1044 freshTemp := big.NewInt(windowFreshStake) 1045 freshTemp.Lsh(freshTemp, 32) // Add padding 1046 targetTemp := big.NewInt(targetForWindow) 1047 1048 // Get the percentage change. 1049 windowAdjusted := freshTemp.Div(freshTemp, targetTemp) 1050 1051 // Weight it exponentially. Be aware that this could at some point 1052 // overflow if alpha or the number of blocks used is really large. 1053 windowAdjusted = windowAdjusted.Lsh(windowAdjusted, 1054 uint((b.chainParams.StakeDiffWindows-windowPeriod)*alpha)) 1055 1056 // Sum up all the different weights incrementally. 1057 weights += 1 << 1058 uint64((b.chainParams.StakeDiffWindows-windowPeriod)*alpha) 1059 1060 // Store it in the slice. 1061 windowChanges[windowPeriod] = windowAdjusted 1062 1063 windowFreshStake = 0 1064 windowPeriod++ 1065 } 1066 1067 if (i + 1) == nodesToTraverse { 1068 break // Exit for loop when we hit the end. 1069 } 1070 1071 // Get the previous node while staying at the genesis block as 1072 // needed. 1073 if oldNode.parent != nil { 1074 oldNode = oldNode.parent 1075 } 1076 } 1077 1078 // Sum up the weighted window periods. 1079 weightedSum = big.NewInt(0) 1080 for i := int64(0); i < b.chainParams.StakeDiffWindows; i++ { 1081 weightedSum.Add(weightedSum, windowChanges[i]) 1082 } 1083 1084 // Divide by the sum of all weights. 1085 weightsBig = big.NewInt(int64(weights)) 1086 weightedSumDiv = weightedSum.Div(weightedSum, weightsBig) 1087 1088 // Multiply by the old stake diff. 1089 oldDiffBig = big.NewInt(oldDiff) 1090 nextDiffBig = weightedSumDiv.Mul(weightedSumDiv, oldDiffBig) 1091 1092 // Right shift to restore the original padding (restore non-fixed point). 1093 nextDiffBig = nextDiffBig.Rsh(nextDiffBig, 32) 1094 nextDiffFreshStake := nextDiffBig.Int64() 1095 1096 // Check to see if we're over the limits for the maximum allowable retarget; 1097 // if we are, return the maximum or minimum except in the case that oldDiff 1098 // is zero. 1099 if oldDiff == 0 { // This should never really happen, but in case it does... 1100 return nextDiffFreshStake, nil 1101 } else if nextDiffFreshStake == 0 { 1102 nextDiffFreshStake = oldDiff / maxRetarget 1103 } else if (nextDiffFreshStake / oldDiff) > (maxRetarget - 1) { 1104 nextDiffFreshStake = oldDiff * maxRetarget 1105 } else if (oldDiff / nextDiffFreshStake) > (maxRetarget - 1) { 1106 nextDiffFreshStake = oldDiff / maxRetarget 1107 } 1108 1109 // Average the two differences using scaled multiplication. 1110 nextDiff := mergeDifficulty(oldDiff, nextDiffTicketPool, nextDiffFreshStake) 1111 1112 // Check to see if we're over the limits for the maximum allowable retarget; 1113 // if we are, return the maximum or minimum except in the case that oldDiff 1114 // is zero. 1115 if oldDiff == 0 { // This should never really happen, but in case it does... 1116 return oldDiff, nil 1117 } else if nextDiff == 0 { 1118 nextDiff = oldDiff / maxRetarget 1119 } else if (nextDiff / oldDiff) > (maxRetarget - 1) { 1120 nextDiff = oldDiff * maxRetarget 1121 } else if (oldDiff / nextDiff) > (maxRetarget - 1) { 1122 nextDiff = oldDiff / maxRetarget 1123 } 1124 1125 // If the next diff is below the network minimum, set the required stake 1126 // difficulty to the minimum. 1127 if nextDiff < b.chainParams.MinimumStakeDiff { 1128 return b.chainParams.MinimumStakeDiff, nil 1129 } 1130 1131 return nextDiff, nil 1132 } 1133 1134 // estimateNextStakeDifficultyV2 estimates the next stake difficulty using the 1135 // algorithm defined in DCP0001 by pretending the provided number of tickets 1136 // will be purchased in the remainder of the interval unless the flag to use max 1137 // tickets is set in which case it will use the max possible number of tickets 1138 // that can be purchased in the remainder of the interval. 1139 // 1140 // This function MUST be called with the chain state lock held (for writes). 1141 func (b *BlockChain) estimateNextStakeDifficultyV2(curNode *blockNode, newTickets int64, useMaxTickets bool) (int64, error) { 1142 // Calculate the next retarget interval height. 1143 curHeight := int64(0) 1144 if curNode != nil { 1145 curHeight = curNode.height 1146 } 1147 ticketMaturity := int64(b.chainParams.TicketMaturity) 1148 intervalSize := b.chainParams.StakeDiffWindowSize 1149 blocksUntilRetarget := intervalSize - curHeight%intervalSize 1150 nextRetargetHeight := curHeight + blocksUntilRetarget 1151 1152 // Calculate the maximum possible number of tickets that could be sold 1153 // in the remainder of the interval and potentially override the number 1154 // of new tickets to include in the estimate per the user-specified 1155 // flag. 1156 maxTicketsPerBlock := int64(b.chainParams.MaxFreshStakePerBlock) 1157 maxRemainingTickets := (blocksUntilRetarget - 1) * maxTicketsPerBlock 1158 if useMaxTickets { 1159 newTickets = maxRemainingTickets 1160 } 1161 1162 // Ensure the specified number of tickets is not too high. 1163 if newTickets > maxRemainingTickets { 1164 return 0, fmt.Errorf("unable to create an estimated stake "+ 1165 "difficulty with %d tickets since it is more than "+ 1166 "the maximum remaining of %d", newTickets, 1167 maxRemainingTickets) 1168 } 1169 1170 // Stake difficulty before any tickets could possibly be purchased is 1171 // the minimum value. 1172 stakeDiffStartHeight := int64(b.chainParams.CoinbaseMaturity) + 1 1173 if nextRetargetHeight < stakeDiffStartHeight { 1174 return b.chainParams.MinimumStakeDiff, nil 1175 } 1176 1177 // Get the pool size and number of tickets that were immature at the 1178 // previous retarget interval 1179 // 1180 // NOTE: Since the stake difficulty must be calculated based on existing 1181 // blocks, it is always calculated for the block after a given block, so 1182 // the information for the previous retarget interval must be retrieved 1183 // relative to the block just before it to coincide with how it was 1184 // originally calculated. 1185 var prevPoolSize int64 1186 prevRetargetHeight := nextRetargetHeight - intervalSize - 1 1187 prevRetargetNode := curNode.Ancestor(prevRetargetHeight) 1188 if prevRetargetNode != nil { 1189 prevPoolSize = int64(prevRetargetNode.poolSize) 1190 } 1191 prevImmatureTickets := b.sumPurchasedTickets(prevRetargetNode, 1192 ticketMaturity) 1193 1194 // Return the existing ticket price for the first few intervals to avoid 1195 // division by zero and encourage initial pool population. 1196 curDiff := curNode.sbits 1197 prevPoolSizeAll := prevPoolSize + prevImmatureTickets 1198 if prevPoolSizeAll == 0 { 1199 return curDiff, nil 1200 } 1201 1202 // Calculate the number of tickets that will still be immature at the 1203 // next retarget based on the known (non-estimated) data. 1204 // 1205 // Note that when the interval size is larger than the ticket maturity, 1206 // the current height might be before the maturity floor (the point 1207 // after which the remaining tickets will remain immature). There are 1208 // therefore no possible remaining immature tickets from the blocks that 1209 // are not being estimated in that case. 1210 var remainingImmatureTickets int64 1211 nextMaturityFloor := nextRetargetHeight - ticketMaturity - 1 1212 if curHeight > nextMaturityFloor { 1213 remainingImmatureTickets = b.sumPurchasedTickets(curNode, 1214 curHeight-nextMaturityFloor) 1215 } 1216 1217 // Add the number of tickets that will still be immature at the next 1218 // retarget based on the estimated data. 1219 maxImmatureTickets := ticketMaturity * maxTicketsPerBlock 1220 if newTickets > maxImmatureTickets { 1221 remainingImmatureTickets += maxImmatureTickets 1222 } else { 1223 remainingImmatureTickets += newTickets 1224 } 1225 1226 // Calculate the number of tickets that will mature in the remainder of 1227 // the interval based on the known (non-estimated) data. 1228 // 1229 // NOTE: The pool size in the block headers does not include the tickets 1230 // maturing at the height in which they mature since they are not 1231 // eligible for selection until the next block, so exclude them by 1232 // starting one block before the next maturity floor. 1233 finalMaturingHeight := nextMaturityFloor - 1 1234 if finalMaturingHeight > curHeight { 1235 finalMaturingHeight = curHeight 1236 } 1237 finalMaturingNode := curNode.Ancestor(finalMaturingHeight) 1238 firstMaturingHeight := curHeight - ticketMaturity 1239 maturingTickets := b.sumPurchasedTickets(finalMaturingNode, 1240 finalMaturingHeight-firstMaturingHeight+1) 1241 1242 // Add the number of tickets that will mature based on the estimated data. 1243 // 1244 // Note that when the ticket maturity is greater than or equal to the 1245 // interval size, the current height will always be after the maturity 1246 // floor. There are therefore no possible maturing estimated tickets 1247 // in that case. 1248 if curHeight < nextMaturityFloor { 1249 maturingEstimateNodes := nextMaturityFloor - curHeight - 1 1250 maturingEstimatedTickets := maxTicketsPerBlock * maturingEstimateNodes 1251 if maturingEstimatedTickets > newTickets { 1252 maturingEstimatedTickets = newTickets 1253 } 1254 maturingTickets += maturingEstimatedTickets 1255 } 1256 1257 // Calculate the number of votes that will occur during the remainder of 1258 // the interval. 1259 stakeValidationHeight := b.chainParams.StakeValidationHeight 1260 var pendingVotes int64 1261 if nextRetargetHeight > stakeValidationHeight { 1262 votingBlocks := blocksUntilRetarget - 1 1263 if curHeight < stakeValidationHeight { 1264 votingBlocks = nextRetargetHeight - stakeValidationHeight 1265 } 1266 votesPerBlock := int64(b.chainParams.TicketsPerBlock) 1267 pendingVotes = votingBlocks * votesPerBlock 1268 } 1269 1270 // Calculate what the pool size would be as of the next interval. 1271 curPoolSize := int64(curNode.poolSize) 1272 estimatedPoolSize := curPoolSize + maturingTickets - pendingVotes 1273 estimatedPoolSizeAll := estimatedPoolSize + remainingImmatureTickets 1274 1275 // Calculate and return the final estimated difficulty. 1276 return calcNextStakeDiffV2(b.chainParams, nextRetargetHeight, curDiff, 1277 prevPoolSizeAll, estimatedPoolSizeAll), nil 1278 } 1279 1280 // estimateNextStakeDifficulty estimates the next stake difficulty by pretending 1281 // the provided number of tickets will be purchased in the remainder of the 1282 // interval unless the flag to use max tickets is set in which case it will use 1283 // the max possible number of tickets that can be purchased in the remainder of 1284 // the interval. 1285 // 1286 // The stake difficulty algorithm is selected based on the active rules. 1287 // 1288 // This function differs from the exported EstimateNextStakeDifficulty in that 1289 // the exported version uses the current best chain as the block node while this 1290 // function accepts any block node. 1291 // 1292 // This function MUST be called with the chain state lock held (for writes). 1293 func (b *BlockChain) estimateNextStakeDifficulty(curNode *blockNode, newTickets int64, useMaxTickets bool) (int64, error) { 1294 // Determine the correct deployment version for the new stake difficulty 1295 // algorithm consensus vote or treat it as active when voting is not enabled 1296 // for the current network. 1297 const deploymentID = chaincfg.VoteIDSDiffAlgorithm 1298 deploymentVer, ok := b.deploymentVers[deploymentID] 1299 if !ok { 1300 return b.calcNextRequiredStakeDifficultyV2(curNode) 1301 } 1302 1303 // Use the new stake difficulty algorithm if the stake vote for the new 1304 // algorithm agenda is active. 1305 // 1306 // NOTE: The choice field of the return threshold state is not examined 1307 // here because there is only one possible choice that can be active 1308 // for the agenda, which is yes, so there is no need to check it. 1309 state, err := b.deploymentState(curNode, deploymentVer, deploymentID) 1310 if err != nil { 1311 return 0, err 1312 } 1313 if state.State == ThresholdActive { 1314 return b.estimateNextStakeDifficultyV2(curNode, newTickets, 1315 useMaxTickets) 1316 } 1317 1318 // Use the old stake difficulty algorithm in any other case. 1319 return b.estimateNextStakeDifficultyV1(curNode, newTickets, 1320 useMaxTickets) 1321 } 1322 1323 // EstimateNextStakeDifficulty estimates the next stake difficulty by pretending 1324 // the provided number of tickets will be purchased in the remainder of the 1325 // interval unless the flag to use max tickets is set in which case it will use 1326 // the max possible number of tickets that can be purchased in the remainder of 1327 // the interval. 1328 // 1329 // This function is safe for concurrent access. 1330 func (b *BlockChain) EstimateNextStakeDifficulty(newTickets int64, useMaxTickets bool) (int64, error) { 1331 b.chainLock.Lock() 1332 estimate, err := b.estimateNextStakeDifficulty(b.bestChain.Tip(), 1333 newTickets, useMaxTickets) 1334 b.chainLock.Unlock() 1335 return estimate, err 1336 }