diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index ca2511b4..222307b2 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -3631,36 +3631,61 @@ TEST (node, bandwidth_limiter) } // 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::system system; nano::node_flags node_flags; node_flags.disable_request_loop = true; node_flags.disable_block_processor_republishing = 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::test_genesis_key.prv); - std::array, std::shared_ptr>, 5> nodes_wallets{}; + std::vector, std::shared_ptr>> nodes_wallets; + bool const sanitizer_or_valgrind (is_sanitizer_build || nano::running_within_valgrind ()); + nodes_wallets.resize (!sanitizer_or_valgrind ? 5 : 3); + std::generate (nodes_wallets.begin (), nodes_wallets.end (), [&system, node_flags]() { - nano::node_config node_config; - node_config.peering_port = nano::get_available_port (); + nano::node_config node_config (nano::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 ()); + + // Send a large amount to create a principal representative in each node auto large_amount = (nano::genesis_amount / 2) / nodes_wallets.size (); + std::vector> 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); - wallet1.send_action (nano::test_genesis_key.pub, keypair.pub, large_amount); + auto block (wallet1.send_action (nano::test_genesis_key.pub, keypair.pub, large_amount)); + genesis_blocks.push_back (block); } - // Wait until all nodes have a representative - system.deadline_set (!is_sanitizer_build ? 5s : 15s); - while (node1.rep_crawler.principal_representatives ().size () != nodes_wallets.size ()) + + // Ensure all nodes have the full genesis chain + for (auto & node_wallet : nodes_wallets) { - ASSERT_NO_ERROR (system.poll ()); + for (auto const & block : genesis_blocks) + { + node_wallet.first->process (*block); + } + ASSERT_EQ (node1.latest (nano::test_genesis_key.pub), node_wallet.first->latest (nano::test_genesis_key.pub)); } + + // Wait until the main node sees all representatives + ASSERT_TIMELY (!sanitizer_or_valgrind ? 10s : 40s, node1.rep_crawler.principal_representatives ().size () == nodes_wallets.size ()); + // Generate blocks and ensure they are sent to all representatives nano::block_builder builder; std::shared_ptr block{}; @@ -3685,27 +3710,15 @@ TEST (node, aggressive_flooding) }); }; - system.deadline_set (!is_sanitizer_build ? 3s : 10s); - while (!all_have_block (block->hash ())) - { - ASSERT_NO_ERROR (system.poll ()); - } + ASSERT_TIMELY (!sanitizer_or_valgrind ? 5s : 25s, all_have_block (block->hash ())); // Do the same for a wallet block auto wallet_block = wallet1.send_sync (nano::test_genesis_key.pub, nano::test_genesis_key.pub, 10); - system.deadline_set (!is_sanitizer_build ? 3s : 10s); - while (!all_have_block (wallet_block)) - { - ASSERT_NO_ERROR (system.poll ()); - } + ASSERT_TIMELY (!sanitizer_or_valgrind ? 5s : 25s, all_have_block (wallet_block)); - // Wait until the main node has all blocks: genesis + (send+open) for each representative + 2 local blocks + // 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 - system.deadline_set (5s); - while (node1.ledger.cache.block_count < 1 + 2 * nodes_wallets.size () + 2) - { - ASSERT_NO_ERROR (system.poll ()); - } + ASSERT_EQ (1 + 2 * nodes_wallets.size () + 2, node1.ledger.cache.block_count); } TEST (active_difficulty, recalculate_work)