Skip to content

Commit b7700b3

Browse files
committed
trivial: use std::atomic to protect connected signer pointers
1 parent 893b46a commit b7700b3

File tree

4 files changed

+41
-38
lines changed

4 files changed

+41
-38
lines changed

src/chainlock/chainlock.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,18 @@ CChainLocksHandler::~CChainLocksHandler()
6464

6565
void CChainLocksHandler::Start(const llmq::CInstantSendManager& isman)
6666
{
67-
if (m_signer) {
68-
m_signer->Start();
67+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
68+
signer->Start();
6969
}
7070
scheduler->scheduleEvery(
7171
[&]() {
72+
auto signer = m_signer.load(std::memory_order_acquire);
7273
CheckActiveState();
7374
EnforceBestChainLock();
7475
Cleanup();
7576
// regularly retry signing the current chaintip as it might have failed before due to missing islocks
76-
if (m_signer) {
77-
m_signer->TrySignChainTip(isman);
77+
if (signer) {
78+
signer->TrySignChainTip(isman);
7879
}
7980
},
8081
std::chrono::seconds{5});
@@ -83,8 +84,8 @@ void CChainLocksHandler::Start(const llmq::CInstantSendManager& isman)
8384
void CChainLocksHandler::Stop()
8485
{
8586
scheduler->stop();
86-
if (m_signer) {
87-
m_signer->Stop();
87+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
88+
signer->Stop();
8889
}
8990
}
9091

@@ -218,11 +219,12 @@ void CChainLocksHandler::UpdatedBlockTip(const llmq::CInstantSendManager& isman)
218219
if (bool expected = false; tryLockChainTipScheduled.compare_exchange_strong(expected, true)) {
219220
scheduler->scheduleFromNow(
220221
[&]() {
222+
auto signer = m_signer.load(std::memory_order_acquire);
221223
CheckActiveState();
222224
EnforceBestChainLock();
223225
Cleanup();
224-
if (m_signer) {
225-
m_signer->TrySignChainTip(isman);
226+
if (signer) {
227+
signer->TrySignChainTip(isman);
226228
}
227229
tryLockChainTipScheduled = false;
228230
},
@@ -274,16 +276,16 @@ void CChainLocksHandler::BlockConnected(const std::shared_ptr<const CBlock>& pbl
274276
}
275277

276278
// We need this information later when we try to sign a new tip, so that we can determine if all included TXs are safe.
277-
if (m_signer) {
278-
m_signer->UpdateBlockHashTxidMap(pindex->GetBlockHash(), pblock->vtx);
279+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
280+
signer->UpdateBlockHashTxidMap(pindex->GetBlockHash(), pblock->vtx);
279281
}
280282
}
281283

282284
void CChainLocksHandler::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock,
283285
gsl::not_null<const CBlockIndex*> pindexDisconnected)
284286
{
285-
if (m_signer) {
286-
m_signer->EraseFromBlockHashTxidMap(pindexDisconnected->GetBlockHash());
287+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
288+
signer->EraseFromBlockHashTxidMap(pindexDisconnected->GetBlockHash());
287289
}
288290
}
289291

@@ -451,8 +453,8 @@ void CChainLocksHandler::Cleanup()
451453
}
452454
}
453455

454-
if (m_signer) {
455-
const auto cleanup_txes{m_signer->Cleanup()};
456+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
457+
const auto cleanup_txes{signer->Cleanup()};
456458
LOCK(cs);
457459
for (const auto& tx : cleanup_txes) {
458460
for (const auto& txid : *tx) {

src/chainlock/chainlock.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class CChainLocksHandler final : public chainlock::ChainLockSignerParent
4646
std::unique_ptr<CScheduler> scheduler;
4747
std::unique_ptr<std::thread> scheduler_thread;
4848

49-
chainlock::ChainLockSigner* m_signer{nullptr};
49+
std::atomic<chainlock::ChainLockSigner*> m_signer{nullptr};
5050

5151
mutable Mutex cs;
5252
std::atomic<bool> tryLockChainTipScheduled{false};
@@ -73,10 +73,10 @@ class CChainLocksHandler final : public chainlock::ChainLockSignerParent
7373
void ConnectSigner(gsl::not_null<chainlock::ChainLockSigner*> signer)
7474
{
7575
// Prohibit double initialization
76-
assert(m_signer == nullptr);
77-
m_signer = signer;
76+
assert(m_signer.load(std::memory_order_acquire) == nullptr);
77+
m_signer.store(signer, std::memory_order_release);
7878
}
79-
void DisconnectSigner() { m_signer = nullptr; }
79+
void DisconnectSigner() { m_signer.store(nullptr, std::memory_order_release); }
8080

8181
void Start(const llmq::CInstantSendManager& isman);
8282
void Stop();

src/instantsend/instantsend.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,15 @@ void CInstantSendManager::Start(PeerManager& peerman)
7575

7676
workThread = std::thread(&util::TraceThread, "isman", [this, &peerman] { WorkThreadMain(peerman); });
7777

78-
if (m_signer) {
79-
m_signer->Start();
78+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
79+
signer->Start();
8080
}
8181
}
8282

8383
void CInstantSendManager::Stop()
8484
{
85-
if (m_signer) {
86-
m_signer->Stop();
85+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
86+
signer->Stop();
8787
}
8888

8989
// make sure to call InterruptWorkerThread() first
@@ -348,8 +348,8 @@ MessageProcessingResult CInstantSendManager::ProcessInstantSendLock(NodeId from,
348348
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s, islock=%s: processing islock, peer=%d\n",
349349
__func__, islock->txid.ToString(), hash.ToString(), from);
350350

351-
if (m_signer) {
352-
m_signer->ClearLockFromQueue(islock);
351+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
352+
signer->ClearLockFromQueue(islock);
353353
}
354354
if (db.KnownInstantSendLock(hash)) {
355355
return {};
@@ -449,8 +449,8 @@ void CInstantSendManager::TransactionAddedToMempool(const CTransactionRef& tx)
449449
}
450450

451451
if (islock == nullptr) {
452-
if (m_signer) {
453-
m_signer->ProcessTx(*tx, false, Params().GetConsensus());
452+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
453+
signer->ProcessTx(*tx, false, Params().GetConsensus());
454454
}
455455
// TX is not locked, so make sure it is tracked
456456
AddNonLockedTx(tx, nullptr);
@@ -491,8 +491,8 @@ void CInstantSendManager::BlockConnected(const std::shared_ptr<const CBlock>& pb
491491
}
492492

493493
if (!IsLocked(tx->GetHash()) && !has_chainlock) {
494-
if (m_signer) {
495-
m_signer->ProcessTx(*tx, true, Params().GetConsensus());
494+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
495+
signer->ProcessTx(*tx, true, Params().GetConsensus());
496496
}
497497
// TX is not locked, so make sure it is tracked
498498
AddNonLockedTx(tx, pindex);
@@ -597,16 +597,16 @@ void CInstantSendManager::RemoveNonLockedTx(const uint256& txid, bool retryChild
597597
void CInstantSendManager::RemoveConflictedTx(const CTransaction& tx)
598598
{
599599
RemoveNonLockedTx(tx.GetHash(), false);
600-
if (m_signer) {
601-
m_signer->ClearInputsFromQueue(GetIdsFromLockable(tx.vin));
600+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
601+
signer->ClearInputsFromQueue(GetIdsFromLockable(tx.vin));
602602
}
603603
}
604604

605605
void CInstantSendManager::TruncateRecoveredSigsForInputs(const instantsend::InstantSendLock& islock)
606606
{
607607
auto ids = GetIdsFromLockable(islock.inputs);
608-
if (m_signer) {
609-
m_signer->ClearInputsFromQueue(ids);
608+
if (auto signer = m_signer.load(std::memory_order_acquire); signer) {
609+
signer->ClearInputsFromQueue(ids);
610610
}
611611
for (const auto& id : ids) {
612612
sigman.TruncateRecoveredSig(Params().GetConsensus().llmqTypeDIP0024InstantSend, id);
@@ -925,7 +925,8 @@ void CInstantSendManager::WorkThreadMain(PeerManager& peerman)
925925
for (auto& [node_id, mpr] : peer_activity) {
926926
peerman.PostProcessMessage(std::move(mpr), node_id);
927927
}
928-
if (!m_signer) return more_work;
928+
auto signer = m_signer.load(std::memory_order_acquire);
929+
if (!signer) return more_work;
929930
// Construct set of non-locked transactions that are pending to retry
930931
std::vector<CTransactionRef> txns{};
931932
{
@@ -942,7 +943,7 @@ void CInstantSendManager::WorkThreadMain(PeerManager& peerman)
942943
}
943944
}
944945
// Retry processing them
945-
m_signer->ProcessPendingRetryLockTxs(txns);
946+
signer->ProcessPendingRetryLockTxs(txns);
946947
return more_work;
947948
}();
948949

src/instantsend/instantsend.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class CInstantSendManager final : public instantsend::InstantSendSignerParent
5959
CTxMemPool& mempool;
6060
const CMasternodeSync& m_mn_sync;
6161

62-
instantsend::InstantSendSigner* m_signer{nullptr};
62+
std::atomic<instantsend::InstantSendSigner*> m_signer{nullptr};
6363

6464
std::thread workThread;
6565
CThreadInterrupt workInterrupt;
@@ -97,10 +97,10 @@ class CInstantSendManager final : public instantsend::InstantSendSignerParent
9797
void ConnectSigner(gsl::not_null<instantsend::InstantSendSigner*> signer)
9898
{
9999
// Prohibit double initialization
100-
assert(m_signer == nullptr);
101-
m_signer = signer;
100+
assert(m_signer.load(std::memory_order_acquire) == nullptr);
101+
m_signer.store(signer, std::memory_order_release);
102102
}
103-
void DisconnectSigner() { m_signer = nullptr; }
103+
void DisconnectSigner() { m_signer.store(nullptr, std::memory_order_release); }
104104

105105
void Start(PeerManager& peerman);
106106
void Stop();

0 commit comments

Comments
 (0)