commit
c929c2a6bb
|
@ -284,4 +284,43 @@ namespace cryptonote {
|
|||
return static_cast<uint64_t>(next_D);
|
||||
}
|
||||
}
|
||||
|
||||
// LWMA-3 difficulty algorithm
|
||||
// Copyright (c) 2017-2018 Zawy, MIT License
|
||||
difficulty_type next_difficulty_v4(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t height) {
|
||||
|
||||
uint64_t T = DIFFICULTY_TARGET_V2;
|
||||
uint64_t N = DIFFICULTY_WINDOW_V2;
|
||||
uint64_t L(0), ST, sum_3_ST(0), next_D, prev_D, this_timestamp, previous_timestamp;
|
||||
|
||||
assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 );
|
||||
|
||||
if ( height == DIFFICULTY_HEIGHT_V2 ){
|
||||
return static_cast<uint64_t>(DIFFICULTY_GUESS);
|
||||
}
|
||||
|
||||
previous_timestamp = timestamps[0];
|
||||
for ( uint64_t i = 1; i <= N; i++) {
|
||||
if ( timestamps[i] > previous_timestamp ) {
|
||||
this_timestamp = timestamps[i];
|
||||
} else { this_timestamp = previous_timestamp+1; }
|
||||
ST = std::min(6*T ,this_timestamp - previous_timestamp);
|
||||
previous_timestamp = this_timestamp;
|
||||
L += ST * i ;
|
||||
if ( i > N-3 ) { sum_3_ST += ST; }
|
||||
}
|
||||
|
||||
next_D = ((cumulative_difficulties[N] - cumulative_difficulties[0])*T*(N+1)*99)/(100*2*L);
|
||||
prev_D = cumulative_difficulties[N] - cumulative_difficulties[N-1];
|
||||
next_D = std::max((prev_D*67)/100, std::min(next_D, (prev_D*150)/100));
|
||||
|
||||
if ( sum_3_ST < (8*T)/10) { next_D = std::max(next_D,(prev_D*108)/100); }
|
||||
|
||||
if ( next_D < DIFFICULTY_MINIMUM ) {
|
||||
return static_cast<uint64_t>(DIFFICULTY_MINIMUM);
|
||||
}
|
||||
else {
|
||||
return static_cast<uint64_t>(next_D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,4 +55,5 @@ namespace cryptonote
|
|||
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
|
||||
difficulty_type next_difficulty_v2(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
|
||||
difficulty_type next_difficulty_v3(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t height);
|
||||
difficulty_type next_difficulty_v4(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t height);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT 60*60*2
|
||||
#define CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE 4
|
||||
|
||||
#define BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 11
|
||||
#define BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW 60
|
||||
|
||||
// MONEY_SUPPLY - total number coins to be generated
|
||||
|
@ -82,6 +83,7 @@
|
|||
#define DIFFICULTY_BLOCKS_COUNT_V2 DIFFICULTY_WINDOW_V2 + 1 // added +1 to make N=N
|
||||
#define DIFFICULTY_BLOCKS_COUNT DIFFICULTY_WINDOW + DIFFICULTY_LAG
|
||||
#define DIFFICULTY_HEIGHT 53666 // v9 fork height
|
||||
#define DIFFICULTY_HEIGHT_V2 777777 // v10 fork height
|
||||
#define DIFFICULTY_GUESS 40000000 // difficulty at fork 40m
|
||||
#define DIFFICULTY_MINIMUM 25000000 // minimum difficulty set to 25m
|
||||
|
||||
|
|
|
@ -838,8 +838,11 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
|
|||
else if (version == 8) {
|
||||
return next_difficulty_v2(timestamps, difficulties, target);
|
||||
}
|
||||
else {
|
||||
else if (version == 9) {
|
||||
return next_difficulty_v3(timestamps, difficulties, height);
|
||||
}
|
||||
else {
|
||||
return next_difficulty_v4(timestamps, difficulties, height);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
@ -1056,9 +1059,12 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
|||
}
|
||||
else if (version == 8) {
|
||||
return next_difficulty_v2(timestamps, cumulative_difficulties, target);
|
||||
}
|
||||
}
|
||||
else if (version == 9) {
|
||||
return next_difficulty_v2(timestamps, cumulative_difficulties, height);
|
||||
}
|
||||
else {
|
||||
return next_difficulty_v3(timestamps, cumulative_difficulties, height);
|
||||
return next_difficulty_v4(timestamps, cumulative_difficulties, height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1350,12 +1356,13 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m
|
|||
bool Blockchain::complete_timestamps_vector(uint64_t start_top_height, std::vector<uint64_t>& timestamps)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
|
||||
if(timestamps.size() >= BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW)
|
||||
const uint8_t hf_version = m_hardfork->get_current_version();
|
||||
size_t blockchain_timestamp_check_window = hf_version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
if(timestamps.size() >= blockchain_timestamp_check_window)
|
||||
return true;
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
size_t need_elements = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW - timestamps.size();
|
||||
size_t need_elements = blockchain_timestamp_check_window - timestamps.size();
|
||||
CHECK_AND_ASSERT_MES(start_top_height < m_db->height(), false, "internal error: passed start_height not < " << " m_db->height() -- " << start_top_height << " >= " << m_db->height());
|
||||
size_t stop_offset = start_top_height > need_elements ? start_top_height - need_elements : 0;
|
||||
while (start_top_height != stop_offset)
|
||||
|
@ -3203,10 +3210,12 @@ bool Blockchain::check_block_timestamp(std::vector<uint64_t>& timestamps, const
|
|||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
median_ts = epee::misc_utils::median(timestamps);
|
||||
const uint8_t hf_version = m_hardfork->get_current_version();
|
||||
size_t blockchain_timestamp_check_window = hf_version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
|
||||
if(b.timestamp < median_ts)
|
||||
{
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", less than median of last " << BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW << " blocks, " << median_ts);
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", less than median of last " << blockchain_timestamp_check_window << " blocks, " << median_ts);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3224,6 +3233,8 @@ bool Blockchain::check_block_timestamp(const block& b, uint64_t& median_ts) cons
|
|||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
uint64_t cryptonote_block_future_time_limit = get_current_hard_fork_version() >= 8 ? CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V2 : CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT;
|
||||
const uint8_t hf_version = m_hardfork->get_current_version();
|
||||
size_t blockchain_timestamp_check_window = hf_version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
if(b.timestamp > get_adjusted_time() + cryptonote_block_future_time_limit)
|
||||
{
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than adjusted time + 10 minutes");
|
||||
|
@ -3231,7 +3242,7 @@ bool Blockchain::check_block_timestamp(const block& b, uint64_t& median_ts) cons
|
|||
}
|
||||
|
||||
// if not enough blocks, no proper median yet, return true
|
||||
if(m_db->height() < BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW)
|
||||
if(m_db->height() < blockchain_timestamp_check_window)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -3240,7 +3251,7 @@ bool Blockchain::check_block_timestamp(const block& b, uint64_t& median_ts) cons
|
|||
auto h = m_db->height();
|
||||
|
||||
// need most recent 60 blocks, get index of first of those
|
||||
size_t offset = h - BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
size_t offset = h - blockchain_timestamp_check_window;
|
||||
for(;offset < h; ++offset)
|
||||
{
|
||||
timestamps.push_back(m_db->get_block_timestamp(offset));
|
||||
|
|
Loading…
Reference in New Issue