Skip to content

Commit 2ee408f

Browse files
committed
refactor: protect some CGovernanceObject variables
Currently, the LOCKs aren't guarding anything. Variables protected were based on existing LOCK'ing patterns (i.e. (de)ser'ed variables except for m_obj).
1 parent 2378a99 commit 2ee408f

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

src/governance/governance.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ bool CGovernanceManager::HaveVoteForHash(const uint256& nHash) const
187187
LOCK(cs_store);
188188

189189
CGovernanceObject* pGovobj = nullptr;
190-
return cmapVoteToObject.Get(nHash, pGovobj) && pGovobj->GetVoteFile().HasVote(nHash);
190+
return cmapVoteToObject.Get(nHash, pGovobj) && WITH_LOCK(pGovobj->cs, return pGovobj->GetVoteFile().HasVote(nHash));
191191
}
192192

193193
int CGovernanceManager::GetVoteCount() const
@@ -201,7 +201,7 @@ bool CGovernanceManager::SerializeVoteForHash(const uint256& nHash, CDataStream&
201201
LOCK(cs_store);
202202

203203
CGovernanceObject* pGovobj = nullptr;
204-
return cmapVoteToObject.Get(nHash, pGovobj) && pGovobj->GetVoteFile().SerializeVoteToStream(nHash, ss);
204+
return cmapVoteToObject.Get(nHash, pGovobj) && WITH_LOCK(pGovobj->cs, return pGovobj->GetVoteFile().SerializeVoteToStream(nHash, ss));
205205
}
206206

207207
void CGovernanceManager::AddPostponedObject(const CGovernanceObject& govobj)
@@ -744,10 +744,12 @@ MessageProcessingResult CGovernanceManager::SyncSingleObjVotes(CNode& peer, cons
744744
return {};
745745
}
746746

747-
const auto& fileVotes = govobj.GetVoteFile();
747+
MessageProcessingResult ret{};
748748
const auto tip_mn_list = Assert(m_dmnman)->GetListAtChainTip();
749749

750-
MessageProcessingResult ret{};
750+
{
751+
LOCK(govobj.cs);
752+
const auto& fileVotes = govobj.GetVoteFile();
751753
for (const auto& vote : fileVotes.GetVotes()) {
752754
uint256 nVoteHash = vote.GetHash();
753755

@@ -758,6 +760,7 @@ MessageProcessingResult CGovernanceManager::SyncSingleObjVotes(CNode& peer, cons
758760
}
759761
ret.m_inventory.emplace_back(MSG_GOVERNANCE_OBJECT_VOTE, nVoteHash);
760762
}
763+
}
761764

762765
CNetMsgMaker msgMaker(peer.GetCommonVersion());
763766
connman.PushMessage(&peer, msgMaker.Make(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_GOVOBJ_VOTE,
@@ -1064,7 +1067,7 @@ void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nH
10641067

10651068
if (pObj) {
10661069
filter = CBloomFilter(Params().GetConsensus().nGovernanceFilterElements, GOVERNANCE_FILTER_FP_RATE, GetRand<int>(/*nMax=*/999999), BLOOM_UPDATE_ALL);
1067-
std::vector<CGovernanceVote> vecVotes = pObj->GetVoteFile().GetVotes();
1070+
std::vector<CGovernanceVote> vecVotes = WITH_LOCK(pObj->cs, return pObj->GetVoteFile().GetVotes());
10681071
nVoteCount = vecVotes.size();
10691072
for (const auto& vote : vecVotes) {
10701073
filter.insert(vote.GetHash());
@@ -1222,7 +1225,7 @@ void CGovernanceManager::RebuildIndexes()
12221225
cmapVoteToObject.Clear();
12231226
for (auto& objPair : mapObjects) {
12241227
CGovernanceObject& govobj = objPair.second;
1225-
std::vector<CGovernanceVote> vecVotes = govobj.GetVoteFile().GetVotes();
1228+
std::vector<CGovernanceVote> vecVotes = WITH_LOCK(govobj.cs, return govobj.GetVoteFile().GetVotes());
12261229
for (const auto& vecVote : vecVotes) {
12271230
cmapVoteToObject.Insert(vecVote.GetHash(), &govobj);
12281231
}

src/governance/object.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ void CGovernanceObject::UpdateSentinelVariables(const CDeterministicMNList& tip_
614614
if (GetAbsoluteYesCount(tip_mn_list, VOTE_SIGNAL_FUNDING) >= nAbsVoteReq) fCachedFunding = true;
615615
if ((GetAbsoluteYesCount(tip_mn_list, VOTE_SIGNAL_DELETE) >= nAbsDeleteReq) && !fCachedDelete) {
616616
fCachedDelete = true;
617+
LOCK(cs);
617618
if (nDeletionTime == 0) {
618619
nDeletionTime = GetTime<std::chrono::seconds>().count();
619620
}

src/governance/object.h

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,15 @@ class CGovernanceObject
8888
public: // Types
8989
using vote_m_t = std::map<COutPoint, vote_rec_t>;
9090

91-
private:
91+
public:
9292
/// critical section to protect the inner data structures
9393
mutable RecursiveMutex cs;
9494

95+
private:
9596
Governance::Object m_obj;
9697

9798
/// time this object was marked for deletion
98-
int64_t nDeletionTime{0};
99+
int64_t nDeletionTime GUARDED_BY(cs){0};
99100

100101
/// is valid by blockchain
101102
bool fCachedLocalValidity{false};
@@ -121,14 +122,14 @@ class CGovernanceObject
121122
bool fDirtyCache{true};
122123

123124
/// Object is no longer of interest
124-
bool fExpired{false};
125+
bool fExpired GUARDED_BY(cs){false};
125126

126127
/// Failed to parse object data
127128
bool fUnparsable{false};
128129

129-
vote_m_t mapCurrentMNVotes;
130+
vote_m_t mapCurrentMNVotes GUARDED_BY(cs);
130131

131-
CGovernanceObjectVoteFile fileVotes;
132+
CGovernanceObjectVoteFile fileVotes GUARDED_BY(cs);
132133

133134
public:
134135
CGovernanceObject();
@@ -141,18 +142,31 @@ class CGovernanceObject
141142
bool IsSetCachedDelete() const { return fCachedDelete; }
142143
bool IsSetCachedEndorsed() const { return fCachedEndorsed; }
143144
bool IsSetDirtyCache() const { return fDirtyCache; }
144-
bool IsSetExpired() const { return fExpired; }
145+
bool IsSetExpired() const EXCLUSIVE_LOCKS_REQUIRED(!cs)
146+
{
147+
return WITH_LOCK(cs, return fExpired);
148+
}
145149
GovernanceObject GetObjectType() const { return m_obj.type; }
146150
int64_t GetCreationTime() const { return m_obj.time; }
147-
int64_t GetDeletionTime() const { return nDeletionTime; }
151+
int64_t GetDeletionTime() const EXCLUSIVE_LOCKS_REQUIRED(!cs)
152+
{
153+
return WITH_LOCK(cs, return nDeletionTime);
154+
}
148155

149-
const CGovernanceObjectVoteFile& GetVoteFile() const { return fileVotes; }
156+
const CGovernanceObjectVoteFile& GetVoteFile() const EXCLUSIVE_LOCKS_REQUIRED(cs)
157+
{
158+
AssertLockHeld(cs);
159+
return fileVotes;
160+
}
150161
const COutPoint& GetMasternodeOutpoint() const { return m_obj.masternodeOutpoint; }
151162
const Governance::Object& Object() const { return m_obj; }
152163
const uint256& GetCollateralHash() const { return m_obj.collateralHash; }
153164

154165
// Setters
155-
void SetExpired() { fExpired = true; }
166+
void SetExpired() EXCLUSIVE_LOCKS_REQUIRED(!cs)
167+
{
168+
WITH_LOCK(cs, fExpired = true);
169+
}
156170
void SetMasternodeOutpoint(const COutPoint& outpoint);
157171
void SetSignature(Span<const uint8_t> sig);
158172

@@ -177,9 +191,10 @@ class CGovernanceObject
177191

178192
void UpdateSentinelVariables(const CDeterministicMNList& tip_mn_list);
179193

180-
void PrepareDeletion(int64_t nDeletionTime_)
194+
void PrepareDeletion(int64_t nDeletionTime_) EXCLUSIVE_LOCKS_REQUIRED(!cs)
181195
{
182196
fCachedDelete = true;
197+
LOCK(cs);
183198
if (nDeletionTime == 0) {
184199
nDeletionTime = nDeletionTime_;
185200
}
@@ -211,15 +226,27 @@ class CGovernanceObject
211226

212227
// SERIALIZER
213228

214-
SERIALIZE_METHODS(CGovernanceObject, obj)
229+
template<typename Stream>
230+
void Serialize(Stream& s) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
215231
{
216232
// SERIALIZE DATA FOR SAVING/LOADING OR NETWORK FUNCTIONS
217-
READWRITE(obj.m_obj);
233+
s << m_obj;
218234
if (s.GetType() & SER_DISK) {
219235
// Only include these for the disk file format
220-
READWRITE(obj.nDeletionTime, obj.fExpired, obj.mapCurrentMNVotes, obj.fileVotes);
236+
LOCK(cs);
237+
s << nDeletionTime << fExpired << mapCurrentMNVotes << fileVotes;
221238
}
239+
}
222240

241+
template<typename Stream>
242+
void Unserialize(Stream& s) EXCLUSIVE_LOCKS_REQUIRED(!cs)
243+
{
244+
s >> m_obj;
245+
if (s.GetType() & SER_DISK) {
246+
// Only include these for the disk file format
247+
LOCK(cs);
248+
s >> nDeletionTime >> fExpired >> mapCurrentMNVotes >> fileVotes;
249+
}
223250
// AFTER DESERIALIZATION OCCURS, CACHED VARIABLES MUST BE CALCULATED MANUALLY
224251
}
225252

0 commit comments

Comments
 (0)