Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aeon difficulty v9 #194

Merged
merged 3 commits into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 56 additions & 34 deletions src/cryptonote_basic/difficulty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ namespace cryptonote {
return !carry;
}

uint64_t next_difficulty_64(std::vector<std::uint64_t> timestamps, std::vector<uint64_t> cumulative_difficulties, size_t target_seconds, uint64_t height, uint64_t last_diff_reset_height, uint64_t last_diff_reset_value) {
uint64_t next_difficulty_64(std::vector<std::uint64_t> timestamps, std::vector<uint64_t> cumulative_difficulties, size_t target_seconds, uint64_t height, uint64_t last_diff_reset_height, uint64_t last_diff_reset_value, uint8_t version) {

bool is_diff_reset = false;
if (last_diff_reset_height != 0 && height >= last_diff_reset_height && height - last_diff_reset_height < timestamps.size())
Expand All @@ -130,10 +130,12 @@ namespace cryptonote {
cumulative_difficulties.erase(cumulative_difficulties.begin(), cumulative_difficulties.begin() + num_ignored_blocks);
}

const uint64_t difficulty_lag = version < 9 ? DIFFICULTY_LAG_V1 : DIFFICULTY_LAG_V9;
stoffu marked this conversation as resolved.
Show resolved Hide resolved
if(timestamps.size() > DIFFICULTY_WINDOW)
{
timestamps.resize(DIFFICULTY_WINDOW);
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
size_t window_start = timestamps.size() >= DIFFICULTY_WINDOW + difficulty_lag ? timestamps.size() - DIFFICULTY_WINDOW - difficulty_lag : 0;
timestamps = std::vector<uint64_t>(timestamps.begin() + window_start, timestamps.begin() + window_start + DIFFICULTY_WINDOW);
cumulative_difficulties = std::vector<uint64_t>(cumulative_difficulties.begin() + window_start, cumulative_difficulties.begin() + window_start + DIFFICULTY_WINDOW);
}


Expand All @@ -148,22 +150,30 @@ namespace cryptonote {
}
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
assert(length <= DIFFICULTY_WINDOW);
sort(timestamps.begin(), timestamps.end());
size_t cut_begin, cut_end;
static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
cut_begin = 0;
cut_end = length;
uint64_t time_span = 0;
uint64_t total_work = 0;
if (version < HF_VERSION_REMOVE_DIFFICULTY_SORT)
{
sort(timestamps.begin(), timestamps.end());
size_t cut_begin, cut_end;
static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
cut_begin = 0;
cut_end = length;
} else {
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
}
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
if (time_span == 0) {
time_span = 1;
}
total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin];
} else {
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
time_span = timestamps.front() < timestamps.back() ? timestamps.back() - timestamps.front() : 1;
total_work = cumulative_difficulties.back() - cumulative_difficulties.front();
}
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
if (time_span == 0) {
time_span = 1;
}
uint64_t total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin];
assert(total_work > 0);
uint64_t low, high;
mul(total_work, target_seconds, low, high);
Expand Down Expand Up @@ -218,7 +228,7 @@ namespace cryptonote {
return check_hash_128(hash, difficulty);
}

difficulty_type next_difficulty(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t height, uint64_t last_diff_reset_height, difficulty_type last_diff_reset_value) {
difficulty_type next_difficulty(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t height, uint64_t last_diff_reset_height, difficulty_type last_diff_reset_value, uint8_t version) {

bool is_diff_reset = false;
if (last_diff_reset_height != 0 && height >= last_diff_reset_height && height - last_diff_reset_height < timestamps.size())
Expand All @@ -230,10 +240,12 @@ namespace cryptonote {
}

//cutoff DIFFICULTY_LAG
const uint64_t difficulty_lag = version < 9 ? DIFFICULTY_LAG_V1 : DIFFICULTY_LAG_V9;
if(timestamps.size() > DIFFICULTY_WINDOW)
{
timestamps.resize(DIFFICULTY_WINDOW);
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
size_t window_start = timestamps.size() >= DIFFICULTY_WINDOW + difficulty_lag ? timestamps.size() - DIFFICULTY_WINDOW - difficulty_lag : 0;
timestamps = std::vector<uint64_t>(timestamps.begin() + window_start, timestamps.begin() + window_start + DIFFICULTY_WINDOW);
cumulative_difficulties = std::vector<difficulty_type>(cumulative_difficulties.begin() + window_start, cumulative_difficulties.begin() + window_start + DIFFICULTY_WINDOW);
}


Expand All @@ -248,22 +260,32 @@ namespace cryptonote {
}
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
assert(length <= DIFFICULTY_WINDOW);
sort(timestamps.begin(), timestamps.end());
size_t cut_begin, cut_end;
static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
cut_begin = 0;
cut_end = length;
} else {
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
uint64_t time_span = 0;
difficulty_type total_work = 0;
if (version < HF_VERSION_REMOVE_DIFFICULTY_SORT)
{
sort(timestamps.begin(), timestamps.end());
size_t cut_begin, cut_end;
static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
cut_begin = 0;
cut_end = length;
} else {
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
}
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
if (time_span == 0) {
time_span = 1;
}
total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin];
}
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
if (time_span == 0) {
time_span = 1;
else
{
time_span = timestamps.front() < timestamps.back() ? timestamps.back() - timestamps.front() : 1;
total_work = cumulative_difficulties.back() - cumulative_difficulties.front();
}
difficulty_type total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin];
assert(total_work > 0);
boost::multiprecision::uint256_t res = (boost::multiprecision::uint256_t(total_work) * target_seconds + time_span - 1) / time_span;
if (height >= HARDFORK_1_HEIGHT && height < HARDFORK_1_HEIGHT+HARDFORK_1_DIFFADJ_WINDOW) {
Expand Down
4 changes: 2 additions & 2 deletions src/cryptonote_basic/difficulty.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ namespace cryptonote
* @return true if valid, else false
*/
bool check_hash_64(const crypto::hash &hash, uint64_t difficulty);
uint64_t next_difficulty_64(std::vector<std::uint64_t> timestamps, std::vector<uint64_t> cumulative_difficulties, size_t target_seconds, uint64_t height, uint64_t last_diff_reset_height, uint64_t last_diff_reset_value);
uint64_t next_difficulty_64(std::vector<std::uint64_t> timestamps, std::vector<uint64_t> cumulative_difficulties, size_t target_seconds, uint64_t height, uint64_t last_diff_reset_height, uint64_t last_diff_reset_value, uint8_t version);

bool check_hash_128(const crypto::hash &hash, difficulty_type difficulty);
bool check_hash(const crypto::hash &hash, difficulty_type difficulty);
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t height, uint64_t last_diff_reset_height, difficulty_type last_diff_reset_value);
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t height, uint64_t last_diff_reset_height, difficulty_type last_diff_reset_value, uint8_t version);
}
7 changes: 5 additions & 2 deletions src/cryptonote_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@
#define DIFFICULTY_TARGET_V2 240 // seconds
#define DIFFICULTY_TARGET_V1 60 // seconds - before first fork
#define DIFFICULTY_WINDOW 720 // blocks
#define DIFFICULTY_LAG 15 // !!!
#define DIFFICULTY_LAG_V1 15 // !!!
#define DIFFICULTY_LAG_V9 8
static_assert(DIFFICULTY_LAG_V9 < DIFFICULTY_LAG_V1, "");
#define DIFFICULTY_CUT 60 // timestamps to cut after sorting
#define DIFFICULTY_BLOCKS_COUNT (DIFFICULTY_WINDOW + DIFFICULTY_LAG)
#define DIFFICULTY_BLOCKS_COUNT (DIFFICULTY_WINDOW + DIFFICULTY_LAG_V1)


#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1 DIFFICULTY_TARGET_V1 * CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS
Expand Down Expand Up @@ -140,6 +142,7 @@
#define HF_VERSION_FIXED_RING_SIZE 8
#define HF_VERSION_ENFORCE_MIN_AGE 8
#define HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY 9
#define HF_VERSION_REMOVE_DIFFICULTY_SORT 9

#define HASH_OF_HASHES_STEP 256

Expand Down
14 changes: 10 additions & 4 deletions src/cryptonote_core/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ static const struct {

// version 8 (PoW change to k12) starts from block 112000 with reset diff 500 million
{ 8, 112000, 0, 1553869222, 500000000 },

// version 9 (difficulty algorithm variant 9) starts from block 131111 with no diff reset
{ 9, 131111, 0, 1600148906, 0 },
};
static const uint64_t testnet_hard_fork_version_1_till = 43999;

Expand Down Expand Up @@ -927,7 +930,8 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
size_t target = get_difficulty_target();
uint64_t last_diff_reset_height = m_hardfork->get_last_diff_reset_height(height);
difficulty_type last_diff_reset_value = m_hardfork->get_last_diff_reset_value(height);
difficulty_type diff = next_difficulty(timestamps, difficulties, target, height, last_diff_reset_height, last_diff_reset_value);
uint8_t hf_version = m_hardfork->get_current_version();
difficulty_type diff = next_difficulty(timestamps, difficulties, target, height, last_diff_reset_height, last_diff_reset_value, hf_version);

CRITICAL_REGION_LOCAL1(m_difficulty_lock);
m_difficulty_for_next_block_top_hash = top_hash;
Expand Down Expand Up @@ -1004,10 +1008,11 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
std::vector<difficulty_type> new_cumulative_difficulties;
for (uint64_t height = start_height; height <= top_height; ++height)
{
size_t target = get_ideal_hard_fork_version(height) < 2 && height < HARDFORK_1_HEIGHT ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
uint8_t hf_version = get_ideal_hard_fork_version(height);
size_t target = hf_version < 2 && height < HARDFORK_1_HEIGHT ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
uint64_t last_diff_reset_height = m_hardfork->get_last_diff_reset_height(height);
difficulty_type last_diff_reset_value = m_hardfork->get_last_diff_reset_value(height);
difficulty_type recalculated_diff = next_difficulty(timestamps, difficulties, target, height, last_diff_reset_height, last_diff_reset_value);
difficulty_type recalculated_diff = next_difficulty(timestamps, difficulties, target, height, last_diff_reset_height, last_diff_reset_value, hf_version);

boost::multiprecision::uint256_t recalculated_cum_diff_256 = boost::multiprecision::uint256_t(recalculated_diff) + last_cum_diff;
CHECK_AND_ASSERT_THROW_MES(recalculated_cum_diff_256 <= std::numeric_limits<difficulty_type>::max(), "Difficulty overflow!");
Expand Down Expand Up @@ -1286,9 +1291,10 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
size_t target = get_ideal_hard_fork_version(bei.height) < 2 && bei.height < HARDFORK_1_HEIGHT ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
uint64_t last_diff_reset_height = m_hardfork->get_last_diff_reset_height(bei.height);
difficulty_type last_diff_reset_value = m_hardfork->get_last_diff_reset_value(bei.height);
uint8_t hf_version = m_hardfork->get_current_version();

// calculate the difficulty target for the block and return it
return next_difficulty(timestamps, cumulative_difficulties, target, bei.height, last_diff_reset_height, last_diff_reset_value);
return next_difficulty(timestamps, cumulative_difficulties, target, bei.height, last_diff_reset_height, last_diff_reset_value, hf_version);
}
//------------------------------------------------------------------
// This function does a sanity check on basic things that all miner
Expand Down
8 changes: 4 additions & 4 deletions tests/core_tests/block_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace
for (size_t i = 0; i < new_block_count; ++i)
{
block blk_next;
difficulty_type diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V1,get_block_height(blk_prev)+1,0,0);
difficulty_type diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V1,get_block_height(blk_prev)+1,0,0,0);
if (!generator.construct_block_manually(blk_next, blk_prev, miner_account,
test_generator::bf_timestamp | test_generator::bf_diffic, 0, 0, blk_prev.timestamp, crypto::hash(), diffic))
return false;
Expand Down Expand Up @@ -176,7 +176,7 @@ bool gen_block_invalid_nonce::generate(std::vector<test_event_entry>& events) co

// Create invalid nonce
const block& blk_last = boost::get<block>(events.back());
difficulty_type diffic = next_difficulty(timestamps, commulative_difficulties,DIFFICULTY_TARGET_V1,get_block_height(blk_last)+1,0,0);
difficulty_type diffic = next_difficulty(timestamps, commulative_difficulties,DIFFICULTY_TARGET_V1,get_block_height(blk_last)+1,0,0,0);
assert(1 < diffic);
uint64_t timestamp = blk_last.timestamp;
block blk_3;
Expand Down Expand Up @@ -572,7 +572,7 @@ bool gen_block_invalid_binary_format::generate(std::vector<test_event_entry>& ev
do
{
blk_last = boost::get<block>(events.back());
diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V1,get_block_height(blk_last)+1,0,0);
diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V1,get_block_height(blk_last)+1,0,0,0);
if (!lift_up_difficulty(events, timestamps, cummulative_difficulties, generator, 1, blk_last, miner_account))
return false;
std::cout << "Block #" << events.size() << ", difficulty: " << diffic << std::endl;
Expand All @@ -587,7 +587,7 @@ bool gen_block_invalid_binary_format::generate(std::vector<test_event_entry>& ev
std::vector<crypto::hash> tx_hashes;
tx_hashes.push_back(get_transaction_hash(tx_0));
size_t txs_weight = get_transaction_weight(tx_0);
diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V1,get_block_height(blk_last)+1,0,0);
diffic = next_difficulty(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V1,get_block_height(blk_last)+1,0,0,0);
if (!generator.construct_block_manually(blk_test, blk_last, miner_account,
test_generator::bf_diffic | test_generator::bf_timestamp | test_generator::bf_tx_hashes, 0, 0, blk_last.timestamp,
crypto::hash(), diffic, transaction(), tx_hashes, txs_weight))
Expand Down
5 changes: 4 additions & 1 deletion tests/difficulty/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ set_property(TARGET difficulty-tests

add_test(
NAME difficulty
COMMAND difficulty-tests "${CMAKE_CURRENT_SOURCE_DIR}/data.txt")
COMMAND difficulty-tests "--filename" "${CMAKE_CURRENT_SOURCE_DIR}/data.txt")
add_test(
NAME wide_difficulty
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/wide_difficulty.py" "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_wide_data.py" "${CMAKE_CURRENT_BINARY_DIR}/difficulty-tests" "${CMAKE_CURRENT_BINARY_DIR}/wide_data.txt")
add_test(
NAME difficulty-variant-v9
COMMAND difficulty-tests "--filename" "${CMAKE_CURRENT_SOURCE_DIR}/data-v9.txt" "--test-variant" "--variant-version" "9")
Loading