Bitcoin ABC  0.24.7
P2P Digital Currency
peertablemodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <qt/peertablemodel.h>
6 
7 #include <qt/guiconstants.h>
8 #include <qt/guiutil.h>
9 
10 #include <interfaces/node.h>
11 
12 #include <utility>
13 
14 #include <QDebug>
15 #include <QList>
16 #include <QTimer>
17 
19  const CNodeCombinedStats &right) const {
20  const CNodeStats *pLeft = &(left.nodeStats);
21  const CNodeStats *pRight = &(right.nodeStats);
22 
23  if (order == Qt::DescendingOrder) {
24  std::swap(pLeft, pRight);
25  }
26 
27  switch (column) {
29  return pLeft->nodeid < pRight->nodeid;
31  return pLeft->addrName.compare(pRight->addrName) < 0;
33  return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
35  return pLeft->m_min_ping_usec < pRight->m_min_ping_usec;
37  return pLeft->nSendBytes < pRight->nSendBytes;
39  return pLeft->nRecvBytes < pRight->nRecvBytes;
40  }
41 
42  return false;
43 }
44 
45 // private implementation
47 public:
49  QList<CNodeCombinedStats> cachedNodeStats;
51  int sortColumn{-1};
53  Qt::SortOrder sortOrder;
55  std::map<NodeId, int> mapNodeRows;
56 
59  {
60  cachedNodeStats.clear();
61 
62  interfaces::Node::NodesStats nodes_stats;
63  node.getNodesStats(nodes_stats);
64  cachedNodeStats.reserve(nodes_stats.size());
65  for (const auto &node_stats : nodes_stats) {
66  CNodeCombinedStats stats;
67  stats.nodeStats = std::get<0>(node_stats);
68  stats.fNodeStateStatsAvailable = std::get<1>(node_stats);
69  stats.nodeStateStats = std::get<2>(node_stats);
70  cachedNodeStats.append(stats);
71  }
72  }
73 
74  if (sortColumn >= 0) {
75  // sort cacheNodeStats (use stable sort to prevent rows jumping
76  // around unnecessarily)
77  std::stable_sort(cachedNodeStats.begin(), cachedNodeStats.end(),
79  }
80 
81  // build index map
82  mapNodeRows.clear();
83  int row = 0;
84  for (const CNodeCombinedStats &stats : cachedNodeStats) {
85  mapNodeRows.insert(
86  std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
87  }
88  }
89 
90  int size() const { return cachedNodeStats.size(); }
91 
93  if (idx >= 0 && idx < cachedNodeStats.size()) {
94  return &cachedNodeStats[idx];
95  }
96 
97  return nullptr;
98  }
99 };
100 
102  : QAbstractTableModel(parent), m_node(node), timer(nullptr) {
103  columns << tr("NodeId") << tr("Node/Service") << tr("Ping") << tr("Sent")
104  << tr("Received") << tr("User Agent");
105  priv.reset(new PeerTablePriv());
106 
107  // set up timer for auto refresh
108  timer = new QTimer(this);
109  connect(timer, &QTimer::timeout, this, &PeerTableModel::refresh);
110  timer->setInterval(MODEL_UPDATE_DELAY);
111 
112  // load initial data
113  refresh();
114 }
115 
117  // Intentionally left empty
118 }
119 
121  timer->start();
122 }
123 
125  timer->stop();
126 }
127 
128 int PeerTableModel::rowCount(const QModelIndex &parent) const {
129  Q_UNUSED(parent);
130  return priv->size();
131 }
132 
133 int PeerTableModel::columnCount(const QModelIndex &parent) const {
134  Q_UNUSED(parent);
135  return columns.length();
136 }
137 
138 QVariant PeerTableModel::data(const QModelIndex &index, int role) const {
139  if (!index.isValid()) {
140  return QVariant();
141  }
142 
143  CNodeCombinedStats *rec =
144  static_cast<CNodeCombinedStats *>(index.internalPointer());
145 
146  if (role == Qt::DisplayRole) {
147  switch (index.column()) {
148  case NetNodeId:
149  return (qint64)rec->nodeStats.nodeid;
150  case Address:
151  // prepend to peer address down-arrow symbol for inbound
152  // connection and up-arrow for outbound connection
153  return QString(rec->nodeStats.fInbound ? "↓ " : "↑ ") +
154  QString::fromStdString(rec->nodeStats.addrName);
155  case Subversion:
156  return QString::fromStdString(rec->nodeStats.cleanSubVer);
157  case Ping:
159  case Sent:
161  case Received:
163  }
164  } else if (role == Qt::TextAlignmentRole) {
165  switch (index.column()) {
166  case Ping:
167  case Sent:
168  case Received:
169  return QVariant(Qt::AlignRight | Qt::AlignVCenter);
170  default:
171  return QVariant();
172  }
173  }
174 
175  return QVariant();
176 }
177 
178 QVariant PeerTableModel::headerData(int section, Qt::Orientation orientation,
179  int role) const {
180  if (orientation == Qt::Horizontal) {
181  if (role == Qt::DisplayRole && section < columns.size()) {
182  return columns[section];
183  }
184  }
185  return QVariant();
186 }
187 
188 Qt::ItemFlags PeerTableModel::flags(const QModelIndex &index) const {
189  if (!index.isValid()) {
190  return Qt::NoItemFlags;
191  }
192 
193  Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
194  return retval;
195 }
196 
197 QModelIndex PeerTableModel::index(int row, int column,
198  const QModelIndex &parent) const {
199  Q_UNUSED(parent);
200  CNodeCombinedStats *data = priv->index(row);
201 
202  if (data) {
203  return createIndex(row, column, data);
204  }
205  return QModelIndex();
206 }
207 
209  return priv->index(idx);
210 }
211 
213  Q_EMIT layoutAboutToBeChanged();
214  priv->refreshPeers(m_node);
215  Q_EMIT layoutChanged();
216 }
217 
219  std::map<NodeId, int>::iterator it = priv->mapNodeRows.find(nodeid);
220  if (it == priv->mapNodeRows.end()) {
221  return -1;
222  }
223 
224  return it->second;
225 }
226 
227 void PeerTableModel::sort(int column, Qt::SortOrder order) {
228  priv->sortColumn = column;
229  priv->sortOrder = order;
230  refresh();
231 }
PeerTableModel::Received
@ Received
Definition: peertablemodel.h:64
PeerTableModel::PeerTableModel
PeerTableModel(interfaces::Node &node, QObject *parent)
Definition: peertablemodel.cpp:101
PeerTablePriv::mapNodeRows
std::map< NodeId, int > mapNodeRows
Index of rows by node ID.
Definition: peertablemodel.cpp:55
PeerTableModel::NetNodeId
@ NetNodeId
Definition: peertablemodel.h:60
PeerTableModel::data
QVariant data(const QModelIndex &index, int role) const override
Definition: peertablemodel.cpp:138
PeerTableModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
Definition: peertablemodel.cpp:178
CNodeCombinedStats::nodeStats
CNodeStats nodeStats
Definition: peertablemodel.h:27
PeerTablePriv::sortColumn
int sortColumn
Column to sort nodes by (default to unsorted)
Definition: peertablemodel.cpp:51
CNodeStats::m_min_ping_usec
int64_t m_min_ping_usec
Definition: net.h:782
CNodeStats::nodeid
NodeId nodeid
Definition: net.h:758
PeerTableModel::columns
QStringList columns
Definition: peertablemodel.h:86
NodeLessThan::operator()
bool operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
Definition: peertablemodel.cpp:18
PeerTableModel::index
QModelIndex index(int row, int column, const QModelIndex &parent) const override
Definition: peertablemodel.cpp:197
node.h
PeerTablePriv::sortOrder
Qt::SortOrder sortOrder
Order (ascending or descending) to sort nodes by.
Definition: peertablemodel.cpp:53
PeerTableModel::Subversion
@ Subversion
Definition: peertablemodel.h:65
NodeLessThan::column
int column
Definition: peertablemodel.h:40
PeerTablePriv
Definition: peertablemodel.cpp:46
PeerTablePriv::refreshPeers
void refreshPeers(interfaces::Node &node)
Pull a full list of peers from vNodes into our cache.
Definition: peertablemodel.cpp:58
PeerTableModel::Address
@ Address
Definition: peertablemodel.h:61
GUIUtil::formatPingTime
QString formatPingTime(int64_t ping_usec)
Definition: guiutil.cpp:818
PeerTableModel::priv
std::unique_ptr< PeerTablePriv > priv
Definition: peertablemodel.h:87
interfaces::Node::NodesStats
std::vector< std::tuple< CNodeStats, bool, CNodeStateStats > > NodesStats
Get stats for connected nodes.
Definition: node.h:97
CNodeStats::nSendBytes
uint64_t nSendBytes
Definition: net.h:774
PeerTableModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: peertablemodel.cpp:188
CNodeStats::addrName
std::string addrName
Definition: net.h:768
PeerTableModel::m_node
interfaces::Node & m_node
Definition: peertablemodel.h:85
CNodeCombinedStats::fNodeStateStatsAvailable
bool fNodeStateStatsAvailable
Definition: peertablemodel.h:29
PeerTablePriv::size
int size() const
Definition: peertablemodel.cpp:90
guiutil.h
PeerTableModel::~PeerTableModel
~PeerTableModel()
Definition: peertablemodel.cpp:116
CNodeCombinedStats
Definition: peertablemodel.h:26
GUIUtil::formatBytes
QString formatBytes(uint64_t bytes)
Definition: guiutil.cpp:859
NodeLessThan::order
Qt::SortOrder order
Definition: peertablemodel.h:41
PeerTableModel::getNodeStats
const CNodeCombinedStats * getNodeStats(int idx)
Definition: peertablemodel.cpp:208
interfaces::Node
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:55
PeerTablePriv::cachedNodeStats
QList< CNodeCombinedStats > cachedNodeStats
Local cache of peer information.
Definition: peertablemodel.cpp:49
PeerTableModel::Ping
@ Ping
Definition: peertablemodel.h:62
interfaces::Node::getNodesStats
virtual bool getNodesStats(NodesStats &stats)=0
PeerTableModel::refresh
void refresh()
Definition: peertablemodel.cpp:212
m_node
NodeContext & m_node
Definition: chain.cpp:485
guiconstants.h
PeerTableModel::Sent
@ Sent
Definition: peertablemodel.h:63
PeerTableModel::startAutoRefresh
void startAutoRefresh()
Definition: peertablemodel.cpp:120
CNodeStats
POD that contains various stats about a node.
Definition: net.h:757
CNodeStats::cleanSubVer
std::string cleanSubVer
Definition: net.h:770
NodeLessThan
Definition: peertablemodel.h:32
PeerTableModel::sort
void sort(int column, Qt::SortOrder order) override
Definition: peertablemodel.cpp:227
NodeId
int64_t NodeId
Definition: nodeid.h:10
PeerTableModel::getRowByNodeId
int getRowByNodeId(NodeId nodeid)
Definition: peertablemodel.cpp:218
peertablemodel.h
CNodeStats::nRecvBytes
uint64_t nRecvBytes
Definition: net.h:776
PeerTableModel::stopAutoRefresh
void stopAutoRefresh()
Definition: peertablemodel.cpp:124
CNodeStats::fInbound
bool fInbound
Definition: net.h:771
PeerTableModel::timer
QTimer * timer
Definition: peertablemodel.h:88
PeerTablePriv::index
CNodeCombinedStats * index(int idx)
Definition: peertablemodel.cpp:92
PeerTableModel::columnCount
int columnCount(const QModelIndex &parent) const override
Definition: peertablemodel.cpp:133
MODEL_UPDATE_DELAY
static const int MODEL_UPDATE_DELAY
Definition: guiconstants.h:11
PeerTableModel::rowCount
int rowCount(const QModelIndex &parent) const override
Definition: peertablemodel.cpp:128
CNodeCombinedStats::nodeStateStats
CNodeStateStats nodeStateStats
Definition: peertablemodel.h:28