r1
This commit is contained in:
@@ -0,0 +1,327 @@
|
||||
// Copyright (c) 2014-2016 The Dash Developers
|
||||
// Copyright (c) 2016-2019 The PIVX developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "masternodelist.h"
|
||||
#include "ui_masternodelist.h"
|
||||
|
||||
#include "activemasternode.h"
|
||||
#include "clientmodel.h"
|
||||
#include "guiutil.h"
|
||||
#include "init.h"
|
||||
#include "masternode-sync.h"
|
||||
#include "masternodeconfig.h"
|
||||
#include "masternodeman.h"
|
||||
#include "sync.h"
|
||||
#include "wallet/wallet.h"
|
||||
#include "walletmodel.h"
|
||||
#include "askpassphrasedialog.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
|
||||
CCriticalSection cs_masternodes;
|
||||
|
||||
MasternodeList::MasternodeList(QWidget* parent) : QWidget(parent),
|
||||
ui(new Ui::MasternodeList),
|
||||
clientModel(0),
|
||||
walletModel(0)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->startButton->setEnabled(false);
|
||||
|
||||
int columnAliasWidth = 100;
|
||||
int columnAddressWidth = 200;
|
||||
int columnProtocolWidth = 60;
|
||||
int columnStatusWidth = 80;
|
||||
int columnActiveWidth = 130;
|
||||
int columnLastSeenWidth = 130;
|
||||
|
||||
ui->tableWidgetMyMasternodes->setAlternatingRowColors(true);
|
||||
ui->tableWidgetMyMasternodes->setColumnWidth(0, columnAliasWidth);
|
||||
ui->tableWidgetMyMasternodes->setColumnWidth(1, columnAddressWidth);
|
||||
ui->tableWidgetMyMasternodes->setColumnWidth(2, columnProtocolWidth);
|
||||
ui->tableWidgetMyMasternodes->setColumnWidth(3, columnStatusWidth);
|
||||
ui->tableWidgetMyMasternodes->setColumnWidth(4, columnActiveWidth);
|
||||
ui->tableWidgetMyMasternodes->setColumnWidth(5, columnLastSeenWidth);
|
||||
|
||||
ui->tableWidgetMyMasternodes->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
QAction* startAliasAction = new QAction(tr("Start alias"), this);
|
||||
contextMenu = new QMenu();
|
||||
contextMenu->addAction(startAliasAction);
|
||||
connect(ui->tableWidgetMyMasternodes, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)));
|
||||
connect(startAliasAction, SIGNAL(triggered()), this, SLOT(on_startButton_clicked()));
|
||||
|
||||
timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateMyNodeList()));
|
||||
timer->start(1000);
|
||||
|
||||
// Fill MN list
|
||||
fFilterUpdated = true;
|
||||
nTimeFilterUpdated = GetTime();
|
||||
}
|
||||
|
||||
MasternodeList::~MasternodeList()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MasternodeList::setClientModel(ClientModel* model)
|
||||
{
|
||||
this->clientModel = model;
|
||||
}
|
||||
|
||||
void MasternodeList::setWalletModel(WalletModel* model)
|
||||
{
|
||||
this->walletModel = model;
|
||||
}
|
||||
|
||||
void MasternodeList::showContextMenu(const QPoint& point)
|
||||
{
|
||||
QTableWidgetItem* item = ui->tableWidgetMyMasternodes->itemAt(point);
|
||||
if (item) contextMenu->exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void MasternodeList::StartAlias(std::string strAlias)
|
||||
{
|
||||
std::string strStatusHtml;
|
||||
strStatusHtml += "<center>Alias: " + strAlias;
|
||||
|
||||
for (CMasternodeConfig::CMasternodeEntry mne : masternodeConfig.getEntries()) {
|
||||
if (mne.getAlias() == strAlias) {
|
||||
std::string strError;
|
||||
CMasternodeBroadcast mnb;
|
||||
|
||||
bool fSuccess = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb);
|
||||
|
||||
if (fSuccess) {
|
||||
strStatusHtml += "<br>Successfully started masternode.";
|
||||
mnodeman.UpdateMasternodeList(mnb);
|
||||
mnb.Relay();
|
||||
} else {
|
||||
strStatusHtml += "<br>Failed to start masternode.<br>Error: " + strError;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
strStatusHtml += "</center>";
|
||||
|
||||
QMessageBox msg;
|
||||
msg.setText(QString::fromStdString(strStatusHtml));
|
||||
msg.exec();
|
||||
|
||||
updateMyNodeList(true);
|
||||
}
|
||||
|
||||
void MasternodeList::StartAll(std::string strCommand)
|
||||
{
|
||||
int nCountSuccessful = 0;
|
||||
int nCountFailed = 0;
|
||||
std::string strFailedHtml;
|
||||
|
||||
for (CMasternodeConfig::CMasternodeEntry mne : masternodeConfig.getEntries()) {
|
||||
std::string strError;
|
||||
CMasternodeBroadcast mnb;
|
||||
|
||||
int nIndex;
|
||||
if(!mne.castOutputIndex(nIndex))
|
||||
continue;
|
||||
|
||||
CTxIn txin = CTxIn(uint256S(mne.getTxHash()), uint32_t(nIndex));
|
||||
CMasternode* pmn = mnodeman.Find(txin);
|
||||
|
||||
if (strCommand == "start-missing" && pmn) continue;
|
||||
|
||||
bool fSuccess = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb);
|
||||
|
||||
if (fSuccess) {
|
||||
nCountSuccessful++;
|
||||
mnodeman.UpdateMasternodeList(mnb);
|
||||
mnb.Relay();
|
||||
} else {
|
||||
nCountFailed++;
|
||||
strFailedHtml += "\nFailed to start " + mne.getAlias() + ". Error: " + strError;
|
||||
}
|
||||
}
|
||||
pwalletMain->Lock();
|
||||
|
||||
std::string returnObj;
|
||||
returnObj = strprintf("Successfully started %d masternodes, failed to start %d, total %d", nCountSuccessful, nCountFailed, nCountFailed + nCountSuccessful);
|
||||
if (nCountFailed > 0) {
|
||||
returnObj += strFailedHtml;
|
||||
}
|
||||
|
||||
QMessageBox msg;
|
||||
msg.setText(QString::fromStdString(returnObj));
|
||||
msg.exec();
|
||||
|
||||
updateMyNodeList(true);
|
||||
}
|
||||
|
||||
void MasternodeList::updateMyMasternodeInfo(QString strAlias, QString strAddr, CMasternode* pmn)
|
||||
{
|
||||
LOCK(cs_mnlistupdate);
|
||||
bool fOldRowFound = false;
|
||||
int nNewRow = 0;
|
||||
|
||||
for (int i = 0; i < ui->tableWidgetMyMasternodes->rowCount(); i++) {
|
||||
if (ui->tableWidgetMyMasternodes->item(i, 0)->text() == strAlias) {
|
||||
fOldRowFound = true;
|
||||
nNewRow = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nNewRow == 0 && !fOldRowFound) {
|
||||
nNewRow = ui->tableWidgetMyMasternodes->rowCount();
|
||||
ui->tableWidgetMyMasternodes->insertRow(nNewRow);
|
||||
}
|
||||
|
||||
QTableWidgetItem* aliasItem = new QTableWidgetItem(strAlias);
|
||||
QTableWidgetItem* addrItem = new QTableWidgetItem(pmn ? QString::fromStdString(pmn->addr.ToString()) : strAddr);
|
||||
QTableWidgetItem* protocolItem = new QTableWidgetItem(QString::number(pmn ? pmn->protocolVersion : -1));
|
||||
QTableWidgetItem* statusItem = new QTableWidgetItem(QString::fromStdString(pmn ? pmn->GetStatus() : "MISSING"));
|
||||
GUIUtil::DHMSTableWidgetItem* activeSecondsItem = new GUIUtil::DHMSTableWidgetItem(pmn ? (pmn->lastPing.sigTime - pmn->sigTime) : 0);
|
||||
QTableWidgetItem* lastSeenItem = new QTableWidgetItem(QString::fromStdString(DateTimeStrFormat("%Y-%m-%d %H:%M", pmn ? pmn->lastPing.sigTime : 0)));
|
||||
QTableWidgetItem* pubkeyItem = new QTableWidgetItem(QString::fromStdString(pmn ? CBitcoinAddress(pmn->pubKeyCollateralAddress.GetID()).ToString() : ""));
|
||||
|
||||
ui->tableWidgetMyMasternodes->setItem(nNewRow, 0, aliasItem);
|
||||
ui->tableWidgetMyMasternodes->setItem(nNewRow, 1, addrItem);
|
||||
ui->tableWidgetMyMasternodes->setItem(nNewRow, 2, protocolItem);
|
||||
ui->tableWidgetMyMasternodes->setItem(nNewRow, 3, statusItem);
|
||||
ui->tableWidgetMyMasternodes->setItem(nNewRow, 4, activeSecondsItem);
|
||||
ui->tableWidgetMyMasternodes->setItem(nNewRow, 5, lastSeenItem);
|
||||
ui->tableWidgetMyMasternodes->setItem(nNewRow, 6, pubkeyItem);
|
||||
}
|
||||
|
||||
void MasternodeList::updateMyNodeList(bool fForce)
|
||||
{
|
||||
static int64_t nTimeMyListUpdated = 0;
|
||||
|
||||
// automatically update my masternode list only once in MY_MASTERNODELIST_UPDATE_SECONDS seconds,
|
||||
// this update still can be triggered manually at any time via button click
|
||||
int64_t nSecondsTillUpdate = nTimeMyListUpdated + MY_MASTERNODELIST_UPDATE_SECONDS - GetTime();
|
||||
ui->secondsLabel->setText(QString::number(nSecondsTillUpdate));
|
||||
|
||||
if (nSecondsTillUpdate > 0 && !fForce) return;
|
||||
nTimeMyListUpdated = GetTime();
|
||||
|
||||
ui->tableWidgetMyMasternodes->setSortingEnabled(false);
|
||||
for (CMasternodeConfig::CMasternodeEntry mne : masternodeConfig.getEntries()) {
|
||||
int nIndex;
|
||||
if(!mne.castOutputIndex(nIndex))
|
||||
continue;
|
||||
|
||||
CTxIn txin = CTxIn(uint256S(mne.getTxHash()), uint32_t(nIndex));
|
||||
CMasternode* pmn = mnodeman.Find(txin);
|
||||
updateMyMasternodeInfo(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), pmn);
|
||||
}
|
||||
ui->tableWidgetMyMasternodes->setSortingEnabled(true);
|
||||
|
||||
// reset "timer"
|
||||
ui->secondsLabel->setText("0");
|
||||
}
|
||||
|
||||
void MasternodeList::on_startButton_clicked()
|
||||
{
|
||||
// Find selected node alias
|
||||
QItemSelectionModel* selectionModel = ui->tableWidgetMyMasternodes->selectionModel();
|
||||
QModelIndexList selected = selectionModel->selectedRows();
|
||||
|
||||
if (selected.count() == 0) return;
|
||||
|
||||
QModelIndex index = selected.at(0);
|
||||
int nSelectedRow = index.row();
|
||||
std::string strAlias = ui->tableWidgetMyMasternodes->item(nSelectedRow, 0)->text().toStdString();
|
||||
|
||||
// Display message box
|
||||
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm masternode start"),
|
||||
tr("Are you sure you want to start masternode %1?").arg(QString::fromStdString(strAlias)),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel);
|
||||
|
||||
if (retval != QMessageBox::Yes) return;
|
||||
|
||||
WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus();
|
||||
|
||||
if (encStatus == walletModel->Locked || encStatus == walletModel->UnlockedForAnonymizationOnly) {
|
||||
WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full));
|
||||
|
||||
if (!ctx.isValid()) return; // Unlock wallet was cancelled
|
||||
|
||||
StartAlias(strAlias);
|
||||
return;
|
||||
}
|
||||
|
||||
StartAlias(strAlias);
|
||||
}
|
||||
|
||||
void MasternodeList::on_startAllButton_clicked()
|
||||
{
|
||||
// Display message box
|
||||
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm all masternodes start"),
|
||||
tr("Are you sure you want to start ALL masternodes?"),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel);
|
||||
|
||||
if (retval != QMessageBox::Yes) return;
|
||||
|
||||
WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus();
|
||||
|
||||
if (encStatus == walletModel->Locked || encStatus == walletModel->UnlockedForAnonymizationOnly) {
|
||||
WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full));
|
||||
|
||||
if (!ctx.isValid()) return; // Unlock wallet was cancelled
|
||||
|
||||
StartAll();
|
||||
return;
|
||||
}
|
||||
|
||||
StartAll();
|
||||
}
|
||||
|
||||
void MasternodeList::on_startMissingButton_clicked()
|
||||
{
|
||||
if (!masternodeSync.IsMasternodeListSynced()) {
|
||||
QMessageBox::critical(this, tr("Command is not available right now"),
|
||||
tr("You can't use this command until masternode list is synced"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Display message box
|
||||
QMessageBox::StandardButton retval = QMessageBox::question(this,
|
||||
tr("Confirm missing masternodes start"),
|
||||
tr("Are you sure you want to start MISSING masternodes?"),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel);
|
||||
|
||||
if (retval != QMessageBox::Yes) return;
|
||||
|
||||
WalletModel::EncryptionStatus encStatus = walletModel->getEncryptionStatus();
|
||||
|
||||
if (encStatus == walletModel->Locked || encStatus == walletModel->UnlockedForAnonymizationOnly) {
|
||||
WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full));
|
||||
|
||||
if (!ctx.isValid()) return; // Unlock wallet was cancelled
|
||||
|
||||
StartAll("start-missing");
|
||||
return;
|
||||
}
|
||||
|
||||
StartAll("start-missing");
|
||||
}
|
||||
|
||||
void MasternodeList::on_tableWidgetMyMasternodes_itemSelectionChanged()
|
||||
{
|
||||
if (ui->tableWidgetMyMasternodes->selectedItems().count() > 0) {
|
||||
ui->startButton->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void MasternodeList::on_UpdateButton_clicked()
|
||||
{
|
||||
updateMyNodeList(true);
|
||||
}
|
||||
Reference in New Issue
Block a user