From 54a76554f7fd8104bbce113fdb37ea2c1e9df6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Wed, 25 Jan 2023 19:50:31 +0100 Subject: [PATCH] Extract common test chain setup code --- nano/core_test/active_transactions.cpp | 99 +-------------- nano/core_test/backlog.cpp | 63 +-------- nano/core_test/bootstrap_server.cpp | 113 ++--------------- nano/lib/blocks.hpp | 3 + nano/test_common/CMakeLists.txt | 2 + nano/test_common/chains.cpp | 169 +++++++++++++++++++++++++ nano/test_common/chains.hpp | 40 ++++++ 7 files changed, 234 insertions(+), 255 deletions(-) create mode 100644 nano/test_common/chains.cpp create mode 100644 nano/test_common/chains.hpp diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 0a2ca2c170..139acea5e7 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -1407,94 +1408,6 @@ TEST (active_transactions, fifo) ASSERT_TIMELY (1s, node.active.election (receive2->qualified_root ()) != nullptr); } -namespace -{ -/* - * Sends `amount` raw from genesis chain into a new account and makes it a representative - */ -nano::keypair setup_rep (nano::test::system & system, nano::node & node, nano::uint128_t const amount) -{ - auto latest = node.latest (nano::dev::genesis_key.pub); - auto balance = node.balance (nano::dev::genesis_key.pub); - - nano::keypair key; - nano::block_builder builder; - - auto send = builder - .send () - .previous (latest) - .destination (key.pub) - .balance (balance - amount) - .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) - .work (*system.work.generate (latest)) - .build_shared (); - - auto open = builder - .open () - .source (send->hash ()) - .representative (key.pub) - .account (key.pub) - .sign (key.prv, key.pub) - .work (*system.work.generate (key.pub)) - .build_shared (); - - EXPECT_TRUE (nano::test::process (node, { send, open })); - EXPECT_TIMELY (5s, nano::test::confirm (node, { send, open })); - EXPECT_TIMELY (5s, nano::test::confirmed (node, { send, open })); - - return key; -} - -/* - * Creates `count` 1 raw sends from genesis to unique accounts and corresponding open blocks. - * The genesis chain is then confirmed, but leaves open blocks unconfirmed. - */ -std::vector> setup_independent_blocks (nano::test::system & system, nano::node & node, int count) -{ - std::vector> blocks; - - auto latest = node.latest (nano::dev::genesis_key.pub); - auto balance = node.balance (nano::dev::genesis_key.pub); - - for (int n = 0; n < count; ++n) - { - nano::keypair key; - nano::block_builder builder; - - balance -= 1; - auto send = builder - .send () - .previous (latest) - .destination (key.pub) - .balance (balance) - .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) - .work (*system.work.generate (latest)) - .build_shared (); - latest = send->hash (); - - auto open = builder - .open () - .source (send->hash ()) - .representative (key.pub) - .account (key.pub) - .sign (key.prv, key.pub) - .work (*system.work.generate (key.pub)) - .build_shared (); - - EXPECT_TRUE (nano::test::process (node, { send, open })); - EXPECT_TIMELY (5s, nano::test::exists (node, { send, open })); // Ensure blocks are in the ledger - - blocks.push_back (open); - } - - // Confirm whole genesis chain at once - EXPECT_TIMELY (5s, nano::test::confirm (node, { latest })); - EXPECT_TIMELY (5s, nano::test::confirmed (node, { latest })); - - return blocks; -} -} - /* * Ensures we limit the number of vote hinted elections in AEC */ @@ -1511,10 +1424,10 @@ TEST (active_transactions, limit_vote_hinted_elections) // Setup representatives // Enough weight to trigger election hinting but not enough to confirm block on its own const auto amount = ((node.online_reps.trended () / 100) * node.config.election_hint_weight_percent) + 1000 * nano::Gxrb_ratio; - nano::keypair rep1 = setup_rep (system, node, amount / 2); - nano::keypair rep2 = setup_rep (system, node, amount / 2); + nano::keypair rep1 = nano::test::setup_rep (system, node, amount / 2); + nano::keypair rep2 = nano::test::setup_rep (system, node, amount / 2); - auto blocks = setup_independent_blocks (system, node, 2); + auto blocks = nano::test::setup_independent_blocks (system, node, 2); auto open0 = blocks[0]; auto open1 = blocks[1]; @@ -1573,7 +1486,7 @@ TEST (active_transactions, allow_limited_overflow) config.active_elections_hinted_limit_percentage = 20; // Should give us a limit of 4 hinted elections auto & node = *system.add_node (config); - auto blocks = setup_independent_blocks (system, node, aec_limit * 4); + auto blocks = nano::test::setup_independent_blocks (system, node, aec_limit * 4); // Split blocks in two halves std::vector> blocks1 (blocks.begin (), blocks.begin () + blocks.size () / 2); @@ -1622,7 +1535,7 @@ TEST (active_transactions, allow_limited_overflow_adapt) config.active_elections_hinted_limit_percentage = 20; // Should give us a limit of 4 hinted elections auto & node = *system.add_node (config); - auto blocks = setup_independent_blocks (system, node, aec_limit * 4); + auto blocks = nano::test::setup_independent_blocks (system, node, aec_limit * 4); // Split blocks in two halves std::vector> blocks1 (blocks.begin (), blocks.begin () + blocks.size () / 2); diff --git a/nano/core_test/backlog.cpp b/nano/core_test/backlog.cpp index 802ccf10ab..0ad651d864 100644 --- a/nano/core_test/backlog.cpp +++ b/nano/core_test/backlog.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -8,65 +9,6 @@ using namespace std::chrono_literals; -namespace -{ -using block_list_t = std::vector>; - -/* - * Creates `count` 1 raw sends from genesis to unique accounts and corresponding open blocks. - * The genesis chain is then confirmed, but leaves open blocks unconfirmed - * The list of unconfirmed open blocks is returned. - */ -block_list_t setup_independent_blocks (nano::test::system & system, nano::node & node, int count) -{ - std::vector> blocks; - - auto latest = node.latest (nano::dev::genesis_key.pub); - auto balance = node.balance (nano::dev::genesis_key.pub); - - for (int n = 0; n < count; ++n) - { - nano::keypair key; - nano::block_builder builder; - - balance -= 1; - auto send = builder - .state () - .account (nano::dev::genesis_key.pub) - .previous (latest) - .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 (latest)) - .build_shared (); - latest = send->hash (); - - auto open = builder - .state () - .account (key.pub) - .previous (0) - .representative (key.pub) - .balance (1) - .link (send->hash ()) - .sign (key.prv, key.pub) - .work (*system.work.generate (key.pub)) - .build_shared (); - - EXPECT_TRUE (nano::test::process (node, { send, open })); - EXPECT_TIMELY (5s, nano::test::exists (node, { send, open })); // Ensure blocks are in the ledger - - blocks.push_back (open); - } - - // Confirm whole genesis chain at once - EXPECT_TIMELY (5s, nano::test::confirm (node, { latest })); - EXPECT_TIMELY (5s, nano::test::confirmed (node, { latest })); - - return blocks; -} -} - /* * Ensures all not confirmed accounts get activated by backlog scan periodically */ @@ -74,6 +16,7 @@ TEST (backlog, population) { nano::mutex mutex; std::unordered_set activated; + nano::test::system system{}; auto & node = *system.add_node (); @@ -83,7 +26,7 @@ TEST (backlog, population) activated.insert (account); }); - auto blocks = setup_independent_blocks (system, node, 256); + auto blocks = nano::test::setup_independent_blocks (system, node, 256); // Checks if `activated` set contains all accounts we previously set up auto all_activated = [&] () { diff --git a/nano/core_test/bootstrap_server.cpp b/nano/core_test/bootstrap_server.cpp index 447eb52730..5ca4a460cb 100644 --- a/nano/core_test/bootstrap_server.cpp +++ b/nano/core_test/bootstrap_server.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -9,98 +10,6 @@ using namespace std::chrono_literals; namespace { -using block_list_t = std::vector>; - -/** - * Creates `block_count` random send blocks in an account chain - */ -block_list_t setup_chain (nano::test::system & system, nano::node & node, nano::keypair key, int block_count) -{ - auto latest = node.latest (key.pub); - auto balance = node.balance (key.pub); - - std::vector> blocks; - for (int n = 0; n < block_count; ++n) - { - nano::keypair throwaway; - nano::block_builder builder; - - balance -= 1; - auto send = builder - .send () - .previous (latest) - .destination (throwaway.pub) - .balance (balance) - .sign (key.prv, key.pub) - .work (*system.work.generate (latest)) - .build_shared (); - - latest = send->hash (); - blocks.push_back (send); - } - - EXPECT_TRUE (nano::test::process (node, blocks)); - // Confirm whole chain at once - EXPECT_TIMELY (5s, nano::test::confirm (node, { blocks.back () })); - EXPECT_TIMELY (5s, nano::test::confirmed (node, blocks)); - - return blocks; -} - -/** - * Creates `count` account chains, each with `block_count` blocks - */ -std::vector> setup_chains (nano::test::system & system, nano::node & node, int count, int block_count) -{ - auto latest = node.latest (nano::dev::genesis_key.pub); - auto balance = node.balance (nano::dev::genesis_key.pub); - - std::vector> chains; - for (int n = 0; n < count; ++n) - { - nano::keypair key; - nano::block_builder builder; - - balance -= block_count * 2; // Send enough to later create `block_count` blocks - auto send = builder - .send () - .previous (latest) - .destination (key.pub) - .balance (balance) - .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) - .work (*system.work.generate (latest)) - .build_shared (); - - auto open = builder - .open () - .source (send->hash ()) - .representative (key.pub) - .account (key.pub) - .sign (key.prv, key.pub) - .work (*system.work.generate (key.pub)) - .build_shared (); - - latest = send->hash (); - - // Ensure blocks are in the ledger and confirmed - EXPECT_TRUE (nano::test::process (node, { send, open })); - EXPECT_TIMELY (5s, nano::test::confirm (node, { send, open })); - EXPECT_TIMELY (5s, nano::test::confirmed (node, { send, open })); - - auto added_blocks = setup_chain (system, node, key, block_count); - - auto blocks = block_list_t{ open }; - blocks.insert (blocks.end (), added_blocks.begin (), added_blocks.end ()); - - chains.emplace_back (key.pub, blocks); - } - - return chains; -} - -/** - * Helper to track responses in thread safe way - */ class responses_helper final { public: @@ -160,7 +69,7 @@ TEST (bootstrap_server, serve_account_blocks) responses.add (response); }); - auto chains = setup_chains (system, node, 1, 128); + auto chains = nano::test::setup_chains (system, node, 1, 128); auto [first_account, first_blocks] = chains.front (); // Request blocks from account root @@ -204,11 +113,11 @@ TEST (bootstrap_server, serve_hash) responses.add (response); }); - auto chains = setup_chains (system, node, 1, 256); + auto chains = nano::test::setup_chains (system, node, 1, 256); auto [account, blocks] = chains.front (); // Skip a few blocks to request hash in the middle of the chain - blocks = block_list_t (std::next (blocks.begin (), 9), blocks.end ()); + blocks = nano::block_list_t{ std::next (blocks.begin (), 9), blocks.end () }; // Request blocks from the middle of the chain nano::asc_pull_req request{ node.network_params.network }; @@ -251,11 +160,11 @@ TEST (bootstrap_server, serve_hash_one) responses.add (response); }); - auto chains = setup_chains (system, node, 1, 256); + auto chains = nano::test::setup_chains (system, node, 1, 256); auto [account, blocks] = chains.front (); // Skip a few blocks to request hash in the middle of the chain - blocks = block_list_t (std::next (blocks.begin (), 9), blocks.end ()); + blocks = nano::block_list_t{ std::next (blocks.begin (), 9), blocks.end () }; // Request blocks from the middle of the chain nano::asc_pull_req request{ node.network_params.network }; @@ -295,7 +204,7 @@ TEST (bootstrap_server, serve_end_of_chain) responses.add (response); }); - auto chains = setup_chains (system, node, 1, 128); + auto chains = nano::test::setup_chains (system, node, 1, 128); auto [account, blocks] = chains.front (); // Request blocks from account frontier @@ -337,7 +246,7 @@ TEST (bootstrap_server, serve_missing) responses.add (response); }); - auto chains = setup_chains (system, node, 1, 128); + auto chains = nano::test::setup_chains (system, node, 1, 128); // Request blocks from account frontier nano::asc_pull_req request{ node.network_params.network }; @@ -377,7 +286,7 @@ TEST (bootstrap_server, serve_multiple) responses.add (response); }); - auto chains = setup_chains (system, node, 32, 16); + auto chains = nano::test::setup_chains (system, node, 32, 16); { // Request blocks from multiple chains at once @@ -440,7 +349,7 @@ TEST (bootstrap_server, serve_account_info) responses.add (response); }); - auto chains = setup_chains (system, node, 1, 128); + auto chains = nano::test::setup_chains (system, node, 1, 128); auto [account, blocks] = chains.front (); // Request blocks from account root @@ -488,7 +397,7 @@ TEST (bootstrap_server, serve_account_info_missing) responses.add (response); }); - auto chains = setup_chains (system, node, 1, 128); + auto chains = nano::test::setup_chains (system, node, 1, 128); auto [account, blocks] = chains.front (); // Request blocks from account root diff --git a/nano/lib/blocks.hpp b/nano/lib/blocks.hpp index 97770f0111..a4320dc4f1 100644 --- a/nano/lib/blocks.hpp +++ b/nano/lib/blocks.hpp @@ -128,6 +128,9 @@ class block private: nano::block_hash generate_hash () const; }; + +using block_list_t = std::vector>; + class send_hashables { public: diff --git a/nano/test_common/CMakeLists.txt b/nano/test_common/CMakeLists.txt index 917d0fb757..337d34211d 100644 --- a/nano/test_common/CMakeLists.txt +++ b/nano/test_common/CMakeLists.txt @@ -1,5 +1,7 @@ add_library( test_common + chains.hpp + chains.cpp ledger.hpp ledger.cpp network.hpp diff --git a/nano/test_common/chains.cpp b/nano/test_common/chains.cpp new file mode 100644 index 0000000000..f416717e21 --- /dev/null +++ b/nano/test_common/chains.cpp @@ -0,0 +1,169 @@ +#include + +using namespace std::chrono_literals; + +nano::block_list_t nano::test::setup_chain (nano::test::system & system, nano::node & node, int count, nano::keypair target) +{ + auto latest = node.latest (target.pub); + auto balance = node.balance (target.pub); + + std::vector> blocks; + for (int n = 0; n < count; ++n) + { + nano::keypair throwaway; + nano::block_builder builder; + + balance -= 1; + auto send = builder + .send () + .previous (latest) + .destination (throwaway.pub) + .balance (balance) + .sign (target.prv, target.pub) + .work (*system.work.generate (latest)) + .build_shared (); + + latest = send->hash (); + + blocks.push_back (send); + } + + EXPECT_TRUE (nano::test::process (node, blocks)); + + // Confirm whole chain at once + EXPECT_TIMELY (5s, nano::test::confirm (node, { blocks.back () })); + EXPECT_TIMELY (5s, nano::test::confirmed (node, blocks)); + + return blocks; +} + +std::vector> nano::test::setup_chains (nano::test::system & system, nano::node & node, int chain_count, int block_count, nano::keypair source) +{ + auto latest = node.latest (source.pub); + auto balance = node.balance (source.pub); + + std::vector> chains; + for (int n = 0; n < chain_count; ++n) + { + nano::keypair key; + nano::block_builder builder; + + balance -= block_count * 2; // Send enough to later create `block_count` blocks + auto send = builder + .send () + .previous (latest) + .destination (key.pub) + .balance (balance) + .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) + .work (*system.work.generate (latest)) + .build_shared (); + + auto open = builder + .open () + .source (send->hash ()) + .representative (key.pub) + .account (key.pub) + .sign (key.prv, key.pub) + .work (*system.work.generate (key.pub)) + .build_shared (); + + latest = send->hash (); + + // Ensure blocks are in the ledger and confirmed + EXPECT_TRUE (nano::test::process (node, { send, open })); + EXPECT_TIMELY (5s, nano::test::confirm (node, { send, open })); + EXPECT_TIMELY (5s, nano::test::confirmed (node, { send, open })); + + auto added_blocks = nano::test::setup_chain (system, node, block_count, key); + + auto blocks = block_list_t{ open }; + blocks.insert (blocks.end (), added_blocks.begin (), added_blocks.end ()); + + chains.emplace_back (key.pub, blocks); + } + + return chains; +} + +nano::block_list_t nano::test::setup_independent_blocks (nano::test::system & system, nano::node & node, int count, nano::keypair source) +{ + std::vector> blocks; + + auto latest = node.latest (source.pub); + auto balance = node.balance (source.pub); + + for (int n = 0; n < count; ++n) + { + nano::keypair key; + nano::block_builder builder; + + balance -= 1; + auto send = builder + .state () + .account (nano::dev::genesis_key.pub) + .previous (latest) + .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 (latest)) + .build_shared (); + + latest = send->hash (); + + auto open = builder + .state () + .account (key.pub) + .previous (0) + .representative (key.pub) + .balance (1) + .link (send->hash ()) + .sign (key.prv, key.pub) + .work (*system.work.generate (key.pub)) + .build_shared (); + + EXPECT_TRUE (nano::test::process (node, { send, open })); + EXPECT_TIMELY (5s, nano::test::exists (node, { send, open })); // Ensure blocks are in the ledger + + blocks.push_back (open); + } + + // Confirm whole genesis chain at once + EXPECT_TIMELY (5s, nano::test::confirm (node, { latest })); + EXPECT_TIMELY (5s, nano::test::confirmed (node, { latest })); + + return blocks; +} + +nano::keypair nano::test::setup_rep (nano::test::system & system, nano::node & node, nano::uint128_t const amount, nano::keypair source) +{ + auto latest = node.latest (source.pub); + auto balance = node.balance (source.pub); + + nano::keypair key; + nano::block_builder builder; + + auto send = builder + .send () + .previous (latest) + .destination (key.pub) + .balance (balance - amount) + .sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub) + .work (*system.work.generate (latest)) + .build_shared (); + + auto open = builder + .open () + .source (send->hash ()) + .representative (key.pub) + .account (key.pub) + .sign (key.prv, key.pub) + .work (*system.work.generate (key.pub)) + .build_shared (); + + EXPECT_TRUE (nano::test::process (node, { send, open })); + EXPECT_TIMELY (5s, nano::test::confirm (node, { send, open })); + EXPECT_TIMELY (5s, nano::test::confirmed (node, { send, open })); + + return key; +} \ No newline at end of file diff --git a/nano/test_common/chains.hpp b/nano/test_common/chains.hpp new file mode 100644 index 0000000000..7c6c52ca7f --- /dev/null +++ b/nano/test_common/chains.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + +#include + +#include +#include + +/* + * Helper functions to deal with common chain setup scenarios + */ +namespace nano::test +{ +/** + * Creates `count` random 1 raw send blocks in a `target` account chain + * @returns created blocks + */ +nano::block_list_t setup_chain (nano::test::system & system, nano::node & node, int count, nano::keypair target = nano::dev::genesis_key); + +/** + * Creates `chain_count` account chains, each with `block_count` 1 raw random send blocks, all accounts are seeded from `source` account + * @returns list of created accounts and their blocks + */ +std::vector> setup_chains (nano::test::system & system, nano::node & node, int chain_count, int block_count, nano::keypair source = nano::dev::genesis_key); + +/** + * Creates `count` 1 raw send blocks from `source` account, each to randomly created account + * The `source` account chain is then confirmed, but leaves open blocks unconfirmed + * @returns list of unconfirmed (open) blocks + */ +nano::block_list_t setup_independent_blocks (nano::test::system & system, nano::node & node, int count, nano::keypair source = nano::dev::genesis_key); + +/** + * Sends `amount` raw from `source` account chain into a newly created account and sets that account as its own representative + * @return created representative + */ +nano::keypair setup_rep (nano::test::system & system, nano::node & node, nano::uint128_t amount, nano::keypair source = nano::dev::genesis_key); +} \ No newline at end of file