config: Convert DIFFICULTY_BLOCKS_V2 to TARGET_BLOCK_TIME

This commit is contained in:
Doyle 2020-08-07 09:44:23 +10:00
parent a62ff316e3
commit 62fe4db413
25 changed files with 84 additions and 112 deletions

View File

@ -4743,12 +4743,12 @@ void BlockchainLMDB::fixup(fixup_context const context)
uint8_t v12_initial_blocks_remaining = 0;
uint8_t start_version = get_hard_fork_version(start_height);
if (start_version < cryptonote::network_version_12_checkpointing) {
v12_initial_blocks_remaining = DIFFICULTY_WINDOW_V2;
} else if (start_version == cryptonote::network_version_12_checkpointing && start_height > DIFFICULTY_WINDOW_V2) {
uint8_t earlier_version = get_hard_fork_version(start_height - DIFFICULTY_WINDOW_V2);
v12_initial_blocks_remaining = DIFFICULTY_WINDOW;
} else if (start_version == cryptonote::network_version_12_checkpointing && start_height > DIFFICULTY_WINDOW) {
uint8_t earlier_version = get_hard_fork_version(start_height - DIFFICULTY_WINDOW);
if (earlier_version < cryptonote::network_version_12_checkpointing) {
start_height -= DIFFICULTY_WINDOW_V2;
v12_initial_blocks_remaining = DIFFICULTY_WINDOW_V2;
start_height -= DIFFICULTY_WINDOW;
v12_initial_blocks_remaining = DIFFICULTY_WINDOW;
LOG_PRINT_L2("Using earlier recalculation start height " << start_height << " to include v12 fork height");
}
}
@ -4756,7 +4756,7 @@ void BlockchainLMDB::fixup(fixup_context const context)
std::vector<uint64_t> timestamps;
std::vector<difficulty_type> difficulties;
{
uint64_t offset = start_height - std::min<size_t>(start_height, static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT_V2));
uint64_t offset = start_height - std::min<size_t>(start_height, static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT));
if (offset == 0)
offset = 1;
@ -4797,7 +4797,7 @@ void BlockchainLMDB::fixup(fixup_context const context)
v12_initial_override = true;
v12_initial_blocks_remaining--;
}
difficulty_type diff = next_difficulty_v2(timestamps, difficulties, DIFFICULTY_TARGET_V2,
difficulty_type diff = next_difficulty_v2(timestamps, difficulties, tools::to_seconds(TARGET_BLOCK_TIME),
version <= cryptonote::network_version_9_service_nodes, v12_initial_override);
MDB_val_set(key, curr_height);
@ -4831,8 +4831,8 @@ void BlockchainLMDB::fixup(fixup_context const context)
return;
}
while (timestamps.size() > DIFFICULTY_BLOCKS_COUNT_V2) timestamps.erase(timestamps.begin());
while (difficulties.size() > DIFFICULTY_BLOCKS_COUNT_V2) difficulties.erase(difficulties.begin());
while (timestamps.size() > DIFFICULTY_BLOCKS_COUNT) timestamps.erase(timestamps.begin());
while (difficulties.size() > DIFFICULTY_BLOCKS_COUNT) difficulties.erase(difficulties.begin());
}
block_wtxn_stop();

View File

@ -31,6 +31,7 @@
#include <ctime>
#include <cstdint>
#include "cryptonote_config.h"
#include "common/util.h"
namespace cryptonote
{
@ -53,7 +54,7 @@ bool is_output_unlocked(uint64_t unlock_time, uint64_t height)
{
//interpret as time
uint64_t current_time = static_cast<uint64_t>(time(NULL));
if(current_time + CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 >= unlock_time)
if(current_time + tools::to_seconds(CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2) >= unlock_time)
return true;
else
return false;

View File

@ -77,6 +77,12 @@ namespace tools
return get_human_readable_timespan(std::chrono::duration_cast<std::chrono::seconds>(d));
}
template <typename Duration>
constexpr uint64_t to_seconds(Duration d)
{
return std::chrono::duration_cast<std::chrono::seconds>(d).count();
}
namespace detail {
// Copy an integer type, swapping to little-endian if needed
template <typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>

View File

@ -102,7 +102,7 @@ namespace cryptonote {
return true;
}
static_assert(DIFFICULTY_TARGET_V2%60==0,"difficulty targets must be a multiple of 60");
static_assert((TARGET_BLOCK_TIME % 1min) == 0s, "difficulty targets must be a multiple of a minute");
uint64_t base_reward =
version >= network_version_16 ? BLOCK_REWARD_HF16 :

View File

@ -140,15 +140,12 @@ namespace cryptonote {
// be reduced from 60*60*2 to 500 seconds to prevent timestamp manipulation from miner's with
// > 50% hash power. If this is too small, it can be increased to 1000 at a cost in protection.
// Cryptonote clones: #define DIFFICULTY_BLOCKS_COUNT_V2 DIFFICULTY_WINDOW_V2 + 1
difficulty_type next_difficulty_v2(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds,
bool use_old_lwma, bool v12_initial_override) {
const int64_t T = static_cast<int64_t>(target_seconds);
size_t N = DIFFICULTY_WINDOW_V2 - 1;
size_t N = DIFFICULTY_WINDOW - 1;
// Return a difficulty of 1 for first 4 blocks if it's the start of the chain.
if (timestamps.size() < 4) {

View File

@ -54,6 +54,6 @@ namespace cryptonote
*/
bool check_hash(const crypto::hash &hash, difficulty_type difficulty);
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_v2(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_second,
bool use_old_lwma, bool v12_initial_override);
}

View File

@ -92,15 +92,15 @@ static_assert(STAKING_PORTIONS % 12 == 0, "Use a multiple of twelve, so that it
#define DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT ((uint64_t)3000)
#define DYNAMIC_FEE_REFERENCE_TRANSACTION_WEIGHT_V12 ((uint64_t)240000) // Only v12 (v13 switches back)
#define DIFFICULTY_TARGET_V2 120 // seconds
#define DIFFICULTY_WINDOW_V2 60
#define DIFFICULTY_BLOCKS_COUNT_V2 (DIFFICULTY_WINDOW_V2 + 1) // added +1 to make N=N
constexpr auto TARGET_BLOCK_TIME = 2min;
constexpr auto DIFFICULTY_WINDOW = 60;
constexpr uint64_t DIFFICULTY_BLOCKS_COUNT = (DIFFICULTY_WINDOW + 1); // added +1 to make N=N
#define BLOCKS_EXPECTED_IN_HOURS(val) (((60 * 60) / DIFFICULTY_TARGET_V2) * (val))
#define BLOCKS_EXPECTED_IN_DAYS(val) (BLOCKS_EXPECTED_IN_HOURS(24) * (val))
#define BLOCKS_EXPECTED_IN_YEARS(val) (BLOCKS_EXPECTED_IN_DAYS(365) * (val))
constexpr uint64_t BLOCKS_EXPECTED_IN_HOURS(int hours) { return (1h / TARGET_BLOCK_TIME); }
constexpr uint64_t BLOCKS_EXPECTED_IN_DAYS(int days) { return BLOCKS_EXPECTED_IN_HOURS(24) * days; }
constexpr uint64_t BLOCKS_EXPECTED_IN_YEARS(int years) { return BLOCKS_EXPECTED_IN_DAYS(365) * years; }
#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 DIFFICULTY_TARGET_V2 * CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS
#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 TARGET_BLOCK_TIME * CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS
#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS 1
@ -223,7 +223,7 @@ namespace config
inline constexpr std::string_view GENESIS_TX = "021e01ff000380808d93f5d771027c4fd4553bc9886f1f49e3f76d945bf71e8632a94e6c177b19cbc780e7e6bdb48080b4ccd4dfc60302c8b9f6461f58ef3f2107e577c7425d06af584a1c7482bf19060e84059c98b4c3808088fccdbcc32302732b53b0b0db706fcc3087074fb4b786da5ab72b2065699f9453448b0db27f892101ed71f2ce3fc70d7b2036f8a4e4b3fb75c66c12184b55a908e7d1a1d6995566cf00"sv;
inline constexpr uint32_t GENESIS_NONCE = 1022201;
inline constexpr uint64_t GOVERNANCE_REWARD_INTERVAL_IN_BLOCKS = ((60 * 60 * 24 * 7) / DIFFICULTY_TARGET_V2);
inline constexpr uint64_t GOVERNANCE_REWARD_INTERVAL_IN_BLOCKS = BLOCKS_EXPECTED_IN_DAYS(7);
inline constexpr std::array GOVERNANCE_WALLET_ADDRESS =
{
"LCFxT37LAogDn1jLQKf4y7aAqfi21DjovX9qyijaLYQSdrxY1U5VGcnMJMjWrD9RhjeK5Lym67wZ73uh9AujXLQ1RKmXEyL"sv, // hardfork v7-10
@ -284,7 +284,7 @@ namespace config
inline constexpr std::string_view GENESIS_TX = "04011e1e01ff00018080c9db97f4fb2702fa27e905f604faa4eb084ee675faca77b0cfea9adec1526da33cae5e286f31624201dae05bf3fa1662b7fd373c92426763d921cf3745e10ee43edb510f690c656f247200000000000000000000000000000000000000000000000000000000000000000000"sv;
inline constexpr uint32_t GENESIS_NONCE = 12345;
inline constexpr uint64_t GOVERNANCE_REWARD_INTERVAL_IN_BLOCKS = ((60 * 60 * 24 * 7) / DIFFICULTY_TARGET_V2);
inline constexpr uint64_t GOVERNANCE_REWARD_INTERVAL_IN_BLOCKS = BLOCKS_EXPECTED_IN_DAYS(7);
inline constexpr std::array GOVERNANCE_WALLET_ADDRESS =
{
"dV3EhSE1xXgSzswBgVioqFNTfcqGopvTrcYjs4YDLHUfU64DuHxFoEmbwoyipTidGiTXx5EuYdgzZhDLMTo9uEv82M4A7Uimp"sv, // hardfork v7-9

View File

@ -975,7 +975,6 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
std::vector<difficulty_type> difficulties;
uint64_t height;
uint8_t version = get_current_hard_fork_version();
size_t difficulty_blocks_count = DIFFICULTY_BLOCKS_COUNT_V2;
top_hash = get_tail_id(height); // get it again now that we have the lock
++height; // top block height to blockchain height
// ND: Speedup
@ -983,15 +982,15 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
// then when the next block difficulty is queried, push the latest height data and
// pop the oldest one from the list. This only requires 1x read per height instead
// of doing 735 (DIFFICULTY_BLOCKS_COUNT).
if (m_timestamps_and_difficulties_height != 0 && ((height - m_timestamps_and_difficulties_height) == 1) && m_timestamps.size() >= difficulty_blocks_count)
if (m_timestamps_and_difficulties_height != 0 && ((height - m_timestamps_and_difficulties_height) == 1) && m_timestamps.size() >= DIFFICULTY_BLOCKS_COUNT)
{
uint64_t index = height - 1;
m_timestamps.push_back(m_db->get_block_timestamp(index));
m_difficulties.push_back(m_db->get_block_cumulative_difficulty(index));
while (m_timestamps.size() > difficulty_blocks_count)
while (m_timestamps.size() > DIFFICULTY_BLOCKS_COUNT)
m_timestamps.erase(m_timestamps.begin());
while (m_difficulties.size() > difficulty_blocks_count)
while (m_difficulties.size() > DIFFICULTY_BLOCKS_COUNT)
m_difficulties.erase(m_difficulties.begin());
m_timestamps_and_difficulties_height = height;
@ -1000,7 +999,7 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
}
else
{
uint64_t offset = height - std::min < size_t > (height, static_cast<size_t>(difficulty_blocks_count));
uint64_t offset = height - std::min < size_t > (height, static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT));
if (offset == 0)
++offset;
@ -1021,14 +1020,12 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
m_timestamps = timestamps;
m_difficulties = difficulties;
}
size_t target = get_difficulty_target();
// HF12 switches to RandomX with a likely drastically reduced hashrate versus Turtle, so override
// difficulty for the first difficulty window blocks:
uint64_t hf12_height = m_hardfork->get_earliest_ideal_height_for_version(network_version_12_checkpointing);
difficulty_type diff = next_difficulty_v2(timestamps, difficulties, target, version <= cryptonote::network_version_9_service_nodes,
height >= hf12_height && height < hf12_height + DIFFICULTY_WINDOW_V2);
difficulty_type diff = next_difficulty_v2(timestamps, difficulties, tools::to_seconds(TARGET_BLOCK_TIME), version <= cryptonote::network_version_9_service_nodes,
height >= hf12_height && height < hf12_height + DIFFICULTY_WINDOW);
std::unique_lock diff_lock{m_difficulty_lock};
m_difficulty_for_next_block_top_hash = top_hash;
@ -1225,17 +1222,16 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
LOG_PRINT_L3("Blockchain::" << __func__);
std::vector<uint64_t> timestamps;
std::vector<difficulty_type> cumulative_difficulties;
size_t difficulty_blocks_count = DIFFICULTY_BLOCKS_COUNT_V2;
// if the alt chain isn't long enough to calculate the difficulty target
// based on its blocks alone, need to get more blocks from the main chain
if(alt_chain.size()< difficulty_blocks_count)
if(alt_chain.size() < DIFFICULTY_BLOCKS_COUNT)
{
std::unique_lock lock{*this};
// Figure out start and stop offsets for main chain blocks
size_t main_chain_stop_offset = alt_chain.size() ? alt_chain.front().height : alt_block_height;
size_t main_chain_count = difficulty_blocks_count - std::min(static_cast<size_t>(difficulty_blocks_count), alt_chain.size());
size_t main_chain_count = DIFFICULTY_BLOCKS_COUNT - std::min(static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT), alt_chain.size());
main_chain_count = std::min(main_chain_count, main_chain_stop_offset);
size_t main_chain_start_offset = main_chain_stop_offset - main_chain_count;
@ -1250,7 +1246,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
}
// make sure we haven't accidentally grabbed too many blocks...maybe don't need this check?
CHECK_AND_ASSERT_MES((alt_chain.size() + timestamps.size()) <= difficulty_blocks_count, false, "Internal error, alt_chain.size()[" << alt_chain.size() << "] + vtimestampsec.size()[" << timestamps.size() << "] NOT <= DIFFICULTY_WINDOW[]" << DIFFICULTY_BLOCKS_COUNT_V2);
CHECK_AND_ASSERT_MES((alt_chain.size() + timestamps.size()) <= DIFFICULTY_BLOCKS_COUNT, false, "Internal error, alt_chain.size()[" << alt_chain.size() << "] + vtimestampsec.size()[" << timestamps.size() << "] NOT <= DIFFICULTY_WINDOW[]" << DIFFICULTY_BLOCKS_COUNT);
for (const auto &bei : alt_chain)
{
@ -1262,8 +1258,8 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
// and timestamps from it alone
else
{
timestamps.resize(static_cast<size_t>(difficulty_blocks_count));
cumulative_difficulties.resize(static_cast<size_t>(difficulty_blocks_count));
timestamps.resize(static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT));
cumulative_difficulties.resize(static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT));
size_t count = 0;
size_t max_i = timestamps.size()-1;
// get difficulties and timestamps from most recent blocks in alt chain
@ -1273,22 +1269,20 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
timestamps[max_i - count] = bei.bl.timestamp;
cumulative_difficulties[max_i - count] = bei.cumulative_difficulty;
count++;
if(count >= difficulty_blocks_count)
if(count >= DIFFICULTY_BLOCKS_COUNT)
break;
}
}
// FIXME: This will fail if fork activation heights are subject to voting
size_t target = DIFFICULTY_TARGET_V2;
// HF12 switches to RandomX with a likely drastically reduced hashrate versus Turtle, so override
// difficulty for the first difficulty window blocks:
uint64_t hf12_height = m_hardfork->get_earliest_ideal_height_for_version(network_version_12_checkpointing);
uint64_t height = (alt_chain.size() ? alt_chain.front().height : alt_block_height) + alt_chain.size() + 1;
// calculate the difficulty target for the block and return it
return next_difficulty_v2(timestamps, cumulative_difficulties, target, get_current_hard_fork_version() <= cryptonote::network_version_9_service_nodes,
height >= hf12_height && height < hf12_height + DIFFICULTY_WINDOW_V2);
return next_difficulty_v2(timestamps, cumulative_difficulties, tools::to_seconds(TARGET_BLOCK_TIME), get_current_hard_fork_version() <= cryptonote::network_version_9_service_nodes,
height >= hf12_height && height < hf12_height + DIFFICULTY_WINDOW);
}
//------------------------------------------------------------------
// This function does a sanity check on basic things that all miner
@ -5315,11 +5309,6 @@ bool Blockchain::get_hard_fork_voting_info(uint8_t version, uint32_t &window, ui
return m_hardfork->get_voting_info(version, window, votes, threshold, earliest_height, voting);
}
uint64_t Blockchain::get_difficulty_target() const
{
return DIFFICULTY_TARGET_V2;
}
std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> Blockchain:: get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const
{
return m_db->get_output_histogram(amounts, unlocked, recent_cutoff, min_count);

View File

@ -856,13 +856,6 @@ namespace cryptonote
*/
bool get_hard_fork_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const;
/**
* @brief get difficulty target based on chain and hardfork version
*
* @return difficulty target
*/
uint64_t get_difficulty_target() const;
/**
* @brief remove transactions from the transaction pool (if present)
*

View File

@ -2392,7 +2392,7 @@ namespace cryptonote
return true;
#endif
static constexpr double threshold = 1. / (864000 / DIFFICULTY_TARGET_V2); // one false positive every 10 days
static constexpr double threshold = 1. / ((24h * 10) / TARGET_BLOCK_TIME); // one false positive every 10 days
static constexpr unsigned int max_blocks_checked = 150;
const time_t now = time(NULL);
@ -2404,7 +2404,7 @@ namespace cryptonote
unsigned int b = 0;
const time_t time_boundary = now - static_cast<time_t>(seconds[n]);
for (time_t ts: timestamps) b += ts >= time_boundary;
const double p = probability(b, seconds[n] / DIFFICULTY_TARGET_V2);
const double p = probability(b, seconds[n] / tools::to_seconds(TARGET_BLOCK_TIME));
MDEBUG("blocks in the last " << seconds[n] / 60 << " minutes: " << b << " (probability " << p << ")");
if (p < threshold)
{
@ -2413,7 +2413,7 @@ namespace cryptonote
std::shared_ptr<tools::Notify> block_rate_notify = m_block_rate_notify;
if (block_rate_notify)
{
auto expected = seconds[n] / DIFFICULTY_TARGET_V2;
auto expected = seconds[n] / tools::to_seconds(TARGET_BLOCK_TIME);
block_rate_notify->notify("%t", std::to_string(seconds[n] / 60).c_str(), "%b", std::to_string(b).c_str(), "%e", std::to_string(expected).c_str(), NULL);
}

View File

@ -29,7 +29,6 @@ constexpr std::string_view round_state_string(round_state state)
{
switch(state)
{
default: assert("Invalid Code Path" == nullptr);
case round_state::wait_next_block: return "Wait Next Block"sv;
case round_state::wait_for_round: return "Wait For Round"sv;
case round_state::round_starts: return "Round Starts"sv;

View File

@ -20,6 +20,8 @@ namespace service_nodes {
constexpr auto PULSE_WAIT_FOR_HANDSHAKES_DURATION = 7s;
constexpr auto PULSE_WAIT_FOR_OTHER_VALIDATOR_HANDSHAKES_DURATION = 7s;
constexpr auto PULSE_WAIT_FOR_BLOCK_TEMPLATE_DURATION = 6s;
constexpr auto PULSE_MIN_BLOCK_TIME = 15s;
constexpr auto PULSE_MAX_BLOCK_TIME = 25s;
constexpr size_t PULSE_QUORUM_NUM_VALIDATORS = 7;
constexpr size_t PULSE_BLOCK_REQUIRED_SIGNATURES = 7; // A block must have exactly N signatures to be considered properly

View File

@ -86,10 +86,6 @@ namespace cryptonote
using seconds_f = std::chrono::duration<double>;
// Converts a duration to integer seconds, truncating sub-second amounts.
template <typename Duration>
auto count_seconds(const Duration &d) { return std::chrono::duration_cast<std::chrono::seconds>(d).count(); }
//-----------------------------------------------------------------------------------------------------------------------
template<class t_core>
t_cryptonote_protocol_handler<t_core>::t_cryptonote_protocol_handler(t_core& rcore, bool offline):m_core(rcore),
@ -233,10 +229,10 @@ namespace cryptonote
cntxt.m_remote_address.str()
<< std::setw(20) << nodetool::peerid_to_string(peer_id)
<< std::setw(20) << std::hex << support_flags
<< std::setw(30) << std::to_string(cntxt.m_recv_cnt) + "(" + std::to_string(count_seconds(now - cntxt.m_last_recv)) + ")" +
"/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(count_seconds(now - cntxt.m_last_send)) + ")"
<< std::setw(30) << std::to_string(cntxt.m_recv_cnt) + "(" + std::to_string(tools::to_seconds(now - cntxt.m_last_recv)) + ")" +
"/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(tools::to_seconds(now - cntxt.m_last_send)) + ")"
<< std::setw(25) << get_protocol_state_string(cntxt.m_state)
<< std::setw(20) << std::to_string(count_seconds(connection_time))
<< std::setw(20) << std::to_string(tools::to_seconds(connection_time))
<< std::setw(12) << std::fixed << (connection_time < 1s ? 0.0 : cntxt.m_recv_cnt / connection_time.count() / 1024)
<< std::setw(14) << std::fixed << cntxt.m_current_speed_down / 1024
<< std::setw(10) << std::fixed << (connection_time < 1s ? 0.0 : cntxt.m_send_cnt / connection_time.count() / 1024)
@ -471,7 +467,7 @@ namespace cryptonote
uint64_t abs_diff = std::abs(diff);
uint64_t max_block_height = std::max(hshd.current_height, curr_height);
MCLOG(is_inital ? el::Level::Info : el::Level::Debug, "global", context << "Sync data returned a new top block candidate: " << curr_height << " -> " << hshd.current_height
<< " [Your node is " << abs_diff << " blocks (" << (abs_diff / (24 * 60 * 60 / DIFFICULTY_TARGET_V2)) << " days) "
<< " [Your node is " << abs_diff << " blocks (" << tools::get_human_readable_timespan(std::chrono::seconds(abs_diff / (24h / TARGET_BLOCK_TIME))) << " "
<< (0 <= diff ? std::string("behind") : std::string("ahead"))
<< "]\nSYNCHRONIZATION started");

View File

@ -612,10 +612,6 @@ bool rpc_command_executor::mining_status() {
return true;
}
// Converts a duration to integer seconds, truncating sub-second amounts.
template <typename Duration>
static auto count_seconds(const Duration &d) { return std::chrono::duration_cast<std::chrono::seconds>(d).count(); }
bool rpc_command_executor::print_connections() {
GET_CONNECTIONS::response res{};
@ -646,9 +642,9 @@ bool rpc_command_executor::print_connections() {
<< std::setw(8) << (get_address_type_name((epee::net_utils::address_type)info.address_type))
<< std::setw(20) << info.peer_id
<< std::setw(20) << info.support_flags
<< std::setw(30) << std::to_string(info.recv_count) + "(" + std::to_string(count_seconds(info.recv_idle_time)) + ")/" + std::to_string(info.send_count) + "(" + std::to_string(count_seconds(info.send_idle_time)) + ")"
<< std::setw(30) << std::to_string(info.recv_count) + "(" + std::to_string(tools::to_seconds(info.recv_idle_time)) + ")/" + std::to_string(info.send_count) + "(" + std::to_string(tools::to_seconds(info.send_idle_time)) + ")"
<< std::setw(25) << info.state
<< std::setw(20) << std::to_string(count_seconds(info.live_time))
<< std::setw(20) << std::to_string(tools::to_seconds(info.live_time))
<< std::setw(12) << info.avg_download
<< std::setw(14) << info.current_download
<< std::setw(10) << info.avg_upload
@ -1028,7 +1024,7 @@ bool rpc_command_executor::print_transaction_pool_stats() {
else
{
uint64_t backlog = (res.pool_stats.bytes_total + full_reward_zone - 1) / full_reward_zone;
backlog_message = (boost::format("estimated %u block (%u minutes) backlog") % backlog % (backlog * DIFFICULTY_TARGET_V2 / 60)).str();
backlog_message = (boost::format("estimated %u block (%u minutes) backlog") % backlog % (backlog * TARGET_BLOCK_TIME / 1min)).str();
}
tools::msg_writer() << n_transactions << " tx(es), " << res.pool_stats.bytes_total << " bytes total (min " << res.pool_stats.bytes_min << ", max " << res.pool_stats.bytes_max << ", avg " << avg_bytes << ", median " << res.pool_stats.bytes_med << ")" << std::endl
@ -1386,7 +1382,7 @@ bool rpc_command_executor::alt_chain_info(const std::string &tip, size_t above,
tools::msg_writer() << "Time span: " << tools::get_human_readable_timespan(std::chrono::seconds(dt));
cryptonote::difficulty_type start_difficulty = bhres.block_headers.back().difficulty;
if (start_difficulty > 0)
tools::msg_writer() << "Approximated " << 100.f * DIFFICULTY_TARGET_V2 * chain.length / dt << "% of network hash rate";
tools::msg_writer() << "Approximated " << 100.f * tools::to_seconds(TARGET_BLOCK_TIME) * chain.length / dt << "% of network hash rate";
else
tools::fail_msg_writer() << "Bad cmumulative difficulty reported by dameon";
}
@ -1579,7 +1575,7 @@ static void append_printable_service_node_list_entry(cryptonote::network_type ne
else
{
uint64_t delta_height = (blockchain_height >= expiry_height) ? 0 : expiry_height - blockchain_height;
uint64_t expiry_epoch_time = now + (delta_height * DIFFICULTY_TARGET_V2);
uint64_t expiry_epoch_time = now + (delta_height * tools::to_seconds(TARGET_BLOCK_TIME));
stream << expiry_height << " (in " << delta_height << ") blocks\n";
stream << indent2 << "Expiry Date (estimated): " << get_date_time(expiry_epoch_time) << " (" << get_human_time_ago(expiry_epoch_time, now) << ")\n";
}

View File

@ -375,7 +375,7 @@ namespace cryptonote { namespace rpc {
}
res.difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block();
res.target = m_core.get_blockchain_storage().get_difficulty_target();
res.target = tools::to_seconds(TARGET_BLOCK_TIME);
res.tx_count = m_core.get_blockchain_storage().get_total_transactions() - res.height; //without coinbase
res.tx_pool_size = m_core.get_pool().get_transactions_count();
res.alt_blocks_count = restricted ? 0 : m_core.get_blockchain_storage().get_alternative_blocks_count();
@ -1266,7 +1266,7 @@ namespace cryptonote { namespace rpc {
const miner& lMiner = m_core.get_miner();
res.active = lMiner.is_mining();
res.block_target = DIFFICULTY_TARGET_V2;
res.block_target = tools::to_seconds(TARGET_BLOCK_TIME);
res.difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block();
if ( lMiner.is_mining() ) {
res.speed = lMiner.get_speed();

View File

@ -584,7 +584,7 @@ namespace rpc {
uint32_t threads_count; // Number of running mining threads.
std::string address; // Account address daemon is mining to. Empty if not mining.
std::string pow_algorithm; // Current hashing algorithm name
uint32_t block_target; // The expected time to solve per block, i.e. DIFFICULTY_TARGET_V2
uint32_t block_target; // The expected time to solve per block, i.e. TARGET_BLOCK_TIME
uint64_t block_reward; // Block reward for the current block being mined.
uint64_t difficulty; // The difficulty for the current block being mined.

View File

@ -457,7 +457,7 @@ namespace rpc
res.info.difficulty = chain.get_difficulty_for_next_block();
res.info.target = chain.get_difficulty_target();
res.info.target = tools::to_seconds(TARGET_BLOCK_TIME);
res.info.tx_count = chain.get_total_transactions() - res.info.height; //without coinbase

View File

@ -9753,7 +9753,7 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args)
else
{
uint64_t current_time = static_cast<uint64_t>(time(NULL));
uint64_t threshold = current_time + CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2;
uint64_t threshold = current_time + tools::to_seconds(CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2);
if (threshold >= pd.m_unlock_time)
success_msg_writer() << "unlocked for " << tools::get_human_readable_timespan(std::chrono::seconds(threshold - pd.m_unlock_time));
else
@ -9803,7 +9803,7 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args)
else
{
uint64_t current_time = static_cast<uint64_t>(time(NULL));
uint64_t threshold = current_time + CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2;
uint64_t threshold = current_time + tools::to_seconds(CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2);
if (threshold >= pd.m_unlock_time)
success_msg_writer() << "unlocked for " << tools::get_human_readable_timespan(std::chrono::seconds(threshold - pd.m_unlock_time));
else

View File

@ -363,7 +363,7 @@ namespace cryptonote
void update(uint64_t height, bool force = false)
{
auto current_time = std::chrono::system_clock::now();
const auto node_update_threshold = std::chrono::seconds(DIFFICULTY_TARGET_V2 / 2);
const auto node_update_threshold = TARGET_BLOCK_TIME / 2;
if (node_update_threshold < current_time - m_blockchain_height_update_time || m_blockchain_height <= height)
{
update_blockchain_height();

View File

@ -889,14 +889,14 @@ gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets, double shap
{
gamma = std::gamma_distribution<double>(shape, scale);
THROW_WALLET_EXCEPTION_IF(rct_offsets.size() <= CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, error::wallet_internal_error, "Bad offset calculation");
const size_t blocks_in_a_year = 86400 * 365 / DIFFICULTY_TARGET_V2;
const size_t blocks_in_a_year = BLOCKS_EXPECTED_IN_YEARS(1);
const size_t blocks_to_consider = std::min<size_t>(rct_offsets.size(), blocks_in_a_year);
const size_t outputs_to_consider = rct_offsets.back() - (blocks_to_consider < rct_offsets.size() ? rct_offsets[rct_offsets.size() - blocks_to_consider - 1] : 0);
begin = rct_offsets.data();
end = rct_offsets.data() + rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
num_rct_outputs = *(end - 1);
THROW_WALLET_EXCEPTION_IF(num_rct_outputs == 0, error::wallet_internal_error, "No rct outputs");
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / outputs_to_consider; // this assumes constant target over the whole rct range
average_output_time = tools::to_seconds(TARGET_BLOCK_TIME) * blocks_to_consider / outputs_to_consider; // this assumes constant target over the whole rct range
};
gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets): gamma_picker(rct_offsets, GAMMA_SHAPE, GAMMA_SCALE) {}
@ -4772,11 +4772,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
uint64_t wallet2::estimate_blockchain_height()
{
// -1 month for fluctuations in block time and machine date/time setup.
// avg seconds per block
const int seconds_per_block = DIFFICULTY_TARGET_V2;
// ~num blocks per month
const uint64_t blocks_per_month = 60*60*24*30/seconds_per_block;
const uint64_t blocks_per_month = BLOCKS_EXPECTED_IN_DAYS(30);
// try asking the daemon first
std::string err;
@ -8563,7 +8559,7 @@ wallet2::request_stake_unlock_result wallet2::can_request_stake_unlock(const cry
result.msg.append(" has already been requested to be unlocked, unlocking at height: ");
result.msg.append(std::to_string(node_info.requested_unlock_height));
result.msg.append(" (about ");
result.msg.append(tools::get_human_readable_timespan(std::chrono::seconds((node_info.requested_unlock_height - curr_height) * DIFFICULTY_TARGET_V2)));
result.msg.append(tools::get_human_readable_timespan(std::chrono::seconds((node_info.requested_unlock_height - curr_height) * TARGET_BLOCK_TIME)));
result.msg.append(")");
return result;
}
@ -8584,7 +8580,7 @@ wallet2::request_stake_unlock_result wallet2::can_request_stake_unlock(const cry
result.msg.append("You will continue receiving rewards until the service node expires at the estimated height: ");
result.msg.append(std::to_string(unlock_height));
result.msg.append(" (about ");
result.msg.append(tools::get_human_readable_timespan(std::chrono::seconds((unlock_height - curr_height) * DIFFICULTY_TARGET_V2)));
result.msg.append(tools::get_human_readable_timespan(std::chrono::seconds((unlock_height - curr_height) * TARGET_BLOCK_TIME)));
result.msg.append(")");
if(!tools::hex_to_type(contribution.key_image, unlock.key_image))
@ -12867,7 +12863,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const
{
const auto& netconf = cryptonote::get_config(m_nettype);
const time_t since_ts = time(nullptr) - netconf.HEIGHT_ESTIMATE_TIMESTAMP;
uint64_t approx_blockchain_height = netconf.HEIGHT_ESTIMATE_HEIGHT + (since_ts > 0 ? (uint64_t)since_ts / DIFFICULTY_TARGET_V2 : 0) - BLOCKS_EXPECTED_IN_DAYS(7); // subtract a week's worth of blocks to be conservative
uint64_t approx_blockchain_height = netconf.HEIGHT_ESTIMATE_HEIGHT + (since_ts > 0 ? (uint64_t)since_ts / tools::to_seconds(TARGET_BLOCK_TIME) : 0) - BLOCKS_EXPECTED_IN_DAYS(7); // subtract a week's worth of blocks to be conservative
LOG_PRINT_L2("Calculated blockchain height: " << approx_blockchain_height);
return approx_blockchain_height;
}

View File

@ -44,13 +44,13 @@ namespace
for (size_t i = 0; i < new_block_count; ++i)
{
block blk_next;
difficulty_type diffic = next_difficulty_v2(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V2, false /*use_old_lwma*/, false);
difficulty_type diffic = next_difficulty_v2(timestamps, cummulative_difficulties,tools::to_seconds(TARGET_BLOCK_TIME), false /*use_old_lwma*/, false);
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;
cummulative_diffic += diffic;
if (timestamps.size() == DIFFICULTY_WINDOW_V2)
if (timestamps.size() == DIFFICULTY_WINDOW)
{
timestamps.erase(timestamps.begin());
cummulative_difficulties.erase(cummulative_difficulties.begin());
@ -174,7 +174,7 @@ bool gen_block_invalid_nonce::generate(std::vector<test_event_entry>& events) co
return false;
// Create invalid nonce
difficulty_type diffic = next_difficulty_v2(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V2, false /*use_old_lwma*/, false);
difficulty_type diffic = next_difficulty_v2(timestamps, cummulative_difficulties,tools::to_seconds(TARGET_BLOCK_TIME), false /*use_old_lwma*/, false);
assert(1 < diffic);
const block& blk_last = std::get<block>(events.back());
uint64_t timestamp = blk_last.timestamp;
@ -624,7 +624,7 @@ bool gen_block_invalid_binary_format::generate(std::vector<test_event_entry>& ev
// Unlock blk_0 outputs
block blk_last = blk_0;
assert(CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW < DIFFICULTY_WINDOW_V2);
assert(CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW < DIFFICULTY_WINDOW);
for (size_t i = 0; i < CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW; ++i)
{
MAKE_NEXT_BLOCK(events, blk_curr, blk_last, miner_account);
@ -638,7 +638,7 @@ bool gen_block_invalid_binary_format::generate(std::vector<test_event_entry>& ev
do
{
blk_last = std::get<block>(events.back());
diffic = next_difficulty_v2(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V2, false /*use_old_lwma*/, false);
diffic = next_difficulty_v2(timestamps, cummulative_difficulties,tools::to_seconds(TARGET_BLOCK_TIME), false /*use_old_lwma*/, false);
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;
@ -653,7 +653,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_v2(timestamps, cummulative_difficulties,DIFFICULTY_TARGET_V2, false /*use_old_lwma*/, false);
diffic = next_difficulty_v2(timestamps, cummulative_difficulties,tools::to_seconds(TARGET_BLOCK_TIME), false /*use_old_lwma*/, false);
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))

View File

@ -973,7 +973,7 @@ loki_create_block_params loki_chain_generator::next_block_params() const
loki_create_block_params result = {};
result.prev = prev;
result.miner_acc = first_miner_;
result.timestamp = prev.block.timestamp + DIFFICULTY_TARGET_V2;
result.timestamp = prev.block.timestamp + TARGET_BLOCK_TIME;
result.block_weights = last_n_block_weights(height(), CRYPTONOTE_REWARD_BLOCKS_WINDOW);
result.hf_version = get_hf_version_at(next_height);
result.block_leader = prev.service_node_state.get_block_leader();
@ -1257,7 +1257,7 @@ bool test_generator::construct_block(cryptonote::block &blk,
uint64_t height = std::get<cryptonote::txin_gen>(blk_prev.miner_tx.vin.front()).height + 1;
crypto::hash prev_id = get_block_hash(blk_prev);
// Keep difficulty unchanged
uint64_t timestamp = blk_prev.timestamp + DIFFICULTY_TARGET_V2; // DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN;
uint64_t timestamp = blk_prev.timestamp + TARGET_BLOCK_TIME; // DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN;
uint64_t already_generated_coins = get_already_generated_coins(prev_id);
std::vector<uint64_t> block_weights;
get_last_n_block_weights(block_weights, prev_id, CRYPTONOTE_REWARD_BLOCKS_WINDOW);

View File

@ -64,8 +64,6 @@
#define TESTS_DEFAULT_FEE ((uint64_t)200000000) // 2 * pow(10, 8)
#define TEST_DEFAULT_DIFFICULTY 1
#define DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN DIFFICULTY_TARGET_V2
#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ < 6
namespace service_nodes {
const std::vector<payout_entry> dummy; // help GCC 5 realize it needs to generate a default constructor

View File

@ -40,7 +40,6 @@
#include "cryptonote_config.h"
#include "cryptonote_basic/difficulty.h"
#define DEFAULT_TEST_DIFFICULTY_TARGET 120
#define DIFFICULTY_LAG 15
int main(int argc, char *argv[]) {
@ -58,16 +57,16 @@ int main(int argc, char *argv[]) {
size_t n = 0;
while (data >> timestamp >> difficulty) {
size_t begin, end;
if (n < DIFFICULTY_WINDOW_V2 + DIFFICULTY_LAG) {
if (n < DIFFICULTY_WINDOW + DIFFICULTY_LAG) {
begin = 0;
end = std::min(n, (size_t) DIFFICULTY_WINDOW_V2);
end = std::min(n, (size_t) DIFFICULTY_WINDOW);
} else {
end = n - DIFFICULTY_LAG;
begin = end - DIFFICULTY_WINDOW_V2;
begin = end - DIFFICULTY_WINDOW;
}
uint64_t res = cryptonote::next_difficulty_v2(
std::vector<uint64_t>(timestamps.begin() + begin, timestamps.begin() + end),
std::vector<uint64_t>(cumulative_difficulties.begin() + begin, cumulative_difficulties.begin() + end), DEFAULT_TEST_DIFFICULTY_TARGET, false/*use_old_lwma2*/, false);
std::vector<uint64_t>(cumulative_difficulties.begin() + begin, cumulative_difficulties.begin() + end), TARGET_BLOCK_TIME, false/*use_old_lwma2*/, false);
if (res != difficulty) {
std::cerr << "Wrong difficulty for block " << n
<< "\nExpected: " << difficulty

View File

@ -269,12 +269,12 @@ bool transactions_flow_test(std::string& working_folder,
LOG_PRINT_L0( "waiting some new blocks...");
epee::misc_utils::sleep_no_w(DIFFICULTY_TARGET_V2*20*1000);//wait two blocks before sync on another wallet on another daemon
epee::misc_utils::sleep_no_w(TARGET_BLOCK_TIME*20*1000);//wait two blocks before sync on another wallet on another daemon
LOG_PRINT_L0( "refreshing...");
bool recvd_money = false;
while(w2.refresh(true, blocks_fetched, recvd_money, ok) && ( (blocks_fetched && recvd_money) || !blocks_fetched ) )
{
epee::misc_utils::sleep_no_w(DIFFICULTY_TARGET_V2*1000);//wait two blocks before sync on another wallet on another daemon
epee::misc_utils::sleep_no_w(TARGET_BLOCK_TIME*1000);//wait two blocks before sync on another wallet on another daemon
}
uint64_t money_2 = w2.balance(0, true);