Skip to content

Commit 757c99e

Browse files
authored
evo/llmq/spork: Fix various (potential) locking issues (#3829)
* Fix potential deadlock in `CSporkManager::UpdateSpork()` * Protect `inputRequestIds` with cs lock * Protect `curDBTransaction` in `CEvoDB::CommitRootTransaction()` * Check for `AssertLockNotHeld` in `EnforceBestChainLock()` instead of just having a comment in code * Protect spork maps on (de)serialization
1 parent ff1ecb6 commit 757c99e

File tree

5 files changed

+15
-5
lines changed

5 files changed

+15
-5
lines changed

src/evo/evodb.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void CEvoDB::RollbackCurTransaction()
5353

5454
bool CEvoDB::CommitRootTransaction()
5555
{
56+
LOCK(cs);
5657
assert(curDBTransaction.IsClean());
5758
rootDBTransaction.Commit();
5859
bool ret = db.WriteBatch(rootBatch);

src/llmq/quorums_chainlocks.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,9 @@ bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid)
488488
// This should also not be called from validation signals, as this might result in recursive calls
489489
void CChainLocksHandler::EnforceBestChainLock()
490490
{
491+
AssertLockNotHeld(cs);
492+
AssertLockNotHeld(cs_main);
493+
491494
CChainLockSig clsig;
492495
const CBlockIndex* pindex;
493496
const CBlockIndex* currentBestChainLockBlockIndex;

src/llmq/quorums_instantsend.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,10 @@ bool CInstantSendManager::ProcessTx(const CTransaction& tx, bool allowReSigning,
458458
for (size_t i = 0; i < tx.vin.size(); i++) {
459459
auto& in = tx.vin[i];
460460
auto& id = ids[i];
461-
inputRequestIds.emplace(id);
461+
{
462+
LOCK(cs);
463+
inputRequestIds.emplace(id);
464+
}
462465
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: trying to vote on input %s with id %s. allowReSigning=%d\n", __func__,
463466
tx.GetHash().ToString(), in.prevout.ToStringShort(), id.ToString(), allowReSigning);
464467
if (quorumSigningManager->AsyncSignIfMember(llmqType, id, tx.GetHash(), allowReSigning)) {
@@ -1119,6 +1122,7 @@ void CInstantSendManager::RemoveConflictedTx(const CTransaction& tx)
11191122

11201123
void CInstantSendManager::TruncateRecoveredSigsForInputs(const llmq::CInstantSendLock& islock)
11211124
{
1125+
AssertLockHeld(cs);
11221126
auto& consensusParams = Params().GetConsensus();
11231127

11241128
for (auto& in : islock.inputs) {

src/spork.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,6 @@ bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& conn
186186
{
187187
CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetAdjustedTime());
188188

189-
LOCK(cs);
190-
191189
if (!spork.Sign(sporkPrivKey)) {
192190
LogPrintf("CSporkManager::%s -- ERROR: signing failed for spork %d\n", __func__, nSporkID);
193191
return false;
@@ -201,8 +199,11 @@ bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue, CConnman& conn
201199

202200
LogPrintf("CSporkManager::%s -- signed %d %s\n", __func__, nSporkID, spork.GetHash().ToString());
203201

204-
mapSporksByHash[spork.GetHash()] = spork;
205-
mapSporksActive[nSporkID][keyIDSigner] = spork;
202+
{
203+
LOCK(cs);
204+
mapSporksByHash[spork.GetHash()] = spork;
205+
mapSporksActive[nSporkID][keyIDSigner] = spork;
206+
}
206207

207208
spork.Relay(connman);
208209
return true;

src/spork.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ class CSporkManager
191191
// we don't serialize pubkey ids because pubkeys should be
192192
// hardcoded or be setted with cmdline or options, should
193193
// not reuse pubkeys from previous dashd run
194+
LOCK(cs);
194195
READWRITE(mapSporksByHash);
195196
READWRITE(mapSporksActive);
196197
// we don't serialize private key to prevent its leakage

0 commit comments

Comments
 (0)