Skip to content

Commit

Permalink
Consensus: Add mnb ADDRv2 guard.
Browse files Browse the repository at this point in the history
So upgraded peers don't create, accept nor broadcast an mnb containing a new addr v2 to non-upgraded peers before the new NU enforcement (introduced in #2492).
  • Loading branch information
furszy committed Aug 10, 2021
1 parent b4515dc commit 34ff7a8
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 6 deletions.
10 changes: 9 additions & 1 deletion src/masternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ bool CMasternodeBroadcast::Create(const std::string& strService,
const std::string& strOutputIndex,
std::string& strErrorRet,
CMasternodeBroadcast& mnbRet,
bool fOffline)
bool fOffline,
int chainHeight)
{
CTxIn txin;
CPubKey pubKeyCollateralAddressNew;
Expand Down Expand Up @@ -293,6 +294,13 @@ bool CMasternodeBroadcast::Create(const std::string& strService,
if (!CheckDefaultPort(_service, strErrorRet, "CMasternodeBroadcast::Create"))
return false;

// Check if the MN has a ADDRv2 and reject it if the new NU wasn't enforced.
if (!_service.IsAddrV1Compatible() &&
!Params().GetConsensus().NetworkUpgradeActive(chainHeight, Consensus::UPGRADE_V5_3)) {
strErrorRet = "Cannot start MN with a v2 address before the v5.3 enforcement\n";
return false;
}

return Create(txin, _service, keyCollateralAddressNew, pubKeyCollateralAddressNew, keyMasternodeNew, pubKeyMasternodeNew, strErrorRet, mnbRet);
}

Expand Down
2 changes: 1 addition & 1 deletion src/masternode.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ class CMasternodeBroadcast : public CMasternode

/// Create Masternode broadcast, needs to be relayed manually after that
static bool Create(const CTxIn& vin, const CService& service, const CKey& keyCollateralAddressNew, const CPubKey& pubKeyCollateralAddressNew, const CKey& keyMasternodeNew, const CPubKey& pubKeyMasternodeNew, std::string& strErrorRet, CMasternodeBroadcast& mnbRet);
static bool Create(const std::string& strService, const std::string& strKey, const std::string& strTxHash, const std::string& strOutputIndex, std::string& strErrorRet, CMasternodeBroadcast& mnbRet, bool fOffline = false);
static bool Create(const std::string& strService, const std::string& strKey, const std::string& strTxHash, const std::string& strOutputIndex, std::string& strErrorRet, CMasternodeBroadcast& mnbRet, bool fOffline, int chainHeight);
static bool CheckDefaultPort(CService service, std::string& strErrorRet, const std::string& strContext);
};

Expand Down
13 changes: 11 additions & 2 deletions src/masternodeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,15 @@ int CMasternodeMan::ProcessMNBroadcast(CNode* pfrom, CMasternodeBroadcast& mnb)
return 0;
}

int chainHeight = GetBestHeight();
const auto& consensus = Params().GetConsensus();
// Check if mnb contains a ADDRv2 and reject it if the new NU wasn't enforced.
if (!mnb.addr.IsAddrV1Compatible() &&
!consensus.NetworkUpgradeActive(chainHeight, Consensus::UPGRADE_V5_3)) {
LogPrint(BCLog::MASTERNODE, "mnb - received a ADDRv2 before enforcement\n");
return 33;
}

int nDoS = 0;
if (!mnb.CheckAndUpdate(nDoS, GetBestHeight())) {
return nDoS;
Expand All @@ -720,7 +729,7 @@ int CMasternodeMan::ProcessMNBroadcast(CNode* pfrom, CMasternodeBroadcast& mnb)
// make sure the vout that was signed is related to the transaction that spawned the Masternode
// - this is expensive, so it's only done once per Masternode
if (!mnb.IsInputAssociatedWithPubkey()) {
LogPrintf("CMasternodeMan::ProcessMessage() : mnb - Got mismatched pubkey and vin\n");
LogPrint(BCLog::MASTERNODE, "%s : mnb - Got mismatched pubkey and vin\n", __func__);
return 33;
}

Expand All @@ -729,7 +738,7 @@ int CMasternodeMan::ProcessMNBroadcast(CNode* pfrom, CMasternodeBroadcast& mnb)

// make sure it's still unspent
// - this is checked later by .check() in many places and by ThreadCheckObfuScationPool()
if (mnb.CheckInputsAndAdd(GetBestHeight(), nDoS)) {
if (mnb.CheckInputsAndAdd(chainHeight, nDoS)) {
// use this as a peer
g_connman->AddNewAddress(CAddress(mnb.addr, NODE_NETWORK), pfrom->addr, 2 * 60 * 60);
masternodeSync.AddedMasternodeList(mnbHash);
Expand Down
2 changes: 1 addition & 1 deletion src/qt/pivx/masternodeswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ void MasterNodesWidget::updateModelAndInform(QString informText)
bool MasterNodesWidget::startMN(const CMasternodeConfig::CMasternodeEntry& mne, std::string& strError)
{
CMasternodeBroadcast mnb;
if (!CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb))
if (!CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb, false, walletModel->getLastBlockProcessedNum()))
return false;

mnodeman.UpdateMasternodeList(mnb);
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/masternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ bool StartMasternodeEntry(UniValue& statusObjRet, CMasternodeBroadcast& mnbRet,
if (strCommand == "disabled" && pmn->IsEnabled()) return false;
}

fSuccessRet = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage, mnbRet);
fSuccessRet = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage, mnbRet, false, mnodeman.GetBestHeight());

statusObjRet.pushKV("alias", mne.getAlias());
statusObjRet.pushKV("result", fSuccessRet ? "success" : "failed");
Expand Down

0 comments on commit 34ff7a8

Please sign in to comment.