From e0d1683bff37e1b845980ab0b00401b82a4c779d Mon Sep 17 00:00:00 2001 From: Shafil Alam <36016500+alamshafil@users.noreply.github.com> Date: Fri, 16 Apr 2021 14:24:27 -0400 Subject: [PATCH] Add a form dialog for adding peers Fixed tabIndex and width in debugwindow.ui Added Qt UI files for each dialog Added Qt UI files Added separate thread for peer dialogs to run RPC commands Fixed tabIndex Remove unneeded includes Fixed error Replaced RPCExecutor with g_connman Replaced RPCExecutor with g_connman Added two input fields for peer address and port Remove peerThread Validate IP addresses Remove Peer now uses selected IP address in peerWidget Interpret RPC response Remove redundant include Use a regular expression to validate IPs Disconnect node if it has been discovered Use port based on current chain Change peerAddress -> peerPort Allowed DNS names to be entered Update src/qt/peerdialog.cpp Co-authored-by: Ross Nicoll Fix typo Co-authored-by: Ross Nicoll Use LookupHost to check address Co-authored-by: Ross Nicoll Fix syntax typo --- src/Makefile.qt.include | 5 + src/qt/forms/addpeerdialog.ui | 73 ++++++++++++++ src/qt/forms/debugwindow.ui | 95 +++++++++++++++--- src/qt/forms/testpeerdialog.ui | 73 ++++++++++++++ src/qt/peerdialog.cpp | 176 +++++++++++++++++++++++++++++++++ src/qt/peerdialog.h | 62 ++++++++++++ src/qt/rpcconsole.cpp | 61 ++++++++++++ src/qt/rpcconsole.h | 8 +- 8 files changed, 538 insertions(+), 15 deletions(-) create mode 100644 src/qt/forms/addpeerdialog.ui create mode 100644 src/qt/forms/testpeerdialog.ui create mode 100644 src/qt/peerdialog.cpp create mode 100644 src/qt/peerdialog.h diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 723e29dc5..1b734ff2b 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -109,6 +109,8 @@ QT_FORMS_UI = \ qt/forms/receivecoinsdialog.ui \ qt/forms/receiverequestdialog.ui \ qt/forms/debugwindow.ui \ + qt/forms/addpeerdialog.ui \ + qt/forms/testpeerdialog.ui \ qt/forms/sendcoinsdialog.ui \ qt/forms/sendcoinsentry.ui \ qt/forms/signverifymessagedialog.ui \ @@ -157,6 +159,7 @@ QT_MOC_CPP = \ qt/moc_transactiontablemodel.cpp \ qt/moc_transactionview.cpp \ qt/moc_utilitydialog.cpp \ + qt/moc_peerdialog.cpp \ qt/moc_verticallabel.cpp \ qt/moc_walletframe.cpp \ qt/moc_walletmodel.cpp \ @@ -230,6 +233,7 @@ BITCOIN_QT_H = \ qt/transactiontablemodel.h \ qt/transactionview.h \ qt/utilitydialog.h \ + qt/peerdialog.h \ qt/verticallabel.h \ qt/walletframe.h \ qt/walletmodel.h \ @@ -320,6 +324,7 @@ BITCOIN_QT_BASE_CPP = \ qt/splashscreen.cpp \ qt/trafficgraphwidget.cpp \ qt/utilitydialog.cpp \ + qt/peerdialog.cpp \ qt/verticallabel.cpp BITCOIN_QT_WINDOWS_CPP = qt/winshutdownmonitor.cpp diff --git a/src/qt/forms/addpeerdialog.ui b/src/qt/forms/addpeerdialog.ui new file mode 100644 index 000000000..7cb09dea3 --- /dev/null +++ b/src/qt/forms/addpeerdialog.ui @@ -0,0 +1,73 @@ + + + AddPeerDialog + + + + 0 + 0 + 466 + 186 + + + + Add Peer + + + + + + + 11 + 75 + true + + + + Enter the peer details below. + + + Qt::AlignCenter + + + + + + + Be careful! Do not blindly trust anyone that tells you to add their node. + + + Qt::AlignCenter + + + + + + + + + Enter the peer's address + + + + + + + Enter the peer's port + + + + + + + + + Add! + + + + + + + + diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 8be4a955b..6eb838c91 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -165,17 +165,17 @@ - - - - 75 - true - - - - Network - - + + + + 75 + true + + + + Network + + @@ -433,12 +433,12 @@ 24 - - - Decrease font size + + + :/icons/fontsmaller:/icons/fontsmaller @@ -854,6 +854,33 @@ 0 + + + + + 300 + 32 + + + + + 16777215 + 32 + + + + + 12 + + + + IBeamCursor + + + Connected peers + + + @@ -870,6 +897,46 @@ + + + + 0 + + + 0 + + + + + PointingHandCursor + + + Add new peer + + + + + + + PointingHandCursor + + + Remove peer + + + + + + + PointingHandCursor + + + One try peer + + + + + diff --git a/src/qt/forms/testpeerdialog.ui b/src/qt/forms/testpeerdialog.ui new file mode 100644 index 000000000..471860529 --- /dev/null +++ b/src/qt/forms/testpeerdialog.ui @@ -0,0 +1,73 @@ + + + TestPeerDialog + + + + 0 + 0 + 466 + 186 + + + + Test Peer + + + + + + + 11 + 75 + true + + + + Enter the peer details below. + + + Qt::AlignCenter + + + + + + + Be careful! Do not blindly trust anyone that tells you to add their node. + + + Qt::AlignCenter + + + + + + + + + Enter the peer's address + + + + + + + Enter the peer's port + + + + + + + + + Test! + + + + + + + + diff --git a/src/qt/peerdialog.cpp b/src/qt/peerdialog.cpp new file mode 100644 index 000000000..3c35c686f --- /dev/null +++ b/src/qt/peerdialog.cpp @@ -0,0 +1,176 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "guiutil.h" +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include +#include + +#include "peerdialog.h" + +#include "ui_addpeerdialog.h" +#include "ui_testpeerdialog.h" + +#include "net.h" +#include "net_processing.h" +#include "netbase.h" +#include "protocol.h" +#include "chainparams.h" +#include "util.h" + +#include + +#include +#include +#include +#include + +/** Function to manage peers */ +QString PeerTools::ManagePeer(QString type, QString peer) +{ + std::string peerAddress = peer.toStdString(); + + if(!g_connman) + return "Error: Peer-to-peer functionality missing or disabled"; + + if (type == "onetry") + { + CAddress addr; + g_connman->OpenNetworkConnection(addr, false, NULL, peerAddress.c_str()); + return "Attempted to one try node."; + } + + if (type == "add") + { + if(!g_connman->AddNode(peerAddress)) + return "Error: Node already added"; + } + else if(type == "remove") + { + if(!g_connman->RemoveAddedNode(peerAddress)) + { + if(!g_connman->DisconnectNode(peerAddress)) + return "Node not found in connected nodes"; + + return "Disconnected the node: " + peer; + } + else + { + if(!g_connman->DisconnectNode(peerAddress)) + return "Node not found in connected nodes"; + } + } + + return "Returned OK."; +} + +/** Check if Peer is valid */ +bool PeerTools::CheckPeerAddress(QString address) +{ + CNetAddr addr; + return LookupHost(address.toStdString().c_str(), addr, true); +} + +/** Get port based on current chain */ +QString PeerTools::GetPort() +{ + return QString::number(Params().GetDefaultPort()); +} + +/** Add Peer Dialog */ +AddPeerDialog::AddPeerDialog(QWidget *parent) : + QWidget(parent), + ui(new Ui::AddPeerDialog) +{ + ui->setupUi(this); + + ui->peerPort->setValidator( new QIntValidator(1, 65535, this) ); + + connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(on_addPeer_clicked())); +} + +AddPeerDialog::~AddPeerDialog() +{ + delete ui; +} + +void AddPeerDialog::on_addPeer_clicked() +{ + QString address = ui->peerAddress->text(); + QString port = ui->peerPort->text(); + QString data = ""; + + if(address.isEmpty()) + { + QMessageBox::critical(this, "Add Peer", "Please enter an address.", QMessageBox::Ok, QMessageBox::Ok); + return; + } + + if(port.isEmpty()) + { + port = PeerTools::GetPort(); + ui->peerPort->setText(port); + } + + if(!PeerTools::CheckPeerAddress(address)) + { + QMessageBox::critical(this, "Add Peer", "Please enter a vaild peer address.", QMessageBox::Ok, QMessageBox::Ok); + return; + } + + data = address + ":" + port; + + if(QMessageBox::Ok == QMessageBox::information(this, "Add Peer", PeerTools::ManagePeer("add", data), QMessageBox::Ok, QMessageBox::Ok)) + this->close(); +} + +/** Add Test Peer Dialog */ +TestPeerDialog::TestPeerDialog(QWidget *parent) : + QWidget(parent), + ui(new Ui::TestPeerDialog) +{ + ui->setupUi(this); + + ui->peerPort->setValidator( new QIntValidator(1, 65535, this) ); + + connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(on_testPeer_clicked())); +} + +TestPeerDialog::~TestPeerDialog() +{ + delete ui; +} + +void TestPeerDialog::on_testPeer_clicked() +{ + QString address = ui->peerAddress->text(); + QString port = ui->peerPort->text(); + QString data = ""; + + if(address.isEmpty()) + { + QMessageBox::critical(this, "Test Peer", "Please enter an address.", QMessageBox::Ok, QMessageBox::Ok); + return; + } + + if(port.isEmpty()) + { + port = PeerTools::GetPort(); + ui->peerPort->setText(port); + } + + if(!PeerTools::CheckPeerAddress(address)) + { + QMessageBox::critical(this, "Test Peer", "Please enter a vaild peer address.", QMessageBox::Ok, QMessageBox::Ok); + return; + } + + data = address + ":" + port; + + if(QMessageBox::Ok == QMessageBox::information(this, "Try Peer", PeerTools::ManagePeer("onetry", data), QMessageBox::Ok, QMessageBox::Ok)) + this->close(); +} diff --git a/src/qt/peerdialog.h b/src/qt/peerdialog.h new file mode 100644 index 000000000..45d3215c4 --- /dev/null +++ b/src/qt/peerdialog.h @@ -0,0 +1,62 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_PEERDIALOG_H +#define BITCOIN_QT_PEERDIALOG_H + +#include +#include +#include +#include "guiutil.h" + +class PeerTools; + +namespace Ui { + class AddPeerDialog; + class RemovePeerDialog; + class TestPeerDialog; +} + +/** Class to manage peers */ +class PeerTools : public QObject +{ + Q_OBJECT + +public: + static QString ManagePeer(QString type, QString peer); + static bool CheckPeerAddress(QString address); + static bool CheckIPAddress(QString ip); + static bool CheckDNS(QString dns); + static QString GetPort(); +}; + +/** "Add peer" dialog box */ +class AddPeerDialog : public QWidget +{ + Q_OBJECT + +public: + explicit AddPeerDialog(QWidget *parent); + ~AddPeerDialog(); +private: + Ui::AddPeerDialog *ui; +private Q_SLOTS: + void on_addPeer_clicked(); +}; + +/** "Test peer" dialog box */ +class TestPeerDialog : public QWidget +{ + Q_OBJECT + +public: + explicit TestPeerDialog(QWidget *parent); + ~TestPeerDialog(); +private: + Ui::TestPeerDialog *ui; +private Q_SLOTS: + void on_testPeer_clicked(); +}; + +#endif diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 77e5e03e6..075da382c 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -2,11 +2,13 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "bitcoingui.h" #if defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" #endif #include "rpcconsole.h" +#include "peerdialog.h" #include "ui_debugwindow.h" #include "bantablemodel.h" @@ -14,6 +16,7 @@ #include "guiutil.h" #include "platformstyle.h" #include "bantablemodel.h" +#include "utilitydialog.h" #include "chainparams.h" #include "netbase.h" @@ -39,6 +42,7 @@ #include #include #include +#include #if QT_VERSION < 0x050000 #include @@ -441,6 +445,15 @@ RPCConsole::RPCConsole(const PlatformStyle *_platformStyle, QWidget *parent) : connect(ui->fontSmallerButton, SIGNAL(clicked()), this, SLOT(fontSmaller())); connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear())); + // Allow user to add new peer + connect(ui->peerAdd, SIGNAL(clicked()), this, SLOT(on_addPeer_clicked())); + + // Allow user to remove peer + connect(ui->peerRemove, SIGNAL(clicked()), this, SLOT(on_removePeer_clicked())); + + // Allow user to test peer + connect(ui->peerTest, SIGNAL(clicked()), this, SLOT(on_testPeer_clicked())); + // set library version labels #ifdef ENABLE_WALLET ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0)); @@ -901,6 +914,54 @@ void RPCConsole::on_openDebugLogfileButton_clicked() GUIUtil::openDebugLogfile(); } +void RPCConsole::on_addPeer_clicked() +{ + + QWidget *win = new AddPeerDialog(0); + + win->showNormal(); + win->show(); + win->raise(); + win->activateWindow(); + + /** Center window */ + const QPoint global = ui->tabWidget->mapToGlobal(ui->tabWidget->rect().center()); + win->move(global.x() - win->width() / 2, global.y() - win->height() / 2); +} + +void RPCConsole::on_removePeer_clicked() +{ + QList ips = GUIUtil::getEntryData(ui->peerWidget, PeerTableModel::Address); + + if(ips.size() != 0) + { + QString address = ips[0].data().toString(); + + if(QMessageBox::Yes == QMessageBox::question(this, "Remove Peer", "Are you sure you want to remove the peer: " + address + "?", QMessageBox::Yes | QMessageBox::No)) + { + QMessageBox::information(this, "Remove Peer", PeerTools::ManagePeer("remove", address), QMessageBox::Ok, QMessageBox::Ok); + } + + } else + { + QMessageBox::information(this, "Remove Peer", "No peer was selected.", QMessageBox::Ok, QMessageBox::Ok); + } +} + +void RPCConsole::on_testPeer_clicked() +{ + QWidget *win = new TestPeerDialog(0); + + win->showNormal(); + win->show(); + win->raise(); + win->activateWindow(); + + /** Center window */ + const QPoint global = ui->tabWidget->mapToGlobal(ui->tabWidget->rect().center()); + win->move(global.x() - win->width() / 2, global.y() - win->height() / 2); +} + void RPCConsole::scrollToEnd() { QScrollBar *scrollbar = ui->messagesWidget->verticalScrollBar(); diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index ec531c99c..4176e2acf 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -17,6 +17,7 @@ class ClientModel; class PlatformStyle; class RPCTimerInterface; +class RPCExecutor; namespace Ui { class RPCConsole; @@ -67,6 +68,12 @@ private Q_SLOTS: void on_tabWidget_currentChanged(int index); /** open the debug.log from the current datadir */ void on_openDebugLogfileButton_clicked(); + /** open dialog to add new peer */ + void on_addPeer_clicked(); + /** open dialog to remove peer */ + void on_removePeer_clicked(); + /** open dialog to test peer */ + void on_testPeer_clicked(); /** change the time range of the network traffic graph */ void on_sldGraphRange_valueChanged(int value); /** update traffic statistics */ @@ -152,7 +159,6 @@ private: int consoleFontSize; QCompleter *autoCompleter; QThread thread; - /** Update UI with latest network info from model. */ void updateNetworkState(); };