Bitcoin Core 28.99.0
P2P Digital Currency
validationinterface_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2020 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <boost/test/unit_test.hpp>
7#include <primitives/block.h>
8#include <scheduler.h>
10#include <util/check.h>
11#include <kernel/chain.h>
12#include <validationinterface.h>
13
14#include <atomic>
15
16BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, ChainTestingSetup)
17
19 void BlockChecked(const CBlock&, const BlockValidationState&) override {}
20};
21
22BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
23{
24 std::atomic<bool> generate{true};
25
26 // Start thread to generate notifications
27 std::thread gen{[&] {
28 const CBlock block_dummy;
29 BlockValidationState state_dummy;
30 while (generate) {
31 m_node.validation_signals->BlockChecked(block_dummy, state_dummy);
32 }
33 }};
34
35 // Start thread to consume notifications
36 std::thread sub{[&] {
37 // keep going for about 1 sec, which is 250k iterations
38 for (int i = 0; i < 250000; i++) {
39 auto sub = std::make_shared<TestSubscriberNoop>();
40 m_node.validation_signals->RegisterSharedValidationInterface(sub);
41 m_node.validation_signals->UnregisterSharedValidationInterface(sub);
42 }
43 // tell the other thread we are done
44 generate = false;
45 }};
46
47 gen.join();
48 sub.join();
50}
51
53{
54public:
55 TestInterface(ValidationSignals& signals, std::function<void()> on_call = nullptr, std::function<void()> on_destroy = nullptr)
56 : m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy)), m_signals{signals}
57 {
58 }
60 {
62 }
63 void BlockChecked(const CBlock& block, const BlockValidationState& state) override
64 {
65 if (m_on_call) m_on_call();
66 }
67 void Call()
68 {
69 CBlock block;
71 m_signals.BlockChecked(block, state);
72 }
73 std::function<void()> m_on_call;
74 std::function<void()> m_on_destroy;
76};
77
78// Regression test to ensure UnregisterAllValidationInterfaces calls don't
79// destroy a validation interface while it is being called. Bug:
80// https://github.com/bitcoin/bitcoin/pull/18551
81BOOST_AUTO_TEST_CASE(unregister_all_during_call)
82{
83 bool destroyed = false;
84 auto shared{std::make_shared<TestInterface>(
86 [&] {
87 // First call should decrements reference count 2 -> 1
88 m_node.validation_signals->UnregisterAllValidationInterfaces();
89 BOOST_CHECK(!destroyed);
90 // Second call should not decrement reference count 1 -> 0
91 m_node.validation_signals->UnregisterAllValidationInterfaces();
92 BOOST_CHECK(!destroyed);
93 },
94 [&] { destroyed = true; })};
95 m_node.validation_signals->RegisterSharedValidationInterface(shared);
96 BOOST_CHECK(shared.use_count() == 2);
97 shared->Call();
98 BOOST_CHECK(shared.use_count() == 1);
99 BOOST_CHECK(!destroyed);
100 shared.reset();
101 BOOST_CHECK(destroyed);
102}
103
node::NodeContext m_node
Definition: bitcoin-gui.cpp:42
Definition: block.h:69
Implement this to subscribe to events generated in validation and mempool.
ValidationSignals & m_signals
TestInterface(ValidationSignals &signals, std::function< void()> on_call=nullptr, std::function< void()> on_destroy=nullptr)
std::function< void()> m_on_call
void BlockChecked(const CBlock &block, const BlockValidationState &state) override
Notifies listeners of a block validation result.
std::function< void()> m_on_destroy
void BlockChecked(const CBlock &, const BlockValidationState &)
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK(expr)
Definition: object.cpp:17
static RPCHelpMan generate()
Definition: mining.cpp:254
Testing setup that performs all steps up until right before ChainstateManager gets initialized.
Definition: setup_common.h:105
void BlockChecked(const CBlock &, const BlockValidationState &) override
Notifies listeners of a block validation result.
std::unique_ptr< ValidationSignals > validation_signals
Issues calls about blocks and transactions.
Definition: context.h:88
BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)