|
34 | 34 | CHUNK_LEN = 100 |
35 | 35 | BUBBLES_ACTIVATION_HEIGHT = 585318 |
36 | 36 | DIFFADJ_ACTIVATION_HEIGHT = 585322 |
| 37 | +BUTTERCUP_ACTIVATION_HEIGHT = 707000 |
37 | 38 |
|
38 | 39 | MAX_TARGET = 0x0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
39 | 40 | POW_AVERAGING_WINDOW = 17 |
40 | 41 | POW_MEDIAN_BLOCK_SPAN = 11 |
41 | 42 | POW_MAX_ADJUST_DOWN = 32 |
42 | 43 | POW_MAX_ADJUST_UP = 16 |
43 | 44 | POW_DAMPING_FACTOR = 4 |
44 | | -POW_TARGET_SPACING = 150 |
| 45 | +PRE_BUTTERCUP_POW_TARGET_SPACING = 150 |
| 46 | +POST_BUTTERCUP_POW_TARGET_SPACING = 75 |
45 | 47 |
|
46 | 48 | TARGET_CALC_BLOCKS = POW_AVERAGING_WINDOW + POW_MEDIAN_BLOCK_SPAN |
47 | 49 |
|
48 | | -AVERAGING_WINDOW_TIMESPAN = POW_AVERAGING_WINDOW * POW_TARGET_SPACING |
| 50 | +def get_pow_target_spacing(height): |
| 51 | + if height >= BUTTERCUP_ACTIVATION_HEIGHT: |
| 52 | + return POST_BUTTERCUP_POW_TARGET_SPACING |
| 53 | + return PRE_BUTTERCUP_POW_TARGET_SPACING |
49 | 54 |
|
50 | | -MIN_ACTUAL_TIMESPAN = AVERAGING_WINDOW_TIMESPAN * \ |
51 | | - (100 - POW_MAX_ADJUST_UP) // 100 |
| 55 | +def get_averaging_window_timespan(height): |
| 56 | + return POW_AVERAGING_WINDOW * get_pow_target_spacing(height) |
52 | 57 |
|
53 | | -MAX_ACTUAL_TIMESPAN = AVERAGING_WINDOW_TIMESPAN * \ |
54 | | - (100 + POW_MAX_ADJUST_DOWN) // 100 |
| 58 | +def get_min_actual_timespan(height): |
| 59 | + return get_averaging_window_timespan(height) * (100 - POW_MAX_ADJUST_UP) // 100 |
55 | 60 |
|
| 61 | +def get_max_actual_timespan(height): |
| 62 | + return get_averaging_window_timespan(height) * (100 + POW_MAX_ADJUST_DOWN) // 100 |
56 | 63 |
|
57 | 64 | def is_post_equihash_fork(height): |
58 | 65 | return height >= BUBBLES_ACTIVATION_HEIGHT |
@@ -231,6 +238,14 @@ def verify_header(self, header, prev_hash, target): |
231 | 238 | ] |
232 | 239 | bits = valid_bits[height%DIFFADJ_ACTIVATION_HEIGHT] |
233 | 240 | target = self.bits_to_target(bits) |
| 241 | + elif height >= BUTTERCUP_ACTIVATION_HEIGHT and height < BUTTERCUP_ACTIVATION_HEIGHT + POW_AVERAGING_WINDOW: |
| 242 | + valid_bits = [ |
| 243 | + 0x1f07ffff, 0x1f00a083, 0x1f00ace2, 0x1f00ba38, 0x1f07ffff, 0x1f016783, |
| 244 | + 0x1f018356, 0x1f01a152, 0x1f01c1a2, 0x1f01e474, 0x1f0209fc, 0x1f02326c, |
| 245 | + 0x1f025e01, 0x1f028cf8, 0x1f02bf93, 0x1f02f61c, 0x1f0330df, |
| 246 | + ] |
| 247 | + bits = valid_bits[height%BUTTERCUP_ACTIVATION_HEIGHT] |
| 248 | + target = self.bits_to_target(bits) |
234 | 249 | if bits != header.get('bits'): |
235 | 250 | raise Exception("bits mismatch: %s vs %s" % (bits, header.get('bits'))) |
236 | 251 | if int('0x' + _hash, 16) > target: |
@@ -426,15 +441,15 @@ def get_target(self, height, chunk_headers=None): |
426 | 441 |
|
427 | 442 | actual_timespan = self.get_median_time(height, chunk_headers) - \ |
428 | 443 | self.get_median_time(height - POW_AVERAGING_WINDOW, chunk_headers) |
429 | | - actual_timespan = AVERAGING_WINDOW_TIMESPAN + \ |
430 | | - int((actual_timespan - AVERAGING_WINDOW_TIMESPAN) / \ |
| 444 | + actual_timespan = get_averaging_window_timespan(height) + \ |
| 445 | + int((actual_timespan - get_averaging_window_timespan(height)) / \ |
431 | 446 | POW_DAMPING_FACTOR) |
432 | | - if actual_timespan < MIN_ACTUAL_TIMESPAN: |
433 | | - actual_timespan = MIN_ACTUAL_TIMESPAN |
434 | | - elif actual_timespan > MAX_ACTUAL_TIMESPAN: |
435 | | - actual_timespan = MAX_ACTUAL_TIMESPAN |
| 447 | + if actual_timespan < get_min_actual_timespan(height): |
| 448 | + actual_timespan = get_min_actual_timespan(height) |
| 449 | + elif actual_timespan > get_max_actual_timespan(height): |
| 450 | + actual_timespan = get_max_actual_timespan(height) |
436 | 451 |
|
437 | | - next_target = mean_target // AVERAGING_WINDOW_TIMESPAN * actual_timespan |
| 452 | + next_target = mean_target // get_averaging_window_timespan(height) * actual_timespan |
438 | 453 |
|
439 | 454 | if next_target > MAX_TARGET: |
440 | 455 | next_target = MAX_TARGET |
|
0 commit comments