@@ -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
0 commit comments