Move network_constants to a dedicated header (#4800)

* Move network_constants to constants.hpp

* Cleanup
This commit is contained in:
Piotr Wójcik 2024-11-30 20:17:44 +01:00 committed by GitHub
commit 45c3045649
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 540 additions and 502 deletions

View file

@ -39,6 +39,8 @@ add_library(
config.hpp
config.cpp
configbase.hpp
constants.hpp
constants.cpp
container_info.hpp
container_info.cpp
diagnosticsconfig.hpp

View file

@ -2,9 +2,9 @@
#include <nano/lib/block_type.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/constants.hpp>
#include <nano/lib/env.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/work_version.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
@ -12,221 +12,8 @@
#include <valgrind/valgrind.h>
namespace
{
// useful for boost_lexical cast to allow conversion of hex strings
template <typename ElemT>
struct HexTo
{
ElemT value;
HexTo () = default;
HexTo (ElemT val) :
value{ val }
{
}
operator ElemT () const
{
return value;
}
friend std::istream & operator>> (std::istream & in, HexTo & out)
{
in >> std::hex >> out.value;
return in;
}
};
} // namespace
nano::work_thresholds const nano::work_thresholds::publish_full (
0xffffffc000000000,
0xfffffff800000000, // 8x higher than epoch_1
0xfffffe0000000000 // 8x lower than epoch_1
);
nano::work_thresholds const nano::work_thresholds::publish_beta (
0xfffff00000000000, // 64x lower than publish_full.epoch_1
0xfffff00000000000, // same as epoch_1
0xffffe00000000000 // 2x lower than epoch_1
);
nano::work_thresholds const nano::work_thresholds::publish_dev (
0xfe00000000000000, // Very low for tests
0xffc0000000000000, // 8x higher than epoch_1
0xf000000000000000 // 8x lower than epoch_1
);
nano::work_thresholds const nano::work_thresholds::publish_test ( // defaults to live network levels
nano::env::get<HexTo<uint64_t>> ("NANO_TEST_EPOCH_1").value_or (0xffffffc000000000),
nano::env::get<HexTo<uint64_t>> ("NANO_TEST_EPOCH_2").value_or (0xfffffff800000000), // 8x higher than epoch_1
nano::env::get<HexTo<uint64_t>> ("NANO_TEST_EPOCH_2_RECV").value_or (0xfffffe0000000000) // 8x lower than epoch_1
);
uint64_t nano::work_thresholds::threshold_entry (nano::work_version const version_a, nano::block_type const type_a) const
{
uint64_t result{ std::numeric_limits<uint64_t>::max () };
if (type_a == nano::block_type::state)
{
switch (version_a)
{
case nano::work_version::work_1:
result = entry;
break;
default:
debug_assert (false && "Invalid version specified to work_threshold_entry");
}
}
else
{
result = epoch_1;
}
return result;
}
#ifndef NANO_FUZZER_TEST
uint64_t nano::work_thresholds::value (nano::root const & root_a, uint64_t work_a) const
{
uint64_t result;
blake2b_state hash;
blake2b_init (&hash, sizeof (result));
blake2b_update (&hash, reinterpret_cast<uint8_t *> (&work_a), sizeof (work_a));
blake2b_update (&hash, root_a.bytes.data (), root_a.bytes.size ());
blake2b_final (&hash, reinterpret_cast<uint8_t *> (&result), sizeof (result));
return result;
}
#else
uint64_t nano::work_thresholds::value (nano::root const & root_a, uint64_t work_a) const
{
return base + 1;
}
#endif
uint64_t nano::work_thresholds::threshold (nano::block_details const & details_a) const
{
static_assert (nano::epoch::max == nano::epoch::epoch_2, "work_v1::threshold is ill-defined");
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) ? epoch_2_receive : epoch_2;
break;
case nano::epoch::epoch_1:
case nano::epoch::epoch_0:
result = epoch_1;
break;
default:
debug_assert (false && "Invalid epoch specified to work_v1 ledger work_threshold");
}
return result;
}
uint64_t nano::work_thresholds::threshold (nano::work_version const version_a, nano::block_details const details_a) const
{
uint64_t result{ std::numeric_limits<uint64_t>::max () };
switch (version_a)
{
case nano::work_version::work_1:
result = threshold (details_a);
break;
default:
debug_assert (false && "Invalid version specified to ledger work_threshold");
}
return result;
}
double nano::work_thresholds::normalized_multiplier (double const multiplier_a, uint64_t const threshold_a) const
{
debug_assert (multiplier_a >= 1);
auto multiplier (multiplier_a);
/* Normalization rules
ratio = multiplier of max work threshold (send epoch 2) from given threshold
i.e. max = 0xfe00000000000000, given = 0xf000000000000000, ratio = 8.0
normalized = (multiplier + (ratio - 1)) / ratio;
Epoch 1
multiplier | normalized
1.0 | 1.0
9.0 | 2.0
25.0 | 4.0
Epoch 2 (receive / epoch subtypes)
multiplier | normalized
1.0 | 1.0
65.0 | 2.0
241.0 | 4.0
*/
if (threshold_a == epoch_1 || threshold_a == epoch_2_receive)
{
auto ratio (nano::difficulty::to_multiplier (epoch_2, threshold_a));
debug_assert (ratio >= 1);
multiplier = (multiplier + (ratio - 1.0)) / ratio;
debug_assert (multiplier >= 1);
}
return multiplier;
}
double nano::work_thresholds::denormalized_multiplier (double const multiplier_a, uint64_t const threshold_a) const
{
debug_assert (multiplier_a >= 1);
auto multiplier (multiplier_a);
if (threshold_a == epoch_1 || threshold_a == epoch_2_receive)
{
auto ratio (nano::difficulty::to_multiplier (epoch_2, threshold_a));
debug_assert (ratio >= 1);
multiplier = multiplier * ratio + 1.0 - ratio;
debug_assert (multiplier >= 1);
}
return multiplier;
}
uint64_t nano::work_thresholds::threshold_base (nano::work_version const version_a) const
{
uint64_t result{ std::numeric_limits<uint64_t>::max () };
switch (version_a)
{
case nano::work_version::work_1:
result = base;
break;
default:
debug_assert (false && "Invalid version specified to work_threshold_base");
}
return result;
}
uint64_t nano::work_thresholds::difficulty (nano::work_version const version_a, nano::root const & root_a, uint64_t const work_a) const
{
uint64_t result{ 0 };
switch (version_a)
{
case nano::work_version::work_1:
result = value (root_a, work_a);
break;
default:
debug_assert (false && "Invalid version specified to work_difficulty");
}
return result;
}
uint64_t nano::work_thresholds::difficulty (nano::block const & block_a) const
{
return difficulty (block_a.work_version (), block_a.root (), block_a.block_work ());
}
bool nano::work_thresholds::validate_entry (nano::work_version const version_a, nano::root const & root_a, uint64_t const work_a) const
{
return difficulty (version_a, root_a, work_a) < threshold_entry (version_a, nano::block_type::state);
}
bool nano::work_thresholds::validate_entry (nano::block const & block_a) const
{
return difficulty (block_a) < threshold_entry (block_a.work_version (), block_a.type ());
}
namespace nano
{
char const * network_constants::active_network_err_msg = "Invalid network. Valid values are live, test, beta and dev.";
uint8_t get_major_node_version ()
{
return boost::numeric_cast<uint8_t> (boost::lexical_cast<int> (NANO_MAJOR_VERSION_STRING));

View file

@ -84,281 +84,7 @@ uint16_t test_rpc_port ();
uint16_t test_ipc_port ();
uint16_t test_websocket_port ();
std::array<uint8_t, 2> test_magic_number ();
/// How often to scan for representatives in local wallet, in milliseconds
uint32_t test_scan_wallet_reps_delay ();
/**
* Network variants with different genesis blocks and network parameters
*/
enum class networks : uint16_t
{
invalid = 0x0,
// Low work parameters, publicly known genesis key, dev IP ports
nano_dev_network = 0x5241, // 'R', 'A'
// Normal work parameters, secret beta genesis key, beta IP ports
nano_beta_network = 0x5242, // 'R', 'B'
// Normal work parameters, secret live key, live IP ports
nano_live_network = 0x5243, // 'R', 'C'
// Normal work parameters, secret test genesis key, test IP ports
nano_test_network = 0x5258, // 'R', 'X'
};
std::string_view to_string (nano::networks);
enum class block_type : uint8_t;
class root;
class block;
class block_details;
enum class work_version;
class work_thresholds
{
public:
uint64_t const epoch_1;
uint64_t const epoch_2;
uint64_t const epoch_2_receive;
// Automatically calculated. The base threshold is the maximum of all thresholds and is used for all work multiplier calculations
uint64_t const base;
// Automatically calculated. The entry threshold is the minimum of all thresholds and defines the required work to enter the node, but does not guarantee a block is processed
uint64_t const entry;
constexpr work_thresholds (uint64_t epoch_1_a, uint64_t epoch_2_a, uint64_t epoch_2_receive_a) :
epoch_1 (epoch_1_a), epoch_2 (epoch_2_a), epoch_2_receive (epoch_2_receive_a),
base (std::max ({ epoch_1, epoch_2, epoch_2_receive })),
entry (std::min ({ epoch_1, epoch_2, epoch_2_receive }))
{
}
work_thresholds () = delete;
work_thresholds operator= (nano::work_thresholds const & other_a)
{
return other_a;
}
uint64_t threshold_entry (nano::work_version const, nano::block_type const) const;
uint64_t threshold (nano::block_details const &) const;
// Ledger threshold
uint64_t threshold (nano::work_version const, nano::block_details const) const;
uint64_t threshold_base (nano::work_version const) const;
uint64_t value (nano::root const & root_a, uint64_t work_a) const;
double normalized_multiplier (double const, uint64_t const) const;
double denormalized_multiplier (double const, uint64_t const) const;
uint64_t difficulty (nano::work_version const, nano::root const &, uint64_t const) const;
uint64_t difficulty (nano::block const & block_a) const;
bool validate_entry (nano::work_version const, nano::root const &, uint64_t const) const;
bool validate_entry (nano::block const &) const;
/** Network work thresholds. Define these inline as constexpr when moving to cpp17. */
static nano::work_thresholds const publish_full;
static nano::work_thresholds const publish_beta;
static nano::work_thresholds const publish_dev;
static nano::work_thresholds const publish_test;
};
class network_constants
{
static constexpr std::chrono::seconds default_cleanup_period = std::chrono::seconds (60);
public:
network_constants (nano::work_thresholds & work_, nano::networks network_a) :
current_network (network_a),
work (work_),
principal_weight_factor (1000), // 0.1% A representative is classified as principal based on its weight and this factor
default_node_port (44000),
default_rpc_port (45000),
default_ipc_port (46000),
default_websocket_port (47000),
aec_loop_interval_ms (300), // Update AEC ~3 times per second
cleanup_period (default_cleanup_period),
merge_period (std::chrono::milliseconds (250)),
keepalive_period (std::chrono::seconds (15)),
idle_timeout (default_cleanup_period * 2),
silent_connection_tolerance_time (std::chrono::seconds (120)),
syn_cookie_cutoff (std::chrono::seconds (5)),
bootstrap_interval (std::chrono::seconds (15 * 60)),
ipv6_subnetwork_prefix_for_limiting (64), // Equivalent to network prefix /64.
peer_dump_interval (std::chrono::seconds (5 * 60)),
vote_broadcast_interval (15 * 1000),
block_broadcast_interval (150 * 1000)
{
if (is_live_network ())
{
default_node_port = 7075;
default_rpc_port = 7076;
default_ipc_port = 7077;
default_websocket_port = 7078;
}
else if (is_beta_network ())
{
default_node_port = 54000;
default_rpc_port = 55000;
default_ipc_port = 56000;
default_websocket_port = 57000;
}
else if (is_test_network ())
{
default_node_port = test_node_port ();
default_rpc_port = test_rpc_port ();
default_ipc_port = test_ipc_port ();
default_websocket_port = test_websocket_port ();
}
else if (is_dev_network ())
{
aec_loop_interval_ms = 20;
cleanup_period = std::chrono::seconds (1);
merge_period = std::chrono::milliseconds (10);
keepalive_period = std::chrono::seconds (1);
idle_timeout = cleanup_period * 15;
peer_dump_interval = std::chrono::seconds (1);
vote_broadcast_interval = 500ms;
block_broadcast_interval = 500ms;
telemetry_request_cooldown = 500ms;
telemetry_cache_cutoff = 2000ms;
telemetry_request_interval = 500ms;
telemetry_broadcast_interval = 500ms;
optimistic_activation_delay = 2s;
rep_crawler_normal_interval = 500ms;
rep_crawler_warmup_interval = 500ms;
}
}
/** Error message when an invalid network is specified */
static char const * active_network_err_msg;
/** The network this param object represents. This may differ from the global active network; this is needed for certain --debug... commands */
nano::networks current_network{ nano::network_constants::active_network };
nano::work_thresholds & work;
unsigned principal_weight_factor;
uint16_t default_node_port;
uint16_t default_rpc_port;
uint16_t default_ipc_port;
uint16_t default_websocket_port;
unsigned aec_loop_interval_ms;
std::chrono::seconds cleanup_period;
std::chrono::milliseconds cleanup_period_half () const
{
return std::chrono::duration_cast<std::chrono::milliseconds> (cleanup_period) / 2;
}
std::chrono::seconds cleanup_cutoff () const
{
return cleanup_period * 5;
}
/** How often to connect to other peers */
std::chrono::milliseconds merge_period;
/** How often to send keepalive messages */
std::chrono::seconds keepalive_period;
/** Default maximum idle time for a socket before it's automatically closed */
std::chrono::seconds idle_timeout;
std::chrono::seconds silent_connection_tolerance_time;
std::chrono::seconds syn_cookie_cutoff;
std::chrono::seconds bootstrap_interval;
size_t ipv6_subnetwork_prefix_for_limiting;
std::chrono::seconds peer_dump_interval;
/** Time to wait before rebroadcasts for active elections */
std::chrono::milliseconds vote_broadcast_interval;
std::chrono::milliseconds block_broadcast_interval;
/** We do not reply to telemetry requests made within cooldown period */
std::chrono::milliseconds telemetry_request_cooldown{ 1000 * 15 };
/** How often to request telemetry from peers */
std::chrono::milliseconds telemetry_request_interval{ 1000 * 60 };
/** How often to broadcast telemetry to peers */
std::chrono::milliseconds telemetry_broadcast_interval{ 1000 * 60 };
/** Telemetry data older than this value is considered stale */
std::chrono::milliseconds telemetry_cache_cutoff{ 1000 * 130 }; // 2 * `telemetry_broadcast_interval` + some margin
/** How much to delay activation of optimistic elections to avoid interfering with election scheduler */
std::chrono::seconds optimistic_activation_delay{ 30 };
std::chrono::milliseconds rep_crawler_normal_interval{ 1000 * 7 };
std::chrono::milliseconds rep_crawler_warmup_interval{ 1000 * 3 };
/** Returns the network this object contains values for */
nano::networks network () const
{
return current_network;
}
/**
* Optionally called on startup to override the global active network.
* If not called, the compile-time option will be used.
* @param network_a The new active network
*/
static void set_active_network (nano::networks network_a)
{
active_network = network_a;
}
/**
* Optionally called on startup to override the global active network.
* If not called, the compile-time option will be used.
* @param network_a The new active network. Valid values are "live", "beta" and "dev"
*/
static bool set_active_network (std::string network_a)
{
auto error{ false };
if (network_a == "live")
{
active_network = nano::networks::nano_live_network;
}
else if (network_a == "beta")
{
active_network = nano::networks::nano_beta_network;
}
else if (network_a == "dev")
{
active_network = nano::networks::nano_dev_network;
}
else if (network_a == "test")
{
active_network = nano::networks::nano_test_network;
}
else
{
error = true;
}
return error;
}
char const * get_current_network_as_string ()
{
return is_live_network () ? "live" : is_beta_network () ? "beta"
: is_test_network () ? "test"
: "dev";
}
bool is_live_network () const
{
return current_network == nano::networks::nano_live_network;
}
bool is_beta_network () const
{
return current_network == nano::networks::nano_beta_network;
}
bool is_dev_network () const
{
return current_network == nano::networks::nano_dev_network;
}
bool is_test_network () const
{
return current_network == nano::networks::nano_test_network;
}
/** Initial value is ACTIVE_NETWORK compile flag, but can be overridden by a CLI flag */
static nano::networks active_network;
/** Current protocol version */
uint8_t const protocol_version = 0x15;
/** Minimum accepted protocol version */
uint8_t const protocol_version_min = 0x14;
/** Minimum accepted protocol version used when bootstrapping */
uint8_t const bootstrap_protocol_version_min = 0x14;
};
uint32_t test_scan_wallet_reps_delay (); // How often to scan for representatives in local wallet, in milliseconds
std::string get_node_toml_config_path (std::filesystem::path const & data_path);
std::string get_rpc_toml_config_path (std::filesystem::path const & data_path);
@ -379,7 +105,10 @@ bool slow_instrumentation ();
/** Set the active network to the dev network */
void force_nano_dev_network ();
}
namespace nano
{
/**
* Attempt to read a configuration file from specified directory. Returns empty tomlconfig if nothing is found.
* @throws std::runtime_error with error code if the file or overrides are not valid toml

219
nano/lib/constants.cpp Normal file
View file

@ -0,0 +1,219 @@
#include <nano/crypto/blake2/blake2.h>
#include <nano/lib/block_type.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/constants.hpp>
#include <nano/lib/env.hpp>
#include <nano/lib/logging.hpp>
#include <nano/lib/work_version.hpp>
namespace
{
// useful for boost_lexical cast to allow conversion of hex strings
template <typename ElemT>
struct HexTo
{
ElemT value;
HexTo () = default;
HexTo (ElemT val) :
value{ val }
{
}
operator ElemT () const
{
return value;
}
friend std::istream & operator>> (std::istream & in, HexTo & out)
{
in >> std::hex >> out.value;
return in;
}
};
}
nano::work_thresholds const nano::work_thresholds::publish_full (
0xffffffc000000000,
0xfffffff800000000, // 8x higher than epoch_1
0xfffffe0000000000 // 8x lower than epoch_1
);
nano::work_thresholds const nano::work_thresholds::publish_beta (
0xfffff00000000000, // 64x lower than publish_full.epoch_1
0xfffff00000000000, // same as epoch_1
0xffffe00000000000 // 2x lower than epoch_1
);
nano::work_thresholds const nano::work_thresholds::publish_dev (
0xfe00000000000000, // Very low for tests
0xffc0000000000000, // 8x higher than epoch_1
0xf000000000000000 // 8x lower than epoch_1
);
nano::work_thresholds const nano::work_thresholds::publish_test ( // defaults to live network levels
nano::env::get<HexTo<uint64_t>> ("NANO_TEST_EPOCH_1").value_or (0xffffffc000000000),
nano::env::get<HexTo<uint64_t>> ("NANO_TEST_EPOCH_2").value_or (0xfffffff800000000), // 8x higher than epoch_1
nano::env::get<HexTo<uint64_t>> ("NANO_TEST_EPOCH_2_RECV").value_or (0xfffffe0000000000) // 8x lower than epoch_1
);
uint64_t nano::work_thresholds::threshold_entry (nano::work_version const version_a, nano::block_type const type_a) const
{
uint64_t result{ std::numeric_limits<uint64_t>::max () };
if (type_a == nano::block_type::state)
{
switch (version_a)
{
case nano::work_version::work_1:
result = entry;
break;
default:
debug_assert (false && "Invalid version specified to work_threshold_entry");
}
}
else
{
result = epoch_1;
}
return result;
}
#ifndef NANO_FUZZER_TEST
uint64_t nano::work_thresholds::value (nano::root const & root_a, uint64_t work_a) const
{
uint64_t result;
blake2b_state hash;
blake2b_init (&hash, sizeof (result));
blake2b_update (&hash, reinterpret_cast<uint8_t *> (&work_a), sizeof (work_a));
blake2b_update (&hash, root_a.bytes.data (), root_a.bytes.size ());
blake2b_final (&hash, reinterpret_cast<uint8_t *> (&result), sizeof (result));
return result;
}
#else
uint64_t nano::work_thresholds::value (nano::root const & root_a, uint64_t work_a) const
{
return base + 1;
}
#endif
uint64_t nano::work_thresholds::threshold (nano::block_details const & details_a) const
{
static_assert (nano::epoch::max == nano::epoch::epoch_2, "work_v1::threshold is ill-defined");
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) ? epoch_2_receive : epoch_2;
break;
case nano::epoch::epoch_1:
case nano::epoch::epoch_0:
result = epoch_1;
break;
default:
debug_assert (false && "Invalid epoch specified to work_v1 ledger work_threshold");
}
return result;
}
uint64_t nano::work_thresholds::threshold (nano::work_version const version_a, nano::block_details const details_a) const
{
uint64_t result{ std::numeric_limits<uint64_t>::max () };
switch (version_a)
{
case nano::work_version::work_1:
result = threshold (details_a);
break;
default:
debug_assert (false && "Invalid version specified to ledger work_threshold");
}
return result;
}
double nano::work_thresholds::normalized_multiplier (double const multiplier_a, uint64_t const threshold_a) const
{
debug_assert (multiplier_a >= 1);
auto multiplier (multiplier_a);
/* Normalization rules
ratio = multiplier of max work threshold (send epoch 2) from given threshold
i.e. max = 0xfe00000000000000, given = 0xf000000000000000, ratio = 8.0
normalized = (multiplier + (ratio - 1)) / ratio;
Epoch 1
multiplier | normalized
1.0 | 1.0
9.0 | 2.0
25.0 | 4.0
Epoch 2 (receive / epoch subtypes)
multiplier | normalized
1.0 | 1.0
65.0 | 2.0
241.0 | 4.0
*/
if (threshold_a == epoch_1 || threshold_a == epoch_2_receive)
{
auto ratio (nano::difficulty::to_multiplier (epoch_2, threshold_a));
debug_assert (ratio >= 1);
multiplier = (multiplier + (ratio - 1.0)) / ratio;
debug_assert (multiplier >= 1);
}
return multiplier;
}
double nano::work_thresholds::denormalized_multiplier (double const multiplier_a, uint64_t const threshold_a) const
{
debug_assert (multiplier_a >= 1);
auto multiplier (multiplier_a);
if (threshold_a == epoch_1 || threshold_a == epoch_2_receive)
{
auto ratio (nano::difficulty::to_multiplier (epoch_2, threshold_a));
debug_assert (ratio >= 1);
multiplier = multiplier * ratio + 1.0 - ratio;
debug_assert (multiplier >= 1);
}
return multiplier;
}
uint64_t nano::work_thresholds::threshold_base (nano::work_version const version_a) const
{
uint64_t result{ std::numeric_limits<uint64_t>::max () };
switch (version_a)
{
case nano::work_version::work_1:
result = base;
break;
default:
debug_assert (false && "Invalid version specified to work_threshold_base");
}
return result;
}
uint64_t nano::work_thresholds::difficulty (nano::work_version const version_a, nano::root const & root_a, uint64_t const work_a) const
{
uint64_t result{ 0 };
switch (version_a)
{
case nano::work_version::work_1:
result = value (root_a, work_a);
break;
default:
debug_assert (false && "Invalid version specified to work_difficulty");
}
return result;
}
uint64_t nano::work_thresholds::difficulty (nano::block const & block_a) const
{
return difficulty (block_a.work_version (), block_a.root (), block_a.block_work ());
}
bool nano::work_thresholds::validate_entry (nano::work_version const version_a, nano::root const & root_a, uint64_t const work_a) const
{
return difficulty (version_a, root_a, work_a) < threshold_entry (version_a, nano::block_type::state);
}
bool nano::work_thresholds::validate_entry (nano::block const & block_a) const
{
return difficulty (block_a) < threshold_entry (block_a.work_version (), block_a.type ());
}

285
nano/lib/constants.hpp Normal file
View file

@ -0,0 +1,285 @@
#pragma once
#include <nano/lib/config.hpp>
#include <nano/lib/fwd.hpp>
#include <chrono>
#include <string_view>
namespace nano
{
/**
* Network variants with different genesis blocks and network parameters
*/
enum class networks : uint16_t
{
invalid = 0x0,
// Low work parameters, publicly known genesis key, dev IP ports
nano_dev_network = 0x5241, // 'R', 'A'
// Normal work parameters, secret beta genesis key, beta IP ports
nano_beta_network = 0x5242, // 'R', 'B'
// Normal work parameters, secret live key, live IP ports
nano_live_network = 0x5243, // 'R', 'C'
// Normal work parameters, secret test genesis key, test IP ports
nano_test_network = 0x5258, // 'R', 'X'
};
std::string_view to_string (nano::networks);
class work_thresholds
{
public:
uint64_t const epoch_1;
uint64_t const epoch_2;
uint64_t const epoch_2_receive;
// Automatically calculated. The base threshold is the maximum of all thresholds and is used for all work multiplier calculations
uint64_t const base;
// Automatically calculated. The entry threshold is the minimum of all thresholds and defines the required work to enter the node, but does not guarantee a block is processed
uint64_t const entry;
constexpr work_thresholds (uint64_t epoch_1_a, uint64_t epoch_2_a, uint64_t epoch_2_receive_a) :
epoch_1 (epoch_1_a), epoch_2 (epoch_2_a), epoch_2_receive (epoch_2_receive_a),
base (std::max ({ epoch_1, epoch_2, epoch_2_receive })),
entry (std::min ({ epoch_1, epoch_2, epoch_2_receive }))
{
}
work_thresholds () = delete;
work_thresholds operator= (nano::work_thresholds const & other_a)
{
return other_a;
}
uint64_t threshold_entry (nano::work_version const, nano::block_type const) const;
uint64_t threshold (nano::block_details const &) const;
// Ledger threshold
uint64_t threshold (nano::work_version const, nano::block_details const) const;
uint64_t threshold_base (nano::work_version const) const;
uint64_t value (nano::root const & root_a, uint64_t work_a) const;
double normalized_multiplier (double const, uint64_t const) const;
double denormalized_multiplier (double const, uint64_t const) const;
uint64_t difficulty (nano::work_version const, nano::root const &, uint64_t const) const;
uint64_t difficulty (nano::block const & block_a) const;
bool validate_entry (nano::work_version const, nano::root const &, uint64_t const) const;
bool validate_entry (nano::block const &) const;
/** Network work thresholds. Define these inline as constexpr when moving to cpp17. */
static nano::work_thresholds const publish_full;
static nano::work_thresholds const publish_beta;
static nano::work_thresholds const publish_dev;
static nano::work_thresholds const publish_test;
};
class network_constants
{
static constexpr std::chrono::seconds default_cleanup_period = std::chrono::seconds (60);
public:
network_constants (nano::work_thresholds & work_, nano::networks network_a) :
current_network (network_a),
work (work_),
principal_weight_factor (1000), // 0.1% A representative is classified as principal based on its weight and this factor
default_node_port (44000),
default_rpc_port (45000),
default_ipc_port (46000),
default_websocket_port (47000),
aec_loop_interval_ms (300), // Update AEC ~3 times per second
cleanup_period (default_cleanup_period),
merge_period (std::chrono::milliseconds (250)),
keepalive_period (std::chrono::seconds (15)),
idle_timeout (default_cleanup_period * 2),
silent_connection_tolerance_time (std::chrono::seconds (120)),
syn_cookie_cutoff (std::chrono::seconds (5)),
bootstrap_interval (std::chrono::seconds (15 * 60)),
ipv6_subnetwork_prefix_for_limiting (64), // Equivalent to network prefix /64.
peer_dump_interval (std::chrono::seconds (5 * 60)),
vote_broadcast_interval (15 * 1000),
block_broadcast_interval (150 * 1000)
{
if (is_live_network ())
{
default_node_port = 7075;
default_rpc_port = 7076;
default_ipc_port = 7077;
default_websocket_port = 7078;
}
else if (is_beta_network ())
{
default_node_port = 54000;
default_rpc_port = 55000;
default_ipc_port = 56000;
default_websocket_port = 57000;
}
else if (is_test_network ())
{
default_node_port = test_node_port ();
default_rpc_port = test_rpc_port ();
default_ipc_port = test_ipc_port ();
default_websocket_port = test_websocket_port ();
}
else if (is_dev_network ())
{
aec_loop_interval_ms = 20;
cleanup_period = std::chrono::seconds (1);
merge_period = std::chrono::milliseconds (10);
keepalive_period = std::chrono::seconds (1);
idle_timeout = cleanup_period * 15;
peer_dump_interval = std::chrono::seconds (1);
vote_broadcast_interval = 500ms;
block_broadcast_interval = 500ms;
telemetry_request_cooldown = 500ms;
telemetry_cache_cutoff = 2000ms;
telemetry_request_interval = 500ms;
telemetry_broadcast_interval = 500ms;
optimistic_activation_delay = 2s;
rep_crawler_normal_interval = 500ms;
rep_crawler_warmup_interval = 500ms;
}
}
/** The network this param object represents. This may differ from the global active network; this is needed for certain --debug... commands */
nano::networks current_network{ nano::network_constants::active_network };
nano::work_thresholds & work;
unsigned principal_weight_factor;
uint16_t default_node_port;
uint16_t default_rpc_port;
uint16_t default_ipc_port;
uint16_t default_websocket_port;
unsigned aec_loop_interval_ms;
std::chrono::seconds cleanup_period;
std::chrono::milliseconds cleanup_period_half () const
{
return std::chrono::duration_cast<std::chrono::milliseconds> (cleanup_period) / 2;
}
std::chrono::seconds cleanup_cutoff () const
{
return cleanup_period * 5;
}
/** How often to connect to other peers */
std::chrono::milliseconds merge_period;
/** How often to send keepalive messages */
std::chrono::seconds keepalive_period;
/** Default maximum idle time for a socket before it's automatically closed */
std::chrono::seconds idle_timeout;
std::chrono::seconds silent_connection_tolerance_time;
std::chrono::seconds syn_cookie_cutoff;
std::chrono::seconds bootstrap_interval;
size_t ipv6_subnetwork_prefix_for_limiting;
std::chrono::seconds peer_dump_interval;
/** Time to wait before rebroadcasts for active elections */
std::chrono::milliseconds vote_broadcast_interval;
std::chrono::milliseconds block_broadcast_interval;
/** We do not reply to telemetry requests made within cooldown period */
std::chrono::milliseconds telemetry_request_cooldown{ 1000 * 15 };
/** How often to request telemetry from peers */
std::chrono::milliseconds telemetry_request_interval{ 1000 * 60 };
/** How often to broadcast telemetry to peers */
std::chrono::milliseconds telemetry_broadcast_interval{ 1000 * 60 };
/** Telemetry data older than this value is considered stale */
std::chrono::milliseconds telemetry_cache_cutoff{ 1000 * 130 }; // 2 * `telemetry_broadcast_interval` + some margin
/** How much to delay activation of optimistic elections to avoid interfering with election scheduler */
std::chrono::seconds optimistic_activation_delay{ 30 };
std::chrono::milliseconds rep_crawler_normal_interval{ 1000 * 7 };
std::chrono::milliseconds rep_crawler_warmup_interval{ 1000 * 3 };
/** Returns the network this object contains values for */
nano::networks network () const
{
return current_network;
}
/**
* Optionally called on startup to override the global active network.
* If not called, the compile-time option will be used.
* @param network_a The new active network
*/
static void set_active_network (nano::networks network_a)
{
active_network = network_a;
}
/**
* Optionally called on startup to override the global active network.
* If not called, the compile-time option will be used.
* @param network_a The new active network. Valid values are "live", "beta" and "dev"
*/
static bool set_active_network (std::string network_a)
{
auto error{ false };
if (network_a == "live")
{
active_network = nano::networks::nano_live_network;
}
else if (network_a == "beta")
{
active_network = nano::networks::nano_beta_network;
}
else if (network_a == "dev")
{
active_network = nano::networks::nano_dev_network;
}
else if (network_a == "test")
{
active_network = nano::networks::nano_test_network;
}
else
{
error = true;
}
return error;
}
std::string_view get_current_network_as_string () const
{
switch (current_network)
{
case nano::networks::nano_live_network:
return "live";
case nano::networks::nano_beta_network:
return "beta";
case nano::networks::nano_dev_network:
return "dev";
case nano::networks::nano_test_network:
return "test";
case networks::invalid:
break;
}
release_assert (false, "invalid network");
}
bool is_live_network () const
{
return current_network == nano::networks::nano_live_network;
}
bool is_beta_network () const
{
return current_network == nano::networks::nano_beta_network;
}
bool is_dev_network () const
{
return current_network == nano::networks::nano_dev_network;
}
bool is_test_network () const
{
return current_network == nano::networks::nano_test_network;
}
/** Initial value is ACTIVE_NETWORK compile flag, but can be overridden by a CLI flag */
static nano::networks active_network;
/** Current protocol version */
uint8_t const protocol_version = 0x15;
/** Minimum accepted protocol version */
uint8_t const protocol_version_min = 0x14;
/** Minimum accepted protocol version used when bootstrapping */
uint8_t const bootstrap_protocol_version_min = 0x14;
};
}

View file

@ -4,21 +4,25 @@
#include <iosfwd>
struct uint8_char_traits;
namespace nano
{
class block;
enum class block_type : uint8_t;
class block_details;
class block_visitor;
class container_info;
enum class epoch : uint8_t;
class jsonconfig;
class mutable_block_visitor;
class network_constants;
class object_stream;
class root;
class thread_pool;
class tomlconfig;
template <typename Key, typename Value>
class uniquer;
enum class block_type : uint8_t;
enum class epoch : uint8_t;
enum class work_version;
using stream = std::basic_streambuf<uint8_t, uint8_char_traits>;
@ -26,6 +30,7 @@ using stream = std::basic_streambuf<uint8_t, uint8_char_traits>;
namespace nano::stat
{
enum class type;
enum class detail;
enum class dir;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <nano/lib/config.hpp>
#include <nano/lib/constants.hpp>
#include <nano/lib/errors.hpp>
#include <nano/lib/threading.hpp>

View file

@ -1,6 +1,7 @@
#include <nano/crypto/blake2/blake2.h>
#include <nano/crypto_lib/random_pool.hpp>
#include <nano/lib/blocks.hpp>
#include <nano/lib/constants.hpp>
#include <nano/lib/epoch.hpp>
#include <nano/lib/thread_roles.hpp>
#include <nano/lib/threading.hpp>

View file

@ -580,7 +580,7 @@ int main (int argc, char * const * argv)
data_paths.push_back (std::move (data_path));
}
auto current_network = nano::dev::network_params.network.get_current_network_as_string ();
std::string current_network{ nano::dev::network_params.network.get_current_network_as_string () };
std::vector<std::unique_ptr<boost::process::child>> nodes;
std::vector<std::unique_ptr<boost::process::child>> rpc_servers;
for (auto const & data_path : data_paths)

View file

@ -170,8 +170,7 @@ void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flag
throw std::runtime_error (std::string ("RPC is configured to spawn a new process however the file cannot be found at: ") + config.rpc.child_process.rpc_path);
}
auto network = node->network_params.network.get_current_network_as_string ();
std::string network{ node->network_params.network.get_current_network_as_string () };
rpc_process = std::make_unique<boost::process::child> (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path.string (), "--network", network);
}
debug_assert (rpc || rpc_process);

View file

@ -173,7 +173,7 @@ int main (int argc, char * const * argv)
auto err (nano::network_constants::set_active_network (network->second.as<std::string> ()));
if (err)
{
std::cerr << nano::network_constants::active_network_err_msg << std::endl;
std::cerr << "Invalid network. Valid values are live, test, beta and dev." << std::endl;
std::exit (1);
}
}

View file

@ -118,7 +118,7 @@ int main (int argc, char * const * argv)
auto err (nano::network_constants::set_active_network (network->second.as<std::string> ()));
if (err)
{
std::cerr << nano::network_constants::active_network_err_msg << std::endl;
std::cerr << "Invalid network. Valid values are live, test, beta and dev." << std::endl;
std::exit (1);
}
}

View file

@ -192,7 +192,7 @@ public:
throw std::runtime_error (std::string ("RPC is configured to spawn a new process however the file cannot be found at: ") + config.rpc.child_process.rpc_path);
}
auto network = node->network_params.network.get_current_network_as_string ();
std::string network{ node->network_params.network.get_current_network_as_string () };
rpc_process = std::make_unique<boost::process::child> (config.rpc.child_process.rpc_path, "--daemon", "--data_path", data_path.string (), "--network", network);
}
}
@ -281,7 +281,7 @@ int main (int argc, char * const * argv)
auto err (nano::network_constants::set_active_network (network->second.as<std::string> ()));
if (err)
{
daemon.show_error (nano::network_constants::active_network_err_msg);
daemon.show_error ("Invalid network. Valid values are live, test, beta and dev.");
std::exit (1);
}
}

View file

@ -1,3 +1,4 @@
#include <nano/lib/constants.hpp>
#include <nano/lib/jsonconfig.hpp>
#include <nano/lib/tomlconfig.hpp>
#include <nano/node/ipc/ipc_config.hpp>

View file

@ -1,6 +1,7 @@
#pragma once
#include <nano/lib/config.hpp>
#include <nano/lib/constants.hpp>
#include <nano/node/openclconfig.hpp>
#include <nano/node/xorshift.hpp>

View file

@ -7,6 +7,8 @@
#include <boost/range/adaptor/filtered.hpp>
#include <fmt/format.h>
std::string nano::mapping_protocol::to_string ()
{
std::stringstream ss;
@ -179,7 +181,7 @@ void nano::port_mapping::refresh_mapping ()
// We don't map the RPC port because, unless RPC authentication was added, this would almost always be a security risk
for (auto & protocol : protocols | boost::adaptors::filtered ([] (auto const & p) { return p.enabled; }))
{
auto upnp_description = std::string ("Nano Node (") + node.network_params.network.get_current_network_as_string () + ")";
auto upnp_description = fmt::format ("Nano Node ({})", node.network_params.network.get_current_network_as_string ());
std::string address_str = address.to_string ();
std::string lease_duration_str = std::to_string (node.network_params.portmapping.lease_duration.count ());

View file

@ -1,6 +1,6 @@
#pragma once
#include <nano/lib/config.hpp>
#include <nano/lib/constants.hpp>
#include <nano/lib/errors.hpp>
#include <memory>

View file

@ -14,6 +14,8 @@
#include <iomanip>
#include <sstream>
#include <fmt/format.h>
namespace
{
void show_line_error (QLineEdit & line)
@ -75,12 +77,14 @@ nano_qt::self_pane::self_pane (nano_qt::wallet & wallet_a, nano::account const &
wallet (wallet_a)
{
your_account_label->setStyleSheet ("font-weight: bold;");
std::string network = wallet.node.network_params.network.get_current_network_as_string ();
// Capitalize the first letter
std::string network{ wallet.node.network_params.network.get_current_network_as_string () };
if (!network.empty ())
{
network[0] = std::toupper (network[0]);
}
version = new QLabel (boost::str (boost::format ("%1% %2% network") % NANO_VERSION_STRING % network).c_str ());
version = new QLabel (fmt::format ("{} {} network", NANO_VERSION_STRING, network).c_str ());
self_layout->addWidget (your_account_label);
self_layout->addStretch ();

View file

@ -4,6 +4,7 @@
#include <nano/lib/blockbuilders.hpp>
#include <nano/lib/common.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/constants.hpp>
#include <nano/lib/epochs.hpp>
#include <nano/lib/fwd.hpp>
#include <nano/lib/numbers.hpp>

View file

@ -1,6 +1,7 @@
#pragma once
#include <nano/lib/config.hpp>
#include <nano/lib/constants.hpp>
#include <functional>