From 50f4c69d4630e9a8b85c3e08d3aa69ee120db764 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Wed, 22 May 2024 12:57:21 -0400 Subject: [PATCH] Change race_volume::finish(...) to return true on first sufficient. --- .../bitcoin/network/async/race_quality.hpp | 2 +- include/bitcoin/network/async/race_speed.hpp | 2 +- include/bitcoin/network/async/race_volume.hpp | 2 +- .../network/impl/async/race_volume.ipp | 7 ++-- test/async/race_volume.cpp | 36 +++++++++---------- 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/include/bitcoin/network/async/race_quality.hpp b/include/bitcoin/network/async/race_quality.hpp index 9a4b9d081..5a3c6afa0 100644 --- a/include/bitcoin/network/async/race_quality.hpp +++ b/include/bitcoin/network/async/race_quality.hpp @@ -52,7 +52,7 @@ class race_quality final /// False implies invalid usage. bool start(handler&& complete) NOEXCEPT; - /// True implies winning finisher (first not failed). + /// True implies winning finisher (first that is not failed). /// First arg is an 'error code', cast to bool (failed if true). /// There may be no winner, in which case last finish is invoked. bool finish(const Args&... args) NOEXCEPT; diff --git a/include/bitcoin/network/async/race_speed.hpp b/include/bitcoin/network/async/race_speed.hpp index 0cb70a775..a51af04ae 100644 --- a/include/bitcoin/network/async/race_speed.hpp +++ b/include/bitcoin/network/async/race_speed.hpp @@ -54,7 +54,7 @@ class race_speed final /// False implies invalid usage. bool start(handler&& complete) NOEXCEPT; - /// True implies winning finisher. + /// True implies winning finisher, there is always exactly one. bool finish(const Args&... args) NOEXCEPT; private: diff --git a/include/bitcoin/network/async/race_volume.hpp b/include/bitcoin/network/async/race_volume.hpp index 67c79f58d..c8816d67a 100644 --- a/include/bitcoin/network/async/race_volume.hpp +++ b/include/bitcoin/network/async/race_volume.hpp @@ -52,7 +52,7 @@ class race_volume final /// False implies invalid usage. bool start(handler&& sufficient, handler&& complete) NOEXCEPT; - /// Signal finisher and pass total count. + /// True implies first sufficient count (there may be none). bool finish(size_t count) NOEXCEPT; private: diff --git a/include/bitcoin/network/impl/async/race_volume.ipp b/include/bitcoin/network/impl/async/race_volume.ipp index e13906d5d..7d36bf23b 100644 --- a/include/bitcoin/network/impl/async/race_volume.ipp +++ b/include/bitcoin/network/impl/async/race_volume.ipp @@ -74,12 +74,15 @@ finish(size_t count) NOEXCEPT if (!running()) return false; - // Determine sufficiency, since not yet reached. + bool winner{ false }; + + // Determine sufficiency if not yet reached. if (sufficient_) { // Invoke sufficient and clear resources before race is finished. if (count >= required_) { + winner = true; (*sufficient_)(Success); sufficient_.reset(); } @@ -91,7 +94,7 @@ finish(size_t count) NOEXCEPT } // false invoke implies logic error. - return invoke(); + return invoke() && winner; } // private diff --git a/test/async/race_volume.cpp b/test/async/race_volume.cpp index 01fe6b2bc..e09d016cd 100644 --- a/test/async/race_volume.cpp +++ b/test/async/race_volume.cpp @@ -41,9 +41,9 @@ BOOST_AUTO_TEST_CASE(race_volume__start__unstarted__true_running) BOOST_REQUIRE(race_volume.running()); // Avoid running at destruct assertion. - BOOST_REQUIRE(race_volume.finish(2)); + BOOST_REQUIRE(!race_volume.finish(2)); BOOST_REQUIRE(race_volume.running()); - BOOST_REQUIRE(race_volume.finish(4)); + BOOST_REQUIRE(!race_volume.finish(4)); BOOST_REQUIRE(!race_volume.running()); } @@ -55,11 +55,11 @@ BOOST_AUTO_TEST_CASE(race_volume__start__started__false_running) BOOST_REQUIRE(race_volume.running()); // Avoid running at destruct assertion. - BOOST_REQUIRE(race_volume.finish(1)); + BOOST_REQUIRE(!race_volume.finish(1)); BOOST_REQUIRE(!race_volume.running()); } -BOOST_AUTO_TEST_CASE(race_volume__running__3_of_3__failed_sufficient_complete) +BOOST_AUTO_TEST_CASE(race_volume__running__3_of_3__insufficient_complete) { race_volume_t race_volume{ 3, 10 }; BOOST_REQUIRE(!race_volume.running()); @@ -79,23 +79,23 @@ BOOST_AUTO_TEST_CASE(race_volume__running__3_of_3__failed_sufficient_complete) BOOST_REQUIRE_EQUAL(sufficient, error::unknown); BOOST_REQUIRE_EQUAL(complete, error::unknown); - BOOST_REQUIRE(race_volume.finish(1)); + BOOST_REQUIRE(!race_volume.finish(1)); BOOST_REQUIRE(race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient, error::unknown); BOOST_REQUIRE_EQUAL(complete, error::unknown); - BOOST_REQUIRE(race_volume.finish(1)); + BOOST_REQUIRE(!race_volume.finish(1)); BOOST_REQUIRE(race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient, error::unknown); BOOST_REQUIRE_EQUAL(complete, error::unknown); - BOOST_REQUIRE(race_volume.finish(1)); + BOOST_REQUIRE(!race_volume.finish(1)); BOOST_REQUIRE(!race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient, error::invalid_magic); BOOST_REQUIRE_EQUAL(complete, error::success); } -BOOST_AUTO_TEST_CASE(race_volume__running__4_of_3__false_finish) +BOOST_AUTO_TEST_CASE(race_volume__running__4_of_3__insufficient) { race_volume_t race_volume{ 3, 10 }; BOOST_REQUIRE(!race_volume.running()); @@ -112,9 +112,9 @@ BOOST_AUTO_TEST_CASE(race_volume__running__4_of_3__false_finish) complete = ec; })); BOOST_REQUIRE(race_volume.running()); - BOOST_REQUIRE(race_volume.finish(1)); - BOOST_REQUIRE(race_volume.finish(1)); - BOOST_REQUIRE(race_volume.finish(1)); + BOOST_REQUIRE(!race_volume.finish(1)); + BOOST_REQUIRE(!race_volume.finish(1)); + BOOST_REQUIRE(!race_volume.finish(1)); BOOST_REQUIRE(!race_volume.finish(1)); } @@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE(race_volume__finish__early_sufficiency__resources_deleted_a BOOST_REQUIRE(!bar_deleted); // First finish is neither sufficient nor complete. - BOOST_REQUIRE(race_volume.finish(5)); + BOOST_REQUIRE(!race_volume.finish(5)); BOOST_REQUIRE(race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient.first, error::unknown); BOOST_REQUIRE_EQUAL(complete.first, error::unknown); @@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(race_volume__finish__early_sufficiency__resources_deleted_a BOOST_REQUIRE(!bar_deleted); // Third finish is complete. - BOOST_REQUIRE(race_volume.finish(42)); + BOOST_REQUIRE(!race_volume.finish(42)); BOOST_REQUIRE(!race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient.first, error::success); BOOST_REQUIRE_EQUAL(complete.first, error::success); @@ -222,7 +222,7 @@ BOOST_AUTO_TEST_CASE(race_volume__finish__late_insufficiency__resources_deleted_ BOOST_REQUIRE(!bar_deleted); // First finish is neither sufficient nor complete. - BOOST_REQUIRE(race_volume.finish(5)); + BOOST_REQUIRE(!race_volume.finish(5)); BOOST_REQUIRE(race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient.first, error::unknown); BOOST_REQUIRE_EQUAL(complete.first, error::unknown); @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(race_volume__finish__late_insufficiency__resources_deleted_ BOOST_REQUIRE(!bar_deleted); // Second finish is neither sufficient nor complete. - BOOST_REQUIRE(race_volume.finish(9)); + BOOST_REQUIRE(!race_volume.finish(9)); BOOST_REQUIRE(race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient.first, error::unknown); BOOST_REQUIRE_EQUAL(complete.first, error::unknown); @@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(race_volume__finish__late_insufficiency__resources_deleted_ BOOST_REQUIRE(!bar_deleted); // Third finish is insufficient and complete. - BOOST_REQUIRE(race_volume.finish(9)); + BOOST_REQUIRE(!race_volume.finish(9)); BOOST_REQUIRE(!race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient.first, error::invalid_magic); BOOST_REQUIRE_EQUAL(complete.first, error::success); @@ -289,7 +289,7 @@ BOOST_AUTO_TEST_CASE(race_volume__finish__late_sufficiency__resources_deleted_as BOOST_REQUIRE(!bar_deleted); // First finish is neither sufficient nor complete. - BOOST_REQUIRE(race_volume.finish(5)); + BOOST_REQUIRE(!race_volume.finish(5)); BOOST_REQUIRE(race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient.first, error::unknown); BOOST_REQUIRE_EQUAL(complete.first, error::unknown); @@ -299,7 +299,7 @@ BOOST_AUTO_TEST_CASE(race_volume__finish__late_sufficiency__resources_deleted_as BOOST_REQUIRE(!bar_deleted); // Second finish is neither sufficient nor complete. - BOOST_REQUIRE(race_volume.finish(9)); + BOOST_REQUIRE(!race_volume.finish(9)); BOOST_REQUIRE(race_volume.running()); BOOST_REQUIRE_EQUAL(sufficient.first, error::unknown); BOOST_REQUIRE_EQUAL(complete.first, error::unknown);