Electroneum
Loading...
Searching...
No Matches
cryptonote::HardFork Class Reference

#include <hardfork.h>

Classes

struct  Params

Public Types

enum  State { LikelyForked , UpdateNeeded , Ready }

Public Member Functions

 HardFork (cryptonote::BlockchainDB &db, uint8_t original_version=1, uint64_t original_version_till_height=DEFAULT_ORIGINAL_VERSION_TILL_HEIGHT, time_t forked_time=DEFAULT_FORKED_TIME, time_t update_time=DEFAULT_UPDATE_TIME, uint64_t window_size=DEFAULT_WINDOW_SIZE, uint8_t default_threshold_percent=DEFAULT_THRESHOLD_PERCENT)
 creates a new HardFork object
bool add_fork (uint8_t version, uint64_t height, uint8_t threshold, time_t time)
 add a new hardfork height
bool add_fork (uint8_t version, uint64_t height, time_t time)
 add a new hardfork height
void init ()
 initialize the object
bool check (const cryptonote::block &block) const
 check whether a new block would be accepted
bool check_for_height (const cryptonote::block &block, uint64_t height) const
 same as check, but for a particular height, rather than the top
bool add (const cryptonote::block &block, uint64_t height)
 add a new block
bool reorganize_from_block_height (uint64_t height)
 called when the blockchain is reorganized
bool reorganize_from_chain_height (uint64_t height)
void on_block_popped (uint64_t new_chain_height)
 called when one or more blocks are popped from the blockchain
State get_state (time_t t) const
 returns current state at the given time
State get_state () const
uint8_t get (uint64_t height) const
 returns the hard fork version for the given block height
uint8_t get_ideal_version () const
 returns the latest "ideal" version
uint8_t get_ideal_version (uint64_t height) const
 returns the "ideal" version for a given height
uint8_t get_next_version () const
 returns the next version
uint8_t get_current_version () const
 returns the current version
uint64_t get_earliest_ideal_height_for_version (uint8_t version) const
 returns the earliest block a given version may activate
bool get_voting_info (uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const
 returns information about current voting state
uint64_t get_window_size () const
 returns the size of the voting window in blocks

Static Public Attributes

static const uint64_t DEFAULT_ORIGINAL_VERSION_TILL_HEIGHT = 0
static const time_t DEFAULT_FORKED_TIME = 31557600
static const time_t DEFAULT_UPDATE_TIME = 31557600 / 2
static const uint64_t DEFAULT_WINDOW_SIZE = 10080
static const uint8_t DEFAULT_THRESHOLD_PERCENT = 80

Detailed Description

Definition at line 39 of file hardfork.h.

Member Enumeration Documentation

◆ State

Enumerator
LikelyForked 
UpdateNeeded 
Ready 

Definition at line 42 of file hardfork.h.

Constructor & Destructor Documentation

◆ HardFork()

HardFork::HardFork ( cryptonote::BlockchainDB & db,
uint8_t original_version = 1,
uint64_t original_version_till_height = DEFAULT_ORIGINAL_VERSION_TILL_HEIGHT,
time_t forked_time = DEFAULT_FORKED_TIME,
time_t update_time = DEFAULT_UPDATE_TIME,
uint64_t window_size = DEFAULT_WINDOW_SIZE,
uint8_t default_threshold_percent = DEFAULT_THRESHOLD_PERCENT )

creates a new HardFork object

Parameters
original_versionthe block version for blocks 0 through to the first fork
forked_timethe time in seconds before thinking we're forked
update_timethe time in seconds before thinking we need to update
window_sizethe size of the window in blocks to consider for version voting
default_threshold_percentthe size of the majority in percents

Definition at line 58 of file hardfork.cpp.

58 :
59 db(db),
60 forked_time(forked_time),
61 update_time(update_time),
62 window_size(window_size),
63 default_threshold_percent(default_threshold_percent),
64 original_version(original_version),
65 original_version_till_height(original_version_till_height),
66 current_fork_index(0)
67{
68 if (window_size == 0)
69 throw "window_size needs to be strictly positive";
70 if (default_threshold_percent > 100)
71 throw "default_threshold_percent needs to be between 0 and 100";
72}

Member Function Documentation

◆ add()

bool HardFork::add ( const cryptonote::block & block,
uint64_t height )

add a new block

returns true if no error, false otherwise

Parameters
blockthe new block

Definition at line 164 of file hardfork.cpp.

165{
166 return add(::get_block_version(block), ::get_block_vote(block), height);
167}
uint64_t height
bool add(const cryptonote::block &block, uint64_t height)
add a new block
Definition hardfork.cpp:164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_fork() [1/2]

bool HardFork::add_fork ( uint8_t version,
uint64_t height,
time_t time )

add a new hardfork height

returns true if no error, false otherwise

Parameters
versionthe major block version for the fork
heightThe height the hardfork takes effect
timeApproximate time of the hardfork (seconds since epoch)

Definition at line 95 of file hardfork.cpp.

96{
97 return add_fork(version, height, default_threshold_percent, time);
98}
uint8_t version
time_t time
bool add_fork(uint8_t version, uint64_t height, uint8_t threshold, time_t time)
add a new hardfork height
Definition hardfork.cpp:74
Here is the call graph for this function:

◆ add_fork() [2/2]

bool HardFork::add_fork ( uint8_t version,
uint64_t height,
uint8_t threshold,
time_t time )

add a new hardfork height

returns true if no error, false otherwise

Parameters
versionthe major block version for the fork
heightThe height the hardfork takes effect
thresholdThe threshold of votes needed for this fork (0-100)
timeApproximate time of the hardfork (seconds since epoch)

Definition at line 74 of file hardfork.cpp.

75{
77
78 // add in order
79 if (version == 0)
80 return false;
81 if (!heights.empty()) {
82 if (version <= heights.back().version)
83 return false;
84 if (height <= heights.back().height)
85 return false;
86 if (time <= heights.back().time)
87 return false;
88 }
89 if (threshold > 100)
90 return false;
91 heights.push_back(Params(version, height, threshold, time));
92 return true;
93}
uint8_t threshold
#define CRITICAL_REGION_LOCAL(x)
Definition syncobj.h:228
Here is the caller graph for this function:

◆ check()

bool HardFork::check ( const cryptonote::block & block) const

check whether a new block would be accepted

returns true if the block is accepted, false otherwise

Parameters
blockthe new block

This check is made by add. It is exposed publicly to allow the caller to inexpensively check whether a block would be accepted or rejected by its version number. Indeed, if this check could only be done as part of add, the caller would either have to add the block to the blockchain first, then call add, then have to pop the block from the blockchain if its version did not satisfy the hard fork requirements, or call add first, then, if the hard fork requirements are met, add the block to the blockchain, upon which a failure (the block being invalid, double spending, etc) would cause the hardfork object to reorganize.

Definition at line 116 of file hardfork.cpp.

117{
119 return do_check(::get_block_version(block), ::get_block_vote(block));
120}

◆ check_for_height()

bool HardFork::check_for_height ( const cryptonote::block & block,
uint64_t height ) const

same as check, but for a particular height, rather than the top

NOTE: this does not play well with voting, and relies on voting to be disabled (that is, forks happen on the scheduled date, whether or not enough blocks have voted for the fork).

returns true if no error, false otherwise

Parameters
blockthe new block
heightwhich height to check for

Definition at line 129 of file hardfork.cpp.

130{
132 return do_check_for_height(::get_block_version(block), ::get_block_vote(block), height);
133}
Here is the caller graph for this function:

◆ get()

uint8_t HardFork::get ( uint64_t height) const

returns the hard fork version for the given block height

Parameters
heightheight of the block to check

Definition at line 348 of file hardfork.cpp.

349{
351 if (height > db.height()) {
352 assert(false);
353 return 255;
354 }
355 if (height == db.height()) {
356 return get_current_version();
357 }
358 return db.get_hard_fork_version(height);
359}
uint8_t get_current_version() const
returns the current version
Definition hardfork.cpp:361
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_current_version()

uint8_t HardFork::get_current_version ( ) const

returns the current version

This is the latest version that's past its trigger date and had enough votes at one point in the past.

Definition at line 361 of file hardfork.cpp.

362{
364 return heights[current_fork_index].version;
365}
Here is the caller graph for this function:

◆ get_earliest_ideal_height_for_version()

uint64_t HardFork::get_earliest_ideal_height_for_version ( uint8_t version) const

returns the earliest block a given version may activate

Definition at line 384 of file hardfork.cpp.

385{
386 uint64_t height = std::numeric_limits<uint64_t>::max();
387 for (auto i = heights.rbegin(); i != heights.rend(); ++i) {
388 if (i->version >= version) {
389 height = i->height;
390 } else {
391 break;
392 }
393 }
394 return height;
395}
unsigned __int64 uint64_t
Definition stdint.h:136
Here is the caller graph for this function:

◆ get_ideal_version() [1/2]

uint8_t HardFork::get_ideal_version ( ) const

returns the latest "ideal" version

This is the latest version that's been scheduled

Definition at line 367 of file hardfork.cpp.

368{
370 return heights.back().version;
371}
Here is the caller graph for this function:

◆ get_ideal_version() [2/2]

uint8_t HardFork::get_ideal_version ( uint64_t height) const

returns the "ideal" version for a given height

Parameters
heightheight of the block to check

Definition at line 373 of file hardfork.cpp.

374{
376 for (unsigned int n = heights.size() - 1; n > 0; --n) {
377 if (height >= heights[n].height) {
378 return heights[n].version;
379 }
380 }
381 return original_version;
382}

◆ get_next_version()

uint8_t HardFork::get_next_version ( ) const

returns the next version

This is the version which will we fork to next

Definition at line 397 of file hardfork.cpp.

398{
400 uint64_t height = db.height();
401 for (auto i = heights.rbegin(); i != heights.rend(); ++i) {
402 if (height >= i->height) {
403 return (i == heights.rbegin() ? i : (i - 1))->version;
404 }
405 }
406 return original_version;
407}
Here is the caller graph for this function:

◆ get_state() [1/2]

HardFork::State HardFork::get_state ( ) const

Definition at line 343 of file hardfork.cpp.

344{
345 return get_state(time(NULL));
346}
State get_state() const
Definition hardfork.cpp:343
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_state() [2/2]

HardFork::State HardFork::get_state ( time_t t) const

returns current state at the given time

Based on the approximate time of the last known hard fork, estimate whether we need to update, or if we're way behind

Parameters
tthe time to consider

Definition at line 327 of file hardfork.cpp.

328{
330
331 // no hard forks setup yet
332 if (heights.size() <= 1)
333 return Ready;
334
335 time_t t_last_fork = heights.back().time;
336 if (t >= t_last_fork + forked_time)
337 return LikelyForked;
338 if (t >= t_last_fork + update_time)
339 return UpdateNeeded;
340 return Ready;
341}
Here is the caller graph for this function:

◆ get_voting_info()

bool HardFork::get_voting_info ( uint8_t version,
uint32_t & window,
uint32_t & votes,
uint32_t & threshold,
uint64_t & earliest_height,
uint8_t & voting ) const

returns information about current voting state

returns true if the given version is enabled (ie, the current version is at least the passed version), false otherwise

Parameters
versionthe version to check voting for
windowthe number of blocks considered in voting
votesnumber of votes for next version
thresholdnumber of votes needed to switch to next version
earliest_heightearliest height at which the version can take effect

Definition at line 409 of file hardfork.cpp.

410{
412
413 const uint8_t current_version = heights[current_fork_index].version;
414 const bool enabled = current_version >= version;
415 window = versions.size();
416 votes = 0;
417 for (size_t n = version; n < 256; ++n)
418 votes += last_versions[n];
419 threshold = (window * heights[current_fork_index].threshold + 99) / 100;
420 //assert((votes >= threshold) == enabled);
422 voting = heights.back().version;
423 return enabled;
424}
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const
returns the earliest block a given version may activate
Definition hardfork.cpp:384
unsigned char uint8_t
Definition stdint.h:124
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_window_size()

uint64_t cryptonote::HardFork::get_window_size ( ) const
inline

returns the size of the voting window in blocks

Definition at line 232 of file hardfork.h.

232{ return window_size; }

◆ init()

void HardFork::init ( )

initialize the object

Must be done after adding all the required hardforks via add above

Definition at line 169 of file hardfork.cpp.

170{
172
173 // add a placeholder for the default version, to avoid special cases
174 if (heights.empty())
175 heights.push_back(Params(original_version, 0, 0, 0));
176
177 versions.clear();
178 for (size_t n = 0; n < 256; ++n)
179 last_versions[n] = 0;
180 current_fork_index = 0;
181
182 // restore state from DB
183 uint64_t height = db.height();
184 if (height > window_size)
185 height -= window_size - 1;
186 else
187 height = 1;
188
189 rescan_from_chain_height(height);
190 MDEBUG("init done");
191}
#define MDEBUG(x)
Definition misc_log_ex.h:76
Here is the caller graph for this function:

◆ on_block_popped()

void HardFork::on_block_popped ( uint64_t new_chain_height)

called when one or more blocks are popped from the blockchain

The current fork will be updated by looking up the db, which is much cheaper than recomputing everything

Parameters
new_chain_heightthe height of the chain after popping

Definition at line 287 of file hardfork.cpp.

288{
289 CHECK_AND_ASSERT_THROW_MES(nblocks > 0, "nblocks must be greater than 0");
290
292
293 const uint64_t new_chain_height = db.height();
294 const uint64_t old_chain_height = new_chain_height + nblocks;
296 for (uint64_t height = old_chain_height - 1; height >= new_chain_height; --height)
297 {
298 version = versions.back();
299 last_versions[version]--;
300 versions.pop_back();
301 version = db.get_hard_fork_version(height);
302 versions.push_front(version);
303 last_versions[version]++;
304 }
305
306 // does not take voting into account
307 for (current_fork_index = heights.size() - 1; current_fork_index > 0; --current_fork_index)
308 if (new_chain_height >= heights[current_fork_index].height)
309 break;
310}
#define CHECK_AND_ASSERT_THROW_MES(expr, message)

◆ reorganize_from_block_height()

bool HardFork::reorganize_from_block_height ( uint64_t height)

called when the blockchain is reorganized

This will rescan the blockchain to determine which hard forks have been triggered

returns true if no error, false otherwise

Parameters
blockchainthe blockchain
heightof the last block kept from the previous blockchain

Definition at line 202 of file hardfork.cpp.

203{
205 if (height >= db.height())
206 return false;
207
208 bool stop_batch = db.batch_start();
209
210 versions.clear();
211
212 for (size_t n = 0; n < 256; ++n)
213 last_versions[n] = 0;
214 const uint64_t rescan_height = height >= (window_size - 1) ? height - (window_size -1) : 0;
215 const uint8_t start_version = height == 0 ? original_version : db.get_hard_fork_version(height);
216 while (current_fork_index > 0 && heights[current_fork_index].version > start_version) {
217 --current_fork_index;
218 }
219 for (uint64_t h = rescan_height; h <= height; ++h) {
220 cryptonote::block b = db.get_block_from_height(h);
221 const uint8_t v = get_effective_version(get_block_vote(b));
222 last_versions[v]++;
223 versions.push_back(v);
224 }
225
226 uint8_t voted = get_voted_fork_index(height + 1);
227 if (voted > current_fork_index) {
228 current_fork_index = voted;
229 }
230
231 const uint64_t bc_height = db.height();
232 for (uint64_t h = height + 1; h < bc_height; ++h) {
233 add(db.get_block_from_height(h), h);
234 }
235
236 if (stop_batch)
237 db.batch_stop();
238
239 return true;
240}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reorganize_from_chain_height()

bool HardFork::reorganize_from_chain_height ( uint64_t height)

Definition at line 242 of file hardfork.cpp.

243{
244 if (height == 0)
245 return false;
247}
bool reorganize_from_block_height(uint64_t height)
called when the blockchain is reorganized
Definition hardfork.cpp:202
Here is the call graph for this function:

Member Data Documentation

◆ DEFAULT_FORKED_TIME

const time_t cryptonote::HardFork::DEFAULT_FORKED_TIME = 31557600
static

Definition at line 49 of file hardfork.h.

◆ DEFAULT_ORIGINAL_VERSION_TILL_HEIGHT

const uint64_t cryptonote::HardFork::DEFAULT_ORIGINAL_VERSION_TILL_HEIGHT = 0
static

Definition at line 48 of file hardfork.h.

◆ DEFAULT_THRESHOLD_PERCENT

const uint8_t cryptonote::HardFork::DEFAULT_THRESHOLD_PERCENT = 80
static

Definition at line 52 of file hardfork.h.

◆ DEFAULT_UPDATE_TIME

const time_t cryptonote::HardFork::DEFAULT_UPDATE_TIME = 31557600 / 2
static

Definition at line 50 of file hardfork.h.

◆ DEFAULT_WINDOW_SIZE

const uint64_t cryptonote::HardFork::DEFAULT_WINDOW_SIZE = 10080
static

Definition at line 51 of file hardfork.h.


The documentation for this class was generated from the following files:
  • /home/abuild/rpmbuild/BUILD/electroneum-5.1.3.1-build/electroneum-5.1.3.1/src/cryptonote_basic/hardfork.h
  • /home/abuild/rpmbuild/BUILD/electroneum-5.1.3.1-build/electroneum-5.1.3.1/src/cryptonote_basic/hardfork.cpp