Skip to content

Commit 1d9f1cb

Browse files
committed
kernel: improve BlockChecked ownership semantics
Subscribers to the BlockChecked validation interface event may need access to the block outside of the callback scope. Currently, this is only possible by copying the block, which makes exposing this validation interface event publicly either cumbersome or with significant copy overhead. By using shared_ptr, we make the shared ownership explicit and allow users to safely use the block outside of the callback scope.
1 parent 9ba1fff commit 1d9f1cb

File tree

8 files changed

+24
-22
lines changed

8 files changed

+24
-22
lines changed

src/bitcoin-chainstate.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ int main(int argc, char* argv[])
200200
explicit submitblock_StateCatcher(const uint256& hashIn) : hash(hashIn), found(false), state() {}
201201

202202
protected:
203-
void BlockChecked(const CBlock& block, const BlockValidationState& stateIn) override
203+
void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& stateIn) override
204204
{
205-
if (block.GetHash() != hash)
205+
if (block->GetHash() != hash)
206206
return;
207207
found = true;
208208
state = stateIn;

src/net_processing.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ class PeerManagerImpl final : public PeerManager
513513
EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
514514
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
515515
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
516-
void BlockChecked(const CBlock& block, const BlockValidationState& state) override
516+
void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& state) override
517517
EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
518518
void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& pblock) override
519519
EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex);
@@ -2103,11 +2103,11 @@ void PeerManagerImpl::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlock
21032103
* Handle invalid block rejection and consequent peer discouragement, maintain which
21042104
* peers announce compact blocks.
21052105
*/
2106-
void PeerManagerImpl::BlockChecked(const CBlock& block, const BlockValidationState& state)
2106+
void PeerManagerImpl::BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& state)
21072107
{
21082108
LOCK(cs_main);
21092109

2110-
const uint256 hash(block.GetHash());
2110+
const uint256 hash(block->GetHash());
21112111
std::map<uint256, std::pair<NodeId, bool>>::iterator it = mapBlockSource.find(hash);
21122112

21132113
// If the block failed validation, we know where it came from and we're still connected

src/rpc/mining.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,9 +1030,9 @@ class submitblock_StateCatcher final : public CValidationInterface
10301030
explicit submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), state() {}
10311031

10321032
protected:
1033-
void BlockChecked(const CBlock& block, const BlockValidationState& stateIn) override {
1034-
if (block.GetHash() != hash)
1035-
return;
1033+
void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& stateIn) override
1034+
{
1035+
if (block->GetHash() != hash) return;
10361036
found = true;
10371037
state = stateIn;
10381038
}

src/test/util/mining.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <versionbits.h>
1919

2020
#include <algorithm>
21+
#include <memory>
2122

2223
using node::BlockAssembler;
2324
using node::NodeContext;
@@ -83,9 +84,9 @@ struct BlockValidationStateCatcher : public CValidationInterface {
8384
m_state{} {}
8485

8586
protected:
86-
void BlockChecked(const CBlock& block, const BlockValidationState& state) override
87+
void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& state) override
8788
{
88-
if (block.GetHash() != m_hash) return;
89+
if (block->GetHash() != m_hash) return;
8990
m_state = state;
9091
}
9192
};

src/test/validationinterface_tests.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
#include <validationinterface.h>
1313

1414
#include <atomic>
15+
#include <memory>
1516

1617
BOOST_FIXTURE_TEST_SUITE(validationinterface_tests, ChainTestingSetup)
1718

1819
struct TestSubscriberNoop final : public CValidationInterface {
19-
void BlockChecked(const CBlock&, const BlockValidationState&) override {}
20+
void BlockChecked(const std::shared_ptr<const CBlock>&, const BlockValidationState&) override {}
2021
};
2122

2223
BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
@@ -25,10 +26,9 @@ BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
2526

2627
// Start thread to generate notifications
2728
std::thread gen{[&] {
28-
const CBlock block_dummy;
2929
BlockValidationState state_dummy;
3030
while (generate) {
31-
m_node.validation_signals->BlockChecked(block_dummy, state_dummy);
31+
m_node.validation_signals->BlockChecked(std::make_shared<const CBlock>(), state_dummy);
3232
}
3333
}};
3434

@@ -60,15 +60,14 @@ class TestInterface : public CValidationInterface
6060
{
6161
if (m_on_destroy) m_on_destroy();
6262
}
63-
void BlockChecked(const CBlock& block, const BlockValidationState& state) override
63+
void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& state) override
6464
{
6565
if (m_on_call) m_on_call();
6666
}
6767
void Call()
6868
{
69-
CBlock block;
7069
BlockValidationState state;
71-
m_signals.BlockChecked(block, state);
70+
m_signals.BlockChecked(std::make_shared<const CBlock>(), state);
7271
}
7372
std::function<void()> m_on_call;
7473
std::function<void()> m_on_destroy;

src/validation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3178,7 +3178,7 @@ bool Chainstate::ConnectTip(
31783178
CCoinsViewCache view(&CoinsTip());
31793179
bool rv = ConnectBlock(*block_to_connect, state, pindexNew, view);
31803180
if (m_chainman.m_options.signals) {
3181-
m_chainman.m_options.signals->BlockChecked(*block_to_connect, state);
3181+
m_chainman.m_options.signals->BlockChecked(block_to_connect, state);
31823182
}
31833183
if (!rv) {
31843184
if (state.IsInvalid())
@@ -4554,7 +4554,7 @@ bool ChainstateManager::ProcessNewBlock(const std::shared_ptr<const CBlock>& blo
45544554
}
45554555
if (!ret) {
45564556
if (m_options.signals) {
4557-
m_options.signals->BlockChecked(*block, state);
4557+
m_options.signals->BlockChecked(block, state);
45584558
}
45594559
LogError("%s: AcceptBlock FAILED (%s)\n", __func__, state.ToString());
45604560
return false;

src/validationinterface.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <util/task_runner.h>
1818

1919
#include <future>
20+
#include <memory>
2021
#include <unordered_map>
2122
#include <utility>
2223

@@ -245,9 +246,10 @@ void ValidationSignals::ChainStateFlushed(ChainstateRole role, const CBlockLocat
245246
locator.IsNull() ? "null" : locator.vHave.front().ToString());
246247
}
247248

248-
void ValidationSignals::BlockChecked(const CBlock& block, const BlockValidationState& state) {
249+
void ValidationSignals::BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& state)
250+
{
249251
LOG_EVENT("%s: block hash=%s state=%s", __func__,
250-
block.GetHash().ToString(), state.ToString());
252+
block->GetHash().ToString(), state.ToString());
251253
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.BlockChecked(block, state); });
252254
}
253255

src/validationinterface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class CValidationInterface {
150150
* is guaranteed to be the current best block at the time the
151151
* callback was generated (not necessarily now).
152152
*/
153-
virtual void BlockChecked(const CBlock&, const BlockValidationState&) {}
153+
virtual void BlockChecked(const std::shared_ptr<const CBlock>&, const BlockValidationState&) {}
154154
/**
155155
* Notifies listeners that a block which builds directly on our current tip
156156
* has been received and connected to the headers tree, though not validated yet.
@@ -224,7 +224,7 @@ class ValidationSignals {
224224
void BlockConnected(ChainstateRole, const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex);
225225
void BlockDisconnected(const std::shared_ptr<const CBlock> &, const CBlockIndex* pindex);
226226
void ChainStateFlushed(ChainstateRole, const CBlockLocator &);
227-
void BlockChecked(const CBlock&, const BlockValidationState&);
227+
void BlockChecked(const std::shared_ptr<const CBlock>&, const BlockValidationState&);
228228
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);
229229
};
230230

0 commit comments

Comments
 (0)