From 7b1b51c418c401b81aa5f4e3e90f00582d999716 Mon Sep 17 00:00:00 2001 From: Dimitrios Siganos Date: Sat, 17 Apr 2021 02:38:51 +0100 Subject: [PATCH 1/4] Handle signals with boost asio signal handler Currently the nano_node has 2 problems: * it uses the function signal which is not very portable * it calls possibly blocking code from signal handler context These problems will become even more crucial when we start using SIGHUP to reload config. In addition, we plan to introduce more processes and it makes sense to have a common signal framework for all the processes. This commit introduces the signal manager, which fixes all the problems listed above. --- nano/core_test/CMakeLists.txt | 1 + nano/core_test/signal_manager.cpp | 106 ++++++++++++++++++++++++++++++ nano/lib/CMakeLists.txt | 2 + nano/lib/signal_manager.cpp | 93 ++++++++++++++++++++++++++ nano/lib/signal_manager.hpp | 82 +++++++++++++++++++++++ nano/nano_node/daemon.cpp | 21 +++--- nano/nano_rpc/entry.cpp | 8 +-- 7 files changed, 297 insertions(+), 16 deletions(-) create mode 100644 nano/core_test/signal_manager.cpp create mode 100644 nano/lib/signal_manager.cpp create mode 100644 nano/lib/signal_manager.hpp diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index 276829df62..901ceac1f7 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -31,6 +31,7 @@ add_executable( peer_container.cpp prioritization.cpp request_aggregator.cpp + signal_manager.cpp signing.cpp socket.cpp telemetry.cpp diff --git a/nano/core_test/signal_manager.cpp b/nano/core_test/signal_manager.cpp new file mode 100644 index 0000000000..e0b0bca28d --- /dev/null +++ b/nano/core_test/signal_manager.cpp @@ -0,0 +1,106 @@ +/** + * IMPORTANT NOTE: + * These unit tests may or may not work, gtest and boost asio signal handling are not really compatible. + * The boost asio signal handling assumes that it is the only one handling signals but gtest + * also does some signal handling of its own. In my testing this setup works although in theory + * I am playing with unspecified behaviour. If these tests start causing problems then we should + * remove them and try some other approach. + * The tests are designed as death tests because, as normal tests, the boost library asserts + * when I define more than one test case. I have not investigated why, I just turned them into death tests. + * + * Update: it appears that these tests only work if run in isolation so I am disabling them. + */ + +#include + +#include + +#include + +#include +#include + +static void handler_print_signal (int signum) +{ + std::cerr << "boost signal handler " << signum << std::endl + << std::flush; +} + +static int wait_for_sig_received (int millisecs, int & sig_received) +{ + for (int i = 0; i < millisecs && sig_received == 0; i++) + { + std::this_thread::sleep_for (std::chrono::microseconds (1)); + } + return sig_received; +} + +static int trap (int signum) +{ + nano::signal_manager sigman; + int sig_received = 0; + + std::function f = [&sig_received] (int signum) { + std::cerr << "boost signal handler " << signum << std::endl + << std::flush; + sig_received = signum; + }; + + sigman.register_signal_handler (signum, f, false); + + raise (signum); + + exit (wait_for_sig_received (10000, sig_received)); +} + +static void repeattest (int signum, bool repeat) +{ + nano::signal_manager sigman; + int sig_received = 0; + + std::function f = [&sig_received] (int signum) { + std::cerr << "boost signal handler" << std::flush; + sig_received = signum; + }; + + sigman.register_signal_handler (signum, f, repeat); + + for (int i = 0; i < 10; i++) + { + sig_received = 0; + raise (signum); + if (wait_for_sig_received (10000, sig_received) != signum) + { + exit (1); + } + } + + exit (0); +} + +TEST (DISABLED_signal_manager_test, trap) +{ + int signum; + + signum = SIGINT; + ASSERT_EXIT (trap (signum), ::testing::ExitedWithCode (signum), ""); + + signum = SIGTERM; + ASSERT_EXIT (trap (signum), ::testing::ExitedWithCode (signum), ""); +} + +TEST (DISABLED_signal_manager_test, repeat) +{ + int signum; + + signum = SIGINT; + ASSERT_EXIT (repeattest (signum, true), ::testing::ExitedWithCode (0), ""); +} + +TEST (DISABLED_signal_manager_test, norepeat) +{ + int signum; + + signum = SIGINT; + ASSERT_DEATH (repeattest (signum, false), "^boost signal handler$"); +} diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index a34d2632d8..3a99d8f25d 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -62,6 +62,8 @@ add_library( rpc_handler_interface.hpp rpcconfig.hpp rpcconfig.cpp + signal_manager.hpp + signal_manager.cpp stats.hpp stats.cpp stream.hpp diff --git a/nano/lib/signal_manager.cpp b/nano/lib/signal_manager.cpp new file mode 100644 index 0000000000..b61d9c8eb9 --- /dev/null +++ b/nano/lib/signal_manager.cpp @@ -0,0 +1,93 @@ +#include +#include + +#include +#include +#include +#include + +#include + +nano::signal_manager::signal_manager () : + work (boost::asio::make_work_guard (ioc)) +{ + smthread = boost::thread ([&ioc = ioc] () { + ioc.run (); + }); +} + +nano::signal_manager::~signal_manager () +{ + /// Indicate that we have finished with the private io_context. Its + /// io_context::run() function will exit once all other work has completed. + work.reset (); + ioc.stop (); + smthread.join (); +} + +nano::signal_manager::signal_descriptor::signal_descriptor (std::shared_ptr sigset_a, signal_manager & sigman_a, std::function handler_func_a, bool repeat_a) : + sigset (sigset_a), sigman (sigman_a), handler_func (handler_func_a), repeat (repeat_a) +{ +} + +void nano::signal_manager::register_signal_handler (int signum, std::function handler, bool repeat) +{ + // create a signal set to hold the mapping between signals and signal handlers + auto sigset = std::make_shared (ioc, signum); + + // a signal descriptor holds all the data needed by the base handler including the signal set + // working with copies of a descriptor is OK + signal_descriptor descriptor (sigset, *this, handler, repeat); + + // ensure the signal set and descriptors live long enough + descriptor_list.push_back (descriptor); + + // asynchronously listen for signals from this signal set + sigset->async_wait ([descriptor] (const boost::system::error_code & error, int signum) { + nano::signal_manager::base_handler (descriptor, error, signum); + }); + + log (boost::str (boost::format ("Registered signal handler for signal %d") % signum)); +} + +std::function nano::signal_manager::get_debug_files_handler (void) +{ + return [] (int) { + nano::dump_crash_stacktrace (); + nano::create_load_memory_address_files (); + }; +} + +void nano::signal_manager::base_handler (nano::signal_manager::signal_descriptor descriptor, const boost::system::error_code & error, int signum) +{ + if (!error) + { + descriptor.sigman.log (boost::str (boost::format ("Signal received: %d") % signum)); + + // call the user supplied function, if one is provided + if (descriptor.handler_func) + { + descriptor.handler_func (signum); + } + + // continue asynchronously listening for signals from this signal set + if (descriptor.repeat) + { + descriptor.sigset->async_wait (boost::bind (base_handler, descriptor, _1, _2)); + descriptor.sigset->async_wait ([descriptor] (const boost::system::error_code & error, int signum) { + nano::signal_manager::base_handler (descriptor, error, signum); + }); + } + else + { + descriptor.sigman.log (boost::str (boost::format ("Signal handler %d will not repeat") % signum)); + descriptor.sigset->clear (); + } + + descriptor.sigman.log (boost::str (boost::format ("Signal processed: %d") % signum)); + } + else + { + descriptor.sigman.log (boost::str (boost::format ("Signal error: %d (%s)") % error.value () % error.message ())); + } +} diff --git a/nano/lib/signal_manager.hpp b/nano/lib/signal_manager.hpp new file mode 100644 index 0000000000..b667ae561f --- /dev/null +++ b/nano/lib/signal_manager.hpp @@ -0,0 +1,82 @@ +#pragma once + +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace nano +{ +/** + * Manages signal handling and allows to register custom handlers for any signal. + * IMPORTANT NOTE: only one instance of this class should be instantiated per process. + * IMPORTANT NOTE: this is an add-only class, there is currently no way to remove a handler, + although that functionality could be easily be added if needed. + */ +class signal_manager final +{ +public: + /** The signal manager expects to have a boost asio context */ + signal_manager (); + + /** stops the signal manager io context and wait for the thread to finish */ + ~signal_manager (); + + /** Register a handler for a signal to be called from a safe context. + * The handler will be called from the "ioc" io context. + */ + void register_signal_handler (int signum, std::function handler, bool repeat); + + /** returns a signal handler that prints a stacktrace and creates some debug files */ + std::function get_debug_files_handler (void); + +private: + struct signal_descriptor final + { + signal_descriptor (std::shared_ptr sigset_a, signal_manager & sigman_a, std::function handler_func_a, bool repeat_a); + + /** a signal set that maps signals to signal handler and provides the connection to boost asio */ + std::shared_ptr sigset; + + /** reference to the signal manager that owns this signal descriptor */ + signal_manager & sigman; + + /** the caller supplied function to call from the base signal handler */ + std::function handler_func; + + /** indicates if the signal handler should continue handling a signal after receiving one */ + bool repeat; + }; + + /** + * Logging function of signal manager. It does nothing at the moment, it throws away the log. + * I expect to revisit this in the future. It also makes it easy to manually introduce logs, if needed temporarily. + */ + void log (std::string const &){}; + + /** + * This is the actual handler that is registered with boost asio. + * It calls the caller supplied function (if one is given) and sets the handler to repeat (or not). + */ + static void base_handler (nano::signal_manager::signal_descriptor descriptor, const boost::system::error_code & error, int signum); + + /** boost asio context to use */ + boost::asio::io_context ioc; + + /** work object to make the thread run function live as long as a signal manager */ + boost::asio::executor_work_guard work; + + /** a list of descriptors to hold data contexts needed by the asyncronous handlers */ + std::vector descriptor_list; + + /** thread to service the signal manager io context */ + boost::thread smthread; +}; + +} diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index b2dc93f330..eb58015f8d 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -13,26 +14,19 @@ #include -#include #include namespace { -void my_abort_signal_handler (int signum) -{ - std::signal (signum, SIG_DFL); - nano::dump_crash_stacktrace (); - nano::create_load_memory_address_files (); -} - volatile sig_atomic_t sig_int_or_term = 0; } void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano::node_flags const & flags) { // Override segmentation fault and aborting. - std::signal (SIGSEGV, &my_abort_signal_handler); - std::signal (SIGABRT, &my_abort_signal_handler); + nano::signal_manager sigman; + sigman.register_signal_handler (SIGSEGV, sigman.get_debug_files_handler (), false); + sigman.register_signal_handler (SIGABRT, sigman.get_debug_files_handler (), false); boost::filesystem::create_directories (data_path); boost::system::error_code error_chmod; @@ -142,8 +136,11 @@ void nano_daemon::daemon::run (boost::filesystem::path const & data_path, nano:: sig_int_or_term = 1; }; - std::signal (SIGINT, &nano::signal_handler); - std::signal (SIGTERM, &nano::signal_handler); + // keep trapping Ctrl-C to avoid a second Ctrl-C interrupting tasks started by the first + sigman.register_signal_handler (SIGINT, &nano::signal_handler, true); + + // sigterm is less likely to come in bunches so only trap it once + sigman.register_signal_handler (SIGTERM, &nano::signal_handler, false); runner = std::make_unique (io_ctx, node->config.io_threads); runner->join (); diff --git a/nano/nano_rpc/entry.cpp b/nano/nano_rpc/entry.cpp index 5597a7196f..26f342478e 100644 --- a/nano/nano_rpc/entry.cpp +++ b/nano/nano_rpc/entry.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -13,8 +14,6 @@ #include #include -#include - namespace { void logging_init (boost::filesystem::path const & application_path_a) @@ -47,6 +46,7 @@ void run (boost::filesystem::path const & data_path, std::vector co { logging_init (data_path); boost::asio::io_context io_ctx; + nano::signal_manager sigman; try { nano::ipc_rpc_processor ipc_rpc_processor (io_ctx, rpc_config); @@ -59,8 +59,8 @@ void run (boost::filesystem::path const & data_path, std::vector co sig_int_or_term = 1; }; - std::signal (SIGINT, &nano::signal_handler); - std::signal (SIGTERM, &nano::signal_handler); + sigman.register_signal_handler (SIGINT, &nano::signal_handler, true); + sigman.register_signal_handler (SIGTERM, &nano::signal_handler, false); runner = std::make_unique (io_ctx, rpc_config.rpc_process.io_threads); runner->join (); From 6d2728905a248f931b2d09ad442534a51a08ba66 Mon Sep 17 00:00:00 2001 From: Thiago Silva <82097354+thsfs@users.noreply.github.com> Date: Thu, 22 Apr 2021 13:37:06 -0300 Subject: [PATCH 2/4] Refactory of block processor thread (#3221) * Refactory of block processor thread * Apply clang-format * Remove block processor thread from node class * Better name for the thread variable --- nano/node/blockprocessor.cpp | 8 ++++++++ nano/node/blockprocessor.hpp | 2 ++ nano/node/node.cpp | 10 ---------- nano/node/node.hpp | 2 -- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 7888a3a96b..b0ddb686c5 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -44,11 +44,19 @@ nano::block_processor::block_processor (nano::node & node_a, nano::write_databas this->condition.notify_all (); } }; + processing_thread = std::thread ([this] () { + nano::thread_role::set (nano::thread_role::name::block_processing); + this->process_blocks (); + }); } nano::block_processor::~block_processor () { stop (); + if (processing_thread.joinable ()) + { + processing_thread.join (); + } } void nano::block_processor::stop () diff --git a/nano/node/blockprocessor.hpp b/nano/node/blockprocessor.hpp index 27f754592e..59dbaf784a 100644 --- a/nano/node/blockprocessor.hpp +++ b/nano/node/blockprocessor.hpp @@ -12,6 +12,7 @@ #include #include +#include #include namespace nano @@ -88,6 +89,7 @@ class block_processor final nano::write_database_queue & write_database_queue; nano::mutex mutex{ mutex_identifier (mutexes::block_processor) }; nano::state_block_signature_verification state_block_signature_verification; + std::thread processing_thread; friend std::unique_ptr collect_container_info (block_processor & block_processor, std::string const & name); }; diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 8a4a1aa8c7..26b57f05bf 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -112,12 +112,6 @@ nano::node::node (boost::asio::io_context & io_ctx_a, boost::filesystem::path co vote_processor (checker, active, observers, stats, config, flags, logger, online_reps, rep_crawler, ledger, network_params), warmed_up (0), block_processor (*this, write_database_queue), - // clang-format off -block_processor_thread ([this]() { - nano::thread_role::set (nano::thread_role::name::block_processing); - this->block_processor.process_blocks (); -}), - // clang-format on online_reps (ledger, config), history{ config.network_params.voting }, vote_uniquer (block_uniquer), @@ -667,10 +661,6 @@ void nano::node::stop () // No tasks may wait for work generation in I/O threads, or termination signal capturing will be unable to call node::stop() distributed_work.stop (); block_processor.stop (); - if (block_processor_thread.joinable ()) - { - block_processor_thread.join (); - } aggregator.stop (); vote_processor.stop (); active.stop (); diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 9972791514..101f486c8f 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -37,7 +37,6 @@ #include #include -#include #include namespace nano @@ -179,7 +178,6 @@ class node final : public std::enable_shared_from_this nano::vote_processor vote_processor; unsigned warmed_up; nano::block_processor block_processor; - std::thread block_processor_thread; nano::block_arrival block_arrival; nano::local_vote_history history; nano::keypair node_id; From 95064c79a61ab52a305f2c24ec61ca97b90d3d1b Mon Sep 17 00:00:00 2001 From: theohax <81556890+theohax@users.noreply.github.com> Date: Sun, 25 Apr 2021 12:55:14 +0300 Subject: [PATCH 3/4] Modernize unit tests: construct state blocks via builder (#3188) * Modernize bootstrap.cpp unit tests -- construct state blocks via builder * Add new line at end of bootstrap.cpp file * Merging and applying new formatting rules. * More unit test modernizing * Fix formatting Co-authored-by: clemahieu --- nano/core_test/block.cpp | 153 ++++--- nano/core_test/bootstrap.cpp | 648 +++++++++++++++++++++++++++--- nano/core_test/network_filter.cpp | 23 +- nano/core_test/websocket.cpp | 107 ++++- nano/core_test/work_watcher.cpp | 24 +- 5 files changed, 836 insertions(+), 119 deletions(-) diff --git a/nano/core_test/block.cpp b/nano/core_test/block.cpp index 88b8766d31..cd9e1f38d1 100644 --- a/nano/core_test/block.cpp +++ b/nano/core_test/block.cpp @@ -319,16 +319,25 @@ TEST (state_block, serialization) { nano::keypair key1; nano::keypair key2; - nano::state_block block1 (key1.pub, 1, key2.pub, 2, 4, key1.prv, key1.pub, 5); - ASSERT_EQ (key1.pub, block1.hashables.account); - ASSERT_EQ (nano::block_hash (1), block1.previous ()); - ASSERT_EQ (key2.pub, block1.hashables.representative); - ASSERT_EQ (nano::amount (2), block1.hashables.balance); - ASSERT_EQ (nano::uint256_union (4), block1.hashables.link); + nano::state_block_builder builder; + auto block1 = builder + .account (key1.pub) + .previous (1) + .representative (key2.pub) + .balance (2) + .link (4) + .sign (key1.prv, key1.pub) + .work (5) + .build_shared (); + ASSERT_EQ (key1.pub, block1->hashables.account); + ASSERT_EQ (nano::block_hash (1), block1->previous ()); + ASSERT_EQ (key2.pub, block1->hashables.representative); + ASSERT_EQ (nano::amount (2), block1->hashables.balance); + ASSERT_EQ (nano::uint256_union (4), block1->hashables.link); std::vector bytes; { nano::vectorstream stream (bytes); - block1.serialize (stream); + block1->serialize (stream); } ASSERT_EQ (0x5, bytes[215]); // Ensure work is serialized big-endian ASSERT_EQ (nano::state_block::size, bytes.size ()); @@ -336,7 +345,7 @@ TEST (state_block, serialization) nano::bufferstream stream (bytes.data (), bytes.size ()); nano::state_block block2 (error1, stream); ASSERT_FALSE (error1); - ASSERT_EQ (block1, block2); + ASSERT_EQ (*block1, block2); block2.hashables.account.clear (); block2.hashables.previous.clear (); block2.hashables.representative.clear (); @@ -346,16 +355,16 @@ TEST (state_block, serialization) block2.work = 0; nano::bufferstream stream2 (bytes.data (), bytes.size ()); ASSERT_FALSE (block2.deserialize (stream2)); - ASSERT_EQ (block1, block2); + ASSERT_EQ (*block1, block2); std::string json; - block1.serialize_json (json); + block1->serialize_json (json); std::stringstream body (json); boost::property_tree::ptree tree; boost::property_tree::read_json (body, tree); bool error2 (false); nano::state_block block3 (error2, tree); ASSERT_FALSE (error2); - ASSERT_EQ (block1, block3); + ASSERT_EQ (*block1, block3); block3.hashables.account.clear (); block3.hashables.previous.clear (); block3.hashables.representative.clear (); @@ -364,45 +373,54 @@ TEST (state_block, serialization) block3.signature.clear (); block3.work = 0; ASSERT_FALSE (block3.deserialize_json (tree)); - ASSERT_EQ (block1, block3); + ASSERT_EQ (*block1, block3); } TEST (state_block, hashing) { nano::keypair key; - nano::state_block block (key.pub, 0, key.pub, 0, 0, key.prv, key.pub, 0); - auto hash (block.hash ()); - ASSERT_EQ (hash, block.hash ()); // check cache works - block.hashables.account.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_NE (hash, block.hash ()); - block.hashables.account.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_EQ (hash, block.hash ()); - block.hashables.previous.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_NE (hash, block.hash ()); - block.hashables.previous.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_EQ (hash, block.hash ()); - block.hashables.representative.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_NE (hash, block.hash ()); - block.hashables.representative.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_EQ (hash, block.hash ()); - block.hashables.balance.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_NE (hash, block.hash ()); - block.hashables.balance.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_EQ (hash, block.hash ()); - block.hashables.link.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_NE (hash, block.hash ()); - block.hashables.link.bytes[0] ^= 0x1; - block.refresh (); - ASSERT_EQ (hash, block.hash ()); + nano::state_block_builder builder; + auto block = builder + .account (key.pub) + .previous (0) + .representative (key.pub) + .balance (0) + .link (0) + .sign (key.prv, key.pub) + .work (0) + .build_shared (); + auto hash (block->hash ()); + ASSERT_EQ (hash, block->hash ()); // check cache works + block->hashables.account.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_NE (hash, block->hash ()); + block->hashables.account.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_EQ (hash, block->hash ()); + block->hashables.previous.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_NE (hash, block->hash ()); + block->hashables.previous.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_EQ (hash, block->hash ()); + block->hashables.representative.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_NE (hash, block->hash ()); + block->hashables.representative.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_EQ (hash, block->hash ()); + block->hashables.balance.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_NE (hash, block->hash ()); + block->hashables.balance.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_EQ (hash, block->hash ()); + block->hashables.link.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_NE (hash, block->hash ()); + block->hashables.link.bytes[0] ^= 0x1; + block->refresh (); + ASSERT_EQ (hash, block->hash ()); } TEST (blocks, work_version) @@ -423,7 +441,16 @@ TEST (block_uniquer, null) TEST (block_uniquer, single) { nano::keypair key; - auto block1 (std::make_shared (0, 0, 0, 0, 0, key.prv, key.pub, 0)); + nano::state_block_builder builder; + auto block1 = builder + .account (0) + .previous (0) + .representative (0) + .balance (0) + .link (0) + .sign (key.prv, key.pub) + .work (0) + .build_shared (); auto block2 (std::make_shared (*block1)); ASSERT_NE (block1, block2); ASSERT_EQ (*block1, *block2); @@ -441,8 +468,27 @@ TEST (block_uniquer, single) TEST (block_uniquer, cleanup) { nano::keypair key; - auto block1 (std::make_shared (0, 0, 0, 0, 0, key.prv, key.pub, 0)); - auto block2 (std::make_shared (0, 0, 0, 0, 0, key.prv, key.pub, 1)); + nano::state_block_builder builder; + auto block1 = builder + .account (0) + .previous (0) + .representative (0) + .balance (0) + .link (0) + .sign (key.prv, key.pub) + .work (0) + .build_shared (); + auto block2 = builder + .make_block () + .account (0) + .previous (0) + .representative (0) + .balance (0) + .link (0) + .sign (key.prv, key.pub) + .work (1) + .build_shared (); + nano::block_uniquer uniquer; auto block3 (uniquer.unique (block1)); auto block4 (uniquer.unique (block2)); @@ -482,8 +528,17 @@ TEST (block_builder, zeroed_state_block) { nano::block_builder builder; nano::keypair key; + nano::state_block_builder state_builder; // Make sure manually- and builder constructed all-zero blocks have equal hashes, and check signature. - auto zero_block_manual (std::make_shared (0, 0, 0, 0, 0, key.prv, key.pub, 0)); + auto zero_block_manual = state_builder + .account (0) + .previous (0) + .representative (0) + .balance (0) + .link (0) + .sign (key.prv, key.pub) + .work (0) + .build_shared (); auto zero_block_build = builder.state ().zero ().sign (key.prv, key.pub).build (); ASSERT_TRUE (zero_block_manual->hash () == zero_block_build->hash ()); ASSERT_FALSE (nano::validate_message (key.pub, zero_block_build->hash (), zero_block_build->signature)); diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index dd11dc54f6..05a9a49a06 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -249,9 +249,29 @@ TEST (bootstrap_processor, process_state) node_flags.disable_bootstrap_bulk_push_client = true; auto node0 (system.add_node (config, node_flags)); nano::genesis genesis; + nano::state_block_builder builder; + system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); - auto block1 (std::make_shared (nano::dev_genesis_key.pub, node0->latest (nano::dev_genesis_key.pub), nano::dev_genesis_key.pub, nano::genesis_amount - 100, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); - auto block2 (std::make_shared (nano::dev_genesis_key.pub, block1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount, block1->hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); + auto block1 = builder + .account (nano::dev_genesis_key.pub) + .previous (node0->latest (nano::dev_genesis_key.pub)) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 100) + .link (nano::dev_genesis_key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (0) + .build_shared (); + auto block2 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (block1->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount) + .link (block1->hash ()) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (0) + .build_shared (); + node0->work_generate_blocking (*block1); node0->work_generate_blocking (*block2); node0->process (*block1); @@ -335,7 +355,18 @@ TEST (bootstrap_processor, DISABLED_pull_requeue_network_error) auto node2 (system.add_node (config, node_flags)); nano::genesis genesis; nano::keypair key1; - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ()))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (genesis.hash ())) + .build_shared (); node1->bootstrap_initiator.bootstrap (node2->network.endpoint ()); auto attempt (node1->bootstrap_initiator.current_attempt ()); @@ -346,7 +377,7 @@ TEST (bootstrap_processor, DISABLED_pull_requeue_network_error) nano::unique_lock lock (node1->bootstrap_initiator.connections->mutex); ASSERT_FALSE (attempt->stopped); ++attempt->pulling; - node1->bootstrap_initiator.connections->pulls.push_back (nano::pull_info (nano::dev_genesis_key.pub, send1->hash (), genesis.hash (), attempt->incremental_id)); + node1->bootstrap_initiator.connections->pulls.emplace_back (nano::dev_genesis_key.pub, send1->hash (), genesis.hash (), attempt->incremental_id); node1->bootstrap_initiator.connections->request_pull (lock); node2->stop (); } @@ -459,10 +490,49 @@ TEST (bootstrap_processor, lazy_hash) nano::keypair key1; nano::keypair key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (genesis.hash ()))); - auto receive1 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, *node0->work_generate_blocking (key1.pub))); - auto send2 (std::make_shared (key1.pub, receive1->hash (), key1.pub, 0, key2.pub, key1.prv, key1.pub, *node0->work_generate_blocking (receive1->hash ()))); - auto receive2 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *node0->work_generate_blocking (key2.pub))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (genesis.hash ())) + .build_shared (); + auto receive1 = builder + .make_block () + .account (key1.pub) + .previous (0) + .representative (key1.pub) + .balance (nano::Gxrb_ratio) + .link (send1->hash ()) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (key1.pub)) + .build_shared (); + auto send2 = builder + .make_block () + .account (key1.pub) + .previous (receive1->hash ()) + .representative (key1.pub) + .balance (0) + .link (key2.pub) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (receive1->hash ())) + .build_shared (); + auto receive2 = builder + .make_block () + .account (key2.pub) + .previous (0) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key2.prv, key2.pub) + .work (*node0->work_generate_blocking (key2.pub)) + .build_shared (); + // Processing test chain node0->block_processor.add (send1); node0->block_processor.add (receive1); @@ -495,10 +565,49 @@ TEST (bootstrap_processor, lazy_hash_bootstrap_id) nano::keypair key1; nano::keypair key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (genesis.hash ()))); - auto receive1 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, *node0->work_generate_blocking (key1.pub))); - auto send2 (std::make_shared (key1.pub, receive1->hash (), key1.pub, 0, key2.pub, key1.prv, key1.pub, *node0->work_generate_blocking (receive1->hash ()))); - auto receive2 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *node0->work_generate_blocking (key2.pub))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (genesis.hash ())) + .build_shared (); + auto receive1 = builder + .make_block () + .account (key1.pub) + .previous (0) + .representative (key1.pub) + .balance (nano::Gxrb_ratio) + .link (send1->hash ()) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (key1.pub)) + .build_shared (); + auto send2 = builder + .make_block () + .account (key1.pub) + .previous (receive1->hash ()) + .representative (key1.pub) + .balance (0) + .link (key2.pub) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (receive1->hash ())) + .build_shared (); + auto receive2 = builder + .make_block () + .account (key2.pub) + .previous (0) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key2.prv, key2.pub) + .work (*node0->work_generate_blocking (key2.pub)) + .build_shared (); + // Processing test chain node0->block_processor.add (send1); node0->block_processor.add (receive1); @@ -533,14 +642,89 @@ TEST (bootstrap_processor, lazy_hash_pruning) nano::keypair key1; nano::keypair key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (genesis.hash ()))); - auto receive1 (std::make_shared (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount, send1->hash (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (send1->hash ()))); - auto change1 (std::make_shared (nano::dev_genesis_key.pub, receive1->hash (), key1.pub, nano::genesis_amount, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (receive1->hash ()))); - auto change2 (std::make_shared (nano::dev_genesis_key.pub, change1->hash (), key2.pub, nano::genesis_amount, 0, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (change1->hash ()))); - auto send2 (std::make_shared (nano::dev_genesis_key.pub, change2->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (change2->hash ()))); - auto receive2 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send2->hash (), key1.prv, key1.pub, *node0->work_generate_blocking (key1.pub))); - auto send3 (std::make_shared (key1.pub, receive2->hash (), key1.pub, 0, key2.pub, key1.prv, key1.pub, *node0->work_generate_blocking (receive2->hash ()))); - auto receive3 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send3->hash (), key2.prv, key2.pub, *node0->work_generate_blocking (key2.pub))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (nano::dev_genesis_key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (genesis.hash ())) + .build_shared (); + auto receive1 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (send1->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount) + .link (send1->hash ()) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (send1->hash ())) + .build_shared (); + auto change1 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (receive1->hash ()) + .representative (key1.pub) + .balance (nano::genesis_amount) + .link (0) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (receive1->hash ())) + .build_shared (); + auto change2 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (change1->hash ()) + .representative (key2.pub) + .balance (nano::genesis_amount) + .link (0) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (change1->hash ())) + .build_shared (); + auto send2 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (change2->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (change2->hash ())) + .build_shared (); + auto receive2 = builder + .make_block () + .account (key1.pub) + .previous (0) + .representative (key1.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (key1.pub)) + .build_shared (); + auto send3 = builder + .make_block () + .account (key1.pub) + .previous (receive2->hash ()) + .representative (key1.pub) + .balance (0) + .link (key2.pub) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (receive2->hash ())) + .build_shared (); + auto receive3 = builder + .make_block () + .account (key2.pub) + .previous (0) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (send3->hash ()) + .sign (key2.prv, key2.pub) + .work (*node0->work_generate_blocking (key2.pub)) + .build_shared (); + // Processing test chain node0->block_processor.add (send1); node0->block_processor.add (receive1); @@ -592,13 +776,78 @@ TEST (bootstrap_processor, lazy_max_pull_count) nano::keypair key1; nano::keypair key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (genesis.hash ()))); - auto receive1 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, *node0->work_generate_blocking (key1.pub))); - auto send2 (std::make_shared (key1.pub, receive1->hash (), key1.pub, 0, key2.pub, key1.prv, key1.pub, *node0->work_generate_blocking (receive1->hash ()))); - auto receive2 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *node0->work_generate_blocking (key2.pub))); - auto change1 (std::make_shared (key2.pub, receive2->hash (), key1.pub, nano::Gxrb_ratio, 0, key2.prv, key2.pub, *node0->work_generate_blocking (receive2->hash ()))); - auto change2 (std::make_shared (key2.pub, change1->hash (), nano::dev_genesis_key.pub, nano::Gxrb_ratio, 0, key2.prv, key2.pub, *node0->work_generate_blocking (change1->hash ()))); - auto change3 (std::make_shared (key2.pub, change2->hash (), key2.pub, nano::Gxrb_ratio, 0, key2.prv, key2.pub, *node0->work_generate_blocking (change2->hash ()))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (genesis.hash ())) + .build_shared (); + auto receive1 = builder + .make_block () + .account (key1.pub) + .previous (0) + .representative (key1.pub) + .balance (nano::Gxrb_ratio) + .link (send1->hash ()) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (key1.pub)) + .build_shared (); + auto send2 = builder + .make_block () + .account (key1.pub) + .previous (receive1->hash ()) + .representative (key1.pub) + .balance (0) + .link (key2.pub) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (receive1->hash ())) + .build_shared (); + auto receive2 = builder + .make_block () + .account (key2.pub) + .previous (0) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key2.prv, key2.pub) + .work (*node0->work_generate_blocking (key2.pub)) + .build_shared (); + auto change1 = builder + .make_block () + .account (key2.pub) + .previous (receive2->hash ()) + .representative (key1.pub) + .balance (nano::Gxrb_ratio) + .link (0) + .sign (key2.prv, key2.pub) + .work (*node0->work_generate_blocking (receive2->hash ())) + .build_shared (); + auto change2 = builder + .make_block () + .account (key2.pub) + .previous (change1->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::Gxrb_ratio) + .link (0) + .sign (key2.prv, key2.pub) + .work (*node0->work_generate_blocking (change1->hash ())) + .build_shared (); + auto change3 = builder + .make_block () + .account (key2.pub) + .previous (change2->hash ()) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (0) + .sign (key2.prv, key2.pub) + .work (*node0->work_generate_blocking (change2->hash ())) + .build_shared (); // Processing test chain node0->block_processor.add (send1); node0->block_processor.add (receive1); @@ -630,13 +879,42 @@ TEST (bootstrap_processor, lazy_unclear_state_link) nano::genesis genesis; nano::keypair key; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ()))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (genesis.hash ())) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); - auto send2 (std::make_shared (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send1->hash ()))); + auto send2 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (send1->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (send1->hash ())) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code); auto open (std::make_shared (send1->hash (), key.pub, key.pub, key.prv, key.pub, *system.work.generate (key.pub))); ASSERT_EQ (nano::process_result::progress, node1->process (*open).code); - auto receive (std::make_shared (key.pub, open->hash (), key.pub, 2 * nano::Gxrb_ratio, send2->hash (), key.prv, key.pub, *system.work.generate (open->hash ()))); // It is not possible to define this block send/receive status based on previous block (legacy open) + auto receive = builder + .make_block () + .account (key.pub) + .previous (open->hash ()) + .representative (key.pub) + .balance (2 * nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key.prv, key.pub) + .work (*system.work.generate (open->hash ())) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node1->process (*receive).code); // Start lazy bootstrap with last block in chain known auto node2 = system.add_node (nano::node_config (nano::get_available_port (), system.logging), node_flags); @@ -664,12 +942,33 @@ TEST (bootstrap_processor, lazy_unclear_state_link_not_existing) nano::genesis genesis; nano::keypair key, key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ()))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (genesis.hash ())) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); auto open (std::make_shared (send1->hash (), key.pub, key.pub, key.prv, key.pub, *system.work.generate (key.pub))); ASSERT_EQ (nano::process_result::progress, node1->process (*open).code); - auto send2 (std::make_shared (key.pub, open->hash (), key.pub, 0, key2.pub, key.prv, key.pub, *system.work.generate (open->hash ()))); // It is not possible to define this block send/receive status based on previous block (legacy open) + auto send2 = builder + .make_block () + .account (key.pub) + .previous (open->hash ()) + .representative (key.pub) + .balance (0) + .link (key2.pub) + .sign (key.prv, key.pub) + .work (*system.work.generate (open->hash ())) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code); + // Start lazy bootstrap with last block in chain known auto node2 = system.add_node (nano::node_config (nano::get_available_port (), system.logging), node_flags); node2->network.udp_channels.insert (node1->network.endpoint (), node1->network_params.protocol.protocol_version); @@ -695,14 +994,44 @@ TEST (bootstrap_processor, DISABLED_lazy_destinations) nano::genesis genesis; nano::keypair key1, key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ()))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (genesis.hash ())) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); - auto send2 (std::make_shared (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key2.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send1->hash ()))); + auto send2 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (send1->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) + .link (key2.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (send1->hash ())) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code); auto open (std::make_shared (send1->hash (), key1.pub, key1.pub, key1.prv, key1.pub, *system.work.generate (key1.pub))); ASSERT_EQ (nano::process_result::progress, node1->process (*open).code); - auto state_open (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *system.work.generate (key2.pub))); + auto state_open = builder + .make_block () + .account (key2.pub) + .previous (0) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key2.prv, key2.pub) + .work (*system.work.generate (key2.pub)) + .build_shared (); ASSERT_EQ (nano::process_result::progress, node1->process (*state_open).code); + // Start lazy bootstrap with last block in sender chain auto node2 = system.add_node (nano::node_config (nano::get_available_port (), system.logging), node_flags); node2->network.udp_channels.insert (node1->network.endpoint (), node1->network_params.protocol.protocol_version); @@ -730,13 +1059,43 @@ TEST (bootstrap_processor, lazy_pruning_missing_block) nano::genesis genesis; nano::keypair key1, key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ()))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (genesis.hash ())) + .build_shared (); node1->process_active (send1); - auto send2 (std::make_shared (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key2.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (send1->hash ()))); + auto send2 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (send1->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) + .link (key2.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (send1->hash ())) + .build_shared (); node1->process_active (send2); auto open (std::make_shared (send1->hash (), key1.pub, key1.pub, key1.prv, key1.pub, *system.work.generate (key1.pub))); node1->process_active (open); - auto state_open (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *system.work.generate (key2.pub))); + auto state_open = builder + .make_block () + .account (key2.pub) + .previous (0) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key2.prv, key2.pub) + .work (*system.work.generate (key2.pub)) + .build_shared (); + node1->process_active (state_open); // Confirm last block to prune previous nano::blocks_confirm (*node1, { send1, send2, open, state_open }, true); @@ -796,7 +1155,19 @@ TEST (bootstrap_processor, lazy_cancel) nano::genesis genesis; nano::keypair key1; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (genesis.hash ()))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (genesis.hash ())) + .build_shared (); + // Start lazy bootstrap with last block in chain known auto node1 (std::make_shared (system.io_ctx, nano::get_available_port (), nano::unique_path (), system.logging, system.work)); node1->network.udp_channels.insert (node0->network.endpoint (), node1->network_params.protocol.protocol_version); @@ -824,10 +1195,49 @@ TEST (bootstrap_processor, wallet_lazy_frontier) nano::keypair key1; nano::keypair key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (genesis.hash ()))); - auto receive1 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, *node0->work_generate_blocking (key1.pub))); - auto send2 (std::make_shared (key1.pub, receive1->hash (), key1.pub, 0, key2.pub, key1.prv, key1.pub, *node0->work_generate_blocking (receive1->hash ()))); - auto receive2 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *node0->work_generate_blocking (key2.pub))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (genesis.hash ())) + .build_shared (); + auto receive1 = builder + .make_block () + .account (key1.pub) + .previous (0) + .representative (key1.pub) + .balance (nano::Gxrb_ratio) + .link (send1->hash ()) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (key1.pub)) + .build_shared (); + auto send2 = builder + .make_block () + .account (key1.pub) + .previous (receive1->hash ()) + .representative (key1.pub) + .balance (0) + .link (key2.pub) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (receive1->hash ())) + .build_shared (); + auto receive2 = builder + .make_block () + .account (key2.pub) + .previous (0) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key2.prv, key2.pub) + .work (*node0->work_generate_blocking (key2.pub)) + .build_shared (); + // Processing test chain node0->block_processor.add (send1); node0->block_processor.add (receive1); @@ -864,9 +1274,39 @@ TEST (bootstrap_processor, wallet_lazy_pending) nano::keypair key1; nano::keypair key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node0->work_generate_blocking (genesis.hash ()))); - auto receive1 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, *node0->work_generate_blocking (key1.pub))); - auto send2 (std::make_shared (key1.pub, receive1->hash (), key1.pub, 0, key2.pub, key1.prv, key1.pub, *node0->work_generate_blocking (receive1->hash ()))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node0->work_generate_blocking (genesis.hash ())) + .build_shared (); + auto receive1 = builder + .make_block () + .account (key1.pub) + .previous (0) + .representative (key1.pub) + .balance (nano::Gxrb_ratio) + .link (send1->hash ()) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (key1.pub)) + .build_shared (); + auto send2 = builder + .make_block () + .account (key1.pub) + .previous (receive1->hash ()) + .representative (key1.pub) + .balance (0) + .link (key2.pub) + .sign (key1.prv, key1.pub) + .work (*node0->work_generate_blocking (receive1->hash ())) + .build_shared (); + // Processing test chain node0->block_processor.add (send1); node0->block_processor.add (receive1); @@ -896,10 +1336,49 @@ TEST (bootstrap_processor, multiple_attempts) nano::keypair key1; nano::keypair key2; // Generating test chain - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *node1->work_generate_blocking (genesis.hash ()))); - auto receive1 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, *node1->work_generate_blocking (key1.pub))); - auto send2 (std::make_shared (key1.pub, receive1->hash (), key1.pub, 0, key2.pub, key1.prv, key1.pub, *node1->work_generate_blocking (receive1->hash ()))); - auto receive2 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *node1->work_generate_blocking (key2.pub))); + + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*node1->work_generate_blocking (genesis.hash ())) + .build_shared (); + auto receive1 = builder + .make_block () + .account (key1.pub) + .previous (0) + .representative (key1.pub) + .balance (nano::Gxrb_ratio) + .link (send1->hash ()) + .sign (key1.prv, key1.pub) + .work (*node1->work_generate_blocking (key1.pub)) + .build_shared (); + auto send2 = builder + .make_block () + .account (key1.pub) + .previous (receive1->hash ()) + .representative (key1.pub) + .balance (0) + .link (key2.pub) + .sign (key1.prv, key1.pub) + .work (*node1->work_generate_blocking (receive1->hash ())) + .build_shared (); + auto receive2 = builder + .make_block () + .account (key2.pub) + .previous (0) + .representative (key2.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key2.prv, key2.pub) + .work (*node1->work_generate_blocking (key2.pub)) + .build_shared (); + // Processing test chain node1->block_processor.add (send1); node1->block_processor.add (receive1); @@ -980,10 +1459,29 @@ TEST (frontier_req, count) nano::genesis genesis; // Public key FB93... after genesis in accounts table nano::keypair key1 ("ED5AE0A6505B14B67435C29FD9FEEBC26F597D147BC92F6D795FFAD7AFD3D967"); - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (0) + .build_shared (); node1->work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); - auto receive1 (std::make_shared (key1.pub, 0, nano::dev_genesis_key.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, 0)); + auto receive1 = builder + .make_block () + .account (key1.pub) + .previous (0) + .representative (nano::dev_genesis_key.pub) + .balance (nano::Gxrb_ratio) + .link (send1->hash ()) + .sign (key1.prv, key1.pub) + .work (0) + .build_shared (); node1->work_generate_blocking (*receive1); ASSERT_EQ (nano::process_result::progress, node1->process (*receive1).code); @@ -1064,17 +1562,53 @@ TEST (frontier_req, confirmed_frontier) priv_key = nano::keypair ().prv; } nano::keypair key_after_genesis (priv_key.to_string ()); - - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key_before_genesis.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); + nano::state_block_builder builder; + + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key_before_genesis.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (0) + .build_shared (); node1->work_generate_blocking (*send1); ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); - auto send2 (std::make_shared (nano::dev_genesis_key.pub, send1->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key_after_genesis.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); + auto send2 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (send1->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) + .link (key_after_genesis.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (0) + .build_shared (); node1->work_generate_blocking (*send2); ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code); - auto receive1 (std::make_shared (key_before_genesis.pub, 0, nano::dev_genesis_key.pub, nano::Gxrb_ratio, send1->hash (), key_before_genesis.prv, key_before_genesis.pub, 0)); + auto receive1 = builder + .make_block () + .account (key_before_genesis.pub) + .previous (0) + .representative (nano::dev_genesis_key.pub) + .balance (nano::Gxrb_ratio) + .link (send1->hash ()) + .sign (key_before_genesis.prv, key_before_genesis.pub) + .work (0) + .build_shared (); node1->work_generate_blocking (*receive1); ASSERT_EQ (nano::process_result::progress, node1->process (*receive1).code); - auto receive2 (std::make_shared (key_after_genesis.pub, 0, nano::dev_genesis_key.pub, nano::Gxrb_ratio, send2->hash (), key_after_genesis.prv, key_after_genesis.pub, 0)); + auto receive2 = builder + .make_block () + .account (key_after_genesis.pub) + .previous (0) + .representative (nano::dev_genesis_key.pub) + .balance (nano::Gxrb_ratio) + .link (send2->hash ()) + .sign (key_after_genesis.prv, key_after_genesis.pub) + .work (0) + .build_shared (); node1->work_generate_blocking (*receive2); ASSERT_EQ (nano::process_result::progress, node1->process (*receive2).code); diff --git a/nano/core_test/network_filter.cpp b/nano/core_test/network_filter.cpp index 5770d83ff4..7129f7d588 100644 --- a/nano/core_test/network_filter.cpp +++ b/nano/core_test/network_filter.cpp @@ -37,7 +37,17 @@ TEST (network_filter, unit) { one_block (genesis.open, true); } - auto new_block (std::make_shared (nano::dev_genesis_key.pub, genesis.open->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - 10 * nano::xrb_ratio, nano::public_key (), nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); + nano::state_block_builder builder; + auto new_block = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.open->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 10 * nano::xrb_ratio) + .link (nano::public_key ()) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (0) + .build_shared (); + one_block (new_block, false); for (int i = 0; i < 10; ++i) { @@ -55,9 +65,18 @@ TEST (network_filter, many) nano::genesis genesis; nano::network_filter filter (4); nano::keypair key1; + nano::state_block_builder builder; for (int i = 0; i < 100; ++i) { - auto block (std::make_shared (nano::dev_genesis_key.pub, genesis.open->hash (), nano::dev_genesis_key.pub, nano::genesis_amount - i * 10 * nano::xrb_ratio, key1.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, 0)); + auto block = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.open->hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - i * 10 * nano::xrb_ratio) + .link (key1.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (0) + .build_shared (); nano::publish message (block); auto bytes (message.to_bytes ()); diff --git a/nano/core_test/websocket.cpp b/nano/core_test/websocket.cpp index b7fec3e16d..414c54fcac 100644 --- a/nano/core_test/websocket.cpp +++ b/nano/core_test/websocket.cpp @@ -167,9 +167,19 @@ TEST (websocket, confirmation) // Quick confirm a state block { + nano::state_block_builder builder; nano::block_hash previous (node1->latest (nano::dev_genesis_key.pub)); balance -= send_amount; - auto send (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, balance, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); + auto send = builder + .account (nano::dev_genesis_key.pub) + .previous (previous) + .representative (nano::dev_genesis_key.pub) + .balance (balance) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (previous)) + .build_shared (); + node1->process_active (send); } @@ -251,7 +261,17 @@ TEST (websocket, confirmation_options) nano::block_hash previous (node1->latest (nano::dev_genesis_key.pub)); { balance -= send_amount; - auto send (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, balance, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); + nano::state_block_builder builder; + auto send = builder + .account (nano::dev_genesis_key.pub) + .previous (previous) + .representative (nano::dev_genesis_key.pub) + .balance (balance) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (previous)) + .build_shared (); + node1->process_active (send); previous = send->hash (); } @@ -274,7 +294,17 @@ TEST (websocket, confirmation_options) // Quick-confirm another block { balance -= send_amount; - auto send (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, balance, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); + nano::state_block_builder builder; + auto send = builder + .account (nano::dev_genesis_key.pub) + .previous (previous) + .representative (nano::dev_genesis_key.pub) + .balance (balance) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (previous)) + .build_shared (); + node1->process_active (send); previous = send->hash (); } @@ -363,8 +393,18 @@ TEST (websocket, confirmation_options_votes) auto send_amount = node1->config.online_weight_minimum.number () + 1; nano::block_hash previous (node1->latest (nano::dev_genesis_key.pub)); { + nano::state_block_builder builder; balance -= send_amount; - auto send (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, balance, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); + auto send = builder + .account (nano::dev_genesis_key.pub) + .previous (previous) + .representative (nano::dev_genesis_key.pub) + .balance (balance) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (previous)) + .build_shared (); + node1->process_active (send); previous = send->hash (); } @@ -453,8 +493,18 @@ TEST (websocket, confirmation_options_update) system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::genesis genesis; nano::keypair key; + nano::state_block_builder builder; auto previous (node1->latest (nano::dev_genesis_key.pub)); - auto send (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); + auto send = builder + .account (nano::dev_genesis_key.pub) + .previous (previous) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Gxrb_ratio) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (previous)) + .build_shared (); + node1->process_active (send); // Wait for delete acknowledgement @@ -462,7 +512,17 @@ TEST (websocket, confirmation_options_update) // Confirm another block previous = send->hash (); - auto send2 (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); + auto send2 = builder + .make_block () + .account (nano::dev_genesis_key.pub) + .previous (previous) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 2 * nano::Gxrb_ratio) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (previous)) + .build_shared (); + node1->process_active (send2); ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready); @@ -492,9 +552,19 @@ TEST (websocket, vote) // Quick-confirm a block nano::keypair key; + nano::state_block_builder builder; system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); nano::block_hash previous (node1->latest (nano::dev_genesis_key.pub)); - auto send (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, nano::genesis_amount - (node1->online_reps.delta () + 1), key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); + auto send = builder + .account (nano::dev_genesis_key.pub) + .previous (previous) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - (node1->online_reps.delta () + 1)) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (previous)) + .build_shared (); + node1->process_active (send); ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready); @@ -581,13 +651,22 @@ TEST (websocket, vote_options_representatives) // Quick-confirm a block nano::keypair key; + nano::state_block_builder builder; auto balance = nano::genesis_amount; system.wallet (0)->insert_adhoc (nano::dev_genesis_key.prv); auto send_amount = node1->online_reps.delta () + 1; auto confirm_block = [&] () { nano::block_hash previous (node1->latest (nano::dev_genesis_key.pub)); balance -= send_amount; - auto send (std::make_shared (nano::dev_genesis_key.pub, previous, nano::dev_genesis_key.pub, balance, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (previous))); + auto send = builder + .account (nano::dev_genesis_key.pub) + .previous (previous) + .representative (nano::dev_genesis_key.pub) + .balance (balance) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (previous)) + .build_shared (); node1->process_active (send); }; confirm_block (); @@ -901,9 +980,19 @@ TEST (websocket, new_unconfirmed_block) ASSERT_TIMELY (5s, ack_ready); + nano::state_block_builder builder; // Process a new block nano::genesis genesis; - auto send1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - 1, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ()))); + auto send1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - 1) + .link (nano::dev_genesis_key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (genesis.hash ())) + .build_shared (); + ASSERT_EQ (nano::process_result::progress, node1->process_local (send1).code); ASSERT_TIMELY (5s, future.wait_for (0s) == std::future_status::ready); diff --git a/nano/core_test/work_watcher.cpp b/nano/core_test/work_watcher.cpp index 49770df17f..7b8077eced 100644 --- a/nano/core_test/work_watcher.cpp +++ b/nano/core_test/work_watcher.cpp @@ -124,6 +124,7 @@ TEST (work_watcher, removed_after_lose) { nano::system system; nano::node_config node_config (nano::get_available_port (), system.logging); + nano::state_block_builder builder; node_config.enable_voting = false; node_config.work_watcher_period = 1s; auto & node = *system.add_node (node_config); @@ -133,7 +134,16 @@ TEST (work_watcher, removed_after_lose) auto const block1 (wallet.send_action (nano::dev_genesis_key.pub, key.pub, 100)); ASSERT_TRUE (node.wallets.watcher->is_watched (block1->qualified_root ())); nano::genesis genesis; - auto fork1 (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::xrb_ratio, nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (genesis.hash ()))); + auto fork1 = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::xrb_ratio) + .link (nano::dev_genesis_key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*system.work.generate (genesis.hash ())) + .build_shared (); + node.process_active (fork1); node.block_processor.flush (); auto vote (std::make_shared (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 0, fork1)); @@ -147,6 +157,7 @@ TEST (work_watcher, generation_disabled) { nano::system system; nano::node_config node_config (nano::get_available_port (), system.logging); + nano::state_block_builder builder; node_config.enable_voting = false; node_config.work_watcher_period = 1s; node_config.work_threads = 0; @@ -157,7 +168,16 @@ TEST (work_watcher, generation_disabled) nano::work_pool pool (std::numeric_limits::max ()); nano::genesis genesis; nano::keypair key; - auto block (std::make_shared (nano::dev_genesis_key.pub, genesis.hash (), nano::dev_genesis_key.pub, nano::genesis_amount - nano::Mxrb_ratio, key.pub, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *pool.generate (genesis.hash ()))); + auto block = builder + .account (nano::dev_genesis_key.pub) + .previous (genesis.hash ()) + .representative (nano::dev_genesis_key.pub) + .balance (nano::genesis_amount - nano::Mxrb_ratio) + .link (key.pub) + .sign (nano::dev_genesis_key.prv, nano::dev_genesis_key.pub) + .work (*pool.generate (genesis.hash ())) + .build_shared (); + auto difficulty (block->difficulty ()); node.wallets.watcher->add (block); ASSERT_FALSE (node.process_local (block).code != nano::process_result::progress); From 88e374ae147c929e97db070b8cbcdca855782f8e Mon Sep 17 00:00:00 2001 From: Sergey Kroshnin Date: Sun, 25 Apr 2021 12:57:02 +0300 Subject: [PATCH 4/4] Check bulk push availability (#3231) --- nano/node/bootstrap/bootstrap_frontier.cpp | 9 +++++++-- nano/node/bootstrap/bootstrap_frontier.hpp | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/nano/node/bootstrap/bootstrap_frontier.cpp b/nano/node/bootstrap/bootstrap_frontier.cpp index f4dcd56a9e..b197b5cc26 100644 --- a/nano/node/bootstrap/bootstrap_frontier.cpp +++ b/nano/node/bootstrap/bootstrap_frontier.cpp @@ -68,9 +68,14 @@ void nano::frontier_req_client::receive_frontier () }); } +bool nano::frontier_req_client::bulk_push_available () +{ + return bulk_push_cost < nano::bootstrap_limits::bulk_push_cost_limit && frontiers_age == std::numeric_limits::max (); +} + void nano::frontier_req_client::unsynced (nano::block_hash const & head, nano::block_hash const & end) { - if (bulk_push_cost < nano::bootstrap_limits::bulk_push_cost_limit && frontiers_age == std::numeric_limits::max ()) + if (bulk_push_available ()) { attempt->add_bulk_push_target (head, end); if (end.is_zero ()) @@ -169,7 +174,7 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con { if (count <= count_limit) { - while (!current.is_zero ()) + while (!current.is_zero () && bulk_push_available ()) { // We know about an account they don't. unsynced (frontier, 0); diff --git a/nano/node/bootstrap/bootstrap_frontier.hpp b/nano/node/bootstrap/bootstrap_frontier.hpp index 1f82bfd787..5ad433e25c 100644 --- a/nano/node/bootstrap/bootstrap_frontier.hpp +++ b/nano/node/bootstrap/bootstrap_frontier.hpp @@ -16,6 +16,7 @@ class frontier_req_client final : public std::enable_shared_from_this connection;