@@ -20,226 +20,113 @@ import (
20
20
)
21
21
22
22
const (
23
- // Custom difficulty parameters (used for blocks before hardfork)
24
- minimumDifficulty = 1000000
25
- difficultyBoundDivisor = 512
26
- // R5 difficulty parameters (used for blocks >= hardfork)
27
- r5MinimumDifficulty = 1000000
28
- r5DifficultyBoundDivisor = 11
29
- // Hardfork block number
30
- hardForkBlock = 45000
31
- // Block time target (in seconds) for both calculations;
32
- // note: for R5 (post-hardfork) this replaces original target.
33
- targetBlockTime = 7
23
+ // targetDurationLimit is the block time target.
24
+ targetDurationLimit = 7
25
+ // minimumDifficulty The minimum that the difficulty may ever be.
26
+ minimumDifficulty = 131072
27
+ // expDiffPeriodUint = 100000
28
+ // difficultyBoundDivisor is the bound divisor (2048),
29
+ // and the right-shifts to use for the division.
30
+ difficultyBoundDivisor = 11
34
31
)
35
32
36
- func roundRat (r * big.Rat ) * big.Int {
37
- num := new (big.Int ).Set (r .Num ())
38
- denom := new (big.Int ).Set (r .Denom ())
39
- quotient , remainder := new (big.Int ).QuoRem (num , denom , new (big.Int ))
40
- if new (big.Int ).Mul (remainder , big .NewInt (2 )).Cmp (denom ) >= 0 {
41
- quotient .Add (quotient , big .NewInt (1 ))
42
- }
43
- return quotient
44
- }
45
-
46
- // CalcDifficultyFrontierU256 calculates the block difficulty using the Frontier rules.
47
- // For blocks with parent.Number >= hardForkBlock the calculation uses the R5 new formula
33
+ // CalcDifficultyFrontierU256 is the difficulty adjustment algorithm using the Frontier rules.
48
34
func CalcDifficultyFrontierU256 (time uint64 , parent * types.Header ) * big.Int {
49
- // If past the hardfork block, use R5 difficulty calculation.
50
- if parent .Number .Uint64 () >= hardForkBlock {
51
- pDiff , _ := uint256 .FromBig (parent .Difficulty )
52
- adjust := pDiff .Clone ()
53
- adjust .Rsh (adjust , r5DifficultyBoundDivisor )
54
- // With a 7-second target, add difficulty if block time is less than 7 sec.
55
- if time - parent .Time < targetBlockTime {
56
- pDiff .Add (pDiff , adjust )
57
- } else {
58
- pDiff .Sub (pDiff , adjust )
59
- }
60
- if pDiff .LtUint64 (r5MinimumDifficulty ) {
61
- pDiff .SetUint64 (r5MinimumDifficulty )
62
- }
63
- return pDiff .ToBig ()
64
- }
35
+ /*
36
+ Modified algorithm:
37
+ block_diff = pdiff + pdiff / 2048 * (1 if time - ptime < 7 else -1)
38
+ */
65
39
66
- // Custom (pre-hardfork) calculation.
67
- pDiff , _ := uint256 .FromBig (parent .Difficulty )
40
+ pDiff , _ := uint256 .FromBig (parent .Difficulty ) // pDiff: parent's difficulty
68
41
adjust := pDiff .Clone ()
69
- adjust .Rsh (adjust , difficultyBoundDivisor )
70
- diffSec := int64 (time - parent .Time )
71
- x := new (big.Rat ).SetFrac64 (diffSec , targetBlockTime )
72
-
73
- cVal := int64 (1 )
74
- if parent .UncleHash != types .EmptyUncleHash {
75
- cVal = 2
76
- }
77
- cRat := new (big.Rat ).SetInt64 (cVal )
78
-
79
- delta := new (big.Rat ).Sub (new (big.Rat ).Quo (x , cRat ), big .NewRat (1 , 1 ))
80
-
81
- adjustBig := adjust .ToBig ()
82
- prod := new (big.Rat ).Mul (new (big.Rat ).SetInt (adjustBig ), delta )
83
- adjAmount := roundRat (prod )
42
+ adjust .Rsh (adjust , difficultyBoundDivisor ) // adjust = parent's difficulty / 2048
84
43
85
- newDiff := new (big.Int ).Set (parent .Difficulty )
86
- if delta .Sign () >= 0 {
87
- newDiff .Sub (newDiff , adjAmount )
44
+ if time - parent .Time < targetDurationLimit {
45
+ pDiff .Add (pDiff , adjust )
88
46
} else {
89
- newDiff . Add ( newDiff , adjAmount )
47
+ pDiff . Sub ( pDiff , adjust )
90
48
}
91
-
92
- if newDiff .Cmp (big .NewInt (minimumDifficulty )) < 0 {
93
- newDiff .SetUint64 (minimumDifficulty )
94
- }
95
- if time - parent .Time < 2 {
96
- newDiff .Mul (newDiff , big .NewInt (11 ))
97
- newDiff .Div (newDiff , big .NewInt (10 ))
98
- }
99
- if parent .Number .Uint64 () < 300 {
100
- newDiff .Mul (newDiff , big .NewInt (3 ))
101
- newDiff .Div (newDiff , big .NewInt (2 ))
49
+ if pDiff .LtUint64 (minimumDifficulty ) {
50
+ pDiff .SetUint64 (minimumDifficulty )
102
51
}
103
- return newDiff
52
+ return pDiff . ToBig ()
104
53
}
105
54
106
- // CalcDifficultyHomesteadU256 calculates the block difficulty using the Homestead rules.
107
- // For blocks with parent.Number >= hardForkBlock the calculation uses the R5 formula.
55
+ // CalcDifficultyHomesteadU256 is the difficulty adjustment algorithm using the Homestead rules.
108
56
func CalcDifficultyHomesteadU256 (time uint64 , parent * types.Header ) * big.Int {
109
- // R5 calculation for post-hardfork blocks.
110
- if parent .Number .Uint64 () >= hardForkBlock {
111
- pDiff , _ := uint256 .FromBig (parent .Difficulty )
112
- adjust := pDiff .Clone ()
113
- adjust .Rsh (adjust , r5DifficultyBoundDivisor )
114
- // Replace the original divisor of 10 with our targetBlockTime (7 seconds)
115
- x := (time - parent .Time ) / targetBlockTime
116
- neg := true
117
- if x == 0 {
118
- x = 1
119
- neg = false
120
- } else if x >= 100 {
121
- x = 99
122
- } else {
123
- x = x - 1
124
- }
125
- z := new (uint256.Int ).SetUint64 (x )
126
- adjust .Mul (adjust , z )
127
- if neg {
128
- pDiff .Sub (pDiff , adjust )
129
- } else {
130
- pDiff .Add (pDiff , adjust )
131
- }
132
- if pDiff .LtUint64 (r5MinimumDifficulty ) {
133
- pDiff .SetUint64 (r5MinimumDifficulty )
134
- }
135
- return pDiff .ToBig ()
136
- }
57
+ /*
58
+ Modified algorithm:
59
+ block_diff = pdiff + pdiff / 2048 * (adjustment factor)
60
+ where adjustment factor is derived from (time - ptime)/7, adjusted so that a gap below 7 sec increases difficulty.
61
+ */
137
62
138
- // Custom (pre-hardfork) calculation.
139
- pDiff , _ := uint256 .FromBig (parent .Difficulty )
63
+ pDiff , _ := uint256 .FromBig (parent .Difficulty ) // pDiff: parent's difficulty
140
64
adjust := pDiff .Clone ()
141
- adjust .Rsh (adjust , difficultyBoundDivisor )
142
- diffSec := int64 (time - parent .Time )
143
- x := new (big.Rat ).SetFrac64 (diffSec , targetBlockTime )
144
-
145
- oneRat := new (big.Rat ).SetInt64 (1 )
146
- factor := new (big.Rat ).Sub (x , oneRat )
147
- neg := false
148
- if factor .Sign () < 0 {
149
- neg = true
150
- factor .Abs (factor )
65
+ adjust .Rsh (adjust , difficultyBoundDivisor ) // adjust = parent's difficulty / 2048
66
+
67
+ x := (time - parent .Time ) / 7 // use 7-second target instead of 10
68
+ var neg = true
69
+ if x == 0 {
70
+ x = 1
71
+ neg = false
72
+ } else if x >= 100 {
73
+ x = 99
74
+ } else {
75
+ x = x - 1
151
76
}
152
-
153
- adjustBig := adjust .ToBig ()
154
- prod := new (big.Rat ).Mul (new (big.Rat ).SetInt (adjustBig ), factor )
155
- adjAmount := roundRat (prod )
156
-
157
- newDiff := new (big.Int ).Set (parent .Difficulty )
77
+ z := new (uint256.Int ).SetUint64 (x )
78
+ adjust .Mul (adjust , z ) // adjust now holds: (parent difficulty / 2048) * adjustment factor
158
79
if neg {
159
- newDiff . Add ( newDiff , adjAmount )
80
+ pDiff . Sub ( pDiff , adjust )
160
81
} else {
161
- newDiff . Sub ( newDiff , adjAmount )
82
+ pDiff . Add ( pDiff , adjust )
162
83
}
163
-
164
- if newDiff .Cmp (big .NewInt (minimumDifficulty )) < 0 {
165
- newDiff .SetUint64 (minimumDifficulty )
166
- }
167
- if time - parent .Time < 2 {
168
- newDiff .Mul (newDiff , big .NewInt (11 ))
169
- newDiff .Div (newDiff , big .NewInt (10 ))
84
+ if pDiff .LtUint64 (minimumDifficulty ) {
85
+ pDiff .SetUint64 (minimumDifficulty )
170
86
}
171
- if parent .Number .Uint64 () < 300 {
172
- newDiff .Mul (newDiff , big .NewInt (3 ))
173
- newDiff .Div (newDiff , big .NewInt (2 ))
174
- }
175
- return newDiff
87
+ return pDiff .ToBig ()
176
88
}
177
89
178
- // MakeDifficultyCalculatorU256 returns a function to calculate difficulty.
179
- // For blocks with parent.Number >= hardForkBlock the returned function uses the R5 formula.
180
- func MakeDifficultyCalculatorU256 () func (time uint64 , parent * types.Header ) * big.Int {
90
+ // MakeDifficultyCalculatorU256 creates a difficulty calculator function using Byzantium rules.
91
+ func MakeDifficultyCalculatorU256 (bombDelay * big.Int ) func (time uint64 , parent * types.Header ) * big.Int {
92
+ // bombDelay parameter is still accepted for compatibility but is now unused.
93
+ _ = bombDelay
181
94
return func (time uint64 , parent * types.Header ) * big.Int {
182
- // R5 calculation for post-hardfork blocks.
183
- if parent .Number .Uint64 () >= hardForkBlock {
184
- x := (time - parent .Time ) / targetBlockTime
185
- c := uint64 (1 )
186
- if parent .UncleHash != types .EmptyUncleHash {
187
- c = 2
188
- }
189
- xNeg := x >= c
190
- if xNeg {
191
- x = x - c
192
- } else {
193
- x = c - x
194
- }
195
- if x > 99 {
196
- x = 99
197
- }
198
- y := new (uint256.Int )
199
- y .SetFromBig (parent .Difficulty )
200
- pDiff := y .Clone ()
201
- z := new (uint256.Int ).SetUint64 (x )
202
- y .Rsh (y , r5DifficultyBoundDivisor )
203
- z .Mul (y , z )
204
- if xNeg {
205
- y .Sub (pDiff , z )
206
- } else {
207
- y .Add (pDiff , z )
208
- }
209
- if y .LtUint64 (r5MinimumDifficulty ) {
210
- y .SetUint64 (r5MinimumDifficulty )
211
- }
212
- return y .ToBig ()
213
- }
214
-
215
- // Custom (pre-hardfork) calculation.
216
- diffSec := int64 (time - parent .Time )
217
- xRat := new (big.Rat ).SetFrac64 (diffSec , targetBlockTime )
218
-
219
- cVal := int64 (1 )
95
+ /*
96
+ Modified algorithm:
97
+ pDiff = parent.difficulty + parent.difficulty/2048 *
98
+ ( (adjustment constant) - ((time - ptime) / 7) )
99
+ The adjustment constant is 1 or 2 depending on the presence of uncles.
100
+ The difficulty bomb is removed.
101
+ */
102
+ x := (time - parent .Time ) / 7 // adjust using 7-second target
103
+ c := uint64 (1 )
220
104
if parent .UncleHash != types .EmptyUncleHash {
221
- cVal = 2
105
+ c = 2
106
+ }
107
+ xNeg := x >= c
108
+ if xNeg {
109
+ x = x - c
110
+ } else {
111
+ x = c - x
112
+ }
113
+ if x > 99 {
114
+ x = 99
222
115
}
223
- cRat := new (big.Rat ).SetInt64 (cVal )
224
-
225
- delta := new (big.Rat ).Sub (new (big.Rat ).Quo (xRat , cRat ), big .NewRat (1 , 1 ))
226
-
227
116
y := new (uint256.Int )
228
117
y .SetFromBig (parent .Difficulty )
118
+ pDiff := y .Clone ()
119
+ z := new (uint256.Int ).SetUint64 (x )
229
120
y .Rsh (y , difficultyBoundDivisor )
230
-
231
- prod := new (big.Rat ).Mul (new (big.Rat ).SetInt (y .ToBig ()), delta )
232
- adjAmount := roundRat (prod )
233
-
234
- if xRat .Cmp (cRat ) >= 0 {
235
- newDiff := new (big.Int ).Sub (parent .Difficulty , adjAmount )
236
- if newDiff .Cmp (big .NewInt (minimumDifficulty )) < 0 {
237
- newDiff .SetUint64 (minimumDifficulty )
238
- }
239
- return newDiff
121
+ z .Mul (y , z )
122
+ if xNeg {
123
+ y .Sub (pDiff , z )
240
124
} else {
241
- newDiff := new (big.Int ).Add (parent .Difficulty , adjAmount )
242
- return newDiff
125
+ y .Add (pDiff , z )
126
+ }
127
+ if y .LtUint64 (minimumDifficulty ) {
128
+ y .SetUint64 (minimumDifficulty )
243
129
}
130
+ return y .ToBig ()
244
131
}
245
132
}
0 commit comments