Merge #162: Add network to peers window and peer details

e262a19b0b gui: display network in peer details (Jon Atack)
9136953073 gui: rename peer tab column headers, initialize in .h (Hennadii Stepanov)
05c08c696a gui: add network column in peers tab/window (Jon Atack)
e0e55060bf gui: fix broken doxygen formatting in src/qt/guiutil.h (Jon Atack)
0d5613f9de gui: create GUIUtil::NetworkToQString() utility function (Jon Atack)
af9103cc79 net, rpc: change CNodeStats::m_network from string to Network (Jon Atack)

Pull request description:

  and rename peers window column headers from NodeId and Node/Service to Peer Id and Address.

  ![Screenshot from 2020-12-27 14-45-31](https://user-images.githubusercontent.com/2415484/103172228-efec8600-4849-11eb-8cee-04a3d2ab1273.png)

ACKs for top commit:
  laanwj:
    ACK e262a19b0b

Tree-SHA512: 709c2a805c109c2dd033aca7b6b6dc94ebe2ce7a0168c71249e1e661c9c57d1f1c781a5b9ccf3b776bedeb83ae2fb5c505637337c45b1eb9a418cb1693a89761
This commit is contained in:
Wladimir J. van der Laan 2020-12-28 22:52:02 +01:00
commit d875bcc8f9
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
9 changed files with 127 additions and 75 deletions

View file

@ -566,7 +566,7 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
X(nServices);
X(addr);
X(addrBind);
stats.m_network = GetNetworkName(ConnectedThroughNetwork());
stats.m_network = ConnectedThroughNetwork();
stats.m_mapped_as = addr.GetMappedAS(m_asmap);
if (m_tx_relay != nullptr) {
LOCK(m_tx_relay->cs_filter);

View file

@ -720,8 +720,8 @@ public:
CAddress addr;
// Bind address of our side of the connection
CAddress addrBind;
// Name of the network the peer connected through
std::string m_network;
// Network the peer connected through
Network m_network;
uint32_t m_mapped_as;
std::string m_conn_type_string;
};

View file

@ -1100,14 +1100,17 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_21">
<widget class="QLabel" name="peerNetworkLabel">
<property name="toolTip">
<string>The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS.</string>
</property>
<property name="text">
<string>Version</string>
<string>Network</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="peerVersion">
<widget class="QLabel" name="peerNetwork">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1123,14 +1126,14 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_28">
<widget class="QLabel" name="label_21">
<property name="text">
<string>User Agent</string>
<string>Version</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="peerSubversion">
<widget class="QLabel" name="peerVersion">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1146,14 +1149,14 @@
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<widget class="QLabel" name="label_28">
<property name="text">
<string>Services</string>
<string>User Agent</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="peerServices">
<widget class="QLabel" name="peerSubversion">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1169,14 +1172,14 @@
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_29">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Starting Block</string>
<string>Services</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="peerHeight">
<widget class="QLabel" name="peerServices">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1192,14 +1195,14 @@
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_27">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Synced Headers</string>
<string>Starting Block</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="peerSyncHeight">
<widget class="QLabel" name="peerHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1215,14 +1218,14 @@
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_25">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Synced Blocks</string>
<string>Synced Headers</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="peerCommonHeight">
<widget class="QLabel" name="peerSyncHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1238,14 +1241,14 @@
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_22">
<widget class="QLabel" name="label_25">
<property name="text">
<string>Connection Time</string>
<string>Synced Blocks</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="peerConnTime">
<widget class="QLabel" name="peerCommonHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1261,14 +1264,14 @@
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_15">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Last Send</string>
<string>Connection Time</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="peerLastSend">
<widget class="QLabel" name="peerConnTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1284,14 +1287,14 @@
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_19">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Last Receive</string>
<string>Last Send</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLabel" name="peerLastRecv">
<widget class="QLabel" name="peerLastSend">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1307,14 +1310,14 @@
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_18">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Sent</string>
<string>Last Receive</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="peerBytesSent">
<widget class="QLabel" name="peerLastRecv">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1330,14 +1333,14 @@
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_20">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Received</string>
<string>Sent</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QLabel" name="peerBytesRecv">
<widget class="QLabel" name="peerBytesSent">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1353,14 +1356,14 @@
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_26">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Ping Time</string>
<string>Received</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QLabel" name="peerPingTime">
<widget class="QLabel" name="peerBytesRecv">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1376,17 +1379,14 @@
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="peerPingWaitLabel">
<property name="toolTip">
<string>The duration of a currently outstanding ping.</string>
</property>
<widget class="QLabel" name="label_26">
<property name="text">
<string>Ping Wait</string>
<string>Ping Time</string>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QLabel" name="peerPingWait">
<widget class="QLabel" name="peerPingTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1402,14 +1402,17 @@
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="peerMinPingLabel">
<widget class="QLabel" name="peerPingWaitLabel">
<property name="toolTip">
<string>The duration of a currently outstanding ping.</string>
</property>
<property name="text">
<string>Min Ping</string>
<string>Ping Wait</string>
</property>
</widget>
</item>
<item row="15" column="1">
<widget class="QLabel" name="peerMinPing">
<widget class="QLabel" name="peerPingWait">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1425,14 +1428,14 @@
</widget>
</item>
<item row="16" column="0">
<widget class="QLabel" name="label_timeoffset">
<widget class="QLabel" name="peerMinPingLabel">
<property name="text">
<string>Time Offset</string>
<string>Min Ping</string>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QLabel" name="timeoffset">
<widget class="QLabel" name="peerMinPing">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1448,17 +1451,14 @@
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="peerMappedASLabel">
<property name="toolTip">
<string>The mapped Autonomous System used for diversifying peer selection.</string>
</property>
<widget class="QLabel" name="label_timeoffset">
<property name="text">
<string>Mapped AS</string>
<string>Time Offset</string>
</property>
</widget>
</item>
<item row="17" column="1">
<widget class="QLabel" name="peerMappedAS">
<widget class="QLabel" name="timeoffset">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1474,6 +1474,32 @@
</widget>
</item>
<item row="18" column="0">
<widget class="QLabel" name="peerMappedASLabel">
<property name="toolTip">
<string>The mapped Autonomous System used for diversifying peer selection.</string>
</property>
<property name="text">
<string>Mapped AS</string>
</property>
</widget>
</item>
<item row="18" column="1">
<widget class="QLabel" name="peerMappedAS">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string>N/A</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="19" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>

View file

@ -749,6 +749,21 @@ QString boostPathToQString(const fs::path &path)
return QString::fromStdString(path.string());
}
QString NetworkToQString(Network net)
{
switch (net) {
case NET_UNROUTABLE: return QObject::tr("Unroutable");
case NET_IPV4: return "IPv4";
case NET_IPV6: return "IPv6";
case NET_ONION: return "Onion";
case NET_I2P: return "I2P";
case NET_CJDNS: return "CJDNS";
case NET_INTERNAL: return QObject::tr("Internal");
case NET_MAX: assert(false);
} // no default case, so the compiler can warn about missing cases
assert(false);
}
QString formatDurationStr(int secs)
{
QStringList strList;

View file

@ -7,6 +7,7 @@
#include <amount.h>
#include <fs.h>
#include <netaddress.h>
#include <QEvent>
#include <QHeaderView>
@ -218,22 +219,25 @@ namespace GUIUtil
bool GetStartOnSystemStartup();
bool SetStartOnSystemStartup(bool fAutoStart);
/* Convert QString to OS specific boost path through UTF-8 */
/** Convert QString to OS specific boost path through UTF-8 */
fs::path qstringToBoostPath(const QString &path);
/* Convert OS specific boost path to QString through UTF-8 */
/** Convert OS specific boost path to QString through UTF-8 */
QString boostPathToQString(const fs::path &path);
/* Convert seconds into a QString with days, hours, mins, secs */
/** Convert enum Network to QString */
QString NetworkToQString(Network net);
/** Convert seconds into a QString with days, hours, mins, secs */
QString formatDurationStr(int secs);
/* Format CNodeStats.nServices bitmask into a user-readable string */
/** Format CNodeStats.nServices bitmask into a user-readable string */
QString formatServicesStr(quint64 mask);
/* Format a CNodeStats.m_ping_usec into a user-readable string or display N/A, if 0*/
/** Format a CNodeStats.m_ping_usec into a user-readable string or display N/A, if 0 */
QString formatPingTime(int64_t ping_usec);
/* Format a CNodeCombinedStats.nTimeOffset into a user-readable string. */
/** Format a CNodeCombinedStats.nTimeOffset into a user-readable string */
QString formatTimeOffset(int64_t nTimeOffset);
QString formatNiceTimeOffset(qint64 secs);

View file

@ -29,14 +29,16 @@ bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombine
return pLeft->nodeid < pRight->nodeid;
case PeerTableModel::Address:
return pLeft->addrName.compare(pRight->addrName) < 0;
case PeerTableModel::Subversion:
return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
case PeerTableModel::Network:
return pLeft->m_network < pRight->m_network;
case PeerTableModel::Ping:
return pLeft->m_min_ping_usec < pRight->m_min_ping_usec;
case PeerTableModel::Sent:
return pLeft->nSendBytes < pRight->nSendBytes;
case PeerTableModel::Received:
return pLeft->nRecvBytes < pRight->nRecvBytes;
case PeerTableModel::Subversion:
return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
}
return false;
@ -104,7 +106,6 @@ PeerTableModel::PeerTableModel(interfaces::Node& node, QObject* parent) :
m_node(node),
timer(nullptr)
{
columns << tr("NodeId") << tr("Node/Service") << tr("Ping") << tr("Sent") << tr("Received") << tr("User Agent");
priv.reset(new PeerTablePriv());
// set up timer for auto refresh
@ -158,17 +159,21 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const
case Address:
// prepend to peer address down-arrow symbol for inbound connection and up-arrow for outbound connection
return QString(rec->nodeStats.fInbound ? "" : "") + QString::fromStdString(rec->nodeStats.addrName);
case Subversion:
return QString::fromStdString(rec->nodeStats.cleanSubVer);
case Network:
return GUIUtil::NetworkToQString(rec->nodeStats.m_network);
case Ping:
return GUIUtil::formatPingTime(rec->nodeStats.m_min_ping_usec);
case Sent:
return GUIUtil::formatBytes(rec->nodeStats.nSendBytes);
case Received:
return GUIUtil::formatBytes(rec->nodeStats.nRecvBytes);
case Subversion:
return QString::fromStdString(rec->nodeStats.cleanSubVer);
}
} else if (role == Qt::TextAlignmentRole) {
switch (index.column()) {
case Network:
return QVariant(Qt::AlignCenter);
case Ping:
case Sent:
case Received:

View file

@ -60,10 +60,11 @@ public:
enum ColumnIndex {
NetNodeId = 0,
Address = 1,
Ping = 2,
Sent = 3,
Received = 4,
Subversion = 5
Network = 2,
Ping = 3,
Sent = 4,
Received = 5,
Subversion = 6
};
/** @name Methods overridden from QAbstractTableModel
@ -82,7 +83,7 @@ public Q_SLOTS:
private:
interfaces::Node& m_node;
QStringList columns;
const QStringList columns{tr("Peer Id"), tr("Address"), tr("Network"), tr("Ping"), tr("Sent"), tr("Received"), tr("User Agent")};
std::unique_ptr<PeerTablePriv> priv;
QTimer *timer;
};

View file

@ -1092,7 +1092,7 @@ void RPCConsole::updateDetailWidget()
const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected_rows.first().row());
// update the detail ui with latest node information
QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName) + " ");
peerAddrDetails += tr("(node id: %1)").arg(QString::number(stats->nodeStats.nodeid));
peerAddrDetails += tr("(peer id: %1)").arg(QString::number(stats->nodeStats.nodeid));
if (!stats->nodeStats.addrLocal.empty())
peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
ui->peerHeading->setText(peerAddrDetails);
@ -1109,6 +1109,7 @@ void RPCConsole::updateDetailWidget()
ui->peerVersion->setText(QString::number(stats->nodeStats.nVersion));
ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound"));
ui->peerNetwork->setText(GUIUtil::NetworkToQString(stats->nodeStats.m_network));
if (stats->nodeStats.m_permissionFlags == PF_NONE) {
ui->peerPermissions->setText(tr("N/A"));
} else {

View file

@ -187,7 +187,7 @@ static RPCHelpMan getpeerinfo()
if (!(stats.addrLocal.empty())) {
obj.pushKV("addrlocal", stats.addrLocal);
}
obj.pushKV("network", stats.m_network);
obj.pushKV("network", GetNetworkName(stats.m_network));
if (stats.m_mapped_as != 0) {
obj.pushKV("mapped_as", uint64_t(stats.m_mapped_as));
}