Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2020-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <boost/test/unit_test.hpp>6#include <consensus/validation.h>7#include <primitives/block.h>8#include <scheduler.h>9#include <test/util/setup_common.h>10#include <util/check.h>11#include <validationinterface.h>13#include <atomic>14#include <memory>16BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, ChainTestingSetup)18struct TestSubscriberNoop final : public CValidationInterface {19void BlockChecked(const std::shared_ptr<const CBlock>&, const BlockValidationState&) override {}20};22BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)23{24std::atomic<bool> generate{true};26// Start thread to generate notifications27std::thread gen{[&] {28BlockValidationState state_dummy;29while (generate) {30m_node.validation_signals->BlockChecked(std::make_shared<const CBlock>(), state_dummy);31}32}};34// Start thread to consume notifications35std::thread sub{[&] {36// keep going for about 1 sec, which is 250k iterations37for (int i = 0; i < 250000; i++) {38auto sub = std::make_shared<TestSubscriberNoop>();39m_node.validation_signals->RegisterSharedValidationInterface(sub);40m_node.validation_signals->UnregisterSharedValidationInterface(sub);41}42// tell the other thread we are done43generate = false;44}};46gen.join();47sub.join();48BOOST_CHECK(!generate);49}51class TestInterface : public CValidationInterface52{53public:54TestInterface(ValidationSignals& signals, std::function<void()> on_call = nullptr, std::function<void()> on_destroy = nullptr)55: m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy)), m_signals{signals}56{57}58virtual ~TestInterface()59{60if (m_on_destroy) m_on_destroy();61}62void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& state) override63{64if (m_on_call) m_on_call();65}66void Call()67{68BlockValidationState state;69m_signals.BlockChecked(std::make_shared<const CBlock>(), state);70}71std::function<void()> m_on_call;72std::function<void()> m_on_destroy;73ValidationSignals& m_signals;74};76// Regression test to ensure UnregisterAllValidationInterfaces calls don't77// destroy a validation interface while it is being called. Bug:78// https://github.com/bitcoin/bitcoin/pull/1855179BOOST_AUTO_TEST_CASE(unregister_all_during_call)80{81bool destroyed = false;82auto shared{std::make_shared<TestInterface>(83*m_node.validation_signals,84[&] {85// First call should decrements reference count 2 -> 186m_node.validation_signals->UnregisterAllValidationInterfaces();87BOOST_CHECK(!destroyed);88// Second call should not decrement reference count 1 -> 089m_node.validation_signals->UnregisterAllValidationInterfaces();90BOOST_CHECK(!destroyed);91},92[&] { destroyed = true; })};93m_node.validation_signals->RegisterSharedValidationInterface(shared);94BOOST_CHECK(shared.use_count() == 2);95shared->Call();96BOOST_CHECK(shared.use_count() == 1);97BOOST_CHECK(!destroyed);98shared.reset();99BOOST_CHECK(destroyed);100}102BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.