diff --git a/src/test/validationinterface_tests.cpp b/src/test/validationinterface_tests.cpp index 60b4023b8..b49caa2c8 100644 --- a/src/test/validationinterface_tests.cpp +++ b/src/test/validationinterface_tests.cpp @@ -1,92 +1,92 @@ // Copyright (c) 2020 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include #include BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup) struct TestSubscriberNoop final : public CValidationInterface { void BlockChecked(const CBlock &, const BlockValidationState &) override {} }; BOOST_AUTO_TEST_CASE(unregister_validation_interface_race) { std::atomic generate{true}; // Start thread to generate notifications std::thread gen{[&] { const CBlock block_dummy; - const BlockValidationState state_dummy; + BlockValidationState state_dummy; while (generate) { GetMainSignals().BlockChecked(block_dummy, state_dummy); } }}; // Start thread to consume notifications std::thread sub{[&] { // keep going for about 1 sec, which is 250k iterations for (int i = 0; i < 250000; i++) { auto subscriber = std::make_shared(); RegisterSharedValidationInterface(subscriber); UnregisterSharedValidationInterface(subscriber); } // tell the other thread we are done generate = false; }}; gen.join(); sub.join(); BOOST_CHECK(!generate); } class TestInterface : public CValidationInterface { public: TestInterface(std::function on_call = nullptr, std::function on_destroy = nullptr) : m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy)) {} virtual ~TestInterface() { if (m_on_destroy) { m_on_destroy(); } } void BlockChecked(const CBlock &block, const BlockValidationState &state) override { if (m_on_call) { m_on_call(); } } static void Call() { CBlock block; BlockValidationState state; GetMainSignals().BlockChecked(block, state); } std::function m_on_call; std::function m_on_destroy; }; // Regression test to ensure UnregisterAllValidationInterfaces calls don't // destroy a validation interface while it is being called. Bug: // https://github.com/bitcoin/bitcoin/pull/18551 BOOST_AUTO_TEST_CASE(unregister_all_during_call) { bool destroyed = false; RegisterSharedValidationInterface(std::make_shared( [&] { // First call should decrements reference count 2 -> 1 UnregisterAllValidationInterfaces(); BOOST_CHECK(!destroyed); // Second call should not decrement reference count 1 -> 0 UnregisterAllValidationInterfaces(); BOOST_CHECK(!destroyed); }, [&] { destroyed = true; })); TestInterface::Call(); BOOST_CHECK(destroyed); } BOOST_AUTO_TEST_SUITE_END()