Skip to content

Commit

Permalink
Promote slow core_test to slow_test (#4206)
Browse files Browse the repository at this point in the history
* Move node.aggressive_flooding test to the slow_test

* Disabling the ascending_bootstrap for node.aggressive_flooding test

* Move node.send_single_many_peers test to slow_test
  • Loading branch information
thsfs committed Apr 5, 2023
1 parent b419432 commit addea48
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 127 deletions.
127 changes: 0 additions & 127 deletions nano/core_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,6 @@ TEST (node, send_single_observing_peer)
ASSERT_TIMELY (10s, std::all_of (system.nodes.begin (), system.nodes.end (), [&] (std::shared_ptr<nano::node> const & node_a) { return !node_a->balance (key2.pub).is_zero (); }));
}

TEST (node, send_single_many_peers)
{
nano::test::system system (nano::memory_intensive_instrumentation () ? 4 : 10);
nano::keypair key2;
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
system.wallet (1)->insert_adhoc (key2.prv);
ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, system.nodes[0]->config.receive_minimum.number ()));
ASSERT_EQ (std::numeric_limits<nano::uint128_t>::max () - system.nodes[0]->config.receive_minimum.number (), system.nodes[0]->balance (nano::dev::genesis_key.pub));
ASSERT_TRUE (system.nodes[0]->balance (key2.pub).is_zero ());
ASSERT_TIMELY (3.5min, std::all_of (system.nodes.begin (), system.nodes.end (), [&] (std::shared_ptr<nano::node> const & node_a) { return !node_a->balance (key2.pub).is_zero (); }));
system.stop ();
for (auto node : system.nodes)
{
ASSERT_TRUE (node->stopped);
}
}

TEST (node, send_out_of_order)
{
nano::test::system system (2);
Expand Down Expand Up @@ -3430,116 +3413,6 @@ TEST (node, bidirectional_tcp)
}
}

// Tests that local blocks are flooded to all principal representatives
// Sanitizers or running within valgrind use different timings and number of nodes
TEST (node, DISABLED_aggressive_flooding)
{
nano::test::system system;
nano::node_flags node_flags;
node_flags.disable_request_loop = true;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_bootstrap_bulk_pull_server = true;
node_flags.disable_bootstrap_listener = true;
node_flags.disable_lazy_bootstrap = true;
node_flags.disable_legacy_bootstrap = true;
node_flags.disable_wallet_bootstrap = true;
auto & node1 (*system.add_node (node_flags));
auto & wallet1 (*system.wallet (0));
wallet1.insert_adhoc (nano::dev::genesis_key.prv);
std::vector<std::pair<std::shared_ptr<nano::node>, std::shared_ptr<nano::wallet>>> nodes_wallets;
nodes_wallets.resize (!nano::memory_intensive_instrumentation () ? 5 : 3);

std::generate (nodes_wallets.begin (), nodes_wallets.end (), [&system, node_flags] () {
nano::node_config node_config (nano::test::get_available_port (), system.logging);
auto node (system.add_node (node_config, node_flags));
return std::make_pair (node, system.wallet (system.nodes.size () - 1));
});

// This test is only valid if a non-aggressive flood would not reach every peer
ASSERT_TIMELY (5s, node1.network.size () == nodes_wallets.size ());
ASSERT_LT (node1.network.fanout (), nodes_wallets.size ());

// Each new node should see genesis representative
ASSERT_TIMELY (10s, std::all_of (nodes_wallets.begin (), nodes_wallets.end (), [] (auto const & node_wallet) { return node_wallet.first->rep_crawler.principal_representatives ().size () != 0; }));

// Send a large amount to create a principal representative in each node
auto large_amount = (nano::dev::constants.genesis_amount / 2) / nodes_wallets.size ();
std::vector<std::shared_ptr<nano::block>> genesis_blocks;
for (auto & node_wallet : nodes_wallets)
{
nano::keypair keypair;
node_wallet.second->store.representative_set (node_wallet.first->wallets.tx_begin_write (), keypair.pub);
node_wallet.second->insert_adhoc (keypair.prv);
auto block (wallet1.send_action (nano::dev::genesis_key.pub, keypair.pub, large_amount));
ASSERT_NE (nullptr, block);
genesis_blocks.push_back (block);
}

// Ensure all nodes have the full genesis chain
for (auto & node_wallet : nodes_wallets)
{
for (auto const & block : genesis_blocks)
{
auto process_result (node_wallet.first->process (*block));
ASSERT_TRUE (nano::process_result::progress == process_result.code || nano::process_result::old == process_result.code);
}
ASSERT_EQ (node1.latest (nano::dev::genesis_key.pub), node_wallet.first->latest (nano::dev::genesis_key.pub));
ASSERT_EQ (genesis_blocks.back ()->hash (), node_wallet.first->latest (nano::dev::genesis_key.pub));
// Confirm blocks for rep crawler & receiving
nano::test::start_elections (system, *node_wallet.first, { genesis_blocks.back () }, true);
}
nano::test::start_elections (system, node1, { genesis_blocks.back () }, true);

// Wait until all genesis blocks are received
auto all_received = [&nodes_wallets] () {
return std::all_of (nodes_wallets.begin (), nodes_wallets.end (), [] (auto const & node_wallet) {
auto local_representative (node_wallet.second->store.representative (node_wallet.first->wallets.tx_begin_read ()));
return node_wallet.first->ledger.account_balance (node_wallet.first->store.tx_begin_read (), local_representative) > 0;
});
};

ASSERT_TIMELY (!nano::slow_instrumentation () ? 10s : 40s, all_received ());

ASSERT_TIMELY (!nano::slow_instrumentation () ? 10s : 40s, node1.ledger.cache.block_count == 1 + 2 * nodes_wallets.size ());

// Wait until the main node sees all representatives
ASSERT_TIMELY (!nano::slow_instrumentation () ? 10s : 40s, node1.rep_crawler.principal_representatives ().size () == nodes_wallets.size ());

// Generate blocks and ensure they are sent to all representatives
nano::state_block_builder builder;
std::shared_ptr<nano::state_block> block{};
{
auto transaction (node1.store.tx_begin_read ());
block = builder.make_block ()
.account (nano::dev::genesis_key.pub)
.representative (nano::dev::genesis_key.pub)
.previous (node1.ledger.latest (transaction, nano::dev::genesis_key.pub))
.balance (node1.ledger.account_balance (transaction, nano::dev::genesis_key.pub) - 1)
.link (nano::dev::genesis_key.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*node1.work_generate_blocking (node1.ledger.latest (transaction, nano::dev::genesis_key.pub)))
.build ();
}
// Processing locally goes through the aggressive block flooding path
ASSERT_EQ (nano::process_result::progress, node1.process_local (block).value ().code);

auto all_have_block = [&nodes_wallets] (nano::block_hash const & hash_a) {
return std::all_of (nodes_wallets.begin (), nodes_wallets.end (), [hash = hash_a] (auto const & node_wallet) {
return node_wallet.first->block (hash) != nullptr;
});
};

ASSERT_TIMELY (!nano::slow_instrumentation () ? 5s : 25s, all_have_block (block->hash ()));

// Do the same for a wallet block
auto wallet_block = wallet1.send_sync (nano::dev::genesis_key.pub, nano::dev::genesis_key.pub, 10);
ASSERT_TIMELY (!nano::slow_instrumentation () ? 5s : 25s, all_have_block (wallet_block));

// All blocks: genesis + (send+open) for each representative + 2 local blocks
// The main node only sees all blocks if other nodes are flooding their PR's open block to all other PRs
ASSERT_EQ (1 + 2 * nodes_wallets.size () + 2, node1.ledger.cache.block_count);
}

TEST (node, node_sequence)
{
nano::test::system system (3);
Expand Down
128 changes: 128 additions & 0 deletions nano/slow_test/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2050,6 +2050,134 @@ TEST (node, mass_block_new)
process_all (receive_blocks);
std::cout << "Receive blocks time: " << timer.stop ().count () << " " << timer.unit () << "\n\n";
}

// Tests that local blocks are flooded to all principal representatives
// Sanitizers or running within valgrind use different timings and number of nodes
TEST (node, aggressive_flooding)
{
nano::test::system system;
nano::node_flags node_flags;
node_flags.disable_request_loop = true;
node_flags.disable_bootstrap_bulk_push_client = true;
node_flags.disable_bootstrap_bulk_pull_server = true;
node_flags.disable_bootstrap_listener = true;
node_flags.disable_lazy_bootstrap = true;
node_flags.disable_legacy_bootstrap = true;
node_flags.disable_wallet_bootstrap = true;
node_flags.disable_ascending_bootstrap = true;
auto & node1 (*system.add_node (node_flags));
auto & wallet1 (*system.wallet (0));
wallet1.insert_adhoc (nano::dev::genesis_key.prv);
std::vector<std::pair<std::shared_ptr<nano::node>, std::shared_ptr<nano::wallet>>> nodes_wallets;
nodes_wallets.resize (!nano::memory_intensive_instrumentation () ? 5 : 3);

std::generate (nodes_wallets.begin (), nodes_wallets.end (), [&system, node_flags] () {
nano::node_config node_config (nano::test::get_available_port (), system.logging);
auto node (system.add_node (node_config, node_flags));
return std::make_pair (node, system.wallet (system.nodes.size () - 1));
});

// This test is only valid if a non-aggressive flood would not reach every peer
ASSERT_TIMELY (5s, node1.network.size () == nodes_wallets.size ());
ASSERT_LT (node1.network.fanout (), nodes_wallets.size ());

// Each new node should see genesis representative
ASSERT_TIMELY (10s, std::all_of (nodes_wallets.begin (), nodes_wallets.end (), [] (auto const & node_wallet) { return node_wallet.first->rep_crawler.principal_representatives ().size () != 0; }));

// Send a large amount to create a principal representative in each node
auto large_amount = (nano::dev::constants.genesis_amount / 2) / nodes_wallets.size ();
std::vector<std::shared_ptr<nano::block>> genesis_blocks;
for (auto & node_wallet : nodes_wallets)
{
nano::keypair keypair;
node_wallet.second->store.representative_set (node_wallet.first->wallets.tx_begin_write (), keypair.pub);
node_wallet.second->insert_adhoc (keypair.prv);
auto block (wallet1.send_action (nano::dev::genesis_key.pub, keypair.pub, large_amount));
ASSERT_NE (nullptr, block);
genesis_blocks.push_back (block);
}

// Ensure all nodes have the full genesis chain
for (auto & node_wallet : nodes_wallets)
{
for (auto const & block : genesis_blocks)
{
auto process_result (node_wallet.first->process (*block));
ASSERT_TRUE (nano::process_result::progress == process_result.code || nano::process_result::old == process_result.code);
}
ASSERT_EQ (node1.latest (nano::dev::genesis_key.pub), node_wallet.first->latest (nano::dev::genesis_key.pub));
ASSERT_EQ (genesis_blocks.back ()->hash (), node_wallet.first->latest (nano::dev::genesis_key.pub));
// Confirm blocks for rep crawler & receiving
nano::test::start_elections (system, *node_wallet.first, { genesis_blocks.back () }, true);
}
nano::test::start_elections (system, node1, { genesis_blocks.back () }, true);

// Wait until all genesis blocks are received
auto all_received = [&nodes_wallets] () {
return std::all_of (nodes_wallets.begin (), nodes_wallets.end (), [] (auto const & node_wallet) {
auto local_representative (node_wallet.second->store.representative (node_wallet.first->wallets.tx_begin_read ()));
return node_wallet.first->ledger.account_balance (node_wallet.first->store.tx_begin_read (), local_representative) > 0;
});
};

ASSERT_TIMELY (!nano::slow_instrumentation () ? 10s : 40s, all_received ());

ASSERT_TIMELY (!nano::slow_instrumentation () ? 10s : 40s, node1.ledger.cache.block_count == 1 + 2 * nodes_wallets.size ());

// Wait until the main node sees all representatives
ASSERT_TIMELY (!nano::slow_instrumentation () ? 10s : 40s, node1.rep_crawler.principal_representatives ().size () == nodes_wallets.size ());

// Generate blocks and ensure they are sent to all representatives
nano::state_block_builder builder;
std::shared_ptr<nano::state_block> block{};
{
auto transaction (node1.store.tx_begin_read ());
block = builder.make_block ()
.account (nano::dev::genesis_key.pub)
.representative (nano::dev::genesis_key.pub)
.previous (node1.ledger.latest (transaction, nano::dev::genesis_key.pub))
.balance (node1.ledger.account_balance (transaction, nano::dev::genesis_key.pub) - 1)
.link (nano::dev::genesis_key.pub)
.sign (nano::dev::genesis_key.prv, nano::dev::genesis_key.pub)
.work (*node1.work_generate_blocking (node1.ledger.latest (transaction, nano::dev::genesis_key.pub)))
.build ();
}
// Processing locally goes through the aggressive block flooding path
ASSERT_EQ (nano::process_result::progress, node1.process_local (block).value ().code);

auto all_have_block = [&nodes_wallets] (nano::block_hash const & hash_a) {
return std::all_of (nodes_wallets.begin (), nodes_wallets.end (), [hash = hash_a] (auto const & node_wallet) {
return node_wallet.first->block (hash) != nullptr;
});
};

ASSERT_TIMELY (!nano::slow_instrumentation () ? 5s : 25s, all_have_block (block->hash ()));

// Do the same for a wallet block
auto wallet_block = wallet1.send_sync (nano::dev::genesis_key.pub, nano::dev::genesis_key.pub, 10);
ASSERT_TIMELY (!nano::slow_instrumentation () ? 5s : 25s, all_have_block (wallet_block));

// All blocks: genesis + (send+open) for each representative + 2 local blocks
// The main node only sees all blocks if other nodes are flooding their PR's open block to all other PRs
ASSERT_EQ (1 + 2 * nodes_wallets.size () + 2, node1.ledger.cache.block_count);
}

TEST (node, send_single_many_peers)
{
nano::test::system system (nano::memory_intensive_instrumentation () ? 4 : 10);
nano::keypair key2;
system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv);
system.wallet (1)->insert_adhoc (key2.prv);
ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, system.nodes[0]->config.receive_minimum.number ()));
ASSERT_EQ (std::numeric_limits<nano::uint128_t>::max () - system.nodes[0]->config.receive_minimum.number (), system.nodes[0]->balance (nano::dev::genesis_key.pub));
ASSERT_TRUE (system.nodes[0]->balance (key2.pub).is_zero ());
ASSERT_TIMELY (3.5min, std::all_of (system.nodes.begin (), system.nodes.end (), [&] (std::shared_ptr<nano::node> const & node_a) { return !node_a->balance (key2.pub).is_zero (); }));
system.stop ();
for (auto node : system.nodes)
{
ASSERT_TRUE (node->stopped);
}
}
}

TEST (node, wallet_create_block_confirm_conflicts)
Expand Down

0 comments on commit addea48

Please sign in to comment.