|
1 | 1 | # encoding: ascii-8bit |
2 | 2 |
|
3 | | -# This module includes (almost) everything necessary to add dogecoin support |
4 | | -# to bitcoin-ruby. When switching to a :dogecoin network, it will load its |
5 | | -# functionality into the Script class. |
6 | | -# The only things not included here should be parsing the AuxPow, which is |
7 | | -# done in Protocol::Block directly, and passing the txout to #store_doge from |
8 | | -# the storage backend. |
9 | | -module Bitcoin::Dogecoin |
10 | | - |
11 | | - def self.load |
12 | | - Bitcoin::Util.class_eval { include Util } |
13 | | - end |
14 | | - |
15 | | - # fixed reward past the 600k block |
16 | | - POST_600K_REWARD = 10000 * Bitcoin::COIN |
17 | | - |
18 | | - # Dogecoin-specific Script methods for parsing and creating of dogecoin scripts, |
19 | | - # as well as methods to extract address, doge_hash, doge and value. |
20 | | - module Util |
21 | | - |
22 | | - def self.included(base) |
23 | | - base.constants.each {|c| const_set(c, base.const_get(c)) unless constants.include?(c) } |
24 | | - base.class_eval do |
| 3 | +module Bitcoin |
| 4 | + # This module includes (almost) everything necessary to add dogecoin support |
| 5 | + # to bitcoin-ruby. When switching to a :dogecoin network, it will load its |
| 6 | + # functionality into the Script class. |
| 7 | + # The only things not included here should be parsing the AuxPow, which is |
| 8 | + # done in Protocol::Block directly, and passing the txout to #store_doge from |
| 9 | + # the storage backend. |
| 10 | + module Dogecoin |
| 11 | + def self.load |
| 12 | + Bitcoin::Util.class_eval { include Util } |
| 13 | + end |
25 | 14 |
|
26 | | - def block_creation_reward(block_height) |
27 | | - if block_height < Bitcoin.network[:difficulty_change_block] |
28 | | - # Dogecoin early rewards were random, using part of the hash of the |
29 | | - # previous block as the seed for the Mersenne Twister algorithm. |
30 | | - # Given we don't have previous block hash available, and this value is |
31 | | - # functionally a maximum (not exact value), I'm using the maximum the random |
32 | | - # reward generator can produce and calling it good enough. |
33 | | - Bitcoin.network[:reward_base] / (2 ** (block_height / Bitcoin.network[:reward_halving].to_f).floor) * 2 |
34 | | - elsif block_height < 600000 |
35 | | - Bitcoin.network[:reward_base] / (2 ** (block_height / Bitcoin.network[:reward_halving].to_f).floor) |
36 | | - else |
37 | | - POST_600K_REWARD |
| 15 | + # fixed reward past the 600k block |
| 16 | + POST_600K_REWARD = 10_000 * Bitcoin::COIN |
| 17 | + |
| 18 | + # Dogecoin-specific Script methods for parsing and creating of dogecoin scripts, |
| 19 | + # as well as methods to extract address, doge_hash, doge and value. |
| 20 | + module Util |
| 21 | + # rubocop:disable CyclomaticComplexity,PerceivedComplexity |
| 22 | + def self.included(base) |
| 23 | + base.constants.each { |c| const_set(c, base.const_get(c)) unless constants.include?(c) } |
| 24 | + base.class_eval do |
| 25 | + def block_creation_reward(block_height) |
| 26 | + reward_scaler = 2**(block_height / Bitcoin.network[:reward_halving].to_f).floor |
| 27 | + if block_height < Bitcoin.network[:difficulty_change_block] |
| 28 | + # Dogecoin early rewards were random, using part of the hash of the |
| 29 | + # previous block as the seed for the Mersenne Twister algorithm. |
| 30 | + # Given we don't have previous block hash available, and this value is |
| 31 | + # functionally a maximum (not exact value), I'm using the maximum the random |
| 32 | + # reward generator can produce and calling it good enough. |
| 33 | + Bitcoin.network[:reward_base] / reward_scaler * 2 |
| 34 | + elsif block_height < 600_000 |
| 35 | + Bitcoin.network[:reward_base] / reward_scaler |
| 36 | + else |
| 37 | + POST_600K_REWARD |
| 38 | + end |
38 | 39 | end |
39 | | - end |
40 | | - |
41 | | - def block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time) |
42 | | - new_difficulty_protocol = (prev_height + 1) >= Bitcoin.network[:difficulty_change_block] |
43 | 40 |
|
44 | | - # target interval for block interval in seconds |
45 | | - retarget_time = Bitcoin.network[:retarget_time] |
| 41 | + def block_new_target(prev_height, prev_block_time, prev_block_bits, last_retarget_time) |
| 42 | + new_difficulty_protocol = (prev_height + 1) >= Bitcoin.network[:difficulty_change_block] |
46 | 43 |
|
47 | | - if new_difficulty_protocol |
48 | | - # what is the ideal interval between the blocks |
49 | | - retarget_time = Bitcoin.network[:retarget_time_new] |
50 | | - end |
| 44 | + # target interval for block interval in seconds |
| 45 | + retarget_time = Bitcoin.network[:retarget_time] |
51 | 46 |
|
52 | | - # actual time elapsed since last retarget |
53 | | - actual_time = prev_block_time - last_retarget_time |
| 47 | + if new_difficulty_protocol |
| 48 | + # what is the ideal interval between the blocks |
| 49 | + retarget_time = Bitcoin.network[:retarget_time_new] |
| 50 | + end |
54 | 51 |
|
55 | | - if new_difficulty_protocol |
56 | | - # DigiShield implementation - thanks to RealSolid & WDC for this code |
57 | | - # We round always towards zero to match the C++ version |
58 | | - if actual_time < retarget_time |
59 | | - actual_time = retarget_time + ((actual_time - retarget_time) / 8.0).ceil |
| 52 | + # actual time elapsed since last retarget |
| 53 | + actual_time = prev_block_time - last_retarget_time |
| 54 | + |
| 55 | + if new_difficulty_protocol |
| 56 | + # DigiShield implementation - thanks to RealSolid & WDC for this code |
| 57 | + # We round always towards zero to match the C++ version |
| 58 | + actual_time = if actual_time < retarget_time |
| 59 | + retarget_time + ((actual_time - retarget_time) / 8.0).ceil |
| 60 | + else |
| 61 | + retarget_time + ((actual_time - retarget_time) / 8.0).floor |
| 62 | + end |
| 63 | + # amplitude filter - thanks to daft27 for this code |
| 64 | + min = retarget_time - (retarget_time / 4) |
| 65 | + max = retarget_time + (retarget_time / 2) |
| 66 | + elsif prev_height + 1 > 10_000 |
| 67 | + min = retarget_time / 4 |
| 68 | + max = retarget_time * 4 |
| 69 | + elsif prev_height + 1 > 5000 |
| 70 | + min = retarget_time / 8 |
| 71 | + max = retarget_time * 4 |
60 | 72 | else |
61 | | - actual_time = retarget_time + ((actual_time - retarget_time) / 8.0).floor |
| 73 | + min = retarget_time / 16 |
| 74 | + max = retarget_time * 4 |
62 | 75 | end |
63 | | - # amplitude filter - thanks to daft27 for this code |
64 | | - min = retarget_time - (retarget_time/4) |
65 | | - max = retarget_time + (retarget_time/2) |
66 | | - elsif prev_height+1 > 10000 |
67 | | - min = retarget_time / 4 |
68 | | - max = retarget_time * 4 |
69 | | - elsif prev_height+1 > 5000 |
70 | | - min = retarget_time / 8 |
71 | | - max = retarget_time * 4 |
72 | | - else |
73 | | - min = retarget_time / 16 |
74 | | - max = retarget_time * 4 |
75 | | - end |
76 | 76 |
|
77 | | - actual_time = min if actual_time < min |
78 | | - actual_time = max if actual_time > max |
| 77 | + actual_time = min if actual_time < min |
| 78 | + actual_time = max if actual_time > max |
79 | 79 |
|
80 | | - # It could be a bit confusing: we are adjusting difficulty of the previous block, while logically |
81 | | - # we should use difficulty of the previous 2016th block ("first") |
| 80 | + # It could be a bit confusing: we are adjusting difficulty of the previous block, |
| 81 | + # while logically we should use difficulty of the previous 2016th block ("first") |
82 | 82 |
|
83 | | - prev_target = decode_compact_bits(prev_block_bits).to_i(16) |
| 83 | + prev_target = decode_compact_bits(prev_block_bits).to_i(16) |
84 | 84 |
|
85 | | - new_target = prev_target * actual_time / retarget_time |
86 | | - if new_target < Bitcoin.decode_compact_bits(Bitcoin.network[:proof_of_work_limit]).to_i(16) |
87 | | - encode_compact_bits(new_target.to_s(16)) |
88 | | - else |
89 | | - Bitcoin.network[:proof_of_work_limit] |
| 85 | + new_target = prev_target * actual_time / retarget_time |
| 86 | + if new_target < Bitcoin.decode_compact_bits( |
| 87 | + Bitcoin.network[:proof_of_work_limit] |
| 88 | + ).to_i(16) |
| 89 | + encode_compact_bits(new_target.to_s(16)) |
| 90 | + else |
| 91 | + Bitcoin.network[:proof_of_work_limit] |
| 92 | + end |
90 | 93 | end |
91 | 94 | end |
92 | 95 | end |
| 96 | + # rubocop:enable CyclomaticComplexity,PerceivedComplexity |
93 | 97 | end |
94 | | - |
95 | 98 | end |
96 | | - |
97 | 99 | end |
0 commit comments