Skip to content

Commit 0b04978

Browse files
committed
evo: make netInfo a shared pointer
1 parent 0a4e726 commit 0b04978

22 files changed

+102
-80
lines changed

src/coinjoin/client.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ void CCoinJoinClientSession::ProcessMessage(CNode& peer, CChainState& active_cha
193193
if (!m_mn_sync.IsBlockchainSynced()) return;
194194

195195
if (!mixingMasternode) return;
196-
if (mixingMasternode->pdmnState->netInfo.GetPrimary() != peer.addr) return;
196+
if (mixingMasternode->pdmnState->netInfo->GetPrimary() != peer.addr) return;
197197

198198
if (msg_type == NetMsgType::DSSTATUSUPDATE) {
199199
CCoinJoinStatusUpdate psssup;
@@ -1113,7 +1113,7 @@ bool CCoinJoinClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymized,
11131113

11141114
m_clientman.AddUsedMasternode(dsq.masternodeOutpoint);
11151115

1116-
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo.GetPrimary())) {
1116+
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo->GetPrimary())) {
11171117
WalletCJLogPrint(m_wallet, /* Continued */
11181118
"CCoinJoinClientSession::JoinExistingQueue -- skipping connection, masternode=%s\n", dmn->proTxHash.ToString());
11191119
continue;
@@ -1185,7 +1185,7 @@ bool CCoinJoinClientSession::StartNewQueue(CAmount nBalanceNeedsAnonymized, CCon
11851185
continue;
11861186
}
11871187

1188-
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo.GetPrimary())) {
1188+
if (connman.IsMasternodeOrDisconnectRequested(dmn->pdmnState->netInfo->GetPrimary())) {
11891189
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::StartNewQueue -- skipping connection, masternode=%s\n",
11901190
dmn->proTxHash.ToString());
11911191
nTries++;
@@ -1225,7 +1225,7 @@ bool CCoinJoinClientSession::ProcessPendingDsaRequest(CConnman& connman)
12251225

12261226
CService mn_addr;
12271227
if (auto dmn = m_dmnman.GetListAtChainTip().GetMN(pendingDsaRequest.GetProTxHash())) {
1228-
mn_addr = Assert(dmn->pdmnState)->netInfo.GetPrimary();
1228+
mn_addr = Assert(dmn->pdmnState)->netInfo->GetPrimary();
12291229
} else {
12301230
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::%s -- cannot find address to connect, masternode=%s\n", __func__,
12311231
pendingDsaRequest.GetProTxHash().ToString());
@@ -1827,7 +1827,7 @@ void CCoinJoinClientSession::RelayIn(const CCoinJoinEntry& entry, CConnman& conn
18271827
{
18281828
if (!mixingMasternode) return;
18291829

1830-
connman.ForNode(mixingMasternode->pdmnState->netInfo.GetPrimary(), [&entry, &connman, this](CNode* pnode) {
1830+
connman.ForNode(mixingMasternode->pdmnState->netInfo->GetPrimary(), [&entry, &connman, this](CNode* pnode) {
18311831
WalletCJLogPrint(m_wallet, "CCoinJoinClientSession::RelayIn -- found master, relaying message to %s\n",
18321832
pnode->addr.ToStringAddrPort());
18331833
CNetMsgMaker msgMaker(pnode->GetCommonVersion());
@@ -1883,7 +1883,7 @@ void CCoinJoinClientSession::GetJsonInfo(UniValue& obj) const
18831883
assert(mixingMasternode->pdmnState);
18841884
obj.pushKV("protxhash", mixingMasternode->proTxHash.ToString());
18851885
obj.pushKV("outpoint", mixingMasternode->collateralOutpoint.ToStringShort());
1886-
obj.pushKV("service", mixingMasternode->pdmnState->netInfo.GetPrimary().ToStringAddrPort());
1886+
obj.pushKV("service", mixingMasternode->pdmnState->netInfo->GetPrimary().ToStringAddrPort());
18871887
}
18881888
obj.pushKV("denomination", ValueFromAmount(CoinJoin::DenominationToAmount(nSessionDenom)));
18891889
obj.pushKV("state", GetStateString());

src/evo/core_write.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
ret.pushKV("type", ToUnderlying(nType));
6868
ret.pushKV("collateralHash", collateralOutpoint.hash.ToString());
6969
ret.pushKV("collateralIndex", (int)collateralOutpoint.n);
70-
ret.pushKV("service", netInfo.GetPrimary().ToStringAddrPort());
70+
ret.pushKV("service", netInfo->GetPrimary().ToStringAddrPort());
7171
ret.pushKV("ownerAddress", EncodeDestination(PKHash(keyIDOwner)));
7272
ret.pushKV("votingAddress", EncodeDestination(PKHash(keyIDVoting)));
7373
if (CTxDestination dest; ExtractDestination(scriptPayout, dest)) {
@@ -114,7 +114,7 @@
114114
ret.pushKV("version", nVersion);
115115
ret.pushKV("type", ToUnderlying(nType));
116116
ret.pushKV("proTxHash", proTxHash.ToString());
117-
ret.pushKV("service", netInfo.GetPrimary().ToStringAddrPort());
117+
ret.pushKV("service", netInfo->GetPrimary().ToStringAddrPort());
118118
if (CTxDestination dest; ExtractDestination(scriptOperatorPayout, dest)) {
119119
ret.pushKV("operatorPayoutAddress", EncodeDestination(dest));
120120
}

src/evo/deterministicmns.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <stats/client.h>
2323
#include <uint256.h>
2424
#include <univalue.h>
25+
#include <util/pointer.h>
2526
#include <validationinterface.h>
2627

2728
#include <optional>
@@ -409,7 +410,7 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTota
409410
throw(std::runtime_error(strprintf("%s: Can't add a masternode %s with a duplicate collateralOutpoint=%s", __func__,
410411
dmn->proTxHash.ToString(), dmn->collateralOutpoint.ToStringShort())));
411412
}
412-
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo.GetEntries()) {
413+
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo->GetEntries()) {
413414
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
414415
const CService& service{service_opt.value()};
415416
if (!AddUniqueProperty(*dmn, service)) {
@@ -459,13 +460,13 @@ void CDeterministicMNList::UpdateMN(const CDeterministicMN& oldDmn, const std::s
459460
// Using this temporary map as a checkpoint to roll back to in case of any issues.
460461
decltype(mnUniquePropertyMap) mnUniquePropertyMapSaved = mnUniquePropertyMap;
461462

462-
auto updateNetInfo = [this](const CDeterministicMN& dmn, const MnNetInfo& oldInfo,
463-
const MnNetInfo& newInfo) -> std::string {
464-
if (oldInfo != newInfo) {
463+
auto updateNetInfo = [this](const CDeterministicMN& dmn, const std::shared_ptr<MnNetInfo>& oldInfo,
464+
const std::shared_ptr<MnNetInfo>& newInfo) -> std::string {
465+
if (util::shared_ptr_not_equal(oldInfo, newInfo)) {
465466
// We track each individual entry in netInfo as opposed to netInfo itself (preventing us from
466467
// using UpdateUniqueProperty()), so we need to successfully purge all old entries and insert
467468
// new entries to successfully update.
468-
for (const NetInfoEntry& old_entry : oldInfo.GetEntries()) {
469+
for (const NetInfoEntry& old_entry : oldInfo->GetEntries()) {
469470
if (const auto& service_opt{old_entry.GetAddrPort()}) {
470471
const CService& service{service_opt.value()};
471472
if (!DeleteUniqueProperty(dmn, service)) {
@@ -475,7 +476,7 @@ void CDeterministicMNList::UpdateMN(const CDeterministicMN& oldDmn, const std::s
475476
return "invalid address";
476477
}
477478
}
478-
for (const NetInfoEntry& new_entry : newInfo.GetEntries()) {
479+
for (const NetInfoEntry& new_entry : newInfo->GetEntries()) {
479480
if (const auto& service_opt{new_entry.GetAddrPort()}) {
480481
const CService& service{service_opt.value()};
481482
if (!AddUniqueProperty(dmn, service)) {
@@ -489,6 +490,7 @@ void CDeterministicMNList::UpdateMN(const CDeterministicMN& oldDmn, const std::s
489490
return "";
490491
};
491492

493+
assert(oldState->netInfo && pdmnState->netInfo);
492494
if (auto err = updateNetInfo(*dmn, oldState->netInfo, pdmnState->netInfo); !err.empty()) {
493495
mnUniquePropertyMap = mnUniquePropertyMapSaved;
494496
throw(std::runtime_error(strprintf("%s: Can't update masternode %s with addresses, reason=%s", __func__,
@@ -549,7 +551,7 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash)
549551
throw(std::runtime_error(strprintf("%s: Can't delete a masternode %s with a collateralOutpoint=%s", __func__,
550552
proTxHash.ToString(), dmn->collateralOutpoint.ToStringShort())));
551553
}
552-
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo.GetEntries()) {
554+
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo->GetEntries()) {
553555
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
554556
const CService& service{service_opt.value()};
555557
if (!DeleteUniqueProperty(*dmn, service)) {
@@ -777,7 +779,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
777779
}
778780
}
779781

780-
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
782+
for (const NetInfoEntry& entry : proTx.netInfo->GetEntries()) {
781783
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
782784
const CService& service{service_opt.value()};
783785
if (newList.HasUniqueProperty(service)) {
@@ -795,7 +797,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
795797

796798
auto dmnState = std::make_shared<CDeterministicMNState>(proTx);
797799
dmnState->nRegisteredHeight = nHeight;
798-
if (proTx.netInfo.IsEmpty()) {
800+
if (proTx.netInfo->IsEmpty()) {
799801
// start in banned pdmnState as we need to wait for a ProUpServTx
800802
dmnState->BanIfNotBanned(nHeight);
801803
}
@@ -813,7 +815,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
813815
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-payload");
814816
}
815817

816-
for (const NetInfoEntry& entry : opt_proTx->netInfo.GetEntries()) {
818+
for (const NetInfoEntry& entry : opt_proTx->netInfo->GetEntries()) {
817819
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
818820
const CService& service{service_opt.value()};
819821
if (newList.HasUniqueProperty(service) &&
@@ -1175,7 +1177,7 @@ void CDeterministicMNManager::CleanupCache(int nHeight)
11751177
template <typename ProTx>
11761178
static bool CheckService(const ProTx& proTx, TxValidationState& state)
11771179
{
1178-
switch (proTx.netInfo.Validate()) {
1180+
switch (proTx.netInfo->Validate()) {
11791181
case NetInfoStatus::BadAddress:
11801182
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-addr");
11811183
case NetInfoStatus::BadPort:
@@ -1228,8 +1230,8 @@ static bool CheckPlatformFields(const ProTx& proTx, TxValidationState& state)
12281230
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-platform-http-port");
12291231
}
12301232

1231-
if (proTx.platformP2PPort == proTx.platformHTTPPort || proTx.platformP2PPort == proTx.netInfo.GetPrimary().GetPort() ||
1232-
proTx.platformHTTPPort == proTx.netInfo.GetPrimary().GetPort()) {
1233+
if (proTx.platformP2PPort == proTx.platformHTTPPort || proTx.platformP2PPort == proTx.netInfo->GetPrimary().GetPort() ||
1234+
proTx.platformHTTPPort == proTx.netInfo->GetPrimary().GetPort()) {
12331235
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-platform-dup-ports");
12341236
}
12351237

@@ -1294,7 +1296,7 @@ bool CheckProRegTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gsl:
12941296

12951297
// It's allowed to set addr to 0, which will put the MN into PoSe-banned state and require a ProUpServTx to be issues later
12961298
// If any of both is set, it must be valid however
1297-
if (!opt_ptx->netInfo.IsEmpty() && !CheckService(*opt_ptx, state)) {
1299+
if (!opt_ptx->netInfo->IsEmpty() && !CheckService(*opt_ptx, state)) {
12981300
// pass the state returned by the function above
12991301
return false;
13001302
}
@@ -1354,7 +1356,7 @@ bool CheckProRegTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gsl:
13541356
auto mnList = dmnman.GetListForBlock(pindexPrev);
13551357

13561358
// only allow reusing of addresses when it's for the same collateral (which replaces the old MN)
1357-
for (const NetInfoEntry& entry : opt_ptx->netInfo.GetEntries()) {
1359+
for (const NetInfoEntry& entry : opt_ptx->netInfo->GetEntries()) {
13581360
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
13591361
const CService& service{service_opt.value()};
13601362
if (mnList.HasUniqueProperty(service) &&
@@ -1432,7 +1434,7 @@ bool CheckProUpServTx(CDeterministicMNManager& dmnman, const CTransaction& tx, g
14321434
}
14331435

14341436
// don't allow updating to addresses already used by other MNs
1435-
for (const NetInfoEntry& entry : opt_ptx->netInfo.GetEntries()) {
1437+
for (const NetInfoEntry& entry : opt_ptx->netInfo->GetEntries()) {
14361438
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
14371439
const CService& service{service_opt.value()};
14381440
if (mnList.HasUniqueProperty(service) && mnList.GetUniquePropertyMN(service)->proTxHash != opt_ptx->proTxHash) {

src/evo/dmnstate.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ std::string CDeterministicMNState::ToString() const
3232
" %s",
3333
nVersion, nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight,
3434
nRevocationReason, EncodeDestination(PKHash(keyIDOwner)), pubKeyOperator.ToString(),
35-
EncodeDestination(PKHash(keyIDVoting)), payoutAddress, operatorPayoutAddress, netInfo.ToString());
35+
EncodeDestination(PKHash(keyIDVoting)), payoutAddress, operatorPayoutAddress, netInfo->ToString());
3636
}
3737

3838
UniValue CDeterministicMNState::ToJson(MnType nType) const
3939
{
4040
UniValue obj(UniValue::VOBJ);
4141
obj.pushKV("version", nVersion);
42-
obj.pushKV("service", netInfo.GetPrimary().ToStringAddrPort());
42+
obj.pushKV("service", netInfo->GetPrimary().ToStringAddrPort());
4343
obj.pushKV("registeredHeight", nRegisteredHeight);
4444
obj.pushKV("lastPaidHeight", nLastPaidHeight);
4545
obj.pushKV("consecutivePayments", nConsecutivePayments);
@@ -73,7 +73,7 @@ UniValue CDeterministicMNStateDiff::ToJson(MnType nType) const
7373
obj.pushKV("version", state.nVersion);
7474
}
7575
if (fields & Field_netInfo) {
76-
obj.pushKV("service", state.netInfo.GetPrimary().ToStringAddrPort());
76+
obj.pushKV("service", state.netInfo->GetPrimary().ToStringAddrPort());
7777
}
7878
if (fields & Field_nRegisteredHeight) {
7979
obj.pushKV("registeredHeight", state.nRegisteredHeight);

src/evo/dmnstate.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <netaddress.h>
1212
#include <pubkey.h>
1313
#include <script/script.h>
14+
#include <util/pointer.h>
1415

1516
#include <memory>
1617
#include <utility>
@@ -54,7 +55,7 @@ class CDeterministicMNState
5455
CKeyID keyIDOwner;
5556
CBLSLazyPublicKey pubKeyOperator;
5657
CKeyID keyIDVoting;
57-
MnNetInfo netInfo;
58+
std::shared_ptr<MnNetInfo> netInfo{MakeNetInfo()};
5859
CScript scriptPayout;
5960
CScript scriptOperatorPayout;
6061

@@ -108,7 +109,7 @@ class CDeterministicMNState
108109
{
109110
nVersion = ProTxVersion::LegacyBLS;
110111
pubKeyOperator = CBLSLazyPublicKey();
111-
netInfo.Clear();
112+
netInfo = MakeNetInfo();
112113
scriptOperatorPayout = CScript();
113114
nRevocationReason = CProUpRevTx::REASON_NOT_SPECIFIED;
114115
platformNodeID = uint160();
@@ -215,9 +216,17 @@ class CDeterministicMNStateDiff
215216
CDeterministicMNStateDiff(const CDeterministicMNState& a, const CDeterministicMNState& b)
216217
{
217218
boost::hana::for_each(members, [&](auto&& member) {
218-
if (member.get(a) != member.get(b)) {
219-
member.get(state) = member.get(b);
220-
fields |= member.mask;
219+
using BaseType = std::decay_t<decltype(member)>;
220+
if constexpr (BaseType::mask == Field_netInfo) {
221+
if (util::shared_ptr_not_equal(member.get(a), member.get(b))) {
222+
member.get(state) = member.get(b);
223+
fields |= member.mask;
224+
}
225+
} else {
226+
if (member.get(a) != member.get(b)) {
227+
member.get(state) = member.get(b);
228+
fields |= member.mask;
229+
}
221230
}
222231
});
223232
if (fields & Field_pubKeyOperator) {

src/evo/netinfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class NetInfoEntry
7171
m_type = NetInfoType::Service;
7272
m_data = service;
7373
}
74+
template <typename Stream>
75+
NetInfoEntry(deserialize_type, Stream& s) { s >> *this; }
7476

7577
~NetInfoEntry() = default;
7678

@@ -134,6 +136,9 @@ class MnNetInfo
134136

135137
public:
136138
MnNetInfo() = default;
139+
template <typename Stream>
140+
MnNetInfo(deserialize_type, Stream& s) { s >> *this; }
141+
137142
~MnNetInfo() = default;
138143

139144
bool operator==(const MnNetInfo& rhs) const { return m_addr == rhs.m_addr; }
@@ -173,4 +178,9 @@ class MnNetInfo
173178
void Clear() { m_addr.Clear(); }
174179
};
175180

181+
inline std::shared_ptr<MnNetInfo> MakeNetInfo()
182+
{
183+
return std::make_shared<MnNetInfo>();
184+
}
185+
176186
#endif // BITCOIN_EVO_NETINFO_H

src/evo/providertx.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ bool CProRegTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState&
3636
if (!scriptPayout.IsPayToPublicKeyHash() && !scriptPayout.IsPayToScriptHash()) {
3737
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-payee");
3838
}
39-
for (const NetInfoEntry& entry : netInfo.GetEntries()) {
39+
for (const NetInfoEntry& entry : netInfo->GetEntries()) {
4040
if (!entry.IsTriviallyValid()) {
4141
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-bad");
4242
}
@@ -99,7 +99,7 @@ std::string CProRegTx::ToString() const
9999
nVersion, ToUnderlying(nType), collateralOutpoint.ToStringShort(), (double)nOperatorReward / 100,
100100
EncodeDestination(PKHash(keyIDOwner)), pubKeyOperator.ToString(),
101101
EncodeDestination(PKHash(keyIDVoting)), payee, platformNodeID.ToString(), platformP2PPort,
102-
platformHTTPPort, netInfo.ToString());
102+
platformHTTPPort, netInfo->ToString());
103103
}
104104

105105
bool CProUpServTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const
@@ -110,10 +110,10 @@ bool CProUpServTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationSta
110110
if (nVersion < ProTxVersion::BasicBLS && nType == MnType::Evo) {
111111
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-protx-evo-version");
112112
}
113-
if (netInfo.IsEmpty()) {
113+
if (netInfo->IsEmpty()) {
114114
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-empty");
115115
}
116-
for (const NetInfoEntry& entry : netInfo.GetEntries()) {
116+
for (const NetInfoEntry& entry : netInfo->GetEntries()) {
117117
if (!entry.IsTriviallyValid()) {
118118
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-bad");
119119
}
@@ -134,7 +134,7 @@ std::string CProUpServTx::ToString() const
134134
"platformNodeID=%s, platformP2PPort=%d, platformHTTPPort=%d)\n"
135135
" %s",
136136
nVersion, ToUnderlying(nType), proTxHash.ToString(), payee, platformNodeID.ToString(),
137-
platformP2PPort, platformHTTPPort, netInfo.ToString());
137+
platformP2PPort, platformHTTPPort, netInfo->ToString());
138138
}
139139

140140
bool CProUpRegTx::IsTriviallyValid(bool is_basic_scheme_active, TxValidationState& state) const

src/evo/providertx.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class CProRegTx
4141
MnType nType{MnType::Regular};
4242
uint16_t nMode{0}; // only 0 supported for now
4343
COutPoint collateralOutpoint{uint256(), (uint32_t)-1}; // if hash is null, we refer to a ProRegTx output
44-
MnNetInfo netInfo;
44+
std::shared_ptr<MnNetInfo> netInfo{MakeNetInfo()};
4545
uint160 platformNodeID{};
4646
uint16_t platformP2PPort{0};
4747
uint16_t platformHTTPPort{0};
@@ -110,7 +110,7 @@ class CProUpServTx
110110
uint16_t nVersion{ProTxVersion::LegacyBLS}; // message version
111111
MnType nType{MnType::Regular};
112112
uint256 proTxHash;
113-
MnNetInfo netInfo;
113+
std::shared_ptr<MnNetInfo> netInfo{MakeNetInfo()};
114114
uint160 platformNodeID{};
115115
uint16_t platformP2PPort{0};
116116
uint16_t platformHTTPPort{0};

0 commit comments

Comments
 (0)