Skip to content

Commit 245a6ee

Browse files
committed
rpc: implement special platform port shim for CDeterministicMNStateDiff
`CDeterministicMNStateDiff` is special because not all of its fields may be populated, so we may not have all the data we need to report on the diff.
1 parent 17d17af commit 245a6ee

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

src/evo/dmnstate.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <script/standard.h>
88

9+
#include <evo/netinfo.h>
910
#include <rpc/evo_util.h>
1011

1112
#include <univalue.h>
@@ -75,7 +76,6 @@ UniValue CDeterministicMNStateDiff::ToJson(MnType nType) const
7576
if (IsServiceDeprecatedRPCEnabled()) {
7677
obj.pushKV("service", state.netInfo->GetPrimary().ToStringAddrPort());
7778
}
78-
obj.pushKV("addresses", state.netInfo->ToJson());
7979
}
8080
if (fields & Field_nRegisteredHeight) {
8181
obj.pushKV("registeredHeight", state.nRegisteredHeight);
@@ -130,5 +130,37 @@ UniValue CDeterministicMNStateDiff::ToJson(MnType nType) const
130130
obj.pushKV("platformHTTPPort", state.platformHTTPPort);
131131
}
132132
}
133+
{
134+
const bool has_netinfo = (fields & Field_netInfo);
135+
136+
UniValue netInfoObj(UniValue::VOBJ);
137+
if (has_netinfo) {
138+
netInfoObj = state.netInfo->ToJson();
139+
}
140+
if (nType == MnType::Evo && (!has_netinfo || !state.netInfo->CanStorePlatform())) {
141+
auto unknownAddr = [](uint16_t port) -> UniValue {
142+
UniValue obj(UniValue::VARR);
143+
// We don't know what the address is because it wasn't changed in the
144+
// diff but we still need to report the port number in addr:port format
145+
obj.push_back(strprintf("255.255.255.255:%d", port));
146+
return obj;
147+
};
148+
if (fields & Field_platformP2PPort) {
149+
netInfoObj.pushKV(PurposeToString(NetInfoPurpose::PLATFORM_P2P).data(),
150+
(has_netinfo)
151+
? ArrFromService(CService(state.netInfo->GetPrimary(), state.platformP2PPort))
152+
: unknownAddr(state.platformP2PPort));
153+
}
154+
if (fields & Field_platformHTTPPort) {
155+
netInfoObj.pushKV(PurposeToString(NetInfoPurpose::PLATFORM_HTTPS).data(),
156+
(has_netinfo)
157+
? ArrFromService(CService(state.netInfo->GetPrimary(), state.platformHTTPPort))
158+
: unknownAddr(state.platformHTTPPort));
159+
}
160+
}
161+
if (!netInfoObj.empty()) {
162+
obj.pushKV("addresses", netInfoObj);
163+
}
164+
}
133165
return obj;
134166
}

test/functional/rpc_netinfo.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
# See CRegTestParams in src/chainparams.cpp
2727
DEFAULT_PORT_PLATFORM_P2P = 22200
2828
DEFAULT_PORT_PLATFORM_HTTP = 22201
29+
# See CDeterministicMNStateDiff::ToJson() in src/evo/dmnstate.h
30+
DMNSTATE_DIFF_DUMMY_ADDR = "255.255.255.255"
2931

3032
class Node:
3133
mn: MasternodeInfo
@@ -240,14 +242,19 @@ def test_deprecation(self):
240242
self.connect_nodes(self.node_evo.mn.nodeIdx, self.node_simple.index) # Needed as restarts don't reconnect nodes
241243

242244
# CProUpServTx::ToJson() <- TxToUniv() <- TxToJSON() <- getrawtransaction
243-
proupservtx_hash = self.node_evo.update_mn(self, f"127.0.0.1:{self.node_evo.mn.nodePort+1}", DEFAULT_PORT_PLATFORM_P2P, DEFAULT_PORT_PLATFORM_HTTP)
245+
# We need to update *thrice*, the first time to incorrect values and the second time, (back) to correct values and the third time, only
246+
# updating Platform fields to trigger the conditions needed to report the dummy address
247+
proupservtx_hash = self.node_evo.update_mn(self, f"127.0.0.1:{self.node_evo.mn.nodePort + 10}", DEFAULT_PORT_PLATFORM_P2P + 10, DEFAULT_PORT_PLATFORM_HTTP + 10)
244248
proupservtx_rpc = self.node_evo.node.getrawtransaction(proupservtx_hash, True)
245249

246-
# We need to update *twice*, the first time to incorrect values and the second time, back to correct values.
247-
# This is to make sure that the fields we need to check against are reflected in the diff.
250+
# Restore back to defaults
248251
proupservtx_hash = self.node_evo.update_mn(self, f"127.0.0.1:{self.node_evo.mn.nodePort}", DEFAULT_PORT_PLATFORM_P2P, DEFAULT_PORT_PLATFORM_HTTP)
249252
proupservtx_rpc = self.node_evo.node.getrawtransaction(proupservtx_hash, True)
250253

254+
# Revert back to incorrect values but only for Platform fields
255+
proupservtx_hash_pl = self.node_evo.update_mn(self, f"127.0.0.1:{self.node_evo.mn.nodePort}", DEFAULT_PORT_PLATFORM_P2P + 10, DEFAULT_PORT_PLATFORM_HTTP + 10)
256+
proupservtx_rpc_pl = self.node_evo.node.getrawtransaction(proupservtx_hash_pl, True)
257+
251258
# CSimplifiedMNListEntry::ToJson() <- CSimplifiedMNListDiff::mnList <- CSimplifiedMNListDiff::ToJson() <- protx_diff
252259
masternode_active_height: int = masternode_status['dmnState']['registeredHeight']
253260
protx_diff_rpc = self.node_evo.node.protx('diff', masternode_active_height - 1, masternode_active_height)
@@ -256,6 +263,10 @@ def test_deprecation(self):
256263
proupservtx_height = proupservtx_rpc['height']
257264
protx_listdiff_rpc = self.node_evo.node.protx('listdiff', proupservtx_height - 1, proupservtx_height)
258265

266+
# If the core P2P address wasn't updated and the platform fields were, CDeterministicMNStateDiff will return a dummy address
267+
proupservtx_height_pl = proupservtx_rpc_pl['height']
268+
protx_listdiff_rpc_pl = self.node_evo.node.protx('listdiff', proupservtx_height_pl - 1, proupservtx_height_pl)
269+
259270
self.log.info("Test RPCs return an 'addresses' field")
260271
assert "addresses" in proregtx_rpc['proRegTx'].keys()
261272
assert "addresses" in masternode_status['dmnState'].keys()
@@ -269,8 +280,12 @@ def test_deprecation(self):
269280
self.check_netinfo_fields(proupservtx_rpc['proUpServTx']['addresses'], self.node_evo.mn.nodePort, DEFAULT_PORT_PLATFORM_HTTP, DEFAULT_PORT_PLATFORM_P2P)
270281
# CSimplifiedMNListEntry doesn't store platform P2P network information before extended addresses
271282
self.check_netinfo_fields(protx_diff_rpc['mnList'][0]['addresses'], self.node_evo.mn.nodePort, DEFAULT_PORT_PLATFORM_HTTP, None)
272-
# TODO: Fix reporting for CDeterministicMNStateDiff
273-
self.check_netinfo_fields(protx_listdiff_rpc['updatedMNs'][0][proregtx_hash]['addresses'], self.node_evo.mn.nodePort, None, None)
283+
# CDeterministicMNStateDiff will fill in the correct address if the core P2P address was updated *alongside* platform fields
284+
self.check_netinfo_fields(protx_listdiff_rpc['updatedMNs'][0][proregtx_hash]['addresses'], self.node_evo.mn.nodePort, DEFAULT_PORT_PLATFORM_HTTP, DEFAULT_PORT_PLATFORM_P2P)
285+
# CDeterministicMNStateDiff will use a dummy address if the core P2P address wasn't updated but Platform fields were to ensure changes are reported
286+
assert "core_p2p" not in protx_listdiff_rpc_pl['updatedMNs'][0][proregtx_hash]['addresses'].keys()
287+
assert_equal(protx_listdiff_rpc_pl['updatedMNs'][0][proregtx_hash]['addresses']['platform_https'][0], f"{DMNSTATE_DIFF_DUMMY_ADDR}:{DEFAULT_PORT_PLATFORM_HTTP + 10}")
288+
assert_equal(protx_listdiff_rpc_pl['updatedMNs'][0][proregtx_hash]['addresses']['platform_p2p'][0], f"{DMNSTATE_DIFF_DUMMY_ADDR}:{DEFAULT_PORT_PLATFORM_P2P + 10}")
274289

275290
self.log.info("Test RPCs by default no longer return a 'service' field")
276291
assert "service" not in proregtx_rpc['proRegTx'].keys()

0 commit comments

Comments
 (0)