git / moonbite-core / src/test/validationinterface_tests.cpp · raw
// 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 <boost/test/unit_test.hpp>#include <consensus/validation.h>#include <primitives/block.h>#include <scheduler.h>#include <test/util/setup_common.h>#include <util/check.h>#include <validationinterface.h>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<bool> generate{true}; // Start thread to generate notifications std::thread gen{[&] { const CBlock block_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 sub = std::make_shared<TestSubscriberNoop>(); RegisterSharedValidationInterface(sub); UnregisterSharedValidationInterface(sub); } // tell the other thread we are done generate = false; }}; gen.join(); sub.join(); BOOST_CHECK(!generate);}class TestInterface : public CValidationInterface{public: TestInterface(std::function<void()> on_call = nullptr, std::function<void()> 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<void()> m_on_call; std::function<void()> 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/18551BOOST_AUTO_TEST_CASE(unregister_all_during_call){ bool destroyed = false; RegisterSharedValidationInterface(std::make_shared<TestInterface>( [&] { // 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()