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 <rnicoll@rnicoll.name>

Fix typo

Co-authored-by: Ross Nicoll <rnicoll@rnicoll.name>

Use LookupHost to check address

Co-authored-by: Ross Nicoll <rnicoll@rnicoll.name>

Fix syntax typo
This commit is contained in:
Shafil Alam 2021-04-16 14:24:27 -04:00
parent bf938187e7
commit e0d1683bff
8 changed files with 538 additions and 15 deletions

View file

@ -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

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AddPeerDialog</class>
<widget class="QWidget" name="AddPeerDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>466</width>
<height>186</height>
</rect>
</property>
<property name="windowTitle">
<string>Add Peer</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Enter the peer details below.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Be careful! Do not blindly trust anyone that tells you to add their node.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="peerAddress">
<property name="placeholderText">
<string>Enter the peer's address</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="peerPort">
<property name="placeholderText">
<string>Enter the peer's port</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Add!</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -165,17 +165,17 @@
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="labelNetwork">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Network</string>
</property>
</widget>
<widget class="QLabel" name="labelNetwork">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Network</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_8">
@ -433,12 +433,12 @@
<height>24</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="toolTip">
<string>Decrease font size</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
<normaloff>:/icons/fontsmaller</normaloff>:/icons/fontsmaller</iconset>
@ -854,6 +854,33 @@
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="peerlistHeading">
<property name="minimumSize">
<size>
<width>300</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>32</height>
</size>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string>Connected peers</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="peerWidget">
<property name="horizontalScrollBarPolicy">
@ -870,6 +897,46 @@
</attribute>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="peerAdd">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Add new peer</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="peerRemove">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>Remove peer</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="peerTest">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>One try peer</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="banHeading">
<property name="sizePolicy">

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TestPeerDialog</class>
<widget class="QWidget" name="TestPeerDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>466</width>
<height>186</height>
</rect>
</property>
<property name="windowTitle">
<string>Test Peer</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Enter the peer details below.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Be careful! Do not blindly trust anyone that tells you to add their node.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="peerAddress">
<property name="placeholderText">
<string>Enter the peer's address</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="peerPort">
<property name="placeholderText">
<string>Enter the peer's port</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Test!</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

176
src/qt/peerdialog.cpp Normal file
View file

@ -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 <iostream>
#include <string>
#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 <stdio.h>
#include <QMessageBox>
#include <QHostAddress>
#include <QAbstractSocket>
#include <QUrl>
/** 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();
}

62
src/qt/peerdialog.h Normal file
View file

@ -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 <QObject>
#include <QWidget>
#include <string>
#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

View file

@ -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 <QTime>
#include <QTimer>
#include <QStringList>
#include <QThread>
#if QT_VERSION < 0x050000
#include <QUrl>
@ -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<QModelIndex> 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();

View file

@ -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();
};