Bitcoin Core  22.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>
6 #include <consensus/validation.h>
7 #include <primitives/block.h>
8 #include <scheduler.h>
10 #include <util/check.h>
11 #include <validationinterface.h>
12 
13 BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, TestingSetup)
14 
16  void BlockChecked(const CBlock&, const BlockValidationState&) override {}
17 };
18 
19 BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
20 {
21  std::atomic<bool> generate{true};
22 
23  // Start thread to generate notifications
24  std::thread gen{[&] {
25  const CBlock block_dummy;
26  BlockValidationState state_dummy;
27  while (generate) {
28  GetMainSignals().BlockChecked(block_dummy, state_dummy);
29  }
30  }};
31 
32  // Start thread to consume notifications
33  std::thread sub{[&] {
34  // keep going for about 1 sec, which is 250k iterations
35  for (int i = 0; i < 250000; i++) {
36  auto sub = std::make_shared<TestSubscriberNoop>();
39  }
40  // tell the other thread we are done
41  generate = false;
42  }};
43 
44  gen.join();
45  sub.join();
47 }
48 
50 {
51 public:
52  TestInterface(std::function<void()> on_call = nullptr, std::function<void()> on_destroy = nullptr)
53  : m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy))
54  {
55  }
56  virtual ~TestInterface()
57  {
59  }
60  void BlockChecked(const CBlock& block, const BlockValidationState& state) override
61  {
62  if (m_on_call) m_on_call();
63  }
64  static void Call()
65  {
66  CBlock block;
68  GetMainSignals().BlockChecked(block, state);
69  }
70  std::function<void()> m_on_call;
71  std::function<void()> m_on_destroy;
72 };
73 
74 // Regression test to ensure UnregisterAllValidationInterfaces calls don't
75 // destroy a validation interface while it is being called. Bug:
76 // https://github.com/bitcoin/bitcoin/pull/18551
77 BOOST_AUTO_TEST_CASE(unregister_all_during_call)
78 {
79  bool destroyed = false;
80  RegisterSharedValidationInterface(std::make_shared<TestInterface>(
81  [&] {
82  // First call should decrements reference count 2 -> 1
84  BOOST_CHECK(!destroyed);
85  // Second call should not decrement reference count 1 -> 0
87  BOOST_CHECK(!destroyed);
88  },
89  [&] { destroyed = true; }));
91  BOOST_CHECK(destroyed);
92 }
93 
CValidationInterface
Implement this to subscribe to events generated in validation.
Definition: validationinterface.h:78
block.h
TestSubscriberNoop
Definition: validationinterface_tests.cpp:15
RegisterSharedValidationInterface
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.
Definition: validationinterface.cpp:121
check.h
BlockValidationState
Definition: validation.h:140
TestInterface::m_on_destroy
std::function< void()> m_on_destroy
Definition: validationinterface_tests.cpp:71
setup_common.h
TestInterface::BlockChecked
void BlockChecked(const CBlock &block, const BlockValidationState &state) override
Notifies listeners of a block validation result.
Definition: validationinterface_tests.cpp:60
validationinterface.h
validation.h
CMainSignals::BlockChecked
void BlockChecked(const CBlock &, const BlockValidationState &)
Definition: validationinterface.cpp:247
BOOST_FIXTURE_TEST_SUITE
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
scheduler.h
GetMainSignals
CMainSignals & GetMainSignals()
Definition: validationinterface.cpp:116
TestInterface::TestInterface
TestInterface(std::function< void()> on_call=nullptr, std::function< void()> on_destroy=nullptr)
Definition: validationinterface_tests.cpp:52
UnregisterSharedValidationInterface
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
Definition: validationinterface.cpp:135
TestInterface::Call
static void Call()
Definition: validationinterface_tests.cpp:64
TestInterface::m_on_call
std::function< void()> m_on_call
Definition: validationinterface_tests.cpp:70
UnregisterAllValidationInterfaces
void UnregisterAllValidationInterfaces()
Unregister all subscribers.
Definition: validationinterface.cpp:147
CBlock
Definition: block.h:62
TestInterface::~TestInterface
virtual ~TestInterface()
Definition: validationinterface_tests.cpp:56
TestSubscriberNoop::BlockChecked
void BlockChecked(const CBlock &, const BlockValidationState &) override
Notifies listeners of a block validation result.
Definition: validationinterface_tests.cpp:16
TestingSetup
Testing setup that configures a complete environment.
Definition: setup_common.h:99
generate
static RPCHelpMan generate()
Definition: mining.cpp:247
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
Definition: validationinterface_tests.cpp:19
TestInterface
Definition: validationinterface_tests.cpp:49
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition: object.cpp:17