Bitcoin Core 30.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 <validationinterface.h>
12
13#include <atomic>
14#include <memory>
15
16BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, ChainTestingSetup)
17
19 void BlockChecked(const std::shared_ptr<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 BlockValidationState state_dummy;
29 while (generate) {
30 m_node.validation_signals->BlockChecked(std::make_shared<const CBlock>(), state_dummy);
31 }
32 }};
33
34 // Start thread to consume notifications
35 std::thread sub{[&] {
36 // keep going for about 1 sec, which is 250k iterations
37 for (int i = 0; i < 250000; i++) {
38 auto sub = std::make_shared<TestSubscriberNoop>();
39 m_node.validation_signals->RegisterSharedValidationInterface(sub);
40 m_node.validation_signals->UnregisterSharedValidationInterface(sub);
41 }
42 // tell the other thread we are done
43 generate = false;
44 }};
45
46 gen.join();
47 sub.join();
49}
50
52{
53public:
54 TestInterface(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 }
59 {
61 }
62 void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& state) override
63 {
64 if (m_on_call) m_on_call();
65 }
66 void Call()
67 {
69 m_signals.BlockChecked(std::make_shared<const CBlock>(), state);
70 }
71 std::function<void()> m_on_call;
72 std::function<void()> m_on_destroy;
74};
75
76// Regression test to ensure UnregisterAllValidationInterfaces calls don't
77// destroy a validation interface while it is being called. Bug:
78// https://github.com/bitcoin/bitcoin/pull/18551
79BOOST_AUTO_TEST_CASE(unregister_all_during_call)
80{
81 bool destroyed = false;
82 auto shared{std::make_shared<TestInterface>(
84 [&] {
85 // First call should decrements reference count 2 -> 1
86 m_node.validation_signals->UnregisterAllValidationInterfaces();
87 BOOST_CHECK(!destroyed);
88 // Second call should not decrement reference count 1 -> 0
89 m_node.validation_signals->UnregisterAllValidationInterfaces();
90 BOOST_CHECK(!destroyed);
91 },
92 [&] { destroyed = true; })};
93 m_node.validation_signals->RegisterSharedValidationInterface(shared);
94 BOOST_CHECK(shared.use_count() == 2);
95 shared->Call();
96 BOOST_CHECK(shared.use_count() == 1);
97 BOOST_CHECK(!destroyed);
98 shared.reset();
99 BOOST_CHECK(destroyed);
100}
101
node::NodeContext m_node
Definition: bitcoin-gui.cpp:43
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 std::shared_ptr< const CBlock > &block, const BlockValidationState &state) override
Notifies listeners of a block validation result.
std::function< void()> m_on_destroy
void BlockChecked(const std::shared_ptr< 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:257
Testing setup that performs all steps up until right before ChainstateManager gets initialized.
Definition: setup_common.h:106
void BlockChecked(const std::shared_ptr< 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)