Skip to content

Commit 8cf759c

Browse files
committed
fix: resolve lock order issues
1 parent 3e8b256 commit 8cf759c

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

src/governance/governance.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ MessageProcessingResult CGovernanceManager::ProcessMessage(CNode& peer, CConnman
321321
return ret;
322322
}
323323

324-
AddGovernanceObject(govobj, &peer);
324+
InternalAddGovernanceObject(govobj, &peer);
325325
return ret;
326326
}
327327

@@ -399,9 +399,12 @@ void CGovernanceManager::CheckOrphanVotes(CGovernanceObject& govobj)
399399
}
400400
}
401401

402-
void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, const CNode* pfrom)
402+
void CGovernanceManager::InternalAddGovernanceObject(CGovernanceObject& govobj, const CNode* pfrom)
403403
{
404+
AssertLockHeld(::cs_main);
405+
AssertLockHeld(cs_store);
404406
AssertLockNotHeld(cs_relay);
407+
405408
uint256 nHash = govobj.GetHash();
406409
std::string strHash = nHash.ToString();
407410

@@ -411,7 +414,6 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, const CN
411414

412415
govobj.UpdateSentinelVariables(tip_mn_list); //this sets local vars in object
413416

414-
LOCK2(::cs_main, cs_store);
415417
std::string strError;
416418

417419
// MAKE SURE THIS OBJECT IS OK
@@ -460,6 +462,15 @@ void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, const CN
460462
GetMainSignals().NotifyGovernanceObject(std::make_shared<const Governance::Object>(govobj.Object()), nHash.ToString());
461463
}
462464

465+
void CGovernanceManager::AddGovernanceObject(CGovernanceObject& govobj, const CNode* pfrom)
466+
{
467+
AssertLockNotHeld(cs_store);
468+
AssertLockNotHeld(cs_relay);
469+
470+
LOCK2(::cs_main, cs_store);
471+
InternalAddGovernanceObject(govobj, pfrom);
472+
}
473+
463474
void CGovernanceManager::CheckAndRemove()
464475
{
465476
AssertLockNotHeld(cs_store);
@@ -991,12 +1002,11 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote,
9911002

9921003
void CGovernanceManager::CheckPostponedObjects()
9931004
{
1005+
AssertLockHeld(::cs_main);
9941006
AssertLockHeld(cs_store);
9951007
AssertLockNotHeld(cs_relay);
9961008
if (!m_mn_sync.IsSynced()) return;
9971009

998-
LOCK(::cs_main);
999-
10001010
// Check postponed proposals
10011011
for (auto it = mapPostponedObjects.begin(); it != mapPostponedObjects.end();) {
10021012
const uint256& nHash = it->first;
@@ -1008,7 +1018,7 @@ void CGovernanceManager::CheckPostponedObjects()
10081018
bool fMissingConfirmations;
10091019
if (govobj.IsCollateralValid(m_chainman, strError, fMissingConfirmations)) {
10101020
if (govobj.IsValidLocally(Assert(m_dmnman)->GetListAtChainTip(), m_chainman, strError, false)) {
1011-
AddGovernanceObject(govobj);
1021+
InternalAddGovernanceObject(govobj);
10121022
} else {
10131023
LogPrint(BCLog::GOBJECT, "CGovernanceManager::CheckPostponedObjects -- %s invalid\n", nHash.ToString());
10141024
}
@@ -1381,7 +1391,7 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex* pindex)
13811391
nCachedBlockHeight = pindex->nHeight;
13821392
LogPrint(BCLog::GOBJECT, "CGovernanceManager::UpdatedBlockTip -- nCachedBlockHeight: %d\n", nCachedBlockHeight);
13831393

1384-
LOCK(cs_store);
1394+
LOCK2(::cs_main, cs_store);
13851395
if (DeploymentDIP0003Enforced(pindex->nHeight, Params().GetConsensus())) {
13861396
RemoveInvalidVotes();
13871397
}

src/governance/governance.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ using vote_time_pair_t = std::pair<CGovernanceVote, int64_t>;
5656
static constexpr int RATE_BUFFER_SIZE = 5;
5757
static constexpr bool DEFAULT_GOVERNANCE_ENABLE{true};
5858

59+
extern RecursiveMutex cs_main;
60+
5961
class CRateCheckBuffer
6062
{
6163
private:
@@ -342,7 +344,7 @@ class CGovernanceManager : public GovernanceStore, public GovernanceSignerParent
342344
std::vector<std::shared_ptr<const CGovernanceObject>> GetApprovedProposals(const CDeterministicMNList& tip_mn_list) override
343345
EXCLUSIVE_LOCKS_REQUIRED(!cs_store);
344346
void AddGovernanceObject(CGovernanceObject& govobj, const CNode* pfrom = nullptr) override
345-
EXCLUSIVE_LOCKS_REQUIRED(!cs_relay);
347+
EXCLUSIVE_LOCKS_REQUIRED(!cs_store, !cs_relay);
346348

347349
// Superblocks
348350
bool GetSuperblockPayments(const CDeterministicMNList& tip_mn_list, int nBlockHeight,
@@ -400,14 +402,19 @@ class CGovernanceManager : public GovernanceStore, public GovernanceSignerParent
400402
const CGovernanceObject* InternalFindConstGovernanceObject(const uint256& nHash) const
401403
EXCLUSIVE_LOCKS_REQUIRED(cs_store);
402404

405+
// Internal counterpart to "Signer interface"
406+
void InternalAddGovernanceObject(CGovernanceObject& govobj, const CNode* pfrom = nullptr)
407+
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, cs_store, !cs_relay);
408+
409+
// ...
403410
void MasternodeRateUpdate(const CGovernanceObject& govobj)
404411
EXCLUSIVE_LOCKS_REQUIRED(cs_store);
405412

406413
bool MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateFailStatus, bool fForce, bool& fRateCheckBypassed)
407414
EXCLUSIVE_LOCKS_REQUIRED(cs_store);
408415

409416
void CheckPostponedObjects()
410-
EXCLUSIVE_LOCKS_REQUIRED(cs_store, !cs_relay);
417+
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, cs_store, !cs_relay);
411418

412419
void InitOnLoad()
413420
EXCLUSIVE_LOCKS_REQUIRED(!cs_store);

0 commit comments

Comments
 (0)