From bab44742747500983fca15119b712c5ea445070a Mon Sep 17 00:00:00 2001 From: cryptocode Date: Mon, 11 Mar 2019 16:10:33 +0100 Subject: [PATCH] Network selector (#1729) * Network selector * Make sure network option is checked before working path is called (migration). Also remove bool assignment from error. * Formatting * Fix merge error * Use network_params for RPC port config (rebase) * Formatting * Rebase * Rebase (debug_opencl, merge fix) * Rebase fix * post-rebase update --- gtest/src/gtest_main.cc | 4 +- nano/core_test/block_store.cpp | 1 + nano/core_test/conflicts.cpp | 1 + nano/core_test/processor_service.cpp | 1 + nano/core_test/testutil.hpp | 19 ++ nano/core_test/uint256_union.cpp | 1 + nano/core_test/work_pool.cpp | 8 +- nano/lib/CMakeLists.txt | 1 + nano/lib/config.cpp | 147 ++++++++++ nano/lib/config.hpp | 173 ++++++++++- nano/lib/errors.hpp | 11 - nano/lib/interface.cpp | 4 +- nano/lib/work.cpp | 17 +- nano/lib/work.hpp | 11 +- nano/nano_node/entry.cpp | 415 ++++++++++++++------------- nano/nano_wallet/entry.cpp | 11 + nano/node/blockprocessor.cpp | 2 +- nano/node/bootstrap.cpp | 6 +- nano/node/bootstrap.hpp | 7 - nano/node/cli.cpp | 4 +- nano/node/common.cpp | 18 +- nano/node/common.hpp | 10 +- nano/node/lmdb.cpp | 10 +- nano/node/lmdb.hpp | 2 + nano/node/node.cpp | 115 ++++---- nano/node/node.hpp | 28 +- nano/node/nodeconfig.cpp | 16 +- nano/node/nodeconfig.hpp | 2 + nano/node/peers.cpp | 2 +- nano/node/peers.hpp | 2 + nano/node/portmapping.cpp | 10 +- nano/node/portmapping.hpp | 4 +- nano/node/rpc.cpp | 16 +- nano/node/rpc.hpp | 1 + nano/node/rpcconfig.cpp | 2 +- nano/node/rpcconfig.hpp | 1 + nano/node/testing.cpp | 1 + nano/node/voting.cpp | 7 +- nano/node/voting.hpp | 8 +- nano/node/wallet.cpp | 9 +- nano/node/wallet.hpp | 9 +- nano/qt/qt.cpp | 19 +- nano/qt_system/entry.cpp | 2 + nano/qt_test/entry.cpp | 5 +- nano/secure/CMakeLists.txt | 29 +- nano/secure/blockstore.cpp | 6 +- nano/secure/blockstore.hpp | 2 + nano/secure/common.cpp | 105 +------ nano/secure/common.hpp | 15 +- nano/secure/ledger.cpp | 6 +- nano/secure/ledger.hpp | 2 + nano/secure/utility.cpp | 7 +- nano/secure/utility.hpp | 1 - nano/slow_test/node.cpp | 1 - 54 files changed, 778 insertions(+), 539 deletions(-) create mode 100644 nano/lib/config.cpp diff --git a/gtest/src/gtest_main.cc b/gtest/src/gtest_main.cc index f30282255..0d9152644 100644 --- a/gtest/src/gtest_main.cc +++ b/gtest/src/gtest_main.cc @@ -29,10 +29,12 @@ #include -#include "gtest/gtest.h" +extern void force_nano_test_network (); +#include "gtest/gtest.h" GTEST_API_ int main(int argc, char **argv) { printf("Running main() from gtest_main.cc\n"); + force_nano_test_network (); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index 00f3f9a1e..7af00e90c 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/nano/core_test/conflicts.cpp b/nano/core_test/conflicts.cpp index 29f750ad6..7fb944818 100644 --- a/nano/core_test/conflicts.cpp +++ b/nano/core_test/conflicts.cpp @@ -1,4 +1,5 @@ #include +#include #include TEST (conflicts, start_stop) diff --git a/nano/core_test/processor_service.cpp b/nano/core_test/processor_service.cpp index 67048974f..512be44df 100644 --- a/nano/core_test/processor_service.cpp +++ b/nano/core_test/processor_service.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/nano/core_test/testutil.hpp b/nano/core_test/testutil.hpp index cc058eb26..d1babc489 100644 --- a/nano/core_test/testutil.hpp +++ b/nano/core_test/testutil.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #define GTEST_TEST_ERROR_CODE(expression, text, actual, expected, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult (expression)) \ @@ -18,3 +21,19 @@ #define ASSERT_IS_ERROR(condition) \ GTEST_TEST_ERROR_CODE ((condition.value () > 0), #condition, "An error was expected", "", \ GTEST_FATAL_FAILURE_) + +/* Convenience globals for core_test */ +namespace nano +{ +using uint128_t = boost::multiprecision::uint128_t; +class keypair; +union uint256_union; +extern nano::keypair const & zero_key; +extern nano::keypair const & test_genesis_key; +extern std::string const & nano_test_genesis; +extern std::string const & genesis_block; +extern nano::uint256_union const & nano_test_account; +extern nano::uint256_union const & genesis_account; +extern nano::uint256_union const & burn_account; +extern nano::uint128_t const & genesis_amount; +} diff --git a/nano/core_test/uint256_union.cpp b/nano/core_test/uint256_union.cpp index 8026fae9f..3458ae255 100644 --- a/nano/core_test/uint256_union.cpp +++ b/nano/core_test/uint256_union.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include diff --git a/nano/core_test/work_pool.cpp b/nano/core_test/work_pool.cpp index a230594f8..0d6354391 100644 --- a/nano/core_test/work_pool.cpp +++ b/nano/core_test/work_pool.cpp @@ -6,24 +6,26 @@ TEST (work, one) { + nano::network_params params; nano::work_pool pool (std::numeric_limits::max (), nullptr); nano::change_block block (1, 1, nano::keypair ().prv, 3, 4); block.block_work_set (pool.generate (block.root ())); uint64_t difficulty; ASSERT_FALSE (nano::work_validate (block, &difficulty)); - ASSERT_LT (nano::work_pool::publish_threshold, difficulty); + ASSERT_LT (params.publish_threshold, difficulty); } TEST (work, validate) { + nano::network_params params; nano::work_pool pool (std::numeric_limits::max (), nullptr); nano::send_block send_block (1, 1, 2, nano::keypair ().prv, 4, 6); uint64_t difficulty; ASSERT_TRUE (nano::work_validate (send_block, &difficulty)); - ASSERT_LT (difficulty, nano::work_pool::publish_threshold); + ASSERT_LT (difficulty, params.publish_threshold); send_block.block_work_set (pool.generate (send_block.root ())); ASSERT_FALSE (nano::work_validate (send_block, &difficulty)); - ASSERT_LT (nano::work_pool::publish_threshold, difficulty); + ASSERT_LT (params.publish_threshold, difficulty); } TEST (work, cancel) diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index a33b7e59e..9798b120a 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -20,6 +20,7 @@ add_library (nano_lib blocks.cpp blocks.hpp config.hpp + config.cpp interface.cpp interface.h jsonconfig.hpp diff --git a/nano/lib/config.cpp b/nano/lib/config.cpp new file mode 100644 index 000000000..6fe40dd8a --- /dev/null +++ b/nano/lib/config.cpp @@ -0,0 +1,147 @@ +#include +#include +#include +#include + +nano::nano_networks nano::network_params::active_network = nano::nano_networks::ACTIVE_NETWORK; + +namespace +{ +char const * test_private_key_data = "34F0A37AAD20F4A260F0A5B3CB3D7FB50673212263E58A380BC10474BB039CE4"; +char const * test_public_key_data = "B0311EA55708D6A53C75CDBF88300259C6D018522FE3D4D0A242E431F9E8B6D0"; // xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo +char const * beta_public_key_data = "A59A47CC4F593E75AE9AD653FDA9358E2F7898D9ACC8C60E80D0495CE20FBA9F"; // xrb_3betaz86ypbygpqbookmzpnmd5jhh4efmd8arr9a3n4bdmj1zgnzad7xpmfp +char const * live_public_key_data = "E89208DD038FBB269987689621D52292AE9C35941A7484756ECCED92A65093BA"; // xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3 +char const * test_genesis_data = R"%%%({ + "type": "open", + "source": "B0311EA55708D6A53C75CDBF88300259C6D018522FE3D4D0A242E431F9E8B6D0", + "representative": "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo", + "account": "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo", + "work": "9680625b39d3363d", + "signature": "ECDA914373A2F0CA1296475BAEE40500A7F0A7AD72A5A80C81D7FAB7F6C802B2CC7DB50F5DD0FB25B2EF11761FA7344A158DD5A700B21BD47DE5BD0F63153A02" + })%%%"; + +char const * beta_genesis_data = R"%%%({ + "type": "open", + "source": "A59A47CC4F593E75AE9AD653FDA9358E2F7898D9ACC8C60E80D0495CE20FBA9F", + "representative": "xrb_3betaz86ypbygpqbookmzpnmd5jhh4efmd8arr9a3n4bdmj1zgnzad7xpmfp", + "account": "xrb_3betaz86ypbygpqbookmzpnmd5jhh4efmd8arr9a3n4bdmj1zgnzad7xpmfp", + "work": "000000000f0aaeeb", + "signature": "A726490E3325E4FA59C1C900D5B6EEBB15FE13D99F49D475B93F0AACC5635929A0614CF3892764A04D1C6732A0D716FFEB254D4154C6F544D11E6630F201450B" + })%%%"; + +char const * live_genesis_data = R"%%%({ + "type": "open", + "source": "E89208DD038FBB269987689621D52292AE9C35941A7484756ECCED92A65093BA", + "representative": "xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3", + "account": "xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3", + "work": "62f05417dd3fb691", + "signature": "9F0C933C8ADE004D808EA1985FA746A7E95BA2A38F867640F53EC8F180BDFE9E2C1268DEAD7C2664F356E37ABA362BC58E46DBA03E523A7B5A19E4B6EB12BB02" + })%%%"; +} + +nano::network_params::network_params () : +network_params (nano::network_params::active_network) +{ +} + +nano::network_params::network_params (nano::nano_networks network_a) : +current_network (network_a), ledger (*this), voting (*this), node (*this), portmapping (*this), bootstrap (*this) +{ + // Local work threshold for rate-limiting publishing blocks. ~5 seconds of work. + uint64_t constexpr publish_test_threshold = 0xff00000000000000; + uint64_t constexpr publish_full_threshold = 0xffffffc000000000; + publish_threshold = is_test_network () ? publish_test_threshold : publish_full_threshold; + + unsigned constexpr kdf_full_work = 64 * 1024; + unsigned constexpr kdf_test_work = 8; + kdf_work = is_test_network () ? kdf_test_work : kdf_full_work; + + default_node_port = is_live_network () ? 7075 : 54000; + default_rpc_port = is_live_network () ? 7076 : 55000; + request_interval_ms = is_test_network () ? 10 : 16000; + header_magic_number = is_test_network () ? std::array{ { 'R', 'A' } } : is_beta_network () ? std::array{ { 'R', 'B' } } : std::array{ { 'R', 'C' } }; +} + +nano::ledger_constants::ledger_constants (nano::network_params & params_a) : +ledger_constants (params_a.network ()) +{ +} + +nano::ledger_constants::ledger_constants (nano::nano_networks network_a) : +zero_key ("0"), +test_genesis_key (test_private_key_data), +nano_test_account (test_public_key_data), +nano_beta_account (beta_public_key_data), +nano_live_account (live_public_key_data), +nano_test_genesis (test_genesis_data), +nano_beta_genesis (beta_genesis_data), +nano_live_genesis (live_genesis_data), +genesis_account (network_a == nano::nano_networks::nano_test_network ? nano_test_account : network_a == nano::nano_networks::nano_beta_network ? nano_beta_account : nano_live_account), +genesis_block (network_a == nano::nano_networks::nano_test_network ? nano_test_genesis : network_a == nano::nano_networks::nano_beta_network ? nano_beta_genesis : nano_live_genesis), +genesis_amount (std::numeric_limits::max ()), +burn_account (0), +not_an_account_m (0) +{ +} + +nano::account const & nano::ledger_constants::not_an_account () +{ + if (not_an_account_m.is_zero ()) + { + // Randomly generating these mean no two nodes will ever have the same sentinel values which protects against some insecure algorithms + nano::random_pool::generate_block (not_an_account_m.bytes.data (), not_an_account_m.bytes.size ()); + } + return not_an_account_m; +} + +nano::node_constants::node_constants (nano::network_params & params_a) +{ + period = params_a.is_test_network () ? std::chrono::seconds (1) : std::chrono::seconds (60); + cutoff = period * 5; + syn_cookie_cutoff = std::chrono::seconds (5); + backup_interval = std::chrono::minutes (5); + search_pending_interval = params_a.is_test_network () ? std::chrono::seconds (1) : std::chrono::seconds (5 * 60); + peer_interval = search_pending_interval; + unchecked_cleaning_interval = std::chrono::hours (2); + process_confirmed_interval = params_a.is_test_network () ? std::chrono::milliseconds (50) : std::chrono::milliseconds (500); + max_weight_samples = params_a.is_live_network () ? 4032 : 864; + weight_period = 5 * 60; // 5 minutes +} + +nano::voting_constants::voting_constants (nano::network_params & params_a) +{ + max_cache = params_a.is_test_network () ? 2 : 1000; + generator_delay = params_a.is_test_network () ? std::chrono::milliseconds (10) : std::chrono::milliseconds (500); +} + +nano::portmapping_constants::portmapping_constants (nano::network_params & params_a) +{ + mapping_timeout = params_a.is_test_network () ? 53 : 3593; + check_timeout = params_a.is_test_network () ? 17 : 53; +} + +nano::bootstrap_constants::bootstrap_constants (nano::network_params & params_a) +{ + lazy_max_pull_blocks = params_a.is_test_network () ? 2 : 512; +} + +/** Called by gtest_main to enforce test network */ +void force_nano_test_network () +{ + nano::network_params::set_active_network (nano::nano_networks::nano_test_network); +} + +/* Convenience constants for core_test which is always on the test network */ +namespace +{ +nano::ledger_constants test_constants (nano::nano_networks::nano_test_network); +} + +nano::keypair const & nano::zero_key (test_constants.zero_key); +nano::keypair const & nano::test_genesis_key (test_constants.test_genesis_key); +nano::account const & nano::nano_test_account (test_constants.nano_test_account); +std::string const & nano::nano_test_genesis (test_constants.nano_test_genesis); +nano::account const & nano::genesis_account (test_constants.genesis_account); +std::string const & nano::genesis_block (test_constants.genesis_block); +nano::uint128_t const & nano::genesis_amount (test_constants.genesis_amount); +nano::account const & nano::burn_account (test_constants.burn_account); diff --git a/nano/lib/config.hpp b/nano/lib/config.hpp index cc69edb6e..a9a2fb5ad 100644 --- a/nano/lib/config.hpp +++ b/nano/lib/config.hpp @@ -1,14 +1,21 @@ #pragma once +#include #include #include -#include +#include +#include +#include +#include namespace nano { +class ledger_constants; +class network_params; + /** * Network variants with different genesis blocks and network parameters - * @warning Enum values are used for comparison; do not change. + * @warning Enum values are used in integral comparisons; do not change. */ enum class nano_networks { @@ -22,15 +29,167 @@ enum class nano_networks nano_live_network = 2, rai_live_network = 2, }; -nano::nano_networks constexpr nano_network = nano_networks::ACTIVE_NETWORK; -bool constexpr is_live_network = nano_network == nano_networks::nano_live_network; -bool constexpr is_beta_network = nano_network == nano_networks::nano_beta_network; -bool constexpr is_test_network = nano_network == nano_networks::nano_test_network; -std::chrono::milliseconds const transaction_timeout = std::chrono::milliseconds (1000); +/** Genesis keys and ledger constants for network variants */ +class ledger_constants +{ +public: + ledger_constants (nano::network_params & params_a); + ledger_constants (nano::nano_networks network_a); + nano::keypair zero_key; + nano::keypair test_genesis_key; + nano::account nano_test_account; + nano::account nano_beta_account; + nano::account nano_live_account; + std::string nano_test_genesis; + std::string nano_beta_genesis; + std::string nano_live_genesis; + nano::account genesis_account; + std::string genesis_block; + nano::uint128_t genesis_amount; + nano::account const & not_an_account (); + nano::account burn_account; + +private: + nano::account not_an_account_m; +}; + +/** Node related constants whose value depends on the active network */ +class node_constants +{ +public: + node_constants (nano::network_params & params_a); + std::chrono::seconds period; + std::chrono::seconds cutoff; + std::chrono::seconds syn_cookie_cutoff; + std::chrono::minutes backup_interval; + std::chrono::seconds search_pending_interval; + std::chrono::seconds peer_interval; + std::chrono::hours unchecked_cleaning_interval; + std::chrono::milliseconds process_confirmed_interval; + + /** The maximum amount of samples for a 2 week period on live or 3 days on beta */ + uint64_t max_weight_samples; + uint64_t weight_period; +}; + +/** Voting related constants whose value depends on the active network */ +class voting_constants +{ +public: + voting_constants (nano::network_params & params_a); + size_t max_cache; + std::chrono::milliseconds generator_delay; +}; + +/** Port-mapping related constants whose value depends on the active network */ +class portmapping_constants +{ +public: + portmapping_constants (nano::network_params & params_a); + // Timeouts are primes so they infrequently happen at the same time + int mapping_timeout; + int check_timeout; +}; + +/** Bootstrap related constants whose value depends on the active network */ +class bootstrap_constants +{ +public: + bootstrap_constants (nano::network_params & params_a); + uint64_t lazy_max_pull_blocks; +}; + +/** Constants whose value depends on the active network */ +class network_params +{ +public: + /** Populate values based on the current active network */ + network_params (); + + /** Populate values based on \p network_a */ + network_params (nano::nano_networks network_a); + + /** The network this param object represents. This may differ from the global active network; this is needed for certain --debug... commands */ + nano::nano_networks current_network; + + std::array header_magic_number; + unsigned request_interval_ms; + uint64_t publish_threshold; + unsigned kdf_work; + uint16_t default_node_port; + uint16_t default_rpc_port; + ledger_constants ledger; + voting_constants voting; + node_constants node; + portmapping_constants portmapping; + bootstrap_constants bootstrap; + + /** Returns the network this object contains values for */ + nano::nano_networks network () + { + 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 The new active network + */ + static void set_active_network (nano::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 "test" + */ + static nano::error set_active_network (std::string network_a) + { + nano::error err; + if (network_a == "live") + { + active_network = nano::nano_networks::nano_live_network; + } + else if (network_a == "beta") + { + active_network = nano::nano_networks::nano_beta_network; + } + else if (network_a == "test") + { + active_network = nano::nano_networks::nano_test_network; + } + else + { + err = "Invalid network. Valid values are live, beta and test."; + } + return err; + } + + bool is_live_network () + { + return current_network == nano_networks::nano_live_network; + } + bool is_beta_network () + { + return current_network == nano_networks::nano_beta_network; + } + bool is_test_network () + { + return current_network == nano_networks::nano_test_network; + } + +private: + /** Initial value is ACTIVE_NETWORK compile flag, but can be overridden by a CLI flag */ + static nano::nano_networks active_network; +}; inline boost::filesystem::path get_config_path (boost::filesystem::path const & data_path) { return data_path / "config.json"; } } + +void force_nano_test_network (); diff --git a/nano/lib/errors.hpp b/nano/lib/errors.hpp index de68ea231..0b7ec716f 100644 --- a/nano/lib/errors.hpp +++ b/nano/lib/errors.hpp @@ -330,17 +330,6 @@ public: return *this; } - /** Set the error to nano::error_common::generic. */ - error & operator= (bool is_error) - { - if (is_error) - { - code = nano::error_common::generic; - } - message.clear (); - return *this; - } - /** Sets the error to nano::error_common::exception and adopts the exception error message. */ error & operator= (std::exception const & exception_a) { diff --git a/nano/lib/interface.cpp b/nano/lib/interface.cpp index 0ea23266b..cf9789eba 100644 --- a/nano/lib/interface.cpp +++ b/nano/lib/interface.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -115,6 +116,7 @@ char * xrb_sign_transaction (const char * transaction, const xrb_uint256 private char * xrb_work_transaction (const char * transaction) { + static nano::network_params network_params; char * result (nullptr); try { @@ -126,7 +128,7 @@ char * xrb_work_transaction (const char * transaction) if (block != nullptr) { nano::work_pool pool (boost::thread::hardware_concurrency ()); - auto work (pool.generate (block->root ())); + auto work (pool.generate (block->root (), network_params.publish_threshold)); block->block_work_set (work); auto json (block->to_json ()); result = reinterpret_cast (malloc (json.size () + 1)); diff --git a/nano/lib/work.cpp b/nano/lib/work.cpp index 8d062f3ae..5c74d21d7 100644 --- a/nano/lib/work.cpp +++ b/nano/lib/work.cpp @@ -7,12 +7,13 @@ bool nano::work_validate (nano::block_hash const & root_a, uint64_t work_a, uint64_t * difficulty_a) { + static nano::network_params network_params; auto value (nano::work_value (root_a, work_a)); if (difficulty_a != nullptr) { *difficulty_a = value; } - return value < nano::work_pool::publish_threshold; + return value < network_params.publish_threshold; } bool nano::work_validate (nano::block const & block_a, uint64_t * difficulty_a) @@ -39,7 +40,7 @@ opencl (opencl_a) static_assert (ATOMIC_INT_LOCK_FREE == 2, "Atomic int needed"); boost::thread::attributes attrs; nano::thread_attributes::set (attrs); - auto count (nano::is_test_network ? 1 : std::min (max_threads_a, std::max (1u, boost::thread::hardware_concurrency ()))); + auto count (network_params.is_test_network () ? 1 : std::min (max_threads_a, std::max (1u, boost::thread::hardware_concurrency ()))); for (auto i (0); i < count; ++i) { auto thread (boost::thread (attrs, [this, i]() { @@ -105,7 +106,7 @@ void nano::work_pool::loop (uint64_t thread) if (ticket == ticket_l) { // If the ticket matches what we started with, we're the ones that found the solution - assert (output >= nano::work_pool::publish_threshold); + assert (output >= network_params.publish_threshold); assert (work_value (current_l.item, work) == output); // Signal other threads to stop their work next time they check ticket ++ticket; @@ -161,6 +162,11 @@ void nano::work_pool::stop () producer_condition.notify_all (); } +void nano::work_pool::generate (nano::uint256_union const & root_a, std::function const &)> callback_a) +{ + generate (root_a, callback_a, network_params.publish_threshold); +} + void nano::work_pool::generate (nano::uint256_union const & root_a, std::function const &)> callback_a, uint64_t difficulty_a) { assert (!root_a.is_zero ()); @@ -183,6 +189,11 @@ void nano::work_pool::generate (nano::uint256_union const & root_a, std::functio } } +uint64_t nano::work_pool::generate (nano::uint256_union const & hash_a) +{ + return generate (hash_a, network_params.publish_threshold); +} + uint64_t nano::work_pool::generate (nano::uint256_union const & hash_a, uint64_t difficulty_a) { std::promise> work; diff --git a/nano/lib/work.hpp b/nano/lib/work.hpp index b8de63f77..9a8481818 100644 --- a/nano/lib/work.hpp +++ b/nano/lib/work.hpp @@ -33,8 +33,11 @@ public: void loop (uint64_t); void stop (); void cancel (nano::uint256_union const &); - void generate (nano::uint256_union const &, std::function const &)>, uint64_t = nano::work_pool::publish_threshold); - uint64_t generate (nano::uint256_union const &, uint64_t = nano::work_pool::publish_threshold); + void generate (nano::uint256_union const &, std::function const &)>); + void generate (nano::uint256_union const &, std::function const &)>, uint64_t); + uint64_t generate (nano::uint256_union const &); + uint64_t generate (nano::uint256_union const &, uint64_t); + nano::network_params network_params; std::atomic ticket; bool done; std::vector threads; @@ -43,10 +46,6 @@ public: std::condition_variable producer_condition; std::function (nano::uint256_union const &, uint64_t)> opencl; nano::observer_set work_observers; - // Local work threshold for rate-limiting publishing blocks. ~5 seconds of work. - static uint64_t const publish_test_threshold = 0xff00000000000000; - static uint64_t const publish_full_threshold = 0xffffffc000000000; - static uint64_t const publish_threshold = nano::is_test_network ? publish_test_threshold : publish_full_threshold; }; std::unique_ptr collect_seq_con_info (work_pool & work_pool, const std::string & name); diff --git a/nano/nano_node/entry.cpp b/nano/nano_node/entry.cpp index 175a1196c..f0fb53162 100644 --- a/nano/nano_node/entry.cpp +++ b/nano/nano_node/entry.cpp @@ -71,6 +71,17 @@ int main (int argc, char * const * argv) boost::program_options::notify (vm); int result (0); + auto network (vm.find ("network")); + if (network != vm.end ()) + { + auto err (nano::network_params::set_active_network (network->second.as ())); + if (err) + { + std::cerr << err.get_message () << std::endl; + std::exit (1); + } + } + auto data_path_it = vm.find ("data_path"); if (data_path_it == vm.end ()) { @@ -225,13 +236,14 @@ int main (int argc, char * const * argv) } else if (vm.count ("debug_profile_kdf")) { + nano::network_params network_params; nano::uint256_union result; nano::uint256_union salt (0); std::string password (""); while (true) { auto begin1 (std::chrono::high_resolution_clock::now ()); - auto success (argon2_hash (1, nano::wallet_store::kdf_work, 1, password.data (), password.size (), salt.bytes.data (), salt.bytes.size (), result.bytes.data (), result.bytes.size (), NULL, 0, Argon2_d, 0x10)); + auto success (argon2_hash (1, network_params.kdf_work, 1, password.data (), password.size (), salt.bytes.data (), salt.bytes.size (), result.bytes.data (), result.bytes.size (), NULL, 0, Argon2_d, 0x10)); (void)success; auto end1 (std::chrono::high_resolution_clock::now ()); std::cerr << boost::str (boost::format ("Derivation time: %1%us\n") % std::chrono::duration_cast (end1 - begin1).count ()); @@ -253,6 +265,7 @@ int main (int argc, char * const * argv) } else if (vm.count ("debug_opencl")) { + nano::network_params network_params; bool error (false); nano::opencl_environment environment (error); if (!error) @@ -299,7 +312,7 @@ int main (int argc, char * const * argv) result = -1; } } - uint64_t difficulty (nano::work_pool::publish_threshold); + uint64_t difficulty (network_params.publish_threshold); auto difficulty_it = vm.find ("difficulty"); if (difficulty_it != vm.end ()) { @@ -424,234 +437,224 @@ int main (int argc, char * const * argv) } else if (vm.count ("debug_profile_process")) { - if (nano::is_test_network) + nano::network_params::set_active_network (nano::nano_networks::nano_test_network); + nano::network_params test_params; + nano::block_builder builder; + size_t num_accounts (100000); + size_t num_interations (5); // 100,000 * 5 * 2 = 1,000,000 blocks + size_t max_blocks (2 * num_accounts * num_interations + num_accounts * 2); // 1,000,000 + 2* 100,000 = 1,200,000 blocks + std::cerr << boost::str (boost::format ("Starting pregenerating %1% blocks\n") % max_blocks); + nano::system system (24000, 1); + nano::node_init init; + nano::work_pool work (std::numeric_limits::max (), nullptr); + nano::logging logging; + auto path (nano::unique_path ()); + logging.init (path); + auto node (std::make_shared (init, system.io_ctx, 24001, path, system.alarm, logging, work)); + nano::block_hash genesis_latest (node->latest (test_params.ledger.test_genesis_key.pub)); + nano::uint128_t genesis_balance (std::numeric_limits::max ()); + // Generating keys + std::vector keys (num_accounts); + std::vector frontiers (num_accounts); + std::vector balances (num_accounts, 1000000000); + // Generating blocks + std::deque> blocks; + for (auto i (0); i != num_accounts; ++i) { - nano::block_builder builder; - size_t num_accounts (100000); - size_t num_interations (5); // 100,000 * 5 * 2 = 1,000,000 blocks - size_t max_blocks (2 * num_accounts * num_interations + num_accounts * 2); // 1,000,000 + 2* 100,000 = 1,200,000 blocks - std::cerr << boost::str (boost::format ("Starting pregenerating %1% blocks\n") % max_blocks); - nano::system system (24000, 1); - nano::node_init init; - nano::work_pool work (std::numeric_limits::max (), nullptr); - nano::logging logging; - auto path (nano::unique_path ()); - logging.init (path); - auto node (std::make_shared (init, system.io_ctx, 24001, path, system.alarm, logging, work)); - nano::block_hash genesis_latest (node->latest (nano::test_genesis_key.pub)); - nano::uint128_t genesis_balance (std::numeric_limits::max ()); - // Generating keys - std::vector keys (num_accounts); - std::vector frontiers (num_accounts); - std::vector balances (num_accounts, 1000000000); - // Generating blocks - std::deque> blocks; - for (auto i (0); i != num_accounts; ++i) + genesis_balance = genesis_balance - 1000000000; + + auto send = builder.state () + .account (test_params.ledger.test_genesis_key.pub) + .previous (genesis_latest) + .representative (test_params.ledger.test_genesis_key.pub) + .balance (genesis_balance) + .link (keys[i].pub) + .sign (keys[i].prv, keys[i].pub) + .work (work.generate (genesis_latest)) + .build (); + + genesis_latest = send->hash (); + blocks.push_back (std::move (send)); + + auto open = builder.state () + .account (keys[i].pub) + .previous (0) + .representative (keys[i].pub) + .balance (balances[i]) + .link (genesis_latest) + .sign (test_params.ledger.test_genesis_key.prv, test_params.ledger.test_genesis_key.pub) + .work (work.generate (keys[i].pub)) + .build (); + + frontiers[i] = open->hash (); + blocks.push_back (std::move (open)); + } + for (auto i (0); i != num_interations; ++i) + { + for (auto j (0); j != num_accounts; ++j) { - genesis_balance = genesis_balance - 1000000000; + size_t other (num_accounts - j - 1); + // Sending to other account + --balances[j]; auto send = builder.state () - .account (nano::test_genesis_key.pub) - .previous (genesis_latest) - .representative (nano::test_genesis_key.pub) - .balance (genesis_balance) - .link (keys[i].pub) - .sign (keys[i].prv, keys[i].pub) - .work (work.generate (genesis_latest)) + .account (keys[j].pub) + .previous (frontiers[j]) + .representative (keys[j].pub) + .balance (balances[j]) + .link (keys[other].pub) + .sign (keys[j].prv, keys[j].pub) + .work (work.generate (frontiers[j])) .build (); - genesis_latest = send->hash (); + frontiers[j] = send->hash (); blocks.push_back (std::move (send)); + // Receiving + ++balances[other]; - auto open = builder.state () - .account (keys[i].pub) - .previous (0) - .representative (keys[i].pub) - .balance (balances[i]) - .link (genesis_latest) - .sign (nano::test_genesis_key.prv, nano::test_genesis_key.pub) - .work (work.generate (keys[i].pub)) - .build (); + auto receive = builder.state () + .account (keys[other].pub) + .previous (frontiers[other]) + .representative (keys[other].pub) + .balance (balances[other]) + .link (frontiers[j]) + .sign (keys[other].prv, keys[other].pub) + .work (work.generate (frontiers[other])) + .build (); - frontiers[i] = open->hash (); - blocks.push_back (std::move (open)); + frontiers[other] = receive->hash (); + blocks.push_back (std::move (receive)); } - for (auto i (0); i != num_interations; ++i) - { - for (auto j (0); j != num_accounts; ++j) - { - size_t other (num_accounts - j - 1); - // Sending to other account - --balances[j]; - - auto send = builder.state () - .account (keys[j].pub) - .previous (frontiers[j]) - .representative (keys[j].pub) - .balance (balances[j]) - .link (keys[other].pub) - .sign (keys[j].prv, keys[j].pub) - .work (work.generate (frontiers[j])) - .build (); - - frontiers[j] = send->hash (); - blocks.push_back (std::move (send)); - // Receiving - ++balances[other]; - - auto receive = builder.state () - .account (keys[other].pub) - .previous (frontiers[other]) - .representative (keys[other].pub) - .balance (balances[other]) - .link (frontiers[j]) - .sign (keys[other].prv, keys[other].pub) - .work (work.generate (frontiers[other])) - .build (); - - frontiers[other] = receive->hash (); - blocks.push_back (std::move (receive)); - } - } - // Processing blocks - std::cerr << boost::str (boost::format ("Starting processing %1% active blocks\n") % max_blocks); - auto begin (std::chrono::high_resolution_clock::now ()); - while (!blocks.empty ()) - { - auto block (blocks.front ()); - node->process_active (block); - blocks.pop_front (); - } - uint64_t block_count (0); - while (block_count < max_blocks + 1) - { - std::this_thread::sleep_for (std::chrono::milliseconds (100)); - auto transaction (node->store.tx_begin ()); - block_count = node->store.block_count (transaction).sum (); - } - auto end (std::chrono::high_resolution_clock::now ()); - auto time (std::chrono::duration_cast (end - begin).count ()); - node->stop (); - std::cerr << boost::str (boost::format ("%|1$ 12d| us \n%2% blocks per second\n") % time % (max_blocks * 1000000 / time)); } - else + // Processing blocks + std::cerr << boost::str (boost::format ("Starting processing %1% active blocks\n") % max_blocks); + auto begin (std::chrono::high_resolution_clock::now ()); + while (!blocks.empty ()) { - std::cerr << "For this test ACTIVE_NETWORK should be nano_test_network" << std::endl; + auto block (blocks.front ()); + node->process_active (block); + blocks.pop_front (); } + uint64_t block_count (0); + while (block_count < max_blocks + 1) + { + std::this_thread::sleep_for (std::chrono::milliseconds (100)); + auto transaction (node->store.tx_begin ()); + block_count = node->store.block_count (transaction).sum (); + } + auto end (std::chrono::high_resolution_clock::now ()); + auto time (std::chrono::duration_cast (end - begin).count ()); + node->stop (); + std::cerr << boost::str (boost::format ("%|1$ 12d| us \n%2% blocks per second\n") % time % (max_blocks * 1000000 / time)); } else if (vm.count ("debug_profile_votes")) { - if (nano::is_test_network) + nano::network_params::set_active_network (nano::nano_networks::nano_test_network); + nano::network_params test_params; + nano::block_builder builder; + size_t num_elections (40000); + size_t num_representatives (25); + size_t max_votes (num_elections * num_representatives); // 40,000 * 25 = 1,000,000 votes + std::cerr << boost::str (boost::format ("Starting pregenerating %1% votes\n") % max_votes); + nano::system system (24000, 1); + nano::node_init init; + nano::work_pool work (std::numeric_limits::max (), nullptr); + nano::logging logging; + auto path (nano::unique_path ()); + logging.init (path); + auto node (std::make_shared (init, system.io_ctx, 24001, path, system.alarm, logging, work)); + nano::block_hash genesis_latest (node->latest (test_params.ledger.test_genesis_key.pub)); + nano::uint128_t genesis_balance (std::numeric_limits::max ()); + // Generating keys + std::vector keys (num_representatives); + nano::uint128_t balance ((node->config.online_weight_minimum.number () / num_representatives) + 1); + for (auto i (0); i != num_representatives; ++i) { - nano::block_builder builder; - size_t num_elections (40000); - size_t num_representatives (25); - size_t max_votes (num_elections * num_representatives); // 40,000 * 25 = 1,000,000 votes - std::cerr << boost::str (boost::format ("Starting pregenerating %1% votes\n") % max_votes); - nano::system system (24000, 1); - nano::node_init init; - nano::work_pool work (std::numeric_limits::max (), nullptr); - nano::logging logging; - auto path (nano::unique_path ()); - logging.init (path); - auto node (std::make_shared (init, system.io_ctx, 24001, path, system.alarm, logging, work)); - nano::block_hash genesis_latest (node->latest (nano::test_genesis_key.pub)); - nano::uint128_t genesis_balance (std::numeric_limits::max ()); - // Generating keys - std::vector keys (num_representatives); - nano::uint128_t balance ((node->config.online_weight_minimum.number () / num_representatives) + 1); - for (auto i (0); i != num_representatives; ++i) - { - auto transaction (node->store.tx_begin_write ()); - genesis_balance = genesis_balance - balance; + auto transaction (node->store.tx_begin_write ()); + genesis_balance = genesis_balance - balance; - auto send = builder.state () - .account (nano::test_genesis_key.pub) - .previous (genesis_latest) - .representative (nano::test_genesis_key.pub) - .balance (genesis_balance) - .link (keys[i].pub) - .sign (nano::test_genesis_key.prv, nano::test_genesis_key.pub) - .work (work.generate (genesis_latest)) - .build (); + auto send = builder.state () + .account (test_params.ledger.test_genesis_key.pub) + .previous (genesis_latest) + .representative (test_params.ledger.test_genesis_key.pub) + .balance (genesis_balance) + .link (keys[i].pub) + .sign (test_params.ledger.test_genesis_key.prv, test_params.ledger.test_genesis_key.pub) + .work (work.generate (genesis_latest)) + .build (); - genesis_latest = send->hash (); - node->ledger.process (transaction, *send); + genesis_latest = send->hash (); + node->ledger.process (transaction, *send); - auto open = builder.state () - .account (keys[i].pub) - .previous (0) - .representative (keys[i].pub) - .balance (balance) - .link (genesis_latest) - .sign (keys[i].prv, keys[i].pub) - .work (work.generate (keys[i].pub)) - .build (); + auto open = builder.state () + .account (keys[i].pub) + .previous (0) + .representative (keys[i].pub) + .balance (balance) + .link (genesis_latest) + .sign (keys[i].prv, keys[i].pub) + .work (work.generate (keys[i].pub)) + .build (); - node->ledger.process (transaction, *open); - } - // Generating blocks - std::deque> blocks; - for (auto i (0); i != num_elections; ++i) - { - genesis_balance = genesis_balance - 1; - nano::keypair destination; - - auto send = builder.state () - .account (nano::test_genesis_key.pub) - .previous (genesis_latest) - .representative (nano::test_genesis_key.pub) - .balance (genesis_balance) - .link (destination.pub) - .sign (nano::test_genesis_key.prv, nano::test_genesis_key.pub) - .work (work.generate (genesis_latest)) - .build (); - - genesis_latest = send->hash (); - blocks.push_back (std::move (send)); - } - // Generating votes - std::deque> votes; - for (auto j (0); j != num_representatives; ++j) - { - uint64_t sequence (1); - for (auto & i : blocks) - { - auto vote (std::make_shared (keys[j].pub, keys[j].prv, sequence, std::vector (1, i->hash ()))); - votes.push_back (vote); - sequence++; - } - } - // Processing block & start elections - while (!blocks.empty ()) - { - auto block (blocks.front ()); - node->process_active (block); - blocks.pop_front (); - } - node->block_processor.flush (); - // Processing votes - std::cerr << boost::str (boost::format ("Starting processing %1% votes\n") % max_votes); - auto begin (std::chrono::high_resolution_clock::now ()); - while (!votes.empty ()) - { - auto vote (votes.front ()); - node->vote_processor.vote (vote, node->network.endpoint ()); - votes.pop_front (); - } - while (!node->active.empty ()) - { - std::this_thread::sleep_for (std::chrono::milliseconds (100)); - } - auto end (std::chrono::high_resolution_clock::now ()); - auto time (std::chrono::duration_cast (end - begin).count ()); - node->stop (); - std::cerr << boost::str (boost::format ("%|1$ 12d| us \n%2% votes per second\n") % time % (max_votes * 1000000 / time)); + node->ledger.process (transaction, *open); } - else + // Generating blocks + std::deque> blocks; + for (auto i (0); i != num_elections; ++i) { - std::cerr << "For this test ACTIVE_NETWORK should be nano_test_network" << std::endl; + genesis_balance = genesis_balance - 1; + nano::keypair destination; + + auto send = builder.state () + .account (test_params.ledger.test_genesis_key.pub) + .previous (genesis_latest) + .representative (test_params.ledger.test_genesis_key.pub) + .balance (genesis_balance) + .link (destination.pub) + .sign (test_params.ledger.test_genesis_key.prv, test_params.ledger.test_genesis_key.pub) + .work (work.generate (genesis_latest)) + .build (); + + genesis_latest = send->hash (); + blocks.push_back (std::move (send)); } + // Generating votes + std::deque> votes; + for (auto j (0); j != num_representatives; ++j) + { + uint64_t sequence (1); + for (auto & i : blocks) + { + auto vote (std::make_shared (keys[j].pub, keys[j].prv, sequence, std::vector (1, i->hash ()))); + votes.push_back (vote); + sequence++; + } + } + // Processing block & start elections + while (!blocks.empty ()) + { + auto block (blocks.front ()); + node->process_active (block); + blocks.pop_front (); + } + node->block_processor.flush (); + // Processing votes + std::cerr << boost::str (boost::format ("Starting processing %1% votes\n") % max_votes); + auto begin (std::chrono::high_resolution_clock::now ()); + while (!votes.empty ()) + { + auto vote (votes.front ()); + node->vote_processor.vote (vote, node->network.endpoint ()); + votes.pop_front (); + } + while (!node->active.empty ()) + { + std::this_thread::sleep_for (std::chrono::milliseconds (100)); + } + auto end (std::chrono::high_resolution_clock::now ()); + auto time (std::chrono::duration_cast (end - begin).count ()); + node->stop (); + std::cerr << boost::str (boost::format ("%|1$ 12d| us \n%2% votes per second\n") % time % (max_votes * 1000000 / time)); } else if (vm.count ("debug_random_feed")) { diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index 65d3b7933..aa6b98283 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -328,6 +328,17 @@ int main (int argc, char * const * argv) boost::program_options::notify (vm); int result (0); + auto network (vm.find ("network")); + if (network != vm.end ()) + { + auto err (nano::network_params::set_active_network (network->second.as ())); + if (err) + { + std::cerr << err.get_message () << std::endl; + std::exit (1); + } + } + if (!vm.count ("data_path")) { std::string error_string; diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 2efa0efed..cbdf1d677 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -7,7 +7,7 @@ std::chrono::milliseconds constexpr nano::block_processor::confirmation_request_delay; nano::block_processor::block_processor (nano::node & node_a) : -generator (node_a, nano::is_test_network ? std::chrono::milliseconds (10) : std::chrono::milliseconds (500)), +generator (node_a), stopped (false), active (false), next_log (std::chrono::steady_clock::now ()), diff --git a/nano/node/bootstrap.cpp b/nano/node/bootstrap.cpp index 6c0f22fb5..9fc9d4ced 100644 --- a/nano/node/bootstrap.cpp +++ b/nano/node/bootstrap.cpp @@ -1391,7 +1391,7 @@ void nano::bootstrap_attempt::lazy_pull_flush () // Recheck if block was already processed if (lazy_blocks.find (pull_start) == lazy_blocks.end () && !node->store.block_exists (transaction, pull_start)) { - pulls.push_back (nano::pull_info (pull_start, pull_start, nano::block_hash (0), lazy_max_pull_blocks)); + pulls.push_back (nano::pull_info (pull_start, pull_start, nano::block_hash (0), node->network_params.bootstrap.lazy_max_pull_blocks)); } } lazy_pulls.clear (); @@ -1602,7 +1602,7 @@ bool nano::bootstrap_attempt::process_block (std::shared_ptr block_ // Disabled until server rewrite // stop_pull = true; // Force drop lazy bootstrap connection for long bulk_pull - if (total_blocks > lazy_max_pull_blocks) + if (total_blocks > node->network_params.bootstrap.lazy_max_pull_blocks) { stop_pull = true; } @@ -1644,7 +1644,7 @@ bool nano::bootstrap_attempt::process_block (std::shared_ptr block_ // Disabled until server rewrite // stop_pull = true; // Force drop lazy bootstrap connection for long bulk_pull - if (total_blocks > lazy_max_pull_blocks) + if (total_blocks > node->network_params.bootstrap.lazy_max_pull_blocks) { stop_pull = true; } diff --git a/nano/node/bootstrap.hpp b/nano/node/bootstrap.hpp index 53aa7c88f..5a3fe2dcf 100644 --- a/nano/node/bootstrap.hpp +++ b/nano/node/bootstrap.hpp @@ -43,12 +43,6 @@ private: std::shared_ptr node; }; -/** - * The length of every message header, parsed by nano::message::read_header () - * The 2 here represents the size of a std::bitset<16>, which is 2 chars long normally - */ -static const int bootstrap_message_header_size = sizeof (nano::message_header::magic_number) + sizeof (uint8_t) + sizeof (uint8_t) + sizeof (uint8_t) + sizeof (nano::message_type) + 2; - class bootstrap_client; class pull_info { @@ -129,7 +123,6 @@ public: std::unordered_set lazy_keys; std::deque lazy_pulls; std::atomic lazy_stopped; - uint64_t lazy_max_pull_blocks = nano::is_test_network ? 2 : 512; uint64_t lazy_max_stopped = 256; std::mutex lazy_mutex; // Wallet lazy bootstrap diff --git a/nano/node/cli.cpp b/nano/node/cli.cpp index 677150e71..46b1a72a4 100644 --- a/nano/node/cli.cpp +++ b/nano/node/cli.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -31,6 +32,7 @@ void nano::add_node_options (boost::program_options::options_description & descr ("vacuum", "Compact database. If data_path is missing, the database in data directory is compacted.") ("snapshot", "Compact database and create snapshot, functions similar to vacuum but does not replace the existing database") ("data_path", boost::program_options::value (), "Use the supplied path as the data directory") + ("network", boost::program_options::value (), "Use the supplied network (live, beta or test)") ("clear_send_ids", "Remove all send IDs from the database (dangerous: not intended for production use)") ("delete_node_id", "Delete the node ID in the database") ("online_weight_clear", "Clear online weight history records") @@ -64,8 +66,8 @@ void nano::add_node_options (boost::program_options::options_description & descr std::error_code nano::handle_node_options (boost::program_options::variables_map & vm) { std::error_code ec; - boost::filesystem::path data_path = vm.count ("data_path") ? boost::filesystem::path (vm["data_path"].as ()) : nano::working_path (); + if (vm.count ("account_create")) { if (vm.count ("wallet") == 1) diff --git a/nano/node/common.cpp b/nano/node/common.cpp index 78397ccab..7356d9995 100644 --- a/nano/node/common.cpp +++ b/nano/node/common.cpp @@ -6,7 +6,6 @@ #include -std::array constexpr nano::message_header::magic_number; std::bitset<16> constexpr nano::message_header::block_type_mask; nano::message_header::message_header (nano::message_type type_a) : @@ -27,7 +26,8 @@ nano::message_header::message_header (bool & error_a, nano::stream & stream_a) void nano::message_header::serialize (nano::stream & stream_a) const { - nano::write (stream_a, nano::message_header::magic_number); + static nano::network_params network_params; + nano::write (stream_a, network_params.header_magic_number); nano::write (stream_a, version_max); nano::write (stream_a, version_using); nano::write (stream_a, version_min); @@ -37,13 +37,14 @@ void nano::message_header::serialize (nano::stream & stream_a) const bool nano::message_header::deserialize (nano::stream & stream_a) { + static nano::network_params network_params; uint16_t extensions_l; std::array magic_number_l; auto error (false); try { read (stream_a, magic_number_l); - if (magic_number_l != magic_number) + if (magic_number_l != network_params.header_magic_number) { throw std::runtime_error ("Magic numbers do not match"); } @@ -206,6 +207,7 @@ status (parse_status::success) void nano::message_parser::deserialize_buffer (uint8_t const * buffer_a, size_t size_a) { + static nano::network_params network_params; status = parse_status::success; auto error (false); if (size_a <= max_safe_udp_message_size) @@ -215,7 +217,7 @@ void nano::message_parser::deserialize_buffer (uint8_t const * buffer_a, size_t nano::message_header header (error, stream); if (!error) { - if (nano::is_beta_network && header.version_using < nano::protocol_version_reasonable_min) + if (network_params.is_beta_network () && header.version_using < nano::protocol_version_reasonable_min) { status = parse_status::outdated_version; } @@ -223,14 +225,6 @@ void nano::message_parser::deserialize_buffer (uint8_t const * buffer_a, size_t { status = parse_status::outdated_version; } - else if (!header.valid_magic ()) - { - status = parse_status::invalid_magic; - } - else if (!header.valid_network ()) - { - status = parse_status::invalid_network; - } else { switch (header.type) diff --git a/nano/node/common.hpp b/nano/node/common.hpp index d2837a1f0..54c7e0bb8 100644 --- a/nano/node/common.hpp +++ b/nano/node/common.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -195,7 +196,6 @@ public: bool deserialize (nano::stream &); nano::block_type block_type () const; void block_type_set (nano::block_type); - static std::array constexpr magic_number = nano::is_test_network ? std::array{ { 'R', 'A' } } : nano::is_beta_network ? std::array{ { 'R', 'B' } } : std::array{ { 'R', 'C' } }; uint8_t version_max; uint8_t version_using; uint8_t version_min; @@ -209,14 +209,6 @@ public: size_t payload_length_bytes () const; static std::bitset<16> constexpr block_type_mask = std::bitset<16> (0x0f00); - bool valid_magic () const - { - return magic_number[0] == 'R' && magic_number[1] >= 'A' && magic_number[1] <= 'C'; - } - bool valid_network () const - { - return (magic_number[1] - 'A') == static_cast (nano::nano_network); - } }; class message { diff --git a/nano/node/lmdb.cpp b/nano/node/lmdb.cpp index c549dae68..d550a486d 100644 --- a/nano/node/lmdb.cpp +++ b/nano/node/lmdb.cpp @@ -835,11 +835,11 @@ void nano::mdb_store::initialize (nano::transaction const & transaction_a, nano: auto hash_l (genesis_a.hash ()); assert (latest_v0_begin (transaction_a) == latest_v0_end ()); assert (latest_v1_begin (transaction_a) == latest_v1_end ()); - nano::block_sideband sideband (nano::block_type::open, nano::genesis_account, 0, nano::genesis_amount, 1, nano::seconds_since_epoch ()); + nano::block_sideband sideband (nano::block_type::open, network_params.ledger.genesis_account, 0, network_params.ledger.genesis_amount, 1, nano::seconds_since_epoch ()); block_put (transaction_a, hash_l, *genesis_a.open, sideband); - account_put (transaction_a, genesis_account, { hash_l, genesis_a.open->hash (), genesis_a.open->hash (), std::numeric_limits::max (), nano::seconds_since_epoch (), 1, 0, nano::epoch::epoch_0 }); - representation_put (transaction_a, genesis_account, std::numeric_limits::max ()); - frontier_put (transaction_a, hash_l, genesis_account); + account_put (transaction_a, network_params.ledger.genesis_account, { hash_l, genesis_a.open->hash (), genesis_a.open->hash (), std::numeric_limits::max (), nano::seconds_since_epoch (), 1, 0, nano::epoch::epoch_0 }); + representation_put (transaction_a, network_params.ledger.genesis_account, std::numeric_limits::max ()); + frontier_put (transaction_a, hash_l, network_params.ledger.genesis_account); } void nano::mdb_store::version_put (nano::transaction const & transaction_a, int version_a) @@ -1187,7 +1187,7 @@ void nano::mdb_store::upgrade_v12_to_v13 (nano::transaction const & transaction_ { size_t cost (0); nano::account account (0); - auto const & not_an_account (nano::not_an_account ()); + auto const & not_an_account (network_params.ledger.not_an_account ()); while (account != not_an_account) { nano::account first (0); diff --git a/nano/node/lmdb.hpp b/nano/node/lmdb.hpp index 7ef49c945..33506923f 100644 --- a/nano/node/lmdb.hpp +++ b/nano/node/lmdb.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -388,6 +389,7 @@ public: MDB_dbi peers{ 0 }; private: + nano::network_params network_params; bool entry_has_sideband (MDB_val, nano::block_type) const; nano::account block_account_computed (nano::transaction const &, nano::block_hash const &) const; nano::uint128_t block_balance_computed (nano::transaction const &, nano::block_hash const &) const; diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 4dfe0bd31..807630b4b 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -16,28 +16,16 @@ double constexpr nano::node::price_max; double constexpr nano::node::free_cutoff; -std::chrono::seconds constexpr nano::node::period; -std::chrono::seconds constexpr nano::node::cutoff; -std::chrono::seconds constexpr nano::node::syn_cookie_cutoff; -std::chrono::minutes constexpr nano::node::backup_interval; -std::chrono::seconds constexpr nano::node::search_pending_interval; -std::chrono::seconds constexpr nano::node::peer_interval; -std::chrono::hours constexpr nano::node::unchecked_cleanup_interval; -std::chrono::milliseconds constexpr nano::node::process_confirmed_interval; - -int constexpr nano::port_mapping::mapping_timeout; -int constexpr nano::port_mapping::check_timeout; -unsigned constexpr nano::active_transactions::request_interval_ms; size_t constexpr nano::active_transactions::max_broadcast_queue; size_t constexpr nano::block_arrival::arrival_size_min; std::chrono::seconds constexpr nano::block_arrival::arrival_time_min; -uint64_t constexpr nano::online_reps::weight_period; -uint64_t constexpr nano::online_reps::weight_samples; namespace nano { -extern unsigned char nano_bootstrap_weights[]; -extern size_t nano_bootstrap_weights_size; +extern unsigned char nano_bootstrap_weights_live[]; +extern size_t nano_bootstrap_weights_live_size; +extern unsigned char nano_bootstrap_weights_beta[]; +extern size_t nano_bootstrap_weights_beta_size; } nano::network::network (nano::node & node_a, uint16_t port) : @@ -1073,7 +1061,7 @@ void nano::vote_processor::vote (std::shared_ptr vote_a, nano::endpo /* Random early delection levels Always process votes for test network (process = true) Stop processing with max 144 * 1024 votes */ - if (!nano::is_test_network) + if (!node.network_params.is_test_network ()) { // Level 0 (< 0.1%) if (votes.size () < 96 * 1024) @@ -1375,7 +1363,7 @@ block_processor_thread ([this]() { nano::thread_role::set (nano::thread_role::name::block_processing); this->block_processor.process_blocks (); }), -online_reps (ledger, config.online_weight_minimum.number ()), +online_reps (*this, config.online_weight_minimum.number ()), stats (config.stat_config), vote_uniquer (block_uniquer), startup_time (std::chrono::steady_clock::now ()) @@ -1525,9 +1513,12 @@ startup_time (std::chrono::steady_clock::now ()) node_id = nano::keypair (store.get_node_id (transaction)); logger.always_log ("Node ID: ", node_id.pub.to_account ()); } - if (nano::is_live_network || nano::is_beta_network) + + const uint8_t * weight_buffer = network_params.is_live_network () ? nano_bootstrap_weights_live : nano_bootstrap_weights_beta; + size_t weight_size = network_params.is_live_network () ? nano_bootstrap_weights_live_size : nano_bootstrap_weights_beta_size; + if (network_params.is_live_network () || network_params.is_beta_network ()) { - nano::bufferstream weight_stream ((const uint8_t *)nano_bootstrap_weights, nano_bootstrap_weights_size); + nano::bufferstream weight_stream ((const uint8_t *)weight_buffer, weight_size); nano::uint128_union block_height; if (!nano::try_read (weight_stream, block_height)) { @@ -1769,7 +1760,7 @@ void nano::gap_cache::vote (std::shared_ptr vote_a) { auto node_l (node.shared ()); auto now (std::chrono::steady_clock::now ()); - node.alarm.add (nano::is_test_network ? now + std::chrono::milliseconds (5) : now + std::chrono::seconds (5), [node_l, hash]() { + node.alarm.add (node_l->network_params.is_test_network () ? now + std::chrono::milliseconds (5) : now + std::chrono::seconds (5), [node_l, hash]() { auto transaction (node_l->store.tx_begin_read ()); if (!node_l->store.block_exists (transaction, hash)) { @@ -1913,7 +1904,7 @@ void nano::node::keepalive_preconfigured (std::vector const & peers { for (auto i (peers_a.begin ()), n (peers_a.end ()); i != n; ++i) { - keepalive (*i, nano::network::node_port, true); + keepalive (*i, network_params.default_node_port, true); } } @@ -1965,13 +1956,13 @@ nano::account nano::node::representative (nano::account const & account_a) void nano::node::ongoing_keepalive () { keepalive_preconfigured (config.preconfigured_peers); - auto peers_l (peers.purge_list (std::chrono::steady_clock::now () - cutoff)); - for (auto i (peers_l.begin ()), j (peers_l.end ()); i != j && std::chrono::steady_clock::now () - i->last_attempt > period; ++i) + auto peers_l (peers.purge_list (std::chrono::steady_clock::now () - network_params.node.cutoff)); + for (auto i (peers_l.begin ()), j (peers_l.end ()); i != j && std::chrono::steady_clock::now () - i->last_attempt > network_params.node.period; ++i) { network.send_keepalive (i->endpoint); } std::weak_ptr node_w (shared_from_this ()); - alarm.add (std::chrono::steady_clock::now () + period, [node_w]() { + alarm.add (std::chrono::steady_clock::now () + network_params.node.period, [node_w]() { if (auto node_l = node_w.lock ()) { node_l->ongoing_keepalive (); @@ -1981,9 +1972,9 @@ void nano::node::ongoing_keepalive () void nano::node::ongoing_syn_cookie_cleanup () { - peers.purge_syn_cookies (std::chrono::steady_clock::now () - syn_cookie_cutoff); + peers.purge_syn_cookies (std::chrono::steady_clock::now () - network_params.node.syn_cookie_cutoff); std::weak_ptr node_w (shared_from_this ()); - alarm.add (std::chrono::steady_clock::now () + (syn_cookie_cutoff * 2), [node_w]() { + alarm.add (std::chrono::steady_clock::now () + (network_params.node.syn_cookie_cutoff * 2), [node_w]() { if (auto node_l = node_w.lock ()) { node_l->ongoing_syn_cookie_cleanup (); @@ -2057,7 +2048,7 @@ void nano::node::ongoing_peer_store () } std::weak_ptr node_w (shared_from_this ()); - alarm.add (std::chrono::steady_clock::now () + peer_interval, [node_w]() { + alarm.add (std::chrono::steady_clock::now () + network_params.node.peer_interval, [node_w]() { if (auto node_l = node_w.lock ()) { node_l->ongoing_peer_store (); @@ -2078,7 +2069,7 @@ void nano::node::backup_wallet () i->second->store.write_backup (transaction, backup_path / (i->first.to_string () + ".json")); } auto this_l (shared ()); - alarm.add (std::chrono::steady_clock::now () + backup_interval, [this_l]() { + alarm.add (std::chrono::steady_clock::now () + network_params.node.backup_interval, [this_l]() { this_l->backup_wallet (); }); } @@ -2090,7 +2081,7 @@ void nano::node::search_pending () // Search pending wallets.search_pending_all (); auto this_l (shared ()); - alarm.add (std::chrono::steady_clock::now () + search_pending_interval, [this_l]() { + alarm.add (std::chrono::steady_clock::now () + network_params.node.search_pending_interval, [this_l]() { this_l->search_pending (); }); } @@ -2154,7 +2145,7 @@ void nano::node::ongoing_unchecked_cleanup () unchecked_cleanup (); } auto this_l (shared ()); - alarm.add (std::chrono::steady_clock::now () + unchecked_cleanup_interval, [this_l]() { + alarm.add (std::chrono::steady_clock::now () + network_params.node.unchecked_cleaning_interval, [this_l]() { this_l->ongoing_unchecked_cleanup (); }); } @@ -2460,17 +2451,32 @@ public: }; } +void nano::node::work_generate_blocking (nano::block & block_a) +{ + work_generate_blocking (block_a, network_params.publish_threshold); +} + void nano::node::work_generate_blocking (nano::block & block_a, uint64_t difficulty_a) { block_a.block_work_set (work_generate_blocking (block_a.root (), difficulty_a)); } +void nano::node::work_generate (nano::uint256_union const & hash_a, std::function callback_a) +{ + work_generate (hash_a, callback_a, network_params.publish_threshold); +} + void nano::node::work_generate (nano::uint256_union const & hash_a, std::function callback_a, uint64_t difficulty_a) { auto work_generation (std::make_shared (shared (), hash_a, callback_a, difficulty_a)); work_generation->start (); } +uint64_t nano::node::work_generate_blocking (nano::uint256_union const & block_a) +{ + return work_generate_blocking (block_a, network_params.publish_threshold); +} + uint64_t nano::node::work_generate_blocking (nano::uint256_union const & hash_a, uint64_t difficulty_a) { std::promise promise; @@ -2518,7 +2524,7 @@ nano::uint128_t nano::node::delta () void nano::node::ongoing_online_weight_calculation_queue () { std::weak_ptr node_w (shared_from_this ()); - alarm.add (std::chrono::steady_clock::now () + (std::chrono::seconds (nano::online_reps::weight_period)), [node_w]() { + alarm.add (std::chrono::steady_clock::now () + (std::chrono::seconds (network_params.node.weight_period)), [node_w]() { if (auto node_l = node_w.lock ()) { node_l->ongoing_online_weight_calculation (); @@ -2645,7 +2651,7 @@ void nano::node::process_confirmed (std::shared_ptr block_a, uint8_ { iteration++; std::weak_ptr node_w (shared ()); - alarm.add (std::chrono::steady_clock::now () + process_confirmed_interval, [node_w, block_a, iteration]() { + alarm.add (std::chrono::steady_clock::now () + network_params.node.process_confirmed_interval, [node_w, block_a, iteration]() { if (auto node_l = node_w.lock ()) { node_l->process_confirmed (block_a, iteration); @@ -2709,18 +2715,18 @@ std::unique_ptr collect_seq_con_info (block_arrival & bl } } -nano::online_reps::online_reps (nano::ledger & ledger_a, nano::uint128_t minimum_a) : -ledger (ledger_a), +nano::online_reps::online_reps (nano::node & node_a, nano::uint128_t minimum_a) : +node (node_a), minimum (minimum_a) { - auto transaction (ledger_a.store.tx_begin_read ()); + auto transaction (node.ledger.store.tx_begin_read ()); online = trend (transaction); } void nano::online_reps::observe (nano::account const & rep_a) { - auto transaction (ledger.store.tx_begin_read ()); - if (ledger.weight (transaction, rep_a) > 0) + auto transaction (node.ledger.store.tx_begin_read ()); + if (node.ledger.weight (transaction, rep_a) > 0) { std::lock_guard lock (mutex); reps.insert (rep_a); @@ -2729,13 +2735,13 @@ void nano::online_reps::observe (nano::account const & rep_a) void nano::online_reps::sample () { - auto transaction (ledger.store.tx_begin_write ()); + auto transaction (node.ledger.store.tx_begin_write ()); // Discard oldest entries - while (ledger.store.online_weight_count (transaction) >= weight_samples) + while (node.ledger.store.online_weight_count (transaction) >= node.network_params.node.max_weight_samples) { - auto oldest (ledger.store.online_weight_begin (transaction)); - assert (oldest != ledger.store.online_weight_end ()); - ledger.store.online_weight_del (transaction, oldest->first); + auto oldest (node.ledger.store.online_weight_begin (transaction)); + assert (oldest != node.ledger.store.online_weight_end ()); + node.ledger.store.online_weight_del (transaction, oldest->first); } // Calculate current active rep weight nano::uint128_t current; @@ -2746,9 +2752,9 @@ void nano::online_reps::sample () } for (auto & i : reps_copy) { - current += ledger.weight (transaction, i); + current += node.ledger.weight (transaction, i); } - ledger.store.online_weight_put (transaction, std::chrono::system_clock::now ().time_since_epoch ().count (), current); + node.ledger.store.online_weight_put (transaction, std::chrono::system_clock::now ().time_since_epoch ().count (), current); auto trend_l (trend (transaction)); std::lock_guard lock (mutex); online = trend_l; @@ -2757,9 +2763,9 @@ void nano::online_reps::sample () nano::uint128_t nano::online_reps::trend (nano::transaction & transaction_a) { std::vector items; - items.reserve (weight_samples + 1); + items.reserve (node.network_params.node.max_weight_samples + 1); items.push_back (minimum); - for (auto i (ledger.store.online_weight_begin (transaction_a)), n (ledger.store.online_weight_end ()); i != n; ++i) + for (auto i (node.ledger.store.online_weight_begin (transaction_a)), n (node.ledger.store.online_weight_end ()); i != n; ++i) { items.push_back (i->second.number ()); } @@ -2814,6 +2820,7 @@ boost::asio::ip::address_v6 mapped_from_v4_bytes (unsigned long address_a) bool nano::reserved_address (nano::endpoint const & endpoint_a, bool allow_local_peers) { + static nano::network_params network_params; assert (endpoint_a.address ().is_v6 ()); auto bytes (endpoint_a.address ().to_v6 ()); auto result (false); @@ -2955,7 +2962,7 @@ confirmed (false), stopped (false), announcements (0) { - last_votes.insert (std::make_pair (nano::not_an_account (), nano::vote_info{ std::chrono::steady_clock::now (), 0, block_a->hash () })); + last_votes.insert (std::make_pair (node.network_params.ledger.not_an_account (), nano::vote_info{ std::chrono::steady_clock::now (), 0, block_a->hash () })); blocks.insert (std::make_pair (block_a->hash (), block_a)); } @@ -3077,7 +3084,7 @@ nano::election_vote_result nano::election::vote (nano::account rep, uint64_t seq auto supply (node.online_reps.online_stake ()); auto weight (node.ledger.weight (transaction, rep)); auto should_process (false); - if (nano::is_test_network || weight > supply / 1000) // 0.1% or above + if (node.network_params.is_test_network () || weight > supply / 1000) // 0.1% or above { unsigned int cooldown; if (weight < supply / 100) // 0.1% to 1% @@ -3248,7 +3255,7 @@ void nano::active_transactions::request_confirm (std::unique_lock & /* Escalation for long unconfirmed elections Start new elections for previous block & source if there are less than 100 active elections */ - if (election_l->announcements % announcement_long == 1 && roots_size < 100 && !nano::is_test_network) + if (election_l->announcements % announcement_long == 1 && roots_size < 100 && !node.network_params.is_test_network ()) { std::shared_ptr previous; auto previous_hash (election_l->status.winner->previous ()); @@ -3320,7 +3327,7 @@ void nano::active_transactions::request_confirm (std::unique_lock & if ((!rep_endpoints->empty () && node.rep_crawler.total_weight () > node.config.online_weight_minimum.number ()) || roots_size > 5) { // broadcast_confirm_req_base modifies reps, so we clone it once to avoid aliasing - if (!nano::is_test_network) + if (!node.network_params.is_test_network ()) { if (confirm_req_bundle.size () < max_broadcast_queue) { @@ -3351,7 +3358,7 @@ void nano::active_transactions::request_confirm (std::unique_lock & } else { - if (!nano::is_test_network) + if (!node.network_params.is_test_network ()) { auto deque_l (node.peers.list (100)); std::vector vec ({ deque_l.begin (), deque_l.end () }); @@ -3387,7 +3394,7 @@ void nano::active_transactions::request_confirm (std::unique_lock & node.network.republish_block_batch (rebroadcast_bundle); } // Batch confirmation request - if (!nano::is_live_network && !requests_bundle.empty ()) + if (!node.network_params.is_live_network () && !requests_bundle.empty ()) { node.network.broadcast_confirm_req_batch (requests_bundle, 50); } @@ -3428,7 +3435,7 @@ void nano::active_transactions::request_loop () { request_confirm (lock); const auto extra_delay (std::min (roots.size (), max_broadcast_queue) * node.network.broadcast_interval_ms * 2); - condition.wait_for (lock, std::chrono::milliseconds (request_interval_ms + extra_delay)); + condition.wait_for (lock, std::chrono::milliseconds (node.network_params.request_interval_ms + extra_delay)); } } diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 2cf311ac0..0572da68e 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -143,7 +143,6 @@ public: static unsigned constexpr announcement_min = 2; // Threshold to start logging blocks haven't yet been confirmed static unsigned constexpr announcement_long = 20; - static unsigned constexpr request_interval_ms = nano::is_test_network ? 10 : 16000; static size_t constexpr election_history_size = 2048; static size_t constexpr max_broadcast_queue = 1000; @@ -252,19 +251,16 @@ std::unique_ptr collect_seq_con_info (block_arrival & bl class online_reps { public: - online_reps (nano::ledger &, nano::uint128_t); + online_reps (nano::node &, nano::uint128_t); void observe (nano::account const &); void sample (); nano::uint128_t online_stake (); std::vector list (); - static uint64_t constexpr weight_period = 5 * 60; // 5 minutes - // The maximum amount of samples for a 2 week period on live or 3 days on beta - static uint64_t constexpr weight_samples = nano::is_live_network ? 4032 : 864; private: nano::uint128_t trend (nano::transaction &); std::mutex mutex; - nano::ledger & ledger; + nano::node & node; std::unordered_set reps; nano::uint128_t online; nano::uint128_t minimum; @@ -359,7 +355,6 @@ public: std::vector packet_processing_threads; nano::node & node; std::atomic on; - static uint16_t const node_port = nano::is_live_network ? 7075 : 54000; static size_t const buffer_size = 512; static size_t const confirm_req_hashes_max = 6; }; @@ -462,9 +457,12 @@ public: void bootstrap_wallet (); void unchecked_cleanup (); int price (nano::uint128_t const &, int); - void work_generate_blocking (nano::block &, uint64_t = nano::work_pool::publish_threshold); - uint64_t work_generate_blocking (nano::uint256_union const &, uint64_t = nano::work_pool::publish_threshold); - void work_generate (nano::uint256_union const &, std::function, uint64_t = nano::work_pool::publish_threshold); + void work_generate_blocking (nano::block &, uint64_t); + void work_generate_blocking (nano::block &); + uint64_t work_generate_blocking (nano::uint256_union const &, uint64_t); + uint64_t work_generate_blocking (nano::uint256_union const &); + void work_generate (nano::uint256_union const &, std::function, uint64_t); + void work_generate (nano::uint256_union const &, std::function); void add_initial_peers (); void block_confirm (std::shared_ptr); void process_fork (nano::transaction const &, std::shared_ptr); @@ -474,6 +472,7 @@ public: void ongoing_online_weight_calculation (); void ongoing_online_weight_calculation_queue (); boost::asio::io_context & io_ctx; + nano::network_params network_params; nano::node_config config; nano::node_flags flags; nano::alarm & alarm; @@ -508,16 +507,9 @@ public: nano::block_uniquer block_uniquer; nano::vote_uniquer vote_uniquer; const std::chrono::steady_clock::time_point startup_time; + std::chrono::seconds unchecked_cutoff = std::chrono::seconds (7 * 24 * 60 * 60); // Week static double constexpr price_max = 16.0; static double constexpr free_cutoff = 1024.0; - static std::chrono::seconds constexpr period = nano::is_test_network ? std::chrono::seconds (1) : std::chrono::seconds (60); - static std::chrono::seconds constexpr cutoff = period * 5; - static std::chrono::seconds constexpr syn_cookie_cutoff = std::chrono::seconds (5); - static std::chrono::minutes constexpr backup_interval = std::chrono::minutes (5); - static std::chrono::seconds constexpr search_pending_interval = nano::is_test_network ? std::chrono::seconds (1) : std::chrono::seconds (5 * 60); - static std::chrono::seconds constexpr peer_interval = search_pending_interval; - static std::chrono::hours constexpr unchecked_cleanup_interval = std::chrono::hours (1); - static std::chrono::milliseconds constexpr process_confirmed_interval = nano::is_test_network ? std::chrono::milliseconds (50) : std::chrono::milliseconds (500); private: void add_confirmation_heights (nano::block_hash const & hash); diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index 3122fd273..6e92040bd 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -13,7 +13,7 @@ const char * default_live_peer_network = "peering.nano.org"; } nano::node_config::node_config () : -node_config (nano::network::node_port, nano::logging ()) +node_config (0, nano::logging ()) { } @@ -35,18 +35,24 @@ bootstrap_connections (4), bootstrap_connections_max (64), callback_port (0), lmdb_max_dbs (128), -allow_local_peers (!nano::is_live_network), // disable by default for live network +allow_local_peers (!network_params.is_live_network ()), // disable by default for live network block_processor_batch_max_time (std::chrono::milliseconds (5000)), unchecked_cutoff_time (std::chrono::seconds (4 * 60 * 60)) // 4 hours { + // The default constructor passes 0 to indicate we should use the default port, + // which is determined at node startup based on active network. + if (peering_port == 0) + { + peering_port = network_params.default_node_port; + } const char * epoch_message ("epoch v1 block"); strncpy ((char *)epoch_block_link.bytes.data (), epoch_message, epoch_block_link.bytes.size ()); - epoch_block_signer = nano::genesis_account; - switch (nano::nano_network) + epoch_block_signer = network_params.ledger.genesis_account; + switch (network_params.network ()) { case nano::nano_networks::nano_test_network: enable_voting = true; - preconfigured_representatives.push_back (nano::genesis_account); + preconfigured_representatives.push_back (network_params.ledger.genesis_account); break; case nano::nano_networks::nano_beta_network: preconfigured_peers.push_back (default_beta_peer_network); diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index 91a25e411..0ed753686 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -23,6 +24,7 @@ public: nano::error deserialize_json (bool &, nano::jsonconfig &); bool upgrade_json (unsigned, nano::jsonconfig &); nano::account random_representative (); + nano::network_params network_params; uint16_t peering_port; nano::logging logging; std::vector> work_peers; diff --git a/nano/node/peers.cpp b/nano/node/peers.cpp index 00b526ad4..7a5dbb290 100644 --- a/nano/node/peers.cpp +++ b/nano/node/peers.cpp @@ -361,7 +361,7 @@ bool nano::peer_container::insert (nano::endpoint const & endpoint_a, unsigned v else { unknown = true; - if (!result && !nano::is_test_network) + if (!result && !network_params.is_test_network ()) { auto ip_peers (peers.get ().count (endpoint_a.address ())); if (ip_peers >= max_peers_per_ip) diff --git a/nano/node/peers.hpp b/nano/node/peers.hpp index fc0f9ced8..233cafdb5 100644 --- a/nano/node/peers.hpp +++ b/nano/node/peers.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,7 @@ public: size_t size (); size_t size_sqrt (); bool empty (); + nano::network_params network_params; std::mutex mutex; nano::endpoint self; boost::multi_index_container< diff --git a/nano/node/portmapping.cpp b/nano/node/portmapping.cpp index e4c926469..165486618 100644 --- a/nano/node/portmapping.cpp +++ b/nano/node/portmapping.cpp @@ -20,7 +20,7 @@ void nano::port_mapping::start () void nano::port_mapping::refresh_devices () { - if (!nano::is_test_network) + if (!network_params.is_test_network ()) { std::lock_guard lock (mutex); int discover_error = 0; @@ -50,7 +50,7 @@ void nano::port_mapping::refresh_devices () void nano::port_mapping::refresh_mapping () { - if (!nano::is_test_network) + if (!network_params.is_test_network ()) { std::lock_guard lock (mutex); auto node_port (std::to_string (node.network.endpoint ().port ())); @@ -60,7 +60,7 @@ void nano::port_mapping::refresh_mapping () { std::array actual_external_port; actual_external_port.fill (0); - auto add_port_mapping_error (UPNP_AddAnyPortMapping (urls.controlURL, data.first.servicetype, node_port.c_str (), node_port.c_str (), address.to_string ().c_str (), nullptr, protocol.name, nullptr, std::to_string (mapping_timeout).c_str (), actual_external_port.data ())); + auto add_port_mapping_error (UPNP_AddAnyPortMapping (urls.controlURL, data.first.servicetype, node_port.c_str (), node_port.c_str (), address.to_string ().c_str (), nullptr, protocol.name, nullptr, std::to_string (network_params.portmapping.mapping_timeout).c_str (), actual_external_port.data ())); if (check_count % 15 == 0) { node.logger.always_log (boost::str (boost::format ("UPnP %1% port mapping response: %2%, actual external port %3%") % protocol.name % add_port_mapping_error % actual_external_port.data ())); @@ -80,7 +80,7 @@ void nano::port_mapping::refresh_mapping () int nano::port_mapping::check_mapping () { int result (3600); - if (!nano::is_test_network) + if (!network_params.is_test_network ()) { // Long discovery time and fast setup/teardown make this impractical for testing std::lock_guard lock (mutex); @@ -124,7 +124,7 @@ int nano::port_mapping::check_mapping () void nano::port_mapping::check_mapping_loop () { - int wait_duration = check_timeout; + int wait_duration = network_params.portmapping.check_timeout; refresh_devices (); if (devices != nullptr) { diff --git a/nano/node/portmapping.hpp b/nano/node/portmapping.hpp index 0f105db91..53405d36b 100644 --- a/nano/node/portmapping.hpp +++ b/nano/node/portmapping.hpp @@ -43,9 +43,7 @@ private: UPNPUrls urls; /** UPnP state */ IGDdatas data; - /** Timeouts are primes so they infrequently happen at the same time */ - static int constexpr mapping_timeout = nano::is_test_network ? 53 : 3593; - static int constexpr check_timeout = nano::is_test_network ? 17 : 53; + nano::network_params network_params; boost::asio::ip::address_v4 address; std::array protocols; uint64_t check_count; diff --git a/nano/node/rpc.cpp b/nano/node/rpc.cpp index 257170180..67ccb4787 100644 --- a/nano/node/rpc.cpp +++ b/nano/node/rpc.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -819,11 +820,11 @@ void nano::rpc_handler::accounts_pending () void nano::rpc_handler::available_supply () { - auto genesis_balance (node.balance (nano::genesis_account)); // Cold storage genesis + auto genesis_balance (node.balance (node.network_params.ledger.genesis_account)); // Cold storage genesis auto landing_balance (node.balance (nano::account ("059F68AAB29DE0D3A27443625C7EA9CDDB6517A8B76FE37727EF6A4D76832AD5"))); // Active unavailable account auto faucet_balance (node.balance (nano::account ("8E319CE6F3025E5B2DF66DA7AB1467FE48F1679C13DD43BFDB29FA2E9FC40D3B"))); // Faucet account auto burned_balance ((node.balance_pending (nano::account (0))).second); // Burning 0 account - auto available (nano::genesis_amount - genesis_balance - landing_balance - faucet_balance - burned_balance); + auto available (node.network_params.ledger.genesis_amount - genesis_balance - landing_balance - faucet_balance - burned_balance); response_l.put ("available", available.convert_to ()); response_errors (); } @@ -1844,15 +1845,15 @@ public: // Report opens as a receive tree.put ("type", "receive"); } - if (block_a.hashables.source != nano::genesis_account) + if (block_a.hashables.source != network_params.ledger.genesis_account) { tree.put ("account", handler.node.ledger.account (transaction, block_a.hashables.source).to_account ()); tree.put ("amount", handler.node.ledger.amount (transaction, hash).convert_to ()); } else { - tree.put ("account", nano::genesis_account.to_account ()); - tree.put ("amount", nano::genesis_amount.convert_to ()); + tree.put ("account", network_params.ledger.genesis_account.to_account ()); + tree.put ("amount", network_params.ledger.genesis_amount.convert_to ()); } } void change_block (nano::change_block const & block_a) @@ -1926,6 +1927,7 @@ public: nano::transaction & transaction; boost::property_tree::ptree & tree; nano::block_hash const & hash; + nano::network_params network_params; }; } @@ -2768,7 +2770,7 @@ void nano::rpc_handler::receive () bool generate_work (work == 0); // Disable work generation if "work" option is provided auto response_a (response); // clang-format off - wallet->receive_async (std::move (block), account, nano::genesis_amount, [response_a](std::shared_ptr block_a) { + wallet->receive_async (std::move (block), account, node.network_params.ledger.genesis_amount, [response_a](std::shared_ptr block_a) { if (block_a != nullptr) { boost::property_tree::ptree response_l; @@ -4151,7 +4153,7 @@ void nano::rpc_handler::work_generate () { rpc_control_impl (); auto hash (hash_impl ()); - uint64_t difficulty (nano::work_pool::publish_threshold); + uint64_t difficulty (node.network_params.publish_threshold); boost::optional difficulty_text (request.get_optional ("difficulty")); if (!ec && difficulty_text.is_initialized ()) { diff --git a/nano/node/rpc.hpp b/nano/node/rpc.hpp index ebd4e2c2e..c594bb20e 100644 --- a/nano/node/rpc.hpp +++ b/nano/node/rpc.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/node/rpcconfig.cpp b/nano/node/rpcconfig.cpp index 9f7d2ceae..8bfead504 100644 --- a/nano/node/rpcconfig.cpp +++ b/nano/node/rpcconfig.cpp @@ -34,7 +34,7 @@ nano::error nano::rpc_secure_config::deserialize_json (nano::jsonconfig & json) nano::rpc_config::rpc_config (bool enable_control_a) : address (boost::asio::ip::address_v6::loopback ()), -port (nano::is_live_network ? 7076 : 55000), +port (network_params.default_rpc_port), enable_control (enable_control_a), max_json_depth (20), enable_sign_hash (false) diff --git a/nano/node/rpcconfig.hpp b/nano/node/rpcconfig.hpp index 7f8ab4ac3..291801a19 100644 --- a/nano/node/rpcconfig.hpp +++ b/nano/node/rpcconfig.hpp @@ -38,6 +38,7 @@ public: rpc_config (bool = false); nano::error serialize_json (nano::jsonconfig &) const; nano::error deserialize_json (bool & upgraded_a, nano::jsonconfig &); + nano::network_params network_params; boost::asio::ip::address_v6 address; uint16_t port; bool enable_control; diff --git a/nano/node/testing.cpp b/nano/node/testing.cpp index ce33ca453..9cf5e71f4 100644 --- a/nano/node/testing.cpp +++ b/nano/node/testing.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include diff --git a/nano/node/voting.cpp b/nano/node/voting.cpp index f15341891..598dc2e93 100644 --- a/nano/node/voting.cpp +++ b/nano/node/voting.cpp @@ -2,9 +2,8 @@ #include -nano::vote_generator::vote_generator (nano::node & node_a, std::chrono::milliseconds wait_a) : +nano::vote_generator::vote_generator (nano::node & node_a) : node (node_a), -wait (wait_a), stopped (false), started (false), thread ([this]() { run (); }) @@ -79,7 +78,7 @@ void nano::vote_generator::run () } else if (cutoff == min) // && hashes.size () < 12 { - cutoff = now + wait; + cutoff = now + network_params.voting.generator_delay; condition.wait_until (lock, cutoff); } else if (now < cutoff) // && hashes.size () < 12 @@ -111,7 +110,7 @@ void nano::votes_cache::add (std::shared_ptr const & vote_a) if (existing == cache.get<1> ().end ()) { // Clean old votes - if (cache.size () >= max_cache) + if (cache.size () >= network_params.voting.max_cache) { cache.erase (cache.begin ()); } diff --git a/nano/node/voting.hpp b/nano/node/voting.hpp index 1e9d578e7..6e5f1adbc 100644 --- a/nano/node/voting.hpp +++ b/nano/node/voting.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -21,7 +22,7 @@ class node; class vote_generator { public: - vote_generator (nano::node &, std::chrono::milliseconds); + vote_generator (nano::node &); void add (nano::block_hash const &); void stop (); @@ -32,7 +33,7 @@ private: std::mutex mutex; std::condition_variable condition; std::deque hashes; - std::chrono::milliseconds wait; + nano::network_params network_params; bool stopped; bool started; boost::thread thread; @@ -63,8 +64,7 @@ private: boost::multi_index::ordered_non_unique>, boost::multi_index::hashed_unique>>> cache; - static size_t constexpr max_cache = (nano::is_test_network) ? 2 : 1000; - + nano::network_params network_params; friend std::unique_ptr collect_seq_con_info (votes_cache & votes_cache, const std::string & name); }; diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index ee27f46f1..4a6ef5c23 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -12,8 +12,6 @@ #include -uint64_t const nano::work_pool::publish_threshold; - nano::uint256_union nano::wallet_store::check (nano::transaction const & transaction_a) { nano::wallet_value value (entry_get_raw (transaction_a, nano::wallet_store::check_special)); @@ -736,8 +734,9 @@ void nano::wallet_store::upgrade_v3_v4 (nano::transaction const & transaction_a) void nano::kdf::phs (nano::raw_key & result_a, std::string const & password_a, nano::uint256_union const & salt_a) { + static nano::network_params network_params; std::lock_guard lock (mutex); - auto success (argon2_hash (1, nano::wallet_store::kdf_work, 1, password_a.data (), password_a.size (), salt_a.bytes.data (), salt_a.bytes.size (), result_a.data.bytes.data (), result_a.data.bytes.size (), NULL, 0, Argon2_d, 0x10)); + auto success (argon2_hash (1, network_params.kdf_work, 1, password_a.data (), password_a.size (), salt_a.bytes.data (), salt_a.bytes.size (), result_a.data.bytes.data (), result_a.data.bytes.size (), NULL, 0, Argon2_d, 0x10)); assert (success == 0); (void)success; } @@ -1331,7 +1330,7 @@ void nano::wallet::work_cache_blocking (nano::account const & account_a, nano::b * The difficulty parameter is the second parameter for `work_generate_blocking()`, * currently we don't supply one so we must fetch the default value. */ - auto difficulty (nano::work_pool::publish_threshold); + auto difficulty (wallets.node.network_params.publish_threshold); wallets.node.logger.try_log ("Work generation for ", root_a.to_string (), ", with a difficulty of ", difficulty, " complete: ", (std::chrono::duration_cast (std::chrono::steady_clock::now () - begin).count ()), " us"); } @@ -1658,7 +1657,7 @@ void nano::wallets::ongoing_compute_reps () { compute_reps (); auto & node_l (node); - auto compute_delay (nano::is_test_network ? std::chrono::milliseconds (10) : std::chrono::milliseconds (15 * 60 * 1000)); // Representation drifts quickly on the test network but very slowly on the live network + auto compute_delay (network_params.is_test_network () ? std::chrono::milliseconds (10) : std::chrono::milliseconds (15 * 60 * 1000)); // Representation drifts quickly on the test network but very slowly on the live network node.alarm.add (std::chrono::steady_clock::now () + compute_delay, [&node_l]() { node_l.wallets.ongoing_compute_reps (); }); diff --git a/nano/node/wallet.hpp b/nano/node/wallet.hpp index 067c47649..9efc5df8c 100644 --- a/nano/node/wallet.hpp +++ b/nano/node/wallet.hpp @@ -1,12 +1,12 @@ #pragma once #include +#include +#include #include #include #include #include - -#include #include namespace nano @@ -104,9 +104,6 @@ public: static size_t const check_iv_index; static size_t const seed_iv_index; static int const special_count; - static unsigned const kdf_full_work = 64 * 1024; - static unsigned const kdf_test_work = 8; - static unsigned const kdf_work = nano::is_test_network ? kdf_test_work : kdf_full_work; nano::kdf & kdf; MDB_dbi handle; std::recursive_mutex mutex; @@ -152,6 +149,7 @@ public: nano::public_key change_seed (nano::transaction const & transaction_a, nano::raw_key const & prv_a, uint32_t count = 0); void deterministic_restore (nano::transaction const & transaction_a); bool live (); + nano::network_params network_params; std::unordered_set free_accounts; std::function lock_observer; nano::wallet_store store; @@ -186,6 +184,7 @@ public: void ongoing_compute_reps (); void split_if_needed (nano::transaction &, nano::block_store &); void move_table (std::string const &, MDB_txn *, MDB_txn *); + nano::network_params network_params; std::function observer; std::unordered_map> items; std::multimap, std::function>, std::greater> actions; diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index d10f1a3f1..b6243fda1 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -1,10 +1,10 @@ -#include - #include #include #include #include #include +#include +#include #include namespace @@ -73,11 +73,11 @@ wallet (wallet_a) { your_account_label->setStyleSheet ("font-weight: bold;"); std::string network = "Live"; - if (nano::is_beta_network) + if (wallet.node.network_params.is_beta_network ()) { network = "Beta"; } - else if (nano::is_test_network) + else if (wallet.node.network_params.is_test_network ()) { network = "Test"; } @@ -541,16 +541,17 @@ public: } void open_block (nano::open_block const & block_a) { + static nano::network_params params; type = "Receive"; - if (block_a.hashables.source != nano::genesis_account) + if (block_a.hashables.source != params.ledger.genesis_account) { account = ledger.account (transaction, block_a.hashables.source); amount = ledger.amount (transaction, block_a.hash ()); } else { - account = nano::genesis_account; - amount = nano::genesis_amount; + account = params.ledger.genesis_account; + amount = params.ledger.genesis_amount; } } void change_block (nano::change_block const & block_a) @@ -1018,7 +1019,7 @@ needs_deterministic_restore (false) empty_password (); settings.update_locked (true, true); send_blocks_layout->addWidget (send_account_label); - send_account->setPlaceholderText (nano::zero_key.pub.to_account ().c_str ()); + send_account->setPlaceholderText (node.network_params.ledger.zero_key.pub.to_account ().c_str ()); send_blocks_layout->addWidget (send_account); send_blocks_layout->addWidget (send_count_label); send_count->setPlaceholderText ("0"); @@ -1521,7 +1522,7 @@ wallet (wallet_a) layout->addWidget (representative); current_representative->setTextInteractionFlags (Qt::TextSelectableByMouse); layout->addWidget (current_representative); - new_representative->setPlaceholderText (nano::zero_key.pub.to_account ().c_str ()); + new_representative->setPlaceholderText (wallet.node.network_params.ledger.zero_key.pub.to_account ().c_str ()); layout->addWidget (new_representative); layout->addWidget (change_rep); layout->addStretch (); diff --git a/nano/qt_system/entry.cpp b/nano/qt_system/entry.cpp index babc8c76f..1726649ac 100644 --- a/nano/qt_system/entry.cpp +++ b/nano/qt_system/entry.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -5,6 +6,7 @@ int main (int argc, char ** argv) { + nano::network_params::set_active_network (nano::nano_networks::nano_test_network); QApplication application (argc, argv); QCoreApplication::setOrganizationName ("Nano"); QCoreApplication::setOrganizationDomain ("nano.org"); diff --git a/nano/qt_test/entry.cpp b/nano/qt_test/entry.cpp index 8d900983e..a9043b430 100644 --- a/nano/qt_test/entry.cpp +++ b/nano/qt_test/entry.cpp @@ -1,11 +1,12 @@ +#include #include -#include - QApplication * test_application = nullptr; +extern void force_nano_test_network (); int main (int argc, char ** argv) { + force_nano_test_network (); QApplication application (argc, argv); test_application = &application; testing::InitGoogleTest (&argc, argv); diff --git a/nano/secure/CMakeLists.txt b/nano/secure/CMakeLists.txt index 24864c7fe..fcbfd8d8c 100644 --- a/nano/secure/CMakeLists.txt +++ b/nano/secure/CMakeLists.txt @@ -10,24 +10,29 @@ else () error ("Unknown platform: ${CMAKE_SYSTEM_NAME}") endif () -# Embed bootstrap representative weights in executable -if (${ACTIVE_NETWORK} MATCHES "nano_beta_network") - set (REP_WEIGHTS_BIN_NAME "rep_weights_beta.bin") -else () - set (REP_WEIGHTS_BIN_NAME "rep_weights_live.bin") -endif () - -file (READ ${CMAKE_SOURCE_DIR}/${REP_WEIGHTS_BIN_NAME} filedata HEX) +# Embed bootstrap representative weights in executable. Both live +# and beta weights are added to accommodate switching networks +# from the command line. +file (READ ${CMAKE_SOURCE_DIR}/rep_weights_live.bin filedata HEX) string (REGEX REPLACE "(..)" "0x\\1," filedata ${filedata}) -file (WRITE ${CMAKE_BINARY_DIR}/bootstrap_weights.cpp "#include \n" +file (WRITE ${CMAKE_BINARY_DIR}/bootstrap_weights_live.cpp "#include \n" "namespace nano {\n" - " unsigned char nano_bootstrap_weights[] = {${filedata} 0x00};\n" - " size_t nano_bootstrap_weights_size = sizeof(nano_bootstrap_weights) - 1;\n" + " unsigned char nano_bootstrap_weights_live[] = {${filedata} 0x00};\n" + " size_t nano_bootstrap_weights_live_size = sizeof(nano_bootstrap_weights_live) - 1;\n" "}\n") +file (READ ${CMAKE_SOURCE_DIR}/rep_weights_beta.bin filedata HEX) +string (REGEX REPLACE "(..)" "0x\\1," filedata ${filedata}) +file (WRITE ${CMAKE_BINARY_DIR}/bootstrap_weights_beta.cpp "#include \n" +"namespace nano {\n" +" unsigned char nano_bootstrap_weights_beta[] = {${filedata} 0x00};\n" +" size_t nano_bootstrap_weights_beta_size = sizeof(nano_bootstrap_weights_beta) - 1;\n" +"}\n") + add_library (secure ${PLATFORM_SECURE_SOURCE} - ${CMAKE_BINARY_DIR}/bootstrap_weights.cpp + ${CMAKE_BINARY_DIR}/bootstrap_weights_live.cpp + ${CMAKE_BINARY_DIR}/bootstrap_weights_beta.cpp common.cpp common.hpp blockstore.cpp diff --git a/nano/secure/blockstore.cpp b/nano/secure/blockstore.cpp index a2d1ce8ab..db41a133e 100644 --- a/nano/secure/blockstore.cpp +++ b/nano/secure/blockstore.cpp @@ -153,13 +153,13 @@ void nano::summation_visitor::open_block (nano::open_block const & block_a) assert (current->type != summation_type::invalid && current != nullptr); if (current->type == summation_type::amount) { - if (block_a.hashables.source != nano::genesis_account) + if (block_a.hashables.source != network_params.ledger.genesis_account) { current->amount_hash = block_a.hashables.source; } else { - sum_set (nano::genesis_amount); + sum_set (network_params.ledger.genesis_amount); current->amount_hash = 0; } } @@ -274,7 +274,7 @@ nano::uint128_t nano::summation_visitor::compute_internal (nano::summation_visit } else { - if (current->amount_hash == nano::genesis_account) + if (current->amount_hash == network_params.ledger.genesis_account) { sum_set (std::numeric_limits::max ()); current->amount_hash = 0; diff --git a/nano/secure/blockstore.hpp b/nano/secure/blockstore.hpp index e0a35059d..4ef8b8a66 100644 --- a/nano/secure/blockstore.hpp +++ b/nano/secure/blockstore.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -72,6 +73,7 @@ public: protected: nano::transaction const & transaction; nano::block_store const & store; + nano::network_params network_params; /** The final result */ nano::uint128_t result{ 0 }; diff --git a/nano/secure/common.cpp b/nano/secure/common.cpp index f345dc9b7..dff2de008 100644 --- a/nano/secure/common.cpp +++ b/nano/secure/common.cpp @@ -13,114 +13,12 @@ #include -// Genesis keys for network variants -namespace -{ -char const * test_private_key_data = "34F0A37AAD20F4A260F0A5B3CB3D7FB50673212263E58A380BC10474BB039CE4"; -char const * test_public_key_data = "B0311EA55708D6A53C75CDBF88300259C6D018522FE3D4D0A242E431F9E8B6D0"; // xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo -char const * beta_public_key_data = "A59A47CC4F593E75AE9AD653FDA9358E2F7898D9ACC8C60E80D0495CE20FBA9F"; // xrb_3betaz86ypbygpqbookmzpnmd5jhh4efmd8arr9a3n4bdmj1zgnzad7xpmfp -char const * live_public_key_data = "E89208DD038FBB269987689621D52292AE9C35941A7484756ECCED92A65093BA"; // xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3 -char const * test_genesis_data = R"%%%({ - "type": "open", - "source": "B0311EA55708D6A53C75CDBF88300259C6D018522FE3D4D0A242E431F9E8B6D0", - "representative": "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo", - "account": "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo", - "work": "9680625b39d3363d", - "signature": "ECDA914373A2F0CA1296475BAEE40500A7F0A7AD72A5A80C81D7FAB7F6C802B2CC7DB50F5DD0FB25B2EF11761FA7344A158DD5A700B21BD47DE5BD0F63153A02" -})%%%"; - -char const * beta_genesis_data = R"%%%({ - "type": "open", - "source": "A59A47CC4F593E75AE9AD653FDA9358E2F7898D9ACC8C60E80D0495CE20FBA9F", - "representative": "xrb_3betaz86ypbygpqbookmzpnmd5jhh4efmd8arr9a3n4bdmj1zgnzad7xpmfp", - "account": "xrb_3betaz86ypbygpqbookmzpnmd5jhh4efmd8arr9a3n4bdmj1zgnzad7xpmfp", - "work": "000000000f0aaeeb", - "signature": "A726490E3325E4FA59C1C900D5B6EEBB15FE13D99F49D475B93F0AACC5635929A0614CF3892764A04D1C6732A0D716FFEB254D4154C6F544D11E6630F201450B" -})%%%"; - -char const * live_genesis_data = R"%%%({ - "type": "open", - "source": "E89208DD038FBB269987689621D52292AE9C35941A7484756ECCED92A65093BA", - "representative": "xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3", - "account": "xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3", - "work": "62f05417dd3fb691", - "signature": "9F0C933C8ADE004D808EA1985FA746A7E95BA2A38F867640F53EC8F180BDFE9E2C1268DEAD7C2664F356E37ABA362BC58E46DBA03E523A7B5A19E4B6EB12BB02" -})%%%"; - -class ledger_constants -{ -public: - ledger_constants () : - zero_key ("0"), - test_genesis_key (test_private_key_data), - nano_test_account (test_public_key_data), - nano_beta_account (beta_public_key_data), - nano_live_account (live_public_key_data), - nano_test_genesis (test_genesis_data), - nano_beta_genesis (beta_genesis_data), - nano_live_genesis (live_genesis_data), - genesis_account (nano::is_test_network ? nano_test_account : nano::is_beta_network ? nano_beta_account : nano_live_account), - genesis_block (nano::is_test_network ? nano_test_genesis : nano::is_beta_network ? nano_beta_genesis : nano_live_genesis), - genesis_amount (std::numeric_limits::max ()), - burn_account (0) - { - } - nano::keypair zero_key; - nano::keypair test_genesis_key; - nano::account nano_test_account; - nano::account nano_beta_account; - nano::account nano_live_account; - std::string nano_test_genesis; - std::string nano_beta_genesis; - std::string nano_live_genesis; - nano::account genesis_account; - std::string genesis_block; - nano::uint128_t genesis_amount; - nano::account burn_account; - - nano::account const & not_an_account () - { - std::lock_guard lk (mutex); - if (!is_initialized) - { - // Randomly generating this means that no two nodes will ever have the same sentinel value which protects against some insecure algorithms - nano::random_pool::generate_block (not_an_account_m.bytes.data (), not_an_account_m.bytes.size ()); - is_initialized = true; - } - return not_an_account_m; - } - -private: - nano::account not_an_account_m; - std::mutex mutex; - bool is_initialized{ false }; -}; -ledger_constants globals; -} - size_t constexpr nano::send_block::size; size_t constexpr nano::receive_block::size; size_t constexpr nano::open_block::size; size_t constexpr nano::change_block::size; size_t constexpr nano::state_block::size; -nano::keypair const & nano::zero_key (globals.zero_key); -nano::keypair const & nano::test_genesis_key (globals.test_genesis_key); -nano::account const & nano::nano_test_account (globals.nano_test_account); -nano::account const & nano::nano_beta_account (globals.nano_beta_account); -nano::account const & nano::nano_live_account (globals.nano_live_account); -std::string const & nano::nano_test_genesis (globals.nano_test_genesis); -std::string const & nano::nano_beta_genesis (globals.nano_beta_genesis); -std::string const & nano::nano_live_genesis (globals.nano_live_genesis); - -nano::account const & nano::genesis_account (globals.genesis_account); -std::string const & nano::genesis_block (globals.genesis_block); -nano::uint128_t const & nano::genesis_amount (globals.genesis_amount); -nano::account const & nano::burn_account (globals.burn_account); -nano::account const & nano::not_an_account () -{ - return globals.not_an_account (); -} // Create a new random keypair nano::keypair::keypair () { @@ -708,8 +606,9 @@ std::unique_ptr collect_seq_con_info (vote_uniquer & vot nano::genesis::genesis () { + static nano::network_params network_params; boost::property_tree::ptree tree; - std::stringstream istream (nano::genesis_block); + std::stringstream istream (network_params.ledger.genesis_block); boost::property_tree::read_json (istream, tree); open = nano::deserialize_block_json (tree); assert (open != nullptr); diff --git a/nano/secure/common.hpp b/nano/secure/common.hpp index 357a99d97..2211293ad 100644 --- a/nano/secure/common.hpp +++ b/nano/secure/common.hpp @@ -300,20 +300,7 @@ enum class tally_result changed, confirm }; -extern nano::keypair const & zero_key; -extern nano::keypair const & test_genesis_key; -extern nano::account const & nano_test_account; -extern nano::account const & nano_beta_account; -extern nano::account const & nano_live_account; -extern std::string const & nano_test_genesis; -extern std::string const & nano_beta_genesis; -extern std::string const & nano_live_genesis; -extern std::string const & genesis_block; -extern nano::account const & genesis_account; -extern nano::account const & burn_account; -extern nano::uint128_t const & genesis_amount; -// An account number that compares inequal to any real account number -extern nano::account const & not_an_account (); + class genesis { public: diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index a0e04ac5f..9745d0259 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -612,7 +612,7 @@ void ledger_processor::open_block (nano::open_block const & block_a) result.code = ledger.store.pending_get (transaction, key, pending) ? nano::process_result::unreceivable : nano::process_result::progress; // Has this source already been received (Malformed) if (result.code == nano::process_result::progress) { - result.code = block_a.hashables.account == nano::burn_account ? nano::process_result::opened_burn_account : nano::process_result::progress; // Is it burning 0 account? (Malicious) + result.code = block_a.hashables.account == ledger.network_params.ledger.burn_account ? nano::process_result::opened_burn_account : nano::process_result::progress; // Is it burning 0 account? (Malicious) if (result.code == nano::process_result::progress) { result.code = pending.epoch == nano::epoch::epoch_0 ? nano::process_result::progress : nano::process_result::unreceivable; // Are we receiving a state-only send? (Malformed) @@ -873,7 +873,7 @@ nano::account nano::ledger::account (nano::transaction const & transaction_a, na nano::uint128_t nano::ledger::amount (nano::transaction const & transaction_a, nano::block_hash const & hash_a) { nano::uint128_t result; - if (hash_a != nano::genesis_account) + if (hash_a != network_params.ledger.genesis_account) { auto block (store.block_get (transaction_a, hash_a)); auto block_balance (balance (transaction_a, hash_a)); @@ -882,7 +882,7 @@ nano::uint128_t nano::ledger::amount (nano::transaction const & transaction_a, n } else { - result = nano::genesis_amount; + result = network_params.ledger.genesis_amount; } return result; } diff --git a/nano/secure/ledger.hpp b/nano/secure/ledger.hpp index 61b0b3099..d02114f36 100644 --- a/nano/secure/ledger.hpp +++ b/nano/secure/ledger.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include namespace nano @@ -46,6 +47,7 @@ public: bool could_fit (nano::transaction const &, nano::block const &); bool is_epoch_link (nano::uint256_union const &); static nano::uint128_t const unit; + nano::network_params network_params; nano::block_store & store; nano::stat & stats; std::unordered_map bootstrap_weights; diff --git a/nano/secure/utility.cpp b/nano/secure/utility.cpp index b59741493..c4ee2bac1 100644 --- a/nano/secure/utility.cpp +++ b/nano/secure/utility.cpp @@ -1,14 +1,15 @@ -#include - +#include #include #include +#include static std::vector all_unique_paths; boost::filesystem::path nano::working_path (bool legacy) { + static nano::network_params network_params; auto result (nano::app_path ()); - switch (nano::nano_network) + switch (network_params.network ()) { case nano::nano_networks::nano_test_network: if (!legacy) diff --git a/nano/secure/utility.hpp b/nano/secure/utility.hpp index f0ef86c43..a85c8aa71 100644 --- a/nano/secure/utility.hpp +++ b/nano/secure/utility.hpp @@ -12,7 +12,6 @@ #include -#include #include #include #include diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 57de06426..9a06735c7 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -1,7 +1,6 @@ #include #include #include - #include TEST (system, generate_mass_activity)