Skip to content

Commit 9bc699f

Browse files
nmarleyUdjinM6
authored andcommitted
Update activemn if protx info changed (#3176)
* Update activemn if protx info changed * Add `==` and `!=` operators to CDeterministicMNState * Only re-init active MN if its IP changed, changes to payout, voting etc. can be done without it * Test `masternode status` updates * Don't track mnListEntry anymore and instead get the DMN on demand * Revert "Add `==` and `!=` operators to CDeterministicMNState" This reverts commit fba4687.
1 parent bbd9b10 commit 9bc699f

File tree

4 files changed

+48
-14
lines changed

4 files changed

+48
-14
lines changed

src/masternode/activemasternode.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ std::string CActiveMasternodeManager::GetStateString() const
2626
return "REMOVED";
2727
case MASTERNODE_OPERATOR_KEY_CHANGED:
2828
return "OPERATOR_KEY_CHANGED";
29+
case MASTERNODE_PROTX_IP_CHANGED:
30+
return "PROTX_IP_CHANGED";
2931
case MASTERNODE_READY:
3032
return "READY";
3133
case MASTERNODE_ERROR:
@@ -46,6 +48,8 @@ std::string CActiveMasternodeManager::GetStatus() const
4648
return "Masternode removed from list";
4749
case MASTERNODE_OPERATOR_KEY_CHANGED:
4850
return "Operator key changed or revoked";
51+
case MASTERNODE_PROTX_IP_CHANGED:
52+
return "IP address specified in ProTx changed";
4953
case MASTERNODE_READY:
5054
return "Ready";
5155
case MASTERNODE_ERROR:
@@ -94,11 +98,9 @@ void CActiveMasternodeManager::Init()
9498
return;
9599
}
96100

97-
mnListEntry = dmn;
101+
LogPrintf("CActiveMasternodeManager::Init -- proTxHash=%s, proTx=%s\n", dmn->proTxHash.ToString(), dmn->ToString());
98102

99-
LogPrintf("CActiveMasternodeManager::Init -- proTxHash=%s, proTx=%s\n", mnListEntry->proTxHash.ToString(), mnListEntry->ToString());
100-
101-
if (activeMasternodeInfo.service != mnListEntry->pdmnState->addr) {
103+
if (activeMasternodeInfo.service != dmn->pdmnState->addr) {
102104
state = MASTERNODE_ERROR;
103105
strError = "Local address does not match the address from ProTx";
104106
LogPrintf("CActiveMasternodeManager::Init -- ERROR: %s", strError);
@@ -120,8 +122,8 @@ void CActiveMasternodeManager::Init()
120122
}
121123
}
122124

123-
activeMasternodeInfo.proTxHash = mnListEntry->proTxHash;
124-
activeMasternodeInfo.outpoint = mnListEntry->collateralOutpoint;
125+
activeMasternodeInfo.proTxHash = dmn->proTxHash;
126+
activeMasternodeInfo.outpoint = dmn->collateralOutpoint;
125127
state = MASTERNODE_READY;
126128
}
127129

@@ -134,24 +136,41 @@ void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, con
134136
if (!deterministicMNManager->IsDIP3Enforced(pindexNew->nHeight)) return;
135137

136138
if (state == MASTERNODE_READY) {
137-
auto mnList = deterministicMNManager->GetListForBlock(pindexNew);
138-
if (!mnList.IsMNValid(mnListEntry->proTxHash)) {
139+
auto oldMNList = deterministicMNManager->GetListForBlock(pindexNew->pprev);
140+
auto newMNList = deterministicMNManager->GetListForBlock(pindexNew);
141+
if (!newMNList.IsMNValid(activeMasternodeInfo.proTxHash)) {
139142
// MN disappeared from MN list
140143
state = MASTERNODE_REMOVED;
141144
activeMasternodeInfo.proTxHash = uint256();
142145
activeMasternodeInfo.outpoint.SetNull();
143146
// MN might have reappeared in same block with a new ProTx
144147
Init();
145-
} else if (mnList.GetMN(mnListEntry->proTxHash)->pdmnState->pubKeyOperator != mnListEntry->pdmnState->pubKeyOperator) {
148+
return;
149+
}
150+
151+
auto oldDmn = oldMNList.GetMN(activeMasternodeInfo.proTxHash);
152+
auto newDmn = newMNList.GetMN(activeMasternodeInfo.proTxHash);
153+
if (newDmn->pdmnState->pubKeyOperator != oldDmn->pdmnState->pubKeyOperator) {
146154
// MN operator key changed or revoked
147155
state = MASTERNODE_OPERATOR_KEY_CHANGED;
148156
activeMasternodeInfo.proTxHash = uint256();
149157
activeMasternodeInfo.outpoint.SetNull();
150158
// MN might have reappeared in same block with a new ProTx
151159
Init();
160+
return;
161+
}
162+
163+
if (newDmn->pdmnState->addr != oldDmn->pdmnState->addr) {
164+
// MN IP changed
165+
state = MASTERNODE_PROTX_IP_CHANGED;
166+
activeMasternodeInfo.proTxHash = uint256();
167+
activeMasternodeInfo.outpoint.SetNull();
168+
Init();
169+
return;
152170
}
153171
} else {
154-
// MN might have (re)appeared with a new ProTx or we've found some peers and figured out our local address
172+
// MN might have (re)appeared with a new ProTx or we've found some peers
173+
// and figured out our local address
155174
Init();
156175
}
157176
}

src/masternode/activemasternode.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ class CActiveMasternodeManager : public CValidationInterface
4040
MASTERNODE_POSE_BANNED,
4141
MASTERNODE_REMOVED,
4242
MASTERNODE_OPERATOR_KEY_CHANGED,
43+
MASTERNODE_PROTX_IP_CHANGED,
4344
MASTERNODE_READY,
4445
MASTERNODE_ERROR,
4546
};
4647

4748
private:
48-
CDeterministicMNCPtr mnListEntry;
4949
masternode_state_t state{MASTERNODE_WAITING_FOR_PROTX};
5050
std::string strError;
5151

@@ -54,8 +54,6 @@ class CActiveMasternodeManager : public CValidationInterface
5454

5555
void Init();
5656

57-
CDeterministicMNCPtr GetDMN() const { return mnListEntry; }
58-
5957
std::string GetStateString() const;
6058
std::string GetStatus() const;
6159

src/rpc/masternode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ UniValue masternode_status(const JSONRPCRequest& request)
402402
mnObj.push_back(Pair("outpoint", activeMasternodeInfo.outpoint.ToStringShort()));
403403
mnObj.push_back(Pair("service", activeMasternodeInfo.service.ToString()));
404404

405-
auto dmn = activeMasternodeManager->GetDMN();
405+
auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(activeMasternodeInfo.proTxHash);
406406
if (dmn) {
407407
mnObj.push_back(Pair("proTxHash", dmn->proTxHash.ToString()));
408408
mnObj.push_back(Pair("collateralHash", dmn->collateralOutpoint.hash.ToString()));

test/functional/dip3-deterministicmns.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,23 @@ def run_test(self):
184184
self.start_mn(new_mn)
185185
self.sync_all()
186186

187+
self.log.info("testing masternode status updates")
188+
# change voting address and see if changes are reflected in `masternode status` rpc output
189+
mn = mns[0]
190+
node = self.nodes[0]
191+
old_dmnState = mn.node.masternode("status")["dmnState"]
192+
old_voting_address = old_dmnState["votingAddress"]
193+
new_voting_address = node.getnewaddress()
194+
assert(old_voting_address != new_voting_address)
195+
# also check if funds from payout address are used when no fee source address is specified
196+
node.sendtoaddress(mn.rewards_address, 0.001)
197+
node.protx('update_registrar', mn.protx_hash, "", new_voting_address, mn.rewards_address)
198+
node.generate(1)
199+
self.sync_all()
200+
new_dmnState = mn.node.masternode("status")["dmnState"]
201+
new_voting_address_from_rpc = new_dmnState["votingAddress"]
202+
assert(new_voting_address_from_rpc == new_voting_address)
203+
187204
def prepare_mn(self, node, idx, alias):
188205
mn = Masternode()
189206
mn.idx = idx

0 commit comments

Comments
 (0)