Bitcoin Core  31.0.0
P2P Digital Currency
validationinterface_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2020-present 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 #include <atomic>
14 #include <memory>
15 
16 BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, ChainTestingSetup)
17 
19  void BlockChecked(const std::shared_ptr<const CBlock>&, const BlockValidationState&) override {}
20 };
21 
22 BOOST_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 {
53 public:
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  }
58  virtual ~TestInterface()
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
79 BOOST_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 
Testing setup that performs all steps up until right before ChainstateManager gets initialized...
Definition: setup_common.h:106
std::function< void()> m_on_destroy
node::NodeContext m_node
Definition: bitcoin-gui.cpp:43
TestInterface(ValidationSignals &signals, std::function< void()> on_call=nullptr, std::function< void()> on_destroy=nullptr)
BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
std::unique_ptr< ValidationSignals > validation_signals
Issues calls about blocks and transactions.
Definition: context.h:88
Definition: common.h:29
void BlockChecked(const std::shared_ptr< const CBlock > &, const BlockValidationState &) override
Notifies listeners of a block validation result.
Implement this to subscribe to events generated in validation and mempool.
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()
std::function< void()> m_on_call
static RPCHelpMan generate()
Definition: mining.cpp:257
void BlockChecked(const std::shared_ptr< const CBlock > &block, const BlockValidationState &state) override
Notifies listeners of a block validation result.
ValidationSignals & m_signals
#define BOOST_CHECK(expr)
Definition: object.cpp:16