github.com/phillinzzz/newBsc@v1.1.6/consensus/ethash/difficulty.go (about) 1 // Copyright 2020 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package ethash 18 19 import ( 20 "math/big" 21 22 "github.com/phillinzzz/newBsc/core/types" 23 "github.com/holiman/uint256" 24 ) 25 26 const ( 27 // frontierDurationLimit is for Frontier: 28 // The decision boundary on the blocktime duration used to determine 29 // whether difficulty should go up or down. 30 frontierDurationLimit = 13 31 // minimumDifficulty The minimum that the difficulty may ever be. 32 minimumDifficulty = 131072 33 // expDiffPeriod is the exponential difficulty period 34 expDiffPeriodUint = 100000 35 // difficultyBoundDivisorBitShift is the bound divisor of the difficulty (2048), 36 // This constant is the right-shifts to use for the division. 37 difficultyBoundDivisor = 11 38 ) 39 40 // CalcDifficultyFrontierU256 is the difficulty adjustment algorithm. It returns the 41 // difficulty that a new block should have when created at time given the parent 42 // block's time and difficulty. The calculation uses the Frontier rules. 43 func CalcDifficultyFrontierU256(time uint64, parent *types.Header) *big.Int { 44 /* 45 Algorithm 46 block_diff = pdiff + pdiff / 2048 * (1 if time - ptime < 13 else -1) + int(2^((num // 100000) - 2)) 47 48 Where: 49 - pdiff = parent.difficulty 50 - ptime = parent.time 51 - time = block.timestamp 52 - num = block.number 53 */ 54 55 pDiff := uint256.NewInt() 56 pDiff.SetFromBig(parent.Difficulty) // pDiff: pdiff 57 adjust := pDiff.Clone() 58 adjust.Rsh(adjust, difficultyBoundDivisor) // adjust: pDiff / 2048 59 60 if time-parent.Time < frontierDurationLimit { 61 pDiff.Add(pDiff, adjust) 62 } else { 63 pDiff.Sub(pDiff, adjust) 64 } 65 if pDiff.LtUint64(minimumDifficulty) { 66 pDiff.SetUint64(minimumDifficulty) 67 } 68 // 'pdiff' now contains: 69 // pdiff + pdiff / 2048 * (1 if time - ptime < 13 else -1) 70 71 if periodCount := (parent.Number.Uint64() + 1) / expDiffPeriodUint; periodCount > 1 { 72 // diff = diff + 2^(periodCount - 2) 73 expDiff := adjust.SetOne() 74 expDiff.Lsh(expDiff, uint(periodCount-2)) // expdiff: 2 ^ (periodCount -2) 75 pDiff.Add(pDiff, expDiff) 76 } 77 return pDiff.ToBig() 78 } 79 80 // CalcDifficultyHomesteadU256 is the difficulty adjustment algorithm. It returns 81 // the difficulty that a new block should have when created at time given the 82 // parent block's time and difficulty. The calculation uses the Homestead rules. 83 func CalcDifficultyHomesteadU256(time uint64, parent *types.Header) *big.Int { 84 /* 85 https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md 86 Algorithm: 87 block_diff = pdiff + pdiff / 2048 * max(1 - (time - ptime) / 10, -99) + 2 ^ int((num / 100000) - 2)) 88 89 Our modification, to use unsigned ints: 90 block_diff = pdiff - pdiff / 2048 * max((time - ptime) / 10 - 1, 99) + 2 ^ int((num / 100000) - 2)) 91 92 Where: 93 - pdiff = parent.difficulty 94 - ptime = parent.time 95 - time = block.timestamp 96 - num = block.number 97 */ 98 99 pDiff := uint256.NewInt() 100 pDiff.SetFromBig(parent.Difficulty) // pDiff: pdiff 101 adjust := pDiff.Clone() 102 adjust.Rsh(adjust, difficultyBoundDivisor) // adjust: pDiff / 2048 103 104 x := (time - parent.Time) / 10 // (time - ptime) / 10) 105 var neg = true 106 if x == 0 { 107 x = 1 108 neg = false 109 } else if x >= 100 { 110 x = 99 111 } else { 112 x = x - 1 113 } 114 z := new(uint256.Int).SetUint64(x) 115 adjust.Mul(adjust, z) // adjust: (pdiff / 2048) * max((time - ptime) / 10 - 1, 99) 116 if neg { 117 pDiff.Sub(pDiff, adjust) // pdiff - pdiff / 2048 * max((time - ptime) / 10 - 1, 99) 118 } else { 119 pDiff.Add(pDiff, adjust) // pdiff + pdiff / 2048 * max((time - ptime) / 10 - 1, 99) 120 } 121 if pDiff.LtUint64(minimumDifficulty) { 122 pDiff.SetUint64(minimumDifficulty) 123 } 124 // for the exponential factor, a.k.a "the bomb" 125 // diff = diff + 2^(periodCount - 2) 126 if periodCount := (1 + parent.Number.Uint64()) / expDiffPeriodUint; periodCount > 1 { 127 expFactor := adjust.Lsh(adjust.SetOne(), uint(periodCount-2)) 128 pDiff.Add(pDiff, expFactor) 129 } 130 return pDiff.ToBig() 131 } 132 133 // MakeDifficultyCalculatorU256 creates a difficultyCalculator with the given bomb-delay. 134 // the difficulty is calculated with Byzantium rules, which differs from Homestead in 135 // how uncles affect the calculation 136 func MakeDifficultyCalculatorU256(bombDelay *big.Int) func(time uint64, parent *types.Header) *big.Int { 137 // Note, the calculations below looks at the parent number, which is 1 below 138 // the block number. Thus we remove one from the delay given 139 bombDelayFromParent := bombDelay.Uint64() - 1 140 return func(time uint64, parent *types.Header) *big.Int { 141 /* 142 https://github.com/ethereum/EIPs/issues/100 143 pDiff = parent.difficulty 144 BLOCK_DIFF_FACTOR = 9 145 a = pDiff + (pDiff // BLOCK_DIFF_FACTOR) * adj_factor 146 b = min(parent.difficulty, MIN_DIFF) 147 child_diff = max(a,b ) 148 */ 149 x := (time - parent.Time) / 9 // (block_timestamp - parent_timestamp) // 9 150 c := uint64(1) // if parent.unclehash == emptyUncleHashHash 151 if parent.UncleHash != types.EmptyUncleHash { 152 c = 2 153 } 154 xNeg := x >= c 155 if xNeg { 156 // x is now _negative_ adjustment factor 157 x = x - c // - ( (t-p)/p -( 2 or 1) ) 158 } else { 159 x = c - x // (2 or 1) - (t-p)/9 160 } 161 if x > 99 { 162 x = 99 // max(x, 99) 163 } 164 // parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99)) 165 y := new(uint256.Int) 166 y.SetFromBig(parent.Difficulty) // y: p_diff 167 pDiff := y.Clone() // pdiff: p_diff 168 z := new(uint256.Int).SetUint64(x) //z : +-adj_factor (either pos or negative) 169 y.Rsh(y, difficultyBoundDivisor) // y: p__diff / 2048 170 z.Mul(y, z) // z: (p_diff / 2048 ) * (+- adj_factor) 171 172 if xNeg { 173 y.Sub(pDiff, z) // y: parent_diff + parent_diff/2048 * adjustment_factor 174 } else { 175 y.Add(pDiff, z) // y: parent_diff + parent_diff/2048 * adjustment_factor 176 } 177 // minimum difficulty can ever be (before exponential factor) 178 if y.LtUint64(minimumDifficulty) { 179 y.SetUint64(minimumDifficulty) 180 } 181 // calculate a fake block number for the ice-age delay 182 // Specification: https://eips.ethereum.org/EIPS/eip-1234 183 var pNum = parent.Number.Uint64() 184 if pNum >= bombDelayFromParent { 185 if fakeBlockNumber := pNum - bombDelayFromParent; fakeBlockNumber >= 2*expDiffPeriodUint { 186 z.SetOne() 187 z.Lsh(z, uint(fakeBlockNumber/expDiffPeriodUint-2)) 188 y.Add(z, y) 189 } 190 } 191 return y.ToBig() 192 } 193 }