diff --git a/src/qt/pivx/masternodeswidget.cpp b/src/qt/pivx/masternodeswidget.cpp index 5e5a1e334e34ce..ac1e6a9c7ac4c0 100644 --- a/src/qt/pivx/masternodeswidget.cpp +++ b/src/qt/pivx/masternodeswidget.cpp @@ -12,10 +12,9 @@ #include "clientmodel.h" #include "guiutil.h" -#include "masternodeconfig.h" -#include "masternodeman.h" #include "qt/pivx/mnmodel.h" #include "qt/pivx/optionbutton.h" +#include "qt/walletmodel.h" #define DECORATION_SIZE 65 #define NUM_ITEMS 3 @@ -214,12 +213,15 @@ void MasterNodesWidget::startAlias(const QString& strAlias) QString strStatusHtml; strStatusHtml += "Alias: " + strAlias + " "; - for (const auto& mne : masternodeConfig.getEntries()) { - if (mne.getAlias() == strAlias.toStdString()) { - std::string strError; - strStatusHtml += (!startMN(mne, walletModel->getLastBlockProcessedNum(), strError)) ? ("failed to start.\nError: " + QString::fromStdString(strError)) : "successfully started."; - break; - } + int failed_amount; + int success_amount; + std::string alias = strAlias.toStdString(); + std::string strError; + mnModel->startAllLegacyMNs(false, failed_amount, success_amount, &alias, &strError); + if (failed_amount > 0) { + strStatusHtml = tr("failed to start.\nError: %1").arg(QString::fromStdString(strError)); + } else if (success_amount > 0) { + strStatusHtml = tr("successfully started"); } // update UI and notify updateModelAndInform(strStatusHtml); @@ -255,27 +257,7 @@ bool MasterNodesWidget::startAll(QString& failText, bool onlyMissing) { int amountOfMnFailed = 0; int amountOfMnStarted = 0; - for (const auto& mne : masternodeConfig.getEntries()) { - // Check for missing only - QString mnAlias = QString::fromStdString(mne.getAlias()); - if (onlyMissing && !mnModel->isMNInactive(mnAlias)) { - if (!mnModel->isMNActive(mnAlias)) - amountOfMnFailed++; - continue; - } - - if (!mnModel->isMNCollateralMature(mnAlias)) { - amountOfMnFailed++; - continue; - } - - std::string strError; - if (!startMN(mne, walletModel->getLastBlockProcessedNum(), strError)) { - amountOfMnFailed++; - } else { - amountOfMnStarted++; - } - } + mnModel->startAllLegacyMNs(onlyMissing, amountOfMnFailed, amountOfMnStarted); if (amountOfMnFailed > 0) { failText = tr("%1 Masternodes failed to start, %2 started").arg(amountOfMnFailed).arg(amountOfMnStarted); return false; diff --git a/src/qt/pivx/masternodeswidget.h b/src/qt/pivx/masternodeswidget.h index 33255535bec440..d91e3dd7a1b82d 100644 --- a/src/qt/pivx/masternodeswidget.h +++ b/src/qt/pivx/masternodeswidget.h @@ -8,7 +8,6 @@ #include "qt/pivx/pwidget.h" #include "qt/pivx/furabstractlistitemdelegate.h" #include "qt/pivx/tooltipmenu.h" -#include "walletmodel.h" #include diff --git a/src/qt/pivx/masternodewizarddialog.cpp b/src/qt/pivx/masternodewizarddialog.cpp index 5a7a992b9b9de2..0136adb5207411 100644 --- a/src/qt/pivx/masternodewizarddialog.cpp +++ b/src/qt/pivx/masternodewizarddialog.cpp @@ -8,6 +8,7 @@ #include "key_io.h" #include "qt/pivx/mnmodel.h" #include "qt/pivx/qtutils.h" +#include "qt/walletmodel.h" #include #include diff --git a/src/qt/pivx/masternodewizarddialog.h b/src/qt/pivx/masternodewizarddialog.h index 7092accd42ada3..899b34e400dfc0 100644 --- a/src/qt/pivx/masternodewizarddialog.h +++ b/src/qt/pivx/masternodewizarddialog.h @@ -5,7 +5,6 @@ #ifndef MASTERNODEWIZARDDIALOG_H #define MASTERNODEWIZARDDIALOG_H -#include "walletmodel.h" #include "qt/pivx/focuseddialog.h" #include "qt/pivx/snackbar.h" #include "masternodeconfig.h" diff --git a/src/qt/pivx/mnmodel.cpp b/src/qt/pivx/mnmodel.cpp index c722d64618e02d..82130dab2b3c81 100644 --- a/src/qt/pivx/mnmodel.cpp +++ b/src/qt/pivx/mnmodel.cpp @@ -268,6 +268,52 @@ bool MNModel::createMNCollateral( return true; } +bool MNModel::startLegacyMN(const CMasternodeConfig::CMasternodeEntry& mne, int chainHeight, std::string& strError) +{ + CMasternodeBroadcast mnb; + if (!CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb, false, chainHeight)) + return false; + + mnodeman.UpdateMasternodeList(mnb); + if (activeMasternode.pubKeyMasternode == mnb.GetPubKey()) { + activeMasternode.EnableHotColdMasterNode(mnb.vin, mnb.addr); + } + mnb.Relay(); + return true; +} + +void MNModel::startAllLegacyMNs(bool onlyMissing, int& amountOfMnFailed, int& amountOfMnStarted, + std::string* aliasFilter, std::string* error_ret) +{ + for (const auto& mne : masternodeConfig.getEntries()) { + if (!aliasFilter) { + // Check for missing only + QString mnAlias = QString::fromStdString(mne.getAlias()); + if (onlyMissing && !isMNInactive(mnAlias)) { + if (!isMNActive(mnAlias)) + amountOfMnFailed++; + continue; + } + + if (!isMNCollateralMature(mnAlias)) { + amountOfMnFailed++; + continue; + } + } else if (*aliasFilter != mne.getAlias()){ + continue; + } + + std::string ret_str; + if (!startLegacyMN(mne, walletModel->getLastBlockProcessedNum(), ret_str)) { + amountOfMnFailed++; + if (error_ret) *error_ret = ret_str; + } else { + amountOfMnStarted++; + } + } +} + +// Future: remove after v6.0 CMasternodeConfig::CMasternodeEntry* MNModel::createLegacyMN(COutPoint& collateralOut, const std::string& alias, std::string& serviceAddr, @@ -276,16 +322,17 @@ CMasternodeConfig::CMasternodeEntry* MNModel::createLegacyMN(COutPoint& collater QString& ret_error) { // Update the conf file - std::string strConfFile = "masternode.conf"; + QString strConfFileQt(PIVX_MASTERNODE_CONF_FILENAME); + std::string strConfFile = strConfFileQt.toStdString(); std::string strDataDir = GetDataDir().string(); fs::path conf_file_path(strConfFile); if (strConfFile != conf_file_path.filename().string()) { - throw std::runtime_error(strprintf(_("masternode.conf %s resides outside data directory %s"), strConfFile, strDataDir)); + throw std::runtime_error(strprintf(_("%s %s resides outside data directory %s"), strConfFile, strConfFile, strDataDir)); } fs::path pathBootstrap = GetDataDir() / strConfFile; if (!fs::exists(pathBootstrap)) { - ret_error = tr("masternode.conf file doesn't exists"); + ret_error = tr("%1 file doesn't exists").arg(strConfFileQt); return nullptr; } @@ -293,7 +340,7 @@ CMasternodeConfig::CMasternodeEntry* MNModel::createLegacyMN(COutPoint& collater fsbridge::ifstream streamConfig(pathMasternodeConfigFile); if (!streamConfig.good()) { - ret_error = tr("Invalid masternode.conf file"); + ret_error = tr("Invalid %1 file").arg(strConfFileQt); return nullptr; } @@ -316,7 +363,7 @@ CMasternodeConfig::CMasternodeEntry* MNModel::createLegacyMN(COutPoint& collater iss.clear(); if (!(iss >> alias >> ip >> privKey >> txHash >> outputIndex)) { streamConfig.close(); - ret_error = tr("Error parsing masternode.conf file"); + ret_error = tr("Error parsing %1 file").arg(strConfFileQt); return nullptr; } } @@ -355,7 +402,7 @@ CMasternodeConfig::CMasternodeEntry* MNModel::createLegacyMN(COutPoint& collater } rename(pathMasternodeConfigFile, pathOldConfFile); - fs::path pathNewConfFile = AbsPathForConfigVal(fs::path("masternode.conf")); + fs::path pathNewConfFile = AbsPathForConfigVal(fs::path(strConfFile)); rename(pathConfigFile, pathNewConfFile); auto ret_mn_entry = masternodeConfig.add(alias, serviceAddr+":"+port, mnKeyString, txID, indexOutStr); @@ -365,18 +412,20 @@ CMasternodeConfig::CMasternodeEntry* MNModel::createLegacyMN(COutPoint& collater return ret_mn_entry; } +// Future: remove after v6.0 bool MNModel::removeLegacyMN(const std::string& alias_to_remove, const std::string& tx_id, unsigned int out_index, QString& ret_error) { - std::string strConfFile = "masternode.conf"; + QString strConfFileQt(PIVX_MASTERNODE_CONF_FILENAME); + std::string strConfFile = strConfFileQt.toStdString(); std::string strDataDir = GetDataDir().string(); fs::path conf_file_path(strConfFile); if (strConfFile != conf_file_path.filename().string()) { - throw std::runtime_error(strprintf(_("masternode.conf %s resides outside data directory %s"), strConfFile, strDataDir)); + throw std::runtime_error(strprintf(_("%s %s resides outside data directory %s"), strConfFile, strConfFile, strDataDir)); } fs::path pathBootstrap = GetDataDir() / strConfFile; if (!fs::exists(pathBootstrap)) { - ret_error = tr("masternode.conf file doesn't exists"); + ret_error = tr("%1 file doesn't exists").arg(strConfFileQt); return false; } @@ -384,7 +433,7 @@ bool MNModel::removeLegacyMN(const std::string& alias_to_remove, const std::stri fsbridge::ifstream streamConfig(pathMasternodeConfigFile); if (!streamConfig.good()) { - ret_error = tr("Invalid masternode.conf file"); + ret_error = tr("Invalid %1 file").arg(strConfFileQt); return false; } @@ -408,7 +457,7 @@ bool MNModel::removeLegacyMN(const std::string& alias_to_remove, const std::stri iss.clear(); if (!(iss >> alias >> ip >> privKey >> txHash >> outputIndex)) { streamConfig.close(); - ret_error = tr("Error parsing masternode.conf file"); + ret_error = tr("Error parsing %1 file").arg(strConfFileQt); return false; } } @@ -428,26 +477,30 @@ bool MNModel::removeLegacyMN(const std::string& alias_to_remove, const std::stri streamConfig.close(); - if (lineNumToRemove != -1) { - fs::path pathConfigFile = AbsPathForConfigVal(fs::path("masternode_temp.conf")); - FILE* configFile = fsbridge::fopen(pathConfigFile, "w"); - fwrite(lineCopy.c_str(), std::strlen(lineCopy.c_str()), 1, configFile); - fclose(configFile); - - fs::path pathOldConfFile = AbsPathForConfigVal(fs::path("old_masternode.conf")); - if (fs::exists(pathOldConfFile)) { - fs::remove(pathOldConfFile); - } - rename(pathMasternodeConfigFile, pathOldConfFile); + if (lineNumToRemove == -1) { + ret_error = tr("MN alias %1 not found in %2 file").arg(QString::fromStdString(alias_to_remove)).arg(strConfFileQt); + return false; + } - fs::path pathNewConfFile = AbsPathForConfigVal(fs::path("masternode.conf")); - rename(pathConfigFile, pathNewConfFile); + // Update file + fs::path pathConfigFile = AbsPathForConfigVal(fs::path("masternode_temp.conf")); + FILE* configFile = fsbridge::fopen(pathConfigFile, "w"); + fwrite(lineCopy.c_str(), std::strlen(lineCopy.c_str()), 1, configFile); + fclose(configFile); - // Unlock collateral - COutPoint collateralOut(uint256S(tx_id), out_index); - walletModel->unlockCoin(collateralOut); - // Remove alias - masternodeConfig.remove(alias_to_remove); - return true; + fs::path pathOldConfFile = AbsPathForConfigVal(fs::path("old_masternode.conf")); + if (fs::exists(pathOldConfFile)) { + fs::remove(pathOldConfFile); } -} \ No newline at end of file + rename(pathMasternodeConfigFile, pathOldConfFile); + + fs::path pathNewConfFile = AbsPathForConfigVal(fs::path(strConfFile)); + rename(pathConfigFile, pathNewConfFile); + + // Unlock collateral + COutPoint collateralOut(uint256S(tx_id), out_index); + walletModel->unlockCoin(collateralOut); + // Remove alias + masternodeConfig.remove(alias_to_remove); + return true; +} diff --git a/src/qt/pivx/mnmodel.h b/src/qt/pivx/mnmodel.h index 4a4fd3c1043bac..05c1656cbd74ee 100644 --- a/src/qt/pivx/mnmodel.h +++ b/src/qt/pivx/mnmodel.h @@ -64,6 +64,10 @@ class MNModel : public QAbstractTableModel int getMasternodeCollateralMinConf(); // Generates the collateral transaction bool createMNCollateral(const QString& alias, const QString& addr, COutPoint& ret_outpoint, QString& ret_error); + // Creates the mnb and broadcast it to the network + bool startLegacyMN(const CMasternodeConfig::CMasternodeEntry& mne, int chainHeight, std::string& strError); + void startAllLegacyMNs(bool onlyMissing, int& amountOfMnFailed, int& amountOfMnStarted, + std::string* aliasFilter = nullptr, std::string* error_ret = nullptr); CMasternodeConfig::CMasternodeEntry* createLegacyMN(COutPoint& collateralOut, const std::string& alias, diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh index 5a65aab5647b31..5c47b4a70f6b1d 100755 --- a/test/lint/lint-circular-dependencies.sh +++ b/test/lint/lint-circular-dependencies.sh @@ -42,7 +42,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=( "chain -> legacy/stakemodifier -> stakeinput -> chain" "chain -> legacy/stakemodifier -> validation -> chain" "chainparamsbase -> util/system -> logging -> chainparamsbase" - "evo/deterministicmns -> masternode -> wallet/wallet -> evo/deterministicmns" "kernel -> stakeinput -> wallet/wallet -> kernel" "legacy/validation_zerocoin_legacy -> wallet/wallet -> validation -> legacy/validation_zerocoin_legacy" "qt/askpassphrasedialog -> qt/pivx/pivxgui -> qt/pivx/topbar -> qt/askpassphrasedialog" @@ -51,6 +50,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=( "qt/pivx/pivxgui -> qt/pivx/send -> qt/pivx/tooltipmenu -> qt/pivx/pivxgui" "chain -> legacy/stakemodifier -> validation -> validationinterface -> chain" "chain -> legacy/stakemodifier -> stakeinput -> txdb -> chain" + "chain -> legacy/stakemodifier -> stakeinput -> wallet/wallet -> evo/deterministicmns -> chain" "chain -> legacy/stakemodifier -> validation -> checkpoints -> chain" "chain -> legacy/stakemodifier -> validation -> undo -> chain" "chain -> legacy/stakemodifier -> validation -> pow -> chain"