Definitions for work thresholds with epoch_2 (#2638)

* Definitions for work thresholds with epoch_2

This article outlines the decision process for these thresholds: [Development Update: V21 PoW Difficulty Increases](https://medium.com/nanocurrency/development-update-v21-pow-difficulty-increases-362b5d052c8e).

Only adds definitions, `nano::work_threshold (version, details)` is not yet used anywhere besides tests.

* Add temporary work validation in blockprocessor::add until ledger validation is in

* Formatting
This commit is contained in:
Guilherme Lawless 2020-03-16 15:47:02 +00:00 committed by GitHub
commit 773be4f6c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 5 deletions

View file

@ -62,7 +62,10 @@ TEST (difficulty, multipliers)
TEST (difficulty, network_constants)
{
ASSERT_NEAR (64., nano::difficulty::to_multiplier (nano::network_constants::publish_full_threshold, nano::network_constants::publish_beta_threshold), 1e-10);
ASSERT_NEAR (8., nano::difficulty::to_multiplier (nano::network_constants::publish_full_epoch_2_threshold, nano::network_constants::publish_full_epoch_1_threshold), 1e-10);
ASSERT_NEAR (1 / 8., nano::difficulty::to_multiplier (nano::network_constants::publish_full_epoch_2_receive_threshold, nano::network_constants::publish_full_epoch_1_threshold), 1e-10);
ASSERT_NEAR (1., nano::difficulty::to_multiplier (nano::network_constants::publish_full_epoch_2_receive_threshold, nano::network_constants::publish_full_threshold), 1e-10);
ASSERT_NEAR (1 / 64., nano::difficulty::to_multiplier (nano::network_constants::publish_beta_threshold, nano::network_constants::publish_full_epoch_1_threshold), 1e-10);
}
TEST (difficulty, overflow)

View file

@ -3,6 +3,7 @@
#include <boost/config.hpp>
#include <boost/version.hpp>
#include <algorithm>
#include <string>
namespace boost
@ -76,6 +77,7 @@ public:
network_constants (nano_networks network_a) :
current_network (network_a)
{
// The minimum threshold to enter the node, does not guarantee a block is processed
publish_threshold = is_test_network () ? publish_test_threshold : is_beta_network () ? publish_beta_threshold : publish_full_threshold;
// A representative is classified as principal based on its weight and this factor
@ -88,9 +90,14 @@ public:
request_interval_ms = is_test_network () ? 20 : 500;
}
/** Network work thresholds. ~5 seconds of work for the live network */
static uint64_t const publish_full_threshold{ 0xffffffc000000000 };
static uint64_t const publish_beta_threshold{ 0xfffff00000000000 }; // 64x lower than full
/** Network work thresholds */
static uint64_t const publish_full_epoch_1_threshold{ 0xffffffc000000000 };
static uint64_t const publish_full_epoch_2_threshold{ 0xfffffff800000000 }; // 8x higher than epoch 1
static uint64_t const publish_full_epoch_2_receive_threshold{ 0xfffffe0000000000 }; // 8x lower than epoch 1
static uint64_t const publish_full_threshold{ std::min ({ publish_full_epoch_1_threshold, publish_full_epoch_2_threshold, publish_full_epoch_2_receive_threshold }) };
static_assert (publish_full_threshold == publish_full_epoch_2_receive_threshold, "publish_full_threshold is ill-defined");
static uint64_t const publish_beta_threshold{ 0xfffff00000000000 }; // 64x lower than epoch 1
static uint64_t const publish_test_threshold{ 0xff00000000000000 }; // very low for tests
/** Error message when an invalid network is specified */

View file

@ -54,7 +54,21 @@ uint64_t nano::work_threshold (nano::work_version const version_a)
result = nano::work_v1::threshold ();
break;
default:
debug_assert (false && "Invalid version specified to work_threshold");
debug_assert (false && "Invalid version specified to entry work_threshold");
}
return result;
}
uint64_t nano::work_threshold (nano::work_version const version_a, nano::block_details const details_a)
{
uint64_t result{ std::numeric_limits<uint64_t>::max () };
switch (version_a)
{
case nano::work_version::work_1:
result = nano::work_v1::threshold (details_a);
break;
default:
debug_assert (false && "Invalid version specified to ledger work_threshold");
}
return result;
}
@ -65,6 +79,32 @@ uint64_t nano::work_v1::threshold ()
return network_constants.publish_threshold;
}
uint64_t nano::work_v1::threshold (nano::block_details const details_a)
{
static_assert (nano::epoch::max == nano::epoch::epoch_2, "work_v1::threshold is ill-defined");
static nano::network_constants network_constants;
if (!network_constants.is_live_network ())
{
return network_constants.publish_threshold;
}
uint64_t result{ std::numeric_limits<uint64_t>::max () };
switch (details_a.epoch)
{
case nano::epoch::epoch_2:
result = (details_a.is_receive || details_a.is_epoch) ? nano::network_constants::publish_full_epoch_2_receive_threshold : nano::network_constants::publish_full_epoch_2_threshold;
break;
case nano::epoch::epoch_1:
case nano::epoch::epoch_0:
result = nano::network_constants::publish_full_epoch_1_threshold;
break;
default:
debug_assert (false && "Invalid epoch specified to work_v1 ledger work_threshold");
}
return result;
}
#ifndef NANO_FUZZER_TEST
uint64_t nano::work_v1::value (nano::root const & root_a, uint64_t work_a)
{

View file

@ -21,16 +21,21 @@ enum class work_version
std::string to_string (nano::work_version const version_a);
class block;
class block_details;
bool work_validate (nano::block const &);
bool work_validate (nano::work_version const, nano::root const &, uint64_t const);
uint64_t work_difficulty (nano::work_version const, nano::root const &, uint64_t const);
// Entry threshold
uint64_t work_threshold (nano::work_version const);
// Ledger threshold
uint64_t work_threshold (nano::work_version const, nano::block_details const);
namespace work_v1
{
uint64_t value (nano::root const & root_a, uint64_t work_a);
uint64_t threshold ();
uint64_t threshold (nano::block_details const);
}
class opencl_work;
class work_item final

View file

@ -75,7 +75,9 @@ void nano::block_processor::add (std::shared_ptr<nano::block> block_a, uint64_t
void nano::block_processor::add (nano::unchecked_info const & info_a)
{
debug_assert (!nano::work_validate (*info_a.block));
bool should_notify{ false };
if (info_a.block->difficulty () >= nano::work_threshold (info_a.block->work_version ()))
{
nano::lock_guard<std::mutex> lock (mutex);
if (info_a.verified == nano::signature_verification::unknown && (info_a.block->type () == nano::block_type::state || info_a.block->type () == nano::block_type::open || !info_a.account.is_zero ()))