Skip to content

Commit 91d9329

Browse files
UdjinM6xdustinface
andauthored
Make CDeterministicMN::internalId private to make sure it's set/accessed properly (#3505)
* Make internalId private to make sure it's set/accessed properly * evo: Make internalId only accessible by the constructor * Tweak constructors Co-authored-by: xdustinface <xdustinfacex@gmail.com>
1 parent 232430f commit 91d9329

File tree

3 files changed

+43
-21
lines changed

3 files changed

+43
-21
lines changed

src/evo/deterministicmns.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ void CDeterministicMNState::ToJson(UniValue& obj) const
6565
}
6666
}
6767

68+
uint64_t CDeterministicMN::GetInternalId() const
69+
{
70+
// can't get it if it wasn't set yet
71+
assert(internalId != std::numeric_limits<uint64_t>::max());
72+
return internalId;
73+
}
74+
6875
std::string CDeterministicMN::ToString() const
6976
{
7077
return strprintf("CDeterministicMN(proTxHash=%s, collateralOutpoint=%s, nOperatorReward=%f, state=%s", proTxHash.ToString(), collateralOutpoint.ToStringShort(), (double)nOperatorReward / 100, pdmnState->ToString());
@@ -359,21 +366,21 @@ CDeterministicMNListDiff CDeterministicMNList::BuildDiff(const CDeterministicMNL
359366
} else if (fromPtr != toPtr || fromPtr->pdmnState != toPtr->pdmnState) {
360367
CDeterministicMNStateDiff stateDiff(*fromPtr->pdmnState, *toPtr->pdmnState);
361368
if (stateDiff.fields) {
362-
diffRet.updatedMNs.emplace(toPtr->internalId, std::move(stateDiff));
369+
diffRet.updatedMNs.emplace(toPtr->GetInternalId(), std::move(stateDiff));
363370
}
364371
}
365372
});
366373
ForEachMN(false, [&](const CDeterministicMNCPtr& fromPtr) {
367374
auto toPtr = to.GetMN(fromPtr->proTxHash);
368375
if (toPtr == nullptr) {
369-
diffRet.removedMns.emplace(fromPtr->internalId);
376+
diffRet.removedMns.emplace(fromPtr->GetInternalId());
370377
}
371378
});
372379

373380
// added MNs need to be sorted by internalId so that these are added in correct order when the diff is applied later
374381
// otherwise internalIds will not match with the original list
375382
std::sort(diffRet.addedMNs.begin(), diffRet.addedMNs.end(), [](const CDeterministicMNCPtr& a, const CDeterministicMNCPtr& b) {
376-
return a->internalId < b->internalId;
383+
return a->GetInternalId() < b->GetInternalId();
377384
});
378385

379386
return diffRet;
@@ -438,8 +445,8 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTota
438445
if (mnMap.find(dmn->proTxHash)) {
439446
throw(std::runtime_error(strprintf("%s: can't add a duplicate masternode with the same proTxHash=%s", __func__, dmn->proTxHash.ToString())));
440447
}
441-
if (mnInternalIdMap.find(dmn->internalId)) {
442-
throw(std::runtime_error(strprintf("%s: can't add a duplicate masternode with the same internalId=%d", __func__, dmn->internalId)));
448+
if (mnInternalIdMap.find(dmn->GetInternalId())) {
449+
throw(std::runtime_error(strprintf("%s: can't add a duplicate masternode with the same internalId=%d", __func__, dmn->GetInternalId())));
443450
}
444451
if (HasUniqueProperty(dmn->pdmnState->addr)) {
445452
throw(std::runtime_error(strprintf("%s: can't add a masternode with a duplicate address %s", __func__, dmn->pdmnState->addr.ToStringIPPort(false))));
@@ -449,7 +456,7 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTota
449456
}
450457

451458
mnMap = mnMap.set(dmn->proTxHash, dmn);
452-
mnInternalIdMap = mnInternalIdMap.set(dmn->internalId, dmn->proTxHash);
459+
mnInternalIdMap = mnInternalIdMap.set(dmn->GetInternalId(), dmn->proTxHash);
453460
AddUniqueProperty(dmn, dmn->collateralOutpoint);
454461
if (dmn->pdmnState->addr != CService()) {
455462
AddUniqueProperty(dmn, dmn->pdmnState->addr);
@@ -460,7 +467,7 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTota
460467
}
461468
if (fBumpTotalCount) {
462469
// nTotalRegisteredCount acts more like a checkpoint, not as a limit,
463-
nTotalRegisteredCount = std::max(dmn->internalId + 1, (uint64_t)nTotalRegisteredCount);
470+
nTotalRegisteredCount = std::max(dmn->GetInternalId() + 1, (uint64_t)nTotalRegisteredCount);
464471
}
465472
}
466473

@@ -515,7 +522,7 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash)
515522
DeleteUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator);
516523
}
517524
mnMap = mnMap.erase(proTxHash);
518-
mnInternalIdMap = mnInternalIdMap.erase(dmn->internalId);
525+
mnInternalIdMap = mnInternalIdMap.erase(dmn->GetInternalId());
519526
}
520527

521528
CDeterministicMNManager::CDeterministicMNManager(CEvoDB& _evoDb) :
@@ -680,9 +687,8 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C
680687
return _state.DoS(100, false, REJECT_INVALID, "bad-protx-payload");
681688
}
682689

683-
auto dmn = std::make_shared<CDeterministicMN>();
690+
auto dmn = std::make_shared<CDeterministicMN>(newList.GetTotalRegisteredCount());
684691
dmn->proTxHash = tx.GetHash();
685-
dmn->internalId = newList.GetTotalRegisteredCount();
686692

687693
// collateralOutpoint is either pointing to an external collateral or to the ProRegTx itself
688694
if (proTx.collateralOutpoint.hash.IsNull()) {
@@ -1028,15 +1034,13 @@ bool CDeterministicMNManager::UpgradeDiff(CDBBatch& batch, const CBlockIndex* pi
10281034
CDeterministicMNListDiff newDiff;
10291035
size_t addedCount = 0;
10301036
for (auto& p : oldDiff.addedMNs) {
1031-
auto dmn = std::make_shared<CDeterministicMN>(*p.second);
1032-
dmn->internalId = curMNList.GetTotalRegisteredCount() + addedCount;
1037+
auto dmn = std::make_shared<CDeterministicMN>(*p.second, curMNList.GetTotalRegisteredCount() + addedCount);
10331038
newDiff.addedMNs.emplace_back(dmn);
1034-
10351039
addedCount++;
10361040
}
10371041
for (auto& p : oldDiff.removedMns) {
10381042
auto dmn = curMNList.GetMN(p);
1039-
newDiff.removedMns.emplace(dmn->internalId);
1043+
newDiff.removedMns.emplace(dmn->GetInternalId());
10401044
}
10411045

10421046
// applies added/removed MNs
@@ -1055,7 +1059,7 @@ bool CDeterministicMNManager::UpgradeDiff(CDBBatch& batch, const CBlockIndex* pi
10551059
}
10561060

10571061
newDiff.updatedMNs.emplace(std::piecewise_construct,
1058-
std::forward_as_tuple(oldMN->internalId),
1062+
std::forward_as_tuple(oldMN->GetInternalId()),
10591063
std::forward_as_tuple(*oldMN->pdmnState, *newMN->pdmnState));
10601064
}
10611065

src/evo/deterministicmns.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,30 @@ class CDeterministicMNStateDiff
187187

188188
class CDeterministicMN
189189
{
190+
private:
191+
uint64_t internalId{std::numeric_limits<uint64_t>::max()};
192+
190193
public:
191-
CDeterministicMN() {}
194+
CDeterministicMN() = delete; // no default constructor, must specify internalId
195+
CDeterministicMN(uint64_t _internalId) : internalId(_internalId)
196+
{
197+
// only non-initial values
198+
assert(_internalId != std::numeric_limits<uint64_t>::max());
199+
}
200+
// TODO: can be removed in a future version
201+
CDeterministicMN(const CDeterministicMN& mn, uint64_t _internalId) : CDeterministicMN(mn) {
202+
// only non-initial values
203+
assert(_internalId != std::numeric_limits<uint64_t>::max());
204+
internalId = _internalId;
205+
}
206+
192207
template <typename Stream>
193208
CDeterministicMN(deserialize_type, Stream& s)
194209
{
195210
s >> *this;
196211
}
197212

198213
uint256 proTxHash;
199-
uint64_t internalId{std::numeric_limits<uint64_t>::max()};
200214
COutPoint collateralOutpoint;
201215
uint16_t nOperatorReward;
202216
CDeterministicMNStateCPtr pdmnState;
@@ -226,7 +240,8 @@ class CDeterministicMN
226240
SerializationOp(s, CSerActionUnserialize(), oldFormat);
227241
}
228242

229-
public:
243+
uint64_t GetInternalId() const;
244+
230245
std::string ToString() const;
231246
void ToJson(UniValue& obj) const;
232247
};
@@ -603,7 +618,10 @@ class CDeterministicMNListDiff_OldFormat
603618
size_t cnt = ReadCompactSize(s);
604619
for (size_t i = 0; i < cnt; i++) {
605620
uint256 proTxHash;
606-
auto dmn = std::make_shared<CDeterministicMN>();
621+
// NOTE: This is a hack and "0" is just a dummy id. The actual internalId is assigned to a copy
622+
// of this dmn via corresponding ctor when we convert the diff format to a new one in UpgradeDiff
623+
// thus the logic that we must set internalId before dmn is used in any meaningful way is preserved.
624+
auto dmn = std::make_shared<CDeterministicMN>(0);
607625
s >> proTxHash;
608626
dmn->Unserialize(s, true);
609627
addedMNs.emplace(proTxHash, dmn);

src/evo/mnauth.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,10 @@ void CMNAuth::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList&
191191
return;
192192
}
193193
bool doRemove = false;
194-
if (diff.removedMns.count(verifiedDmn->internalId)) {
194+
if (diff.removedMns.count(verifiedDmn->GetInternalId())) {
195195
doRemove = true;
196196
} else {
197-
auto it = diff.updatedMNs.find(verifiedDmn->internalId);
197+
auto it = diff.updatedMNs.find(verifiedDmn->GetInternalId());
198198
if (it != diff.updatedMNs.end()) {
199199
if ((it->second.fields & CDeterministicMNStateDiff::Field_pubKeyOperator) && it->second.state.pubKeyOperator.GetHash() != pnode->verifiedPubKeyHash) {
200200
doRemove = true;

0 commit comments

Comments
 (0)