Skip to content

Commit b69ca87

Browse files
committed
rpc: allow platform{P2P,HTTP}Port to return port of first address
This is to ensure that even when the fields have been deprecated, they can still return values by reading from `netInfo`. This will require us to constrain ExtNetInfo's validation rules to continue under legacy assumptions *until* we remove the legacy reporting fields altogether.
1 parent 245a6ee commit b69ca87

File tree

6 files changed

+67
-25
lines changed

6 files changed

+67
-25
lines changed

src/evo/core_write.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@
8585
ret.pushKV("operatorReward", (double)nOperatorReward / 100);
8686
if (nType == MnType::Evo) {
8787
ret.pushKV("platformNodeID", platformNodeID.ToString());
88-
ret.pushKV("platformP2PPort", platformP2PPort);
89-
ret.pushKV("platformHTTPPort", platformHTTPPort);
88+
ret.pushKV("platformP2PPort", GetPlatformPort</*is_p2p=*/true>(*this));
89+
ret.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*this));
9090
}
9191
ret.pushKV("inputsHash", inputsHash.ToString());
9292
return ret;
@@ -131,8 +131,8 @@
131131
}
132132
if (nType == MnType::Evo) {
133133
ret.pushKV("platformNodeID", platformNodeID.ToString());
134-
ret.pushKV("platformP2PPort", platformP2PPort);
135-
ret.pushKV("platformHTTPPort", platformHTTPPort);
134+
ret.pushKV("platformP2PPort", GetPlatformPort</*is_p2p=*/true>(*this));
135+
ret.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*this));
136136
}
137137
ret.pushKV("inputsHash", inputsHash.ToString());
138138
return ret;
@@ -170,7 +170,7 @@
170170
obj.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
171171
obj.pushKV("isValid", isValid);
172172
if (nType == MnType::Evo) {
173-
obj.pushKV("platformHTTPPort", platformHTTPPort);
173+
obj.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*this));
174174
obj.pushKV("platformNodeID", platformNodeID.ToString());
175175
}
176176

src/evo/dmnstate.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ UniValue CDeterministicMNState::ToJson(MnType nType) const
5151
obj.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
5252
if (nType == MnType::Evo) {
5353
obj.pushKV("platformNodeID", platformNodeID.ToString());
54-
obj.pushKV("platformP2PPort", platformP2PPort);
55-
obj.pushKV("platformHTTPPort", platformHTTPPort);
54+
obj.pushKV("platformP2PPort", GetPlatformPort</*is_p2p=*/true>(*this));
55+
obj.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*this));
5656
}
5757

5858
CTxDestination dest;

src/evo/netinfo.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,15 @@ NetInfoStatus MnNetInfo::AddEntry(const NetInfoPurpose purpose, const std::strin
218218
return NetInfoStatus::BadInput;
219219
}
220220

221-
NetInfoList MnNetInfo::GetEntries() const
221+
NetInfoList MnNetInfo::GetEntries(std::optional<NetInfoPurpose> purpose_opt) const
222222
{
223-
if (!IsEmpty()) {
223+
if (!IsEmpty() && (!purpose_opt || *purpose_opt == NetInfoPurpose::CORE_P2P)) {
224224
ASSERT_IF_DEBUG(m_addr.GetAddrPort().has_value());
225225
return {m_addr};
226226
}
227-
// If MnNetInfo is empty, we probably don't expect any entries to show up, so
228-
// we return a blank set instead.
229-
return {};
227+
// If MnNetInfo is empty or we are given an unexpected purpose code, we don't
228+
// expect any entries to show up, so we return a blank set instead.
229+
return NetInfoList{};
230230
}
231231

232232
CService MnNetInfo::GetPrimary() const
@@ -370,11 +370,17 @@ NetInfoStatus ExtNetInfo::AddEntry(const NetInfoPurpose purpose, const std::stri
370370
return NetInfoStatus::BadInput; /* Lookup() failed */
371371
}
372372

373-
NetInfoList ExtNetInfo::GetEntries() const
373+
NetInfoList ExtNetInfo::GetEntries(std::optional<NetInfoPurpose> purpose_opt) const
374374
{
375-
// ExtNetInfo is an append-only structure, we can avoid re-calculating
376-
// a list of all entries by maintaining a small cache.
377-
return m_all_entries;
375+
if (!purpose_opt) {
376+
// Without a purpose code specified, we're being requested for a flattened list of all
377+
// entries. ExtNetInfo is an append-only structure, so we can avoid re-calculating a
378+
// list of all entries by maintaining a small cache.
379+
return m_all_entries;
380+
}
381+
if (!IsValidPurpose(*purpose_opt)) return NetInfoList{};
382+
const auto& it{m_data.find(*purpose_opt)};
383+
return it != m_data.end() ? it->second : NetInfoList{};
378384
}
379385

380386
CService ExtNetInfo::GetPrimary() const

src/evo/netinfo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ class NetInfoInterface
193193
virtual ~NetInfoInterface() = default;
194194

195195
virtual NetInfoStatus AddEntry(const NetInfoPurpose purpose, const std::string& service) = 0;
196-
virtual NetInfoList GetEntries() const = 0;
196+
virtual NetInfoList GetEntries(std::optional<NetInfoPurpose> purpose_opt = std::nullopt) const = 0;
197197

198198
virtual CService GetPrimary() const = 0;
199199
virtual bool CanStorePlatform() const = 0;
@@ -251,7 +251,7 @@ class MnNetInfo final : public NetInfoInterface
251251
}
252252

253253
NetInfoStatus AddEntry(const NetInfoPurpose purpose, const std::string& service) override;
254-
NetInfoList GetEntries() const override;
254+
NetInfoList GetEntries(std::optional<NetInfoPurpose> purpose_opt = std::nullopt) const override;
255255

256256
CService GetPrimary() const override;
257257
bool HasEntries(NetInfoPurpose purpose) const override { return purpose == NetInfoPurpose::CORE_P2P && !IsEmpty(); }
@@ -339,7 +339,7 @@ class ExtNetInfo final : public NetInfoInterface
339339
}
340340

341341
NetInfoStatus AddEntry(const NetInfoPurpose purpose, const std::string& input) override;
342-
NetInfoList GetEntries() const override;
342+
NetInfoList GetEntries(std::optional<NetInfoPurpose> purpose_opt = std::nullopt) const override;
343343

344344
CService GetPrimary() const override;
345345
bool HasEntries(NetInfoPurpose purpose) const override;

src/rpc/evo_util.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,40 @@ UniValue GetNetInfoWithLegacyFields(const Obj& obj, const MnType& type)
4949
return ret;
5050
}
5151

52+
/** Returns platform port based on purpose and network info version */
53+
template <bool is_p2p, typename Obj>
54+
int32_t GetPlatformPort(const Obj& obj)
55+
{
56+
// Currently, there is nothing that prevents PLATFORM_{HTTPS,P2P} to be registered to
57+
// an addr *different* from the primary addr for CORE_P2P. This breaks the assumptions
58+
// under which platform{HTTP,P2P}Port operate under (i.e. all three are hosted with the
59+
// same addr).
60+
//
61+
// TODO: Introduce restrictions that enforce this assumption *until* we remove legacy
62+
// fields for good.
63+
//
64+
bool is_legacy{!(CHECK_NONFATAL(obj.netInfo)->CanStorePlatform())};
65+
if constexpr (is_p2p) {
66+
static_assert(!std::is_same_v<std::decay_t<Obj>, CSimplifiedMNListEntry>,
67+
"CSimplifiedMNListEntry doesn't have platformP2PPort");
68+
if (is_legacy) {
69+
return obj.platformP2PPort;
70+
}
71+
if (obj.netInfo->IsEmpty()) {
72+
return -1; // Blank entry, nothing to report
73+
}
74+
CHECK_NONFATAL(obj.netInfo->HasEntries(NetInfoPurpose::PLATFORM_P2P));
75+
return obj.netInfo->GetEntries(NetInfoPurpose::PLATFORM_P2P)[0].GetPort();
76+
} else {
77+
if (is_legacy) {
78+
return obj.platformHTTPPort;
79+
}
80+
if (obj.netInfo->IsEmpty()) {
81+
return -1; // Blank entry, nothing to report
82+
}
83+
CHECK_NONFATAL(obj.netInfo->HasEntries(NetInfoPurpose::PLATFORM_HTTPS));
84+
return obj.netInfo->GetEntries(NetInfoPurpose::PLATFORM_HTTPS)[0].GetPort();
85+
}
86+
}
87+
5288
#endif // BITCOIN_RPC_EVO_UTIL_H

src/rpc/masternode.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@
66
#include <evo/assetlocktx.h>
77
#include <evo/chainhelper.h>
88
#include <evo/deterministicmns.h>
9-
#include <index/txindex.h>
10-
#include <node/blockstorage.h>
11-
#include <node/context.h>
129
#include <governance/governance.h>
10+
#include <index/txindex.h>
1311
#include <masternode/node.h>
1412
#include <masternode/payments.h>
1513
#include <net.h>
1614
#include <netbase.h>
17-
#include <rpc/server.h>
15+
#include <node/blockstorage.h>
16+
#include <node/context.h>
1817
#include <rpc/evo_util.h>
18+
#include <rpc/server.h>
1919
#include <rpc/server_util.h>
2020
#include <rpc/util.h>
2121
#include <univalue.h>
@@ -623,8 +623,8 @@ static RPCHelpMan masternodelist_helper(bool is_composite)
623623
objMN.pushKV("type", std::string(GetMnType(dmn.nType).description));
624624
if (dmn.nType == MnType::Evo) {
625625
objMN.pushKV("platformNodeID", dmn.pdmnState->platformNodeID.ToString());
626-
objMN.pushKV("platformP2PPort", dmn.pdmnState->platformP2PPort);
627-
objMN.pushKV("platformHTTPPort", dmn.pdmnState->platformHTTPPort);
626+
objMN.pushKV("platformP2PPort", GetPlatformPort</*is_p2p=*/true>(*dmn.pdmnState));
627+
objMN.pushKV("platformHTTPPort", GetPlatformPort</*is_p2p=*/false>(*dmn.pdmnState));
628628
}
629629
objMN.pushKV("pospenaltyscore", dmn.pdmnState->nPoSePenalty);
630630
objMN.pushKV("consecutivePayments", dmn.pdmnState->nConsecutivePayments);

0 commit comments

Comments
 (0)