From 649a8e8f67b3e61e925741e55b0d539900710f97 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Mon, 22 Jan 2024 22:30:37 +0100 Subject: [PATCH 1/5] Added two convenience functions --- nano/test_common/testutil.cpp | 18 ++++++++++++++++++ nano/test_common/testutil.hpp | 10 ++++++++++ 2 files changed, 28 insertions(+) diff --git a/nano/test_common/testutil.cpp b/nano/test_common/testutil.cpp index 56d89419f1..dea953861c 100644 --- a/nano/test_common/testutil.cpp +++ b/nano/test_common/testutil.cpp @@ -115,6 +115,24 @@ bool nano::test::exists (nano::node & node, std::vector hashes) +{ + auto transaction = node.store.tx_begin_read (); + for (const auto & hash : hashes) + { + if (!node.ledger.block_or_pruned_exists (transaction, hash)) + { + return false; + } + } + return true; +} + +bool nano::test::block_or_pruned_exists (nano::node & node, std::vector> blocks) +{ + return block_or_pruned_exists (node, blocks_to_hashes (blocks)); +} + bool nano::test::activate (nano::node & node, std::vector hashes) { for (auto & hash : hashes) diff --git a/nano/test_common/testutil.hpp b/nano/test_common/testutil.hpp index 3203fdfb3e..5b885c66b6 100644 --- a/nano/test_common/testutil.hpp +++ b/nano/test_common/testutil.hpp @@ -350,6 +350,16 @@ namespace test * @return true if all blocks are fully processed and inserted in the ledger, false otherwise */ bool exists (nano::node & node, std::vector> blocks); + /* + * Convenience function to check whether a list of hashes exists in node ledger or in the pruned table. + * @return true if all blocks are fully processed and inserted in the ledger, false otherwise + */ + bool block_or_pruned_exists (nano::node & node, std::vector hashes); + /* + * Convenience function to check whether a list of blocks exists in node ledger or their hash exists in the pruned table. + * @return true if all blocks are fully processed and inserted in the ledger, false otherwise + */ + bool block_or_pruned_exists (nano::node & node, std::vector> blocks); /* * Convenience function to start elections for a list of hashes. Blocks are loaded from ledger. * @return true if all blocks exist and were queued to election scheduler From 58a80b995fe980cc7fcc15f86a2b2c314123335b Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Tue, 23 Jan 2024 20:53:39 +0100 Subject: [PATCH 2/5] Bootstrap unit tests --- nano/core_test/bootstrap.cpp | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index 963385d594..7255728e57 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -1126,10 +1126,7 @@ TEST (bootstrap_processor, DISABLED_lazy_unclear_state_link) node2->bootstrap_initiator.bootstrap_lazy (receive->hash ()); // Check processed blocks ASSERT_TIMELY (10s, !node2->bootstrap_initiator.in_progress ()); - ASSERT_TIMELY (5s, node2->ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_TIMELY (5s, node2->ledger.block_or_pruned_exists (send2->hash ())); - ASSERT_TIMELY (5s, node2->ledger.block_or_pruned_exists (open->hash ())); - ASSERT_TIMELY (5s, node2->ledger.block_or_pruned_exists (receive->hash ())); + ASSERT_TIMELY (5s, nano::test::block_or_pruned_exists (*node2, { send1, send2, open, receive })); ASSERT_EQ (0, node2->stats.count (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_failed_account, nano::stat::dir::in)); } @@ -1185,9 +1182,7 @@ TEST (bootstrap_processor, lazy_unclear_state_link_not_existing) node2->bootstrap_initiator.bootstrap_lazy (send2->hash ()); // Check processed blocks ASSERT_TIMELY (15s, !node2->bootstrap_initiator.in_progress ()); - ASSERT_TIMELY (5s, node2->ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_TIMELY (5s, node2->ledger.block_or_pruned_exists (open->hash ())); - ASSERT_TIMELY (5s, node2->ledger.block_or_pruned_exists (send2->hash ())); + ASSERT_TIMELY (15s, nano::test::block_or_pruned_exists (*node2, { send1, open, send2 })); ASSERT_EQ (1, node2->stats.count (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_failed_account, nano::stat::dir::in)); } @@ -1254,10 +1249,7 @@ TEST (bootstrap_processor, DISABLED_lazy_destinations) node2->bootstrap_initiator.bootstrap_lazy (send2->hash ()); // Check processed blocks ASSERT_TIMELY (10s, !node2->bootstrap_initiator.in_progress ()); - ASSERT_TRUE (node2->ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_TRUE (node2->ledger.block_or_pruned_exists (send2->hash ())); - ASSERT_TRUE (node2->ledger.block_or_pruned_exists (open->hash ())); - ASSERT_TRUE (node2->ledger.block_or_pruned_exists (state_open->hash ())); + ASSERT_TRUE (nano::test::block_or_pruned_exists (*node2, { send1, send2, open, state_open })); } TEST (bootstrap_processor, lazy_pruning_missing_block) @@ -1329,10 +1321,7 @@ TEST (bootstrap_processor, lazy_pruning_missing_block) node1->ledger_pruning (2, false, false); ASSERT_EQ (5, node1->ledger.cache.block_count); ASSERT_EQ (1, node1->ledger.cache.pruned_count); - ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send1->hash ())); // true for pruned - ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send2->hash ())); - ASSERT_TRUE (node1->ledger.block_or_pruned_exists (open->hash ())); - ASSERT_TRUE (node1->ledger.block_or_pruned_exists (state_open->hash ())); + ASSERT_TRUE (nano::test::block_or_pruned_exists (*node1, { send1, send2, open, state_open })); // Start lazy bootstrap with last block in sender chain config.peering_port = system.get_available_port (); auto node2 (std::make_shared (system.io_ctx, nano::unique_path (), config, system.work, node_flags, 1)); @@ -1345,10 +1334,7 @@ TEST (bootstrap_processor, lazy_pruning_missing_block) // Some blocks cannot be retrieved from pruned node node2->block_processor.flush (); ASSERT_EQ (1, node2->ledger.cache.block_count); - ASSERT_FALSE (node2->ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_FALSE (node2->ledger.block_or_pruned_exists (send2->hash ())); - ASSERT_FALSE (node2->ledger.block_or_pruned_exists (open->hash ())); - ASSERT_FALSE (node2->ledger.block_or_pruned_exists (state_open->hash ())); + ASSERT_FALSE (nano::test::block_or_pruned_exists (*node2, { send1, send2, open, state_open })); { auto transaction (node2->store.tx_begin_read ()); ASSERT_TRUE (node2->unchecked.exists (nano::unchecked_key (send2->root ().as_block_hash (), send2->hash ()))); @@ -1359,10 +1345,8 @@ TEST (bootstrap_processor, lazy_pruning_missing_block) ASSERT_TIMELY (5s, !node2->bootstrap_initiator.in_progress ()); node2->block_processor.flush (); ASSERT_EQ (3, node2->ledger.cache.block_count); - ASSERT_TRUE (node2->ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_TRUE (node2->ledger.block_or_pruned_exists (send2->hash ())); - ASSERT_FALSE (node2->ledger.block_or_pruned_exists (open->hash ())); - ASSERT_FALSE (node2->ledger.block_or_pruned_exists (state_open->hash ())); + ASSERT_TRUE (nano::test::block_or_pruned_exists (*node2, { send1, send2 })); + ASSERT_FALSE (nano::test::block_or_pruned_exists (*node2, { open, state_open })); node2->stop (); } @@ -2034,9 +2018,7 @@ TEST (bulk, DISABLED_genesis_pruning) node1->ledger_pruning (2, false, false); ASSERT_EQ (2, node1->ledger.cache.pruned_count); ASSERT_EQ (4, node1->ledger.cache.block_count); - ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send1->hash ())); // true for pruned - ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send2->hash ())); // true for pruned - ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send3->hash ())); + ASSERT_TRUE (nano::test::block_or_pruned_exists (*node2, { send1, send2, send3 })); // Bootstrap with missing blocks for node2 node2->bootstrap_initiator.bootstrap (node1->network.endpoint (), false); node2->network.merge_peer (node1->network.endpoint ()); From 159b27940b3ac79477ef0bbe49a465915cf25330 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Tue, 23 Jan 2024 21:57:11 +0100 Subject: [PATCH 3/5] Node unit tests --- nano/core_test/node.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index a6f3e16928..1f4fefba9b 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -820,16 +820,14 @@ TEST (node, fork_multi_flip) ASSERT_NE (nullptr, election1); ASSERT_EQ (1, election1->votes ().size ()); ASSERT_TRUE (node1.ledger.block_or_pruned_exists (publish1.block->hash ())); - ASSERT_TRUE (node2.ledger.block_or_pruned_exists (publish2.block->hash ())); - ASSERT_TRUE (node2.ledger.block_or_pruned_exists (publish3.block->hash ())); + ASSERT_TRUE (nano::test::block_or_pruned_exists (node2, { publish2.block, publish3.block })); ASSERT_TIMELY (10s, node2.ledger.block_or_pruned_exists (publish1.block->hash ())); auto winner (*election1->tally ().begin ()); ASSERT_EQ (*publish1.block, *winner.second); ASSERT_EQ (nano::dev::constants.genesis_amount - 100, winner.first); ASSERT_TRUE (node1.ledger.block_or_pruned_exists (publish1.block->hash ())); ASSERT_TRUE (node2.ledger.block_or_pruned_exists (publish1.block->hash ())); - ASSERT_FALSE (node2.ledger.block_or_pruned_exists (publish2.block->hash ())); - ASSERT_FALSE (node2.ledger.block_or_pruned_exists (publish3.block->hash ())); + ASSERT_FALSE (nano::test::block_or_pruned_exists (node2, { publish2.block, publish3.block })); } // Blocks that are no longer actively being voted on should be able to be evicted through bootstrapping. @@ -4184,9 +4182,7 @@ TEST (node, pruning_automatic) ASSERT_EQ (1, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (nano::dev::genesis->hash ())); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (send2->hash ())); + ASSERT_TRUE (nano::test::block_or_pruned_exists (node1, { nano::dev::genesis, send1, send2 })); } TEST (node, pruning_age) @@ -4245,9 +4241,7 @@ TEST (node, pruning_age) ASSERT_EQ (1, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (nano::dev::genesis->hash ())); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (send2->hash ())); + ASSERT_TRUE (nano::test::block_or_pruned_exists (node1, { nano::dev::genesis, send1, send2 })); } // Test that a node configured with `enable_pruning` will @@ -4308,9 +4302,7 @@ TEST (node, pruning_depth) ASSERT_EQ (1, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (nano::dev::genesis->hash ())); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_TRUE (node1.ledger.block_or_pruned_exists (send2->hash ())); + ASSERT_TRUE (nano::test::block_or_pruned_exists (node1, { nano::dev::genesis, send1, send2 })); } TEST (node_config, node_id_private_key_persistence) From 68502a1b4844ce05ac1442565ef181043d3f87b4 Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Wed, 24 Jan 2024 13:52:20 +0100 Subject: [PATCH 4/5] Rpc unit test --- nano/rpc_test/rpc.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index f8bba8ae02..4e8cee736b 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -6503,8 +6503,7 @@ TEST (rpc, account_lazy_start) // needs timed assert because the writing (put) operation is done by a different // thread, it might not get done before DB get operation. - ASSERT_TIMELY (10s, node2->ledger.block_or_pruned_exists (send1->hash ())); - ASSERT_TIMELY (10s, node2->ledger.block_or_pruned_exists (open->hash ())); + ASSERT_TIMELY (15s, nano::test::block_or_pruned_exists (*node2, { send1, open })); } TEST (rpc, receive) From 3045222b11e378aec48f4f099b7c3e5ffb86192f Mon Sep 17 00:00:00 2001 From: RickiNano <81099017+RickiNano@users.noreply.github.com> Date: Wed, 24 Jan 2024 21:50:10 +0100 Subject: [PATCH 5/5] Fixed assert_false logic error --- nano/core_test/bootstrap.cpp | 16 ++++++++-------- nano/core_test/node.cpp | 10 +++++----- nano/rpc_test/rpc.cpp | 2 +- nano/test_common/testutil.cpp | 32 +++++++++++++++++++++----------- nano/test_common/testutil.hpp | 18 ++++++++++++++---- 5 files changed, 49 insertions(+), 29 deletions(-) diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index 7255728e57..e4769d0af8 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -1126,7 +1126,7 @@ TEST (bootstrap_processor, DISABLED_lazy_unclear_state_link) node2->bootstrap_initiator.bootstrap_lazy (receive->hash ()); // Check processed blocks ASSERT_TIMELY (10s, !node2->bootstrap_initiator.in_progress ()); - ASSERT_TIMELY (5s, nano::test::block_or_pruned_exists (*node2, { send1, send2, open, receive })); + ASSERT_TIMELY (5s, nano::test::block_or_pruned_all_exists (*node2, { send1, send2, open, receive })); ASSERT_EQ (0, node2->stats.count (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_failed_account, nano::stat::dir::in)); } @@ -1182,7 +1182,7 @@ TEST (bootstrap_processor, lazy_unclear_state_link_not_existing) node2->bootstrap_initiator.bootstrap_lazy (send2->hash ()); // Check processed blocks ASSERT_TIMELY (15s, !node2->bootstrap_initiator.in_progress ()); - ASSERT_TIMELY (15s, nano::test::block_or_pruned_exists (*node2, { send1, open, send2 })); + ASSERT_TIMELY (15s, nano::test::block_or_pruned_all_exists (*node2, { send1, open, send2 })); ASSERT_EQ (1, node2->stats.count (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_failed_account, nano::stat::dir::in)); } @@ -1249,7 +1249,7 @@ TEST (bootstrap_processor, DISABLED_lazy_destinations) node2->bootstrap_initiator.bootstrap_lazy (send2->hash ()); // Check processed blocks ASSERT_TIMELY (10s, !node2->bootstrap_initiator.in_progress ()); - ASSERT_TRUE (nano::test::block_or_pruned_exists (*node2, { send1, send2, open, state_open })); + ASSERT_TRUE (nano::test::block_or_pruned_all_exists (*node2, { send1, send2, open, state_open })); } TEST (bootstrap_processor, lazy_pruning_missing_block) @@ -1321,7 +1321,7 @@ TEST (bootstrap_processor, lazy_pruning_missing_block) node1->ledger_pruning (2, false, false); ASSERT_EQ (5, node1->ledger.cache.block_count); ASSERT_EQ (1, node1->ledger.cache.pruned_count); - ASSERT_TRUE (nano::test::block_or_pruned_exists (*node1, { send1, send2, open, state_open })); + ASSERT_TRUE (nano::test::block_or_pruned_all_exists (*node1, { send1, send2, open, state_open })); // Start lazy bootstrap with last block in sender chain config.peering_port = system.get_available_port (); auto node2 (std::make_shared (system.io_ctx, nano::unique_path (), config, system.work, node_flags, 1)); @@ -1334,7 +1334,7 @@ TEST (bootstrap_processor, lazy_pruning_missing_block) // Some blocks cannot be retrieved from pruned node node2->block_processor.flush (); ASSERT_EQ (1, node2->ledger.cache.block_count); - ASSERT_FALSE (nano::test::block_or_pruned_exists (*node2, { send1, send2, open, state_open })); + ASSERT_TRUE (nano::test::block_or_pruned_none_exists (*node2, { send1, send2, open, state_open })); { auto transaction (node2->store.tx_begin_read ()); ASSERT_TRUE (node2->unchecked.exists (nano::unchecked_key (send2->root ().as_block_hash (), send2->hash ()))); @@ -1345,8 +1345,8 @@ TEST (bootstrap_processor, lazy_pruning_missing_block) ASSERT_TIMELY (5s, !node2->bootstrap_initiator.in_progress ()); node2->block_processor.flush (); ASSERT_EQ (3, node2->ledger.cache.block_count); - ASSERT_TRUE (nano::test::block_or_pruned_exists (*node2, { send1, send2 })); - ASSERT_FALSE (nano::test::block_or_pruned_exists (*node2, { open, state_open })); + ASSERT_TRUE (nano::test::block_or_pruned_all_exists (*node2, { send1, send2 })); + ASSERT_TRUE (nano::test::block_or_pruned_none_exists (*node2, { open, state_open })); node2->stop (); } @@ -2018,7 +2018,7 @@ TEST (bulk, DISABLED_genesis_pruning) node1->ledger_pruning (2, false, false); ASSERT_EQ (2, node1->ledger.cache.pruned_count); ASSERT_EQ (4, node1->ledger.cache.block_count); - ASSERT_TRUE (nano::test::block_or_pruned_exists (*node2, { send1, send2, send3 })); + ASSERT_TRUE (nano::test::block_or_pruned_all_exists (*node2, { send1, send2, send3 })); // Bootstrap with missing blocks for node2 node2->bootstrap_initiator.bootstrap (node1->network.endpoint (), false); node2->network.merge_peer (node1->network.endpoint ()); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 1f4fefba9b..fb04217432 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -820,14 +820,14 @@ TEST (node, fork_multi_flip) ASSERT_NE (nullptr, election1); ASSERT_EQ (1, election1->votes ().size ()); ASSERT_TRUE (node1.ledger.block_or_pruned_exists (publish1.block->hash ())); - ASSERT_TRUE (nano::test::block_or_pruned_exists (node2, { publish2.block, publish3.block })); + ASSERT_TRUE (nano::test::block_or_pruned_all_exists (node2, { publish2.block, publish3.block })); ASSERT_TIMELY (10s, node2.ledger.block_or_pruned_exists (publish1.block->hash ())); auto winner (*election1->tally ().begin ()); ASSERT_EQ (*publish1.block, *winner.second); ASSERT_EQ (nano::dev::constants.genesis_amount - 100, winner.first); ASSERT_TRUE (node1.ledger.block_or_pruned_exists (publish1.block->hash ())); ASSERT_TRUE (node2.ledger.block_or_pruned_exists (publish1.block->hash ())); - ASSERT_FALSE (nano::test::block_or_pruned_exists (node2, { publish2.block, publish3.block })); + ASSERT_TRUE (nano::test::block_or_pruned_none_exists (node2, { publish2.block, publish3.block })); } // Blocks that are no longer actively being voted on should be able to be evicted through bootstrapping. @@ -4182,7 +4182,7 @@ TEST (node, pruning_automatic) ASSERT_EQ (1, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); - ASSERT_TRUE (nano::test::block_or_pruned_exists (node1, { nano::dev::genesis, send1, send2 })); + ASSERT_TRUE (nano::test::block_or_pruned_all_exists (node1, { nano::dev::genesis, send1, send2 })); } TEST (node, pruning_age) @@ -4241,7 +4241,7 @@ TEST (node, pruning_age) ASSERT_EQ (1, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); - ASSERT_TRUE (nano::test::block_or_pruned_exists (node1, { nano::dev::genesis, send1, send2 })); + ASSERT_TRUE (nano::test::block_or_pruned_all_exists (node1, { nano::dev::genesis, send1, send2 })); } // Test that a node configured with `enable_pruning` will @@ -4302,7 +4302,7 @@ TEST (node, pruning_depth) ASSERT_EQ (1, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); - ASSERT_TRUE (nano::test::block_or_pruned_exists (node1, { nano::dev::genesis, send1, send2 })); + ASSERT_TRUE (nano::test::block_or_pruned_all_exists (node1, { nano::dev::genesis, send1, send2 })); } TEST (node_config, node_id_private_key_persistence) diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 4e8cee736b..6b01755150 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -6503,7 +6503,7 @@ TEST (rpc, account_lazy_start) // needs timed assert because the writing (put) operation is done by a different // thread, it might not get done before DB get operation. - ASSERT_TIMELY (15s, nano::test::block_or_pruned_exists (*node2, { send1, open })); + ASSERT_TIMELY (15s, nano::test::block_or_pruned_all_exists (*node2, { send1, open })); } TEST (rpc, receive) diff --git a/nano/test_common/testutil.cpp b/nano/test_common/testutil.cpp index dea953861c..68b6e7ee92 100644 --- a/nano/test_common/testutil.cpp +++ b/nano/test_common/testutil.cpp @@ -115,22 +115,32 @@ bool nano::test::exists (nano::node & node, std::vector hashes) +bool nano::test::block_or_pruned_all_exists (nano::node & node, std::vector hashes) { auto transaction = node.store.tx_begin_read (); - for (const auto & hash : hashes) - { - if (!node.ledger.block_or_pruned_exists (transaction, hash)) - { - return false; - } - } - return true; + return std::all_of (hashes.begin (), hashes.end (), + [&] (const auto & hash) { + return node.ledger.block_or_pruned_exists (transaction, hash); + }); +} + +bool nano::test::block_or_pruned_all_exists (nano::node & node, std::vector> blocks) +{ + return block_or_pruned_all_exists (node, blocks_to_hashes (blocks)); +} + +bool nano::test::block_or_pruned_none_exists (nano::node & node, std::vector hashes) +{ + auto transaction = node.store.tx_begin_read (); + return std::none_of (hashes.begin (), hashes.end (), + [&] (const auto & hash) { + return node.ledger.block_or_pruned_exists (transaction, hash); + }); } -bool nano::test::block_or_pruned_exists (nano::node & node, std::vector> blocks) +bool nano::test::block_or_pruned_none_exists (nano::node & node, std::vector> blocks) { - return block_or_pruned_exists (node, blocks_to_hashes (blocks)); + return block_or_pruned_none_exists (node, blocks_to_hashes (blocks)); } bool nano::test::activate (nano::node & node, std::vector hashes) diff --git a/nano/test_common/testutil.hpp b/nano/test_common/testutil.hpp index 5b885c66b6..26e91dd7fc 100644 --- a/nano/test_common/testutil.hpp +++ b/nano/test_common/testutil.hpp @@ -351,15 +351,25 @@ namespace test */ bool exists (nano::node & node, std::vector> blocks); /* - * Convenience function to check whether a list of hashes exists in node ledger or in the pruned table. + * Convenience function to check whether *all* of the hashes exists in node ledger or in the pruned table. * @return true if all blocks are fully processed and inserted in the ledger, false otherwise */ - bool block_or_pruned_exists (nano::node & node, std::vector hashes); + bool block_or_pruned_all_exists (nano::node & node, std::vector hashes); /* - * Convenience function to check whether a list of blocks exists in node ledger or their hash exists in the pruned table. + * Convenience function to check whether *all* of the blocks exists in node ledger or their hash exists in the pruned table. * @return true if all blocks are fully processed and inserted in the ledger, false otherwise */ - bool block_or_pruned_exists (nano::node & node, std::vector> blocks); + bool block_or_pruned_all_exists (nano::node & node, std::vector> blocks); + /* + * Convenience function to check whether *none* of the hashes exists in node ledger or in the pruned table. + * @return true if none of the blocks are processed and inserted in the ledger, false otherwise + */ + bool block_or_pruned_none_exists (nano::node & node, std::vector hashes); + /* + * Convenience function to check whether *none* of the blocks exists in node ledger or their hash exists in the pruned table. + * @return true if none of the blocks are processed and inserted in the ledger, false otherwise + */ + bool block_or_pruned_none_exists (nano::node & node, std::vector> blocks); /* * Convenience function to start elections for a list of hashes. Blocks are loaded from ledger. * @return true if all blocks exist and were queued to election scheduler