Skip to content

Commit 3c7210c

Browse files
committed
evo: return MnNetInfo::GetEntries() with NetInfoEntry
1 parent a8263e7 commit 3c7210c

File tree

8 files changed

+103
-53
lines changed

8 files changed

+103
-53
lines changed

src/evo/deterministicmns.cpp

Lines changed: 80 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -470,11 +470,18 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTota
470470
throw(std::runtime_error(strprintf("%s: Can't add a masternode %s with a duplicate collateralOutpoint=%s", __func__,
471471
dmn->proTxHash.ToString(), dmn->collateralOutpoint.ToStringShort())));
472472
}
473-
for (const CService& entry : dmn->pdmnState->netInfo.GetEntries()) {
474-
if (!AddUniqueProperty(*dmn, entry)) {
473+
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo.GetEntries()) {
474+
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
475+
const CService& service{service_opt.value()};
476+
if (!AddUniqueProperty(*dmn, service)) {
477+
mnUniquePropertyMap = mnUniquePropertyMapSaved;
478+
throw std::runtime_error(strprintf("%s: Can't add a masternode %s with a duplicate address=%s",
479+
__func__, dmn->proTxHash.ToString(), service.ToStringAddrPort()));
480+
}
481+
} else {
475482
mnUniquePropertyMap = mnUniquePropertyMapSaved;
476-
throw(std::runtime_error(strprintf("%s: Can't add a masternode %s with a duplicate address=%s", __func__,
477-
dmn->proTxHash.ToString(), entry.ToStringAddrPort())));
483+
throw std::runtime_error(
484+
strprintf("%s: Can't add a masternode %s with invalid address", __func__, dmn->proTxHash.ToString()));
478485
}
479486
}
480487
if (!AddUniqueProperty(*dmn, dmn->pdmnState->keyIDOwner)) {
@@ -513,28 +520,40 @@ void CDeterministicMNList::UpdateMN(const CDeterministicMN& oldDmn, const std::s
513520
// Using this temporary map as a checkpoint to roll back to in case of any issues.
514521
decltype(mnUniquePropertyMap) mnUniquePropertyMapSaved = mnUniquePropertyMap;
515522

516-
const auto updateNetInfo = [&]() {
517-
if (oldState->netInfo != pdmnState->netInfo) {
523+
auto updateNetInfo = [this](const CDeterministicMN& dmn, const MnNetInfo& oldInfo,
524+
const MnNetInfo& newInfo) -> std::string {
525+
if (oldInfo != newInfo) {
518526
// We track each individual entry in netInfo as opposed to netInfo itself (preventing us from
519527
// using UpdateUniqueProperty()), so we need to successfully purge all old entries and insert
520528
// new entries to successfully update.
521-
for (const CService& old_entry : oldState->netInfo.GetEntries()) {
522-
if (!DeleteUniqueProperty(*dmn, old_entry)) {
523-
return strprintf("internal error"); // This shouldn't be possible
529+
for (const NetInfoEntry& old_entry : oldInfo.GetEntries()) {
530+
if (const auto& service_opt{old_entry.GetAddrPort()}) {
531+
const CService& service{service_opt.value()};
532+
if (!DeleteUniqueProperty(dmn, service)) {
533+
return "internal error"; // This shouldn't be possible
534+
}
535+
} else {
536+
return "invalid address";
524537
}
525538
}
526-
for (const CService& new_entry : pdmnState->netInfo.GetEntries()) {
527-
if (!AddUniqueProperty(*dmn, new_entry)) {
528-
return strprintf("duplicate (%s)", new_entry.ToStringAddrPort());
539+
for (const NetInfoEntry& new_entry : newInfo.GetEntries()) {
540+
if (const auto& service_opt{new_entry.GetAddrPort()}) {
541+
const CService& service{service_opt.value()};
542+
if (!AddUniqueProperty(dmn, service)) {
543+
return strprintf("duplicate (%s)", service.ToStringAddrPort());
544+
}
545+
} else {
546+
return "invalid address";
529547
}
530548
}
531549
}
532-
return strprintf("");
533-
}();
534-
if (!updateNetInfo.empty()) {
550+
return "";
551+
};
552+
553+
if (auto err = updateNetInfo(*dmn, oldState->netInfo, pdmnState->netInfo); !err.empty()) {
535554
mnUniquePropertyMap = mnUniquePropertyMapSaved;
536555
throw(std::runtime_error(strprintf("%s: Can't update masternode %s with addresses, reason=%s", __func__,
537-
oldDmn.proTxHash.ToString(), updateNetInfo)));
556+
oldDmn.proTxHash.ToString(), err)));
538557
}
539558
if (!UpdateUniqueProperty(*dmn, oldState->keyIDOwner, pdmnState->keyIDOwner)) {
540559
mnUniquePropertyMap = mnUniquePropertyMapSaved;
@@ -591,11 +610,18 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash)
591610
throw(std::runtime_error(strprintf("%s: Can't delete a masternode %s with a collateralOutpoint=%s", __func__,
592611
proTxHash.ToString(), dmn->collateralOutpoint.ToStringShort())));
593612
}
594-
for (const CService& entry : dmn->pdmnState->netInfo.GetEntries()) {
595-
if (!DeleteUniqueProperty(*dmn, entry)) {
613+
for (const NetInfoEntry& entry : dmn->pdmnState->netInfo.GetEntries()) {
614+
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
615+
const CService& service{service_opt.value()};
616+
if (!DeleteUniqueProperty(*dmn, service)) {
617+
mnUniquePropertyMap = mnUniquePropertyMapSaved;
618+
throw std::runtime_error(strprintf("%s: Can't delete a masternode %s with an address=%s", __func__,
619+
proTxHash.ToString(), service.ToStringAddrPort()));
620+
}
621+
} else {
596622
mnUniquePropertyMap = mnUniquePropertyMapSaved;
597-
throw(std::runtime_error(strprintf("%s: Can't delete a masternode %s with an address=%s", __func__,
598-
proTxHash.ToString(), entry.ToStringAddrPort())));
623+
throw std::runtime_error(strprintf("%s: Can't delete a masternode %s with invalid address", __func__,
624+
dmn->proTxHash.ToString()));
599625
}
600626
}
601627
if (!DeleteUniqueProperty(*dmn, dmn->pdmnState->keyIDOwner)) {
@@ -811,9 +837,14 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
811837
}
812838
}
813839

814-
for (const CService& entry : proTx.netInfo.GetEntries()) {
815-
if (newList.HasUniqueProperty(entry)) {
816-
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-dup-netinfo-entry");
840+
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
841+
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
842+
const CService& service{service_opt.value()};
843+
if (newList.HasUniqueProperty(service)) {
844+
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-dup-netinfo-entry");
845+
}
846+
} else {
847+
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-netinfo-entry");
817848
}
818849
}
819850
if (newList.HasUniqueProperty(proTx.keyIDOwner) || newList.HasUniqueProperty(proTx.pubKeyOperator)) {
@@ -842,10 +873,15 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, gsl::no
842873
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-payload");
843874
}
844875

845-
for (const CService& entry : opt_proTx->netInfo.GetEntries()) {
846-
if (newList.HasUniqueProperty(entry) &&
847-
newList.GetUniquePropertyMN(entry)->proTxHash != opt_proTx->proTxHash) {
848-
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-dup-netinfo-entry");
876+
for (const NetInfoEntry& entry : opt_proTx->netInfo.GetEntries()) {
877+
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
878+
const CService& service{service_opt.value()};
879+
if (newList.HasUniqueProperty(service) &&
880+
newList.GetUniquePropertyMN(service)->proTxHash != opt_proTx->proTxHash) {
881+
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-dup-netinfo-entry");
882+
}
883+
} else {
884+
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-protx-netinfo-entry");
849885
}
850886
}
851887

@@ -1382,10 +1418,15 @@ bool CheckProRegTx(CDeterministicMNManager& dmnman, const CTransaction& tx, gsl:
13821418
auto mnList = dmnman.GetListForBlock(pindexPrev);
13831419

13841420
// only allow reusing of addresses when it's for the same collateral (which replaces the old MN)
1385-
for (const CService& entry : opt_ptx->netInfo.GetEntries()) {
1386-
if (mnList.HasUniqueProperty(entry) &&
1387-
mnList.GetUniquePropertyMN(entry)->collateralOutpoint != collateralOutpoint) {
1388-
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-dup-netinfo-entry");
1421+
for (const NetInfoEntry& entry : opt_ptx->netInfo.GetEntries()) {
1422+
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
1423+
const CService& service{service_opt.value()};
1424+
if (mnList.HasUniqueProperty(service) &&
1425+
mnList.GetUniquePropertyMN(service)->collateralOutpoint != collateralOutpoint) {
1426+
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-dup-netinfo-entry");
1427+
}
1428+
} else {
1429+
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-entry");
13891430
}
13901431
}
13911432

@@ -1455,9 +1496,14 @@ bool CheckProUpServTx(CDeterministicMNManager& dmnman, const CTransaction& tx, g
14551496
}
14561497

14571498
// don't allow updating to addresses already used by other MNs
1458-
for (const CService& entry : opt_ptx->netInfo.GetEntries()) {
1459-
if (mnList.HasUniqueProperty(entry) && mnList.GetUniquePropertyMN(entry)->proTxHash != opt_ptx->proTxHash) {
1460-
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-dup-netinfo-entry");
1499+
for (const NetInfoEntry& entry : opt_ptx->netInfo.GetEntries()) {
1500+
if (const auto& service_opt{entry.GetAddrPort()}; service_opt.has_value()) {
1501+
const CService& service{service_opt.value()};
1502+
if (mnList.HasUniqueProperty(service) && mnList.GetUniquePropertyMN(service)->proTxHash != opt_ptx->proTxHash) {
1503+
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-dup-netinfo-entry");
1504+
}
1505+
} else {
1506+
return state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "bad-protx-netinfo-entry");
14611507
}
14621508
}
14631509

src/evo/deterministicmns.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ class CDeterministicMNList
398398
static_assert(!std::is_same_v<std::decay_t<T>, name>, "GetUniquePropertyHash cannot be templated against " #name)
399399
DMNL_NO_TEMPLATE(CBLSPublicKey);
400400
DMNL_NO_TEMPLATE(MnNetInfo);
401+
DMNL_NO_TEMPLATE(NetInfoEntry);
401402
#undef DMNL_NO_TEMPLATE
402403
return ::SerializeHash(v);
403404
}

src/evo/netinfo.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,23 +176,22 @@ NetInfoStatus MnNetInfo::AddEntry(const std::string& input)
176176
const auto ret{ValidateService(*service_opt)};
177177
if (ret == NetInfoStatus::Success) {
178178
m_addr = NetInfoEntry{*service_opt};
179-
ASSERT_IF_DEBUG(GetPrimary() != empty_service);
179+
ASSERT_IF_DEBUG(m_addr.GetAddrPort().has_value());
180180
}
181181
return ret;
182182
}
183183
return NetInfoStatus::BadInput;
184184
}
185185

186-
CServiceList MnNetInfo::GetEntries() const
186+
NetInfoList MnNetInfo::GetEntries() const
187187
{
188-
CServiceList ret;
189188
if (!IsEmpty()) {
190-
ASSERT_IF_DEBUG(GetPrimary() != empty_service);
191-
ret.push_back(GetPrimary());
189+
ASSERT_IF_DEBUG(m_addr.GetAddrPort().has_value());
190+
return {m_addr};
192191
}
193192
// If MnNetInfo is empty, we probably don't expect any entries to show up, so
194193
// we return a blank set instead.
195-
return ret;
194+
return {};
196195
}
197196

198197
const CService& MnNetInfo::GetPrimary() const

src/evo/netinfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class NetInfoEntry
119119

120120
template<> struct is_serializable_enum<NetInfoEntry::NetInfoType> : std::true_type {};
121121

122-
using CServiceList = std::vector<std::reference_wrapper<const CService>>;
122+
using NetInfoList = std::vector<std::reference_wrapper<const NetInfoEntry>>;
123123

124124
class MnNetInfo
125125
{
@@ -160,7 +160,7 @@ class MnNetInfo
160160
}
161161

162162
NetInfoStatus AddEntry(const std::string& service);
163-
CServiceList GetEntries() const;
163+
NetInfoList GetEntries() const;
164164

165165
const CService& GetPrimary() const;
166166
bool IsEmpty() const { return *this == MnNetInfo(); }

src/rpc/masternode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ static RPCHelpMan masternodelist_helper(bool is_composite)
568568
std::string strAddress{};
569569
if (strMode == "addr" || strMode == "full" || strMode == "info" || strMode == "json" || strMode == "recent" ||
570570
strMode == "evo") {
571-
for (const CService& entry : dmn.pdmnState->netInfo.GetEntries()) {
571+
for (const NetInfoEntry& entry : dmn.pdmnState->netInfo.GetEntries()) {
572572
strAddress += entry.ToStringAddrPort() + " ";
573573
}
574574
if (!strAddress.empty()) strAddress.pop_back(); // Remove trailing space

src/test/evo_netinfo_tests.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ const std::vector<std::pair</*input=*/std::string, /*expected_ret=*/NetInfoStatu
3737
{":9999", NetInfoStatus::BadInput},
3838
};
3939

40-
void ValidateGetEntries(const CServiceList& entries, const size_t expected_size)
40+
void ValidateGetEntries(const NetInfoList& entries, const size_t expected_size)
4141
{
4242
BOOST_CHECK_EQUAL(entries.size(), expected_size);
43+
for (const NetInfoEntry& entry : entries) {
44+
BOOST_CHECK(entry.IsTriviallyValid());
45+
}
4346
}
4447

4548
BOOST_AUTO_TEST_CASE(mnnetinfo_rules)

src/txmempool.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, con
691691
if (!proTx.collateralOutpoint.hash.IsNull()) {
692692
mapProTxRefs.emplace(tx_hash, proTx.collateralOutpoint.hash);
693693
}
694-
for (const CService& entry : proTx.netInfo.GetEntries()) {
694+
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
695695
mapProTxAddresses.emplace(entry, tx_hash);
696696
}
697697
mapProTxPubKeyIDs.emplace(proTx.keyIDOwner, tx_hash);
@@ -704,7 +704,7 @@ void CTxMemPool::addUncheckedProTx(indexed_transaction_set::iterator& newit, con
704704
} else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) {
705705
auto proTx = *Assert(GetTxPayload<CProUpServTx>(tx));
706706
mapProTxRefs.emplace(proTx.proTxHash, tx_hash);
707-
for (const CService& entry : proTx.netInfo.GetEntries()) {
707+
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
708708
mapProTxAddresses.emplace(entry, tx_hash);
709709
}
710710
} else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) {
@@ -795,7 +795,7 @@ void CTxMemPool::removeUncheckedProTx(const CTransaction& tx)
795795
if (!proTx.collateralOutpoint.IsNull()) {
796796
eraseProTxRef(tx_hash, proTx.collateralOutpoint.hash);
797797
}
798-
for (const CService& entry : proTx.netInfo.GetEntries()) {
798+
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
799799
mapProTxAddresses.erase(entry);
800800
}
801801
mapProTxPubKeyIDs.erase(proTx.keyIDOwner);
@@ -805,7 +805,7 @@ void CTxMemPool::removeUncheckedProTx(const CTransaction& tx)
805805
} else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) {
806806
auto proTx = *Assert(GetTxPayload<CProUpServTx>(tx));
807807
eraseProTxRef(proTx.proTxHash, tx_hash);
808-
for (const CService& entry : proTx.netInfo.GetEntries()) {
808+
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
809809
mapProTxAddresses.erase(entry);
810810
}
811811
} else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) {
@@ -1034,7 +1034,7 @@ void CTxMemPool::removeProTxConflicts(const CTransaction &tx)
10341034
}
10351035
auto& proTx = *opt_proTx;
10361036

1037-
for (const CService& entry : proTx.netInfo.GetEntries()) {
1037+
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
10381038
if (mapProTxAddresses.count(entry)) {
10391039
uint256 conflictHash = mapProTxAddresses[entry];
10401040
if (conflictHash != tx_hash && mapTx.count(conflictHash)) {
@@ -1056,7 +1056,7 @@ void CTxMemPool::removeProTxConflicts(const CTransaction &tx)
10561056
return;
10571057
}
10581058

1059-
for (const CService& entry : opt_proTx->netInfo.GetEntries()) {
1059+
for (const NetInfoEntry& entry : opt_proTx->netInfo.GetEntries()) {
10601060
if (mapProTxAddresses.count(entry)) {
10611061
uint256 conflictHash = mapProTxAddresses[entry];
10621062
if (conflictHash != tx_hash && mapTx.count(conflictHash)) {
@@ -1394,7 +1394,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
13941394
return true; // i.e. can't decode payload == conflict
13951395
}
13961396
auto& proTx = *opt_proTx;
1397-
for (const CService& entry : proTx.netInfo.GetEntries()) {
1397+
for (const NetInfoEntry& entry : proTx.netInfo.GetEntries()) {
13981398
if (mapProTxAddresses.count(entry)) {
13991399
return true;
14001400
}
@@ -1419,7 +1419,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
14191419
LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
14201420
return true; // i.e. can't decode payload == conflict
14211421
}
1422-
for (const CService& entry : opt_proTx->netInfo.GetEntries()) {
1422+
for (const NetInfoEntry& entry : opt_proTx->netInfo.GetEntries()) {
14231423
auto it = mapProTxAddresses.find(entry);
14241424
if (it != mapProTxAddresses.end() && it->second != opt_proTx->proTxHash) {
14251425
return true;

src/txmempool.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <addressindex.h>
1818
#include <coins.h>
1919
#include <consensus/amount.h>
20+
#include <evo/netinfo.h>
2021
#include <gsl/pointers.h>
2122
#include <indirectmap.h>
2223
#include <netaddress.h>
@@ -525,7 +526,7 @@ class CTxMemPool
525526
std::map<uint256, std::vector<CSpentIndexKey>> mapSpentInserted;
526527

527528
std::multimap<uint256, uint256> mapProTxRefs; // proTxHash -> transaction (all TXs that refer to an existing proTx)
528-
std::map<CService, uint256> mapProTxAddresses;
529+
std::map<NetInfoEntry, uint256> mapProTxAddresses;
529530
std::map<CKeyID, uint256> mapProTxPubKeyIDs;
530531
std::map<uint256, uint256> mapProTxBlsPubKeyHashes;
531532
std::map<COutPoint, uint256> mapProTxCollaterals;

0 commit comments

Comments
 (0)