Dash Core  0.12.2.1
P2P Digital Currency
rpcconsole.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Copyright (c) 2014-2017 The Dash Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "rpcconsole.h"
7 #include "ui_debugwindow.h"
8 
9 #include "bantablemodel.h"
10 #include "clientmodel.h"
11 #include "guiutil.h"
12 #include "platformstyle.h"
13 
14 #include "chainparams.h"
15 #include "netbase.h"
16 #include "rpc/server.h"
17 #include "rpc/client.h"
18 #include "util.h"
19 
20 #include <openssl/crypto.h>
21 
22 #include <univalue.h>
23 
24 #ifdef ENABLE_WALLET
25 #include <db_cxx.h>
26 #endif
27 
28 #include <QDir>
29 #include <QKeyEvent>
30 #include <QMenu>
31 #include <QScrollBar>
32 #include <QSettings>
33 #include <QSignalMapper>
34 #include <QThread>
35 #include <QTime>
36 #include <QTimer>
37 #include <QStringList>
38 
39 #if QT_VERSION < 0x050000
40 #include <QUrl>
41 #endif
42 
43 // TODO: add a scrollback limit, as there is currently none
44 // TODO: make it possible to filter out categories (esp debug messages when implemented)
45 // TODO: receive errors and debug messages through ClientModel
46 
47 const int CONSOLE_HISTORY = 50;
48 const QSize FONT_RANGE(4, 40);
49 const char fontSizeSettingsKey[] = "consoleFontSize";
50 
52 
53 // Repair parameters
54 const QString SALVAGEWALLET("-salvagewallet");
55 const QString RESCAN("-rescan");
56 const QString ZAPTXES1("-zapwallettxes=1");
57 const QString ZAPTXES2("-zapwallettxes=2");
58 const QString UPGRADEWALLET("-upgradewallet");
59 const QString REINDEX("-reindex");
60 
61 const struct {
62  const char *url;
63  const char *source;
64 } ICON_MAPPING[] = {
65  {"cmd-request", "tx_input"},
66  {"cmd-reply", "tx_output"},
67  {"cmd-error", "tx_output"},
68  {"misc", "tx_inout"},
69  {NULL, NULL}
70 };
71 
72 /* Object for executing console RPC commands in a separate thread.
73 */
74 class RPCExecutor : public QObject
75 {
76  Q_OBJECT
77 
78 public Q_SLOTS:
79  void request(const QString &command);
80 
81 Q_SIGNALS:
82  void reply(int category, const QString &command);
83 };
84 
88 class QtRPCTimerBase: public QObject, public RPCTimerBase
89 {
90  Q_OBJECT
91 public:
92  QtRPCTimerBase(boost::function<void(void)>& func, int64_t millis):
93  func(func)
94  {
95  timer.setSingleShot(true);
96  connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
97  timer.start(millis);
98  }
100 private Q_SLOTS:
101  void timeout() { func(); }
102 private:
103  QTimer timer;
104  boost::function<void(void)> func;
105 };
106 
108 {
109 public:
111  const char *Name() { return "Qt"; }
112  RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis)
113  {
114  return new QtRPCTimerBase(func, millis);
115  }
116 };
117 
118 
119 #include "rpcconsole.moc"
120 
135 bool parseCommandLine(std::vector<std::string> &args, const std::string &strCommand)
136 {
137  enum CmdParseState
138  {
139  STATE_EATING_SPACES,
140  STATE_ARGUMENT,
141  STATE_SINGLEQUOTED,
142  STATE_DOUBLEQUOTED,
143  STATE_ESCAPE_OUTER,
144  STATE_ESCAPE_DOUBLEQUOTED
145  } state = STATE_EATING_SPACES;
146  std::string curarg;
147  Q_FOREACH(char ch, strCommand)
148  {
149  switch(state)
150  {
151  case STATE_ARGUMENT: // In or after argument
152  case STATE_EATING_SPACES: // Handle runs of whitespace
153  switch(ch)
154  {
155  case '"': state = STATE_DOUBLEQUOTED; break;
156  case '\'': state = STATE_SINGLEQUOTED; break;
157  case '\\': state = STATE_ESCAPE_OUTER; break;
158  case ' ': case '\n': case '\t':
159  if(state == STATE_ARGUMENT) // Space ends argument
160  {
161  args.push_back(curarg);
162  curarg.clear();
163  }
164  state = STATE_EATING_SPACES;
165  break;
166  default: curarg += ch; state = STATE_ARGUMENT;
167  }
168  break;
169  case STATE_SINGLEQUOTED: // Single-quoted string
170  switch(ch)
171  {
172  case '\'': state = STATE_ARGUMENT; break;
173  default: curarg += ch;
174  }
175  break;
176  case STATE_DOUBLEQUOTED: // Double-quoted string
177  switch(ch)
178  {
179  case '"': state = STATE_ARGUMENT; break;
180  case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break;
181  default: curarg += ch;
182  }
183  break;
184  case STATE_ESCAPE_OUTER: // '\' outside quotes
185  curarg += ch; state = STATE_ARGUMENT;
186  break;
187  case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text
188  if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself
189  curarg += ch; state = STATE_DOUBLEQUOTED;
190  break;
191  }
192  }
193  switch(state) // final state
194  {
195  case STATE_EATING_SPACES:
196  return true;
197  case STATE_ARGUMENT:
198  args.push_back(curarg);
199  return true;
200  default: // ERROR to end in one of the other states
201  return false;
202  }
203 }
204 
205 void RPCExecutor::request(const QString &command)
206 {
207  std::vector<std::string> args;
208  if(!parseCommandLine(args, command.toStdString()))
209  {
210  Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
211  return;
212  }
213  if(args.empty())
214  return; // Nothing to do
215  try
216  {
217  std::string strPrint;
218  // Convert argument list to JSON objects in method-dependent way,
219  // and pass it along with the method name to the dispatcher.
221  args[0],
222  RPCConvertValues(args[0], std::vector<std::string>(args.begin() + 1, args.end())));
223 
224  // Format result reply
225  if (result.isNull())
226  strPrint = "";
227  else if (result.isStr())
228  strPrint = result.get_str();
229  else
230  strPrint = result.write(2);
231 
232  Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint));
233  }
234  catch (UniValue& objError)
235  {
236  try // Nice formatting for standard-format error
237  {
238  int code = find_value(objError, "code").get_int();
239  std::string message = find_value(objError, "message").get_str();
240  Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")");
241  }
242  catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message
243  { // Show raw JSON object
244  Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(objError.write()));
245  }
246  }
247  catch (const std::exception& e)
248  {
249  Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what()));
250  }
251 }
252 
253 RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) :
254  QWidget(parent),
255  ui(new Ui::RPCConsole),
256  clientModel(0),
257  historyPtr(0),
258  platformStyle(platformStyle),
259  peersTableContextMenu(0),
260  banTableContextMenu(0),
261  consoleFontSize(0)
262 {
263  ui->setupUi(this);
264  GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this);
265  QString theme = GUIUtil::getThemeName();
267  ui->openDebugLogfileButton->setIcon(QIcon(":/icons/" + theme + "/export"));
268  }
269  // Needed on Mac also
270  ui->clearButton->setIcon(QIcon(":/icons/" + theme + "/remove"));
271  ui->fontBiggerButton->setIcon(QIcon(":/icons/" + theme + "/fontbigger"));
272  ui->fontSmallerButton->setIcon(QIcon(":/icons/" + theme + "/fontsmaller"));
273 
274  // Install event filter for up and down arrow
275  ui->lineEdit->installEventFilter(this);
276  ui->messagesWidget->installEventFilter(this);
277 
278  connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
279  connect(ui->fontBiggerButton, SIGNAL(clicked()), this, SLOT(fontBigger()));
280  connect(ui->fontSmallerButton, SIGNAL(clicked()), this, SLOT(fontSmaller()));
281  connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear()));
282 
283  // Wallet Repair Buttons
284  // connect(ui->btn_salvagewallet, SIGNAL(clicked()), this, SLOT(walletSalvage()));
285  // Disable salvage option in GUI, it's way too powerful and can lead to funds loss
286  ui->btn_salvagewallet->setEnabled(false);
287  connect(ui->btn_rescan, SIGNAL(clicked()), this, SLOT(walletRescan()));
288  connect(ui->btn_zapwallettxes1, SIGNAL(clicked()), this, SLOT(walletZaptxes1()));
289  connect(ui->btn_zapwallettxes2, SIGNAL(clicked()), this, SLOT(walletZaptxes2()));
290  connect(ui->btn_upgradewallet, SIGNAL(clicked()), this, SLOT(walletUpgrade()));
291  connect(ui->btn_reindex, SIGNAL(clicked()), this, SLOT(walletReindex()));
292 
293  // set library version labels
294 #ifdef ENABLE_WALLET
295  ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0));
296  std::string walletPath = GetDataDir().string();
297  walletPath += QDir::separator().toLatin1() + GetArg("-wallet", "wallet.dat");
298  ui->wallet_path->setText(QString::fromStdString(walletPath));
299 #else
300  ui->label_berkeleyDBVersion->hide();
301  ui->berkeleyDBVersion->hide();
302 #endif
303  // Register RPC timer interface
306 
308 
309  ui->peerHeading->setText(tr("Select a peer to view detailed information."));
310 
311  QSettings settings;
312  consoleFontSize = settings.value(fontSizeSettingsKey, QFontInfo(QFont()).pointSize()).toInt();
313  clear();
314 }
315 
317 {
318  GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this);
320  delete rpcTimerInterface;
321  delete ui;
322 }
323 
324 bool RPCConsole::eventFilter(QObject* obj, QEvent *event)
325 {
326  if(event->type() == QEvent::KeyPress) // Special key handling
327  {
328  QKeyEvent *keyevt = static_cast<QKeyEvent*>(event);
329  int key = keyevt->key();
330  Qt::KeyboardModifiers mod = keyevt->modifiers();
331  switch(key)
332  {
333  case Qt::Key_Up: if(obj == ui->lineEdit) { browseHistory(-1); return true; } break;
334  case Qt::Key_Down: if(obj == ui->lineEdit) { browseHistory(1); return true; } break;
335  case Qt::Key_PageUp: /* pass paging keys to messages widget */
336  case Qt::Key_PageDown:
337  if(obj == ui->lineEdit)
338  {
339  QApplication::postEvent(ui->messagesWidget, new QKeyEvent(*keyevt));
340  return true;
341  }
342  break;
343  case Qt::Key_Return:
344  case Qt::Key_Enter:
345  // forward these events to lineEdit
346  if(obj == autoCompleter->popup()) {
347  QApplication::postEvent(ui->lineEdit, new QKeyEvent(*keyevt));
348  return true;
349  }
350  break;
351  default:
352  // Typing in messages widget brings focus to line edit, and redirects key there
353  // Exclude most combinations and keys that emit no text, except paste shortcuts
354  if(obj == ui->messagesWidget && (
355  (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) ||
356  ((mod & Qt::ControlModifier) && key == Qt::Key_V) ||
357  ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert)))
358  {
359  ui->lineEdit->setFocus();
360  QApplication::postEvent(ui->lineEdit, new QKeyEvent(*keyevt));
361  return true;
362  }
363  }
364  }
365  return QWidget::eventFilter(obj, event);
366 }
367 
369 {
370  clientModel = model;
371  ui->trafficGraph->setClientModel(model);
373  // Keep up to date with client
375  connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
376 
377  setNumBlocks(model->getNumBlocks(), model->getLastBlockDate(), model->getVerificationProgress(NULL), false);
378  connect(model, SIGNAL(numBlocksChanged(int,QDateTime,double,bool)), this, SLOT(setNumBlocks(int,QDateTime,double,bool)));
379 
381  connect(model, SIGNAL(networkActiveChanged(bool)), this, SLOT(setNetworkActive(bool)));
382 
384  connect(model, SIGNAL(strMasternodesChanged(QString)), this, SLOT(setMasternodeCount(QString)));
385 
387  connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
388 
389  connect(model, SIGNAL(mempoolSizeChanged(long,size_t)), this, SLOT(setMempoolSize(long,size_t)));
390 
391  // set up peer table
392  ui->peerWidget->setModel(model->getPeerTableModel());
393  ui->peerWidget->verticalHeader()->hide();
394  ui->peerWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
395  ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
396  ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
397  ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
401  ui->peerWidget->horizontalHeader()->setStretchLastSection(true);
402 
403  // create peer table context menu actions
404  QAction* disconnectAction = new QAction(tr("&Disconnect"), this);
405  QAction* banAction1h = new QAction(tr("Ban for") + " " + tr("1 &hour"), this);
406  QAction* banAction24h = new QAction(tr("Ban for") + " " + tr("1 &day"), this);
407  QAction* banAction7d = new QAction(tr("Ban for") + " " + tr("1 &week"), this);
408  QAction* banAction365d = new QAction(tr("Ban for") + " " + tr("1 &year"), this);
409 
410  // create peer table context menu
411  peersTableContextMenu = new QMenu(this);
412  peersTableContextMenu->addAction(disconnectAction);
413  peersTableContextMenu->addAction(banAction1h);
414  peersTableContextMenu->addAction(banAction24h);
415  peersTableContextMenu->addAction(banAction7d);
416  peersTableContextMenu->addAction(banAction365d);
417 
418  // Add a signal mapping to allow dynamic context menu arguments.
419  // We need to use int (instead of int64_t), because signal mapper only supports
420  // int or objects, which is okay because max bantime (1 year) is < int_max.
421  QSignalMapper* signalMapper = new QSignalMapper(this);
422  signalMapper->setMapping(banAction1h, 60*60);
423  signalMapper->setMapping(banAction24h, 60*60*24);
424  signalMapper->setMapping(banAction7d, 60*60*24*7);
425  signalMapper->setMapping(banAction365d, 60*60*24*365);
426  connect(banAction1h, SIGNAL(triggered()), signalMapper, SLOT(map()));
427  connect(banAction24h, SIGNAL(triggered()), signalMapper, SLOT(map()));
428  connect(banAction7d, SIGNAL(triggered()), signalMapper, SLOT(map()));
429  connect(banAction365d, SIGNAL(triggered()), signalMapper, SLOT(map()));
430  connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(banSelectedNode(int)));
431 
432  // peer table context menu signals
433  connect(ui->peerWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPeersTableContextMenu(const QPoint&)));
434  connect(disconnectAction, SIGNAL(triggered()), this, SLOT(disconnectSelectedNode()));
435 
436  // peer table signal handling - update peer details when selecting new node
437  connect(ui->peerWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
438  this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &)));
439  // peer table signal handling - update peer details when new nodes are added to the model
440  connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged()));
441  // peer table signal handling - cache selected node ids
442  connect(model->getPeerTableModel(), SIGNAL(layoutAboutToBeChanged()), this, SLOT(peerLayoutAboutToChange()));
443 
444  // set up ban table
445  ui->banlistWidget->setModel(model->getBanTableModel());
446  ui->banlistWidget->verticalHeader()->hide();
447  ui->banlistWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
448  ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
449  ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
450  ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
453  ui->banlistWidget->horizontalHeader()->setStretchLastSection(true);
454 
455  // create ban table context menu action
456  QAction* unbanAction = new QAction(tr("&Unban"), this);
457 
458  // create ban table context menu
459  banTableContextMenu = new QMenu(this);
460  banTableContextMenu->addAction(unbanAction);
461 
462  // ban table context menu signals
463  connect(ui->banlistWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showBanTableContextMenu(const QPoint&)));
464  connect(unbanAction, SIGNAL(triggered()), this, SLOT(unbanSelectedNode()));
465 
466  // ban table signal handling - clear peer details when clicking a peer in the ban table
467  connect(ui->banlistWidget, SIGNAL(clicked(const QModelIndex&)), this, SLOT(clearSelectedNode()));
468  // ban table signal handling - ensure ban table is shown or hidden (if empty)
469  connect(model->getBanTableModel(), SIGNAL(layoutChanged()), this, SLOT(showOrHideBanTableIfRequired()));
471 
472  // Provide initial values
473  ui->clientVersion->setText(model->formatFullVersion());
474  ui->clientUserAgent->setText(model->formatSubVersion());
475  ui->clientName->setText(model->clientName());
476  ui->dataDir->setText(model->dataDir());
477  ui->startupTime->setText(model->formatClientStartupTime());
478  ui->networkName->setText(QString::fromStdString(Params().NetworkIDString()));
479 
480  //Setup autocomplete and attach it
481  QStringList wordList;
482  std::vector<std::string> commandList = tableRPC.listCommands();
483  for (size_t i = 0; i < commandList.size(); ++i)
484  {
485  wordList << commandList[i].c_str();
486  }
487 
488  autoCompleter = new QCompleter(wordList, this);
489  ui->lineEdit->setCompleter(autoCompleter);
490  autoCompleter->popup()->installEventFilter(this);
491  // Start thread to execute RPC commands.
492  startExecutor();
493  }
494  if (!model) {
495  // Client model is being set to 0, this means shutdown() is about to be called.
496  // Make sure we clean up the executor thread
497  Q_EMIT stopExecutor();
498  thread.wait();
499  }
500 }
501 
502 static QString categoryClass(int category)
503 {
504  switch(category)
505  {
506  case RPCConsole::CMD_REQUEST: return "cmd-request"; break;
507  case RPCConsole::CMD_REPLY: return "cmd-reply"; break;
508  case RPCConsole::CMD_ERROR: return "cmd-error"; break;
509  default: return "misc";
510  }
511 }
512 
514 {
516 }
517 
519 {
521 }
522 
523 void RPCConsole::setFontSize(int newSize)
524 {
525  QSettings settings;
526 
527  //don't allow a insane font size
528  if (newSize < FONT_RANGE.width() || newSize > FONT_RANGE.height())
529  return;
530 
531  // temp. store the console content
532  QString str = ui->messagesWidget->toHtml();
533 
534  // replace font tags size in current content
535  str.replace(QString("font-size:%1pt").arg(consoleFontSize), QString("font-size:%1pt").arg(newSize));
536 
537  // store the new font size
538  consoleFontSize = newSize;
540 
541  // clear console (reset icon sizes, default stylesheet) and re-add the content
542  float oldPosFactor = 1.0 / ui->messagesWidget->verticalScrollBar()->maximum() * ui->messagesWidget->verticalScrollBar()->value();
543  clear(false);
544  ui->messagesWidget->setHtml(str);
545  ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor * ui->messagesWidget->verticalScrollBar()->maximum());
546 }
547 
550 {
552 }
553 
556 {
558 }
559 
562 {
564 }
565 
568 {
570 }
571 
574 {
576 }
577 
580 {
582 }
583 
586 {
587  // Get command-line arguments and remove the application name
588  QStringList args = QApplication::arguments();
589  args.removeFirst();
590 
591  // Remove existing repair-options
592  args.removeAll(SALVAGEWALLET);
593  args.removeAll(RESCAN);
594  args.removeAll(ZAPTXES1);
595  args.removeAll(ZAPTXES2);
596  args.removeAll(UPGRADEWALLET);
597  args.removeAll(REINDEX);
598 
599  // Append repair parameter to command line.
600  args.append(arg);
601 
602  // Send command-line arguments to BitcoinGUI::handleRestart()
603  Q_EMIT handleRestart(args);
604 }
605 
606 void RPCConsole::clear(bool clearHistory)
607 {
608  ui->messagesWidget->clear();
609  if(clearHistory)
610  {
611  history.clear();
612  historyPtr = 0;
613  }
614  ui->lineEdit->clear();
615  ui->lineEdit->setFocus();
616 
617  // Add smoothly scaled icon images.
618  // (when using width/height on an img, Qt uses nearest instead of linear interpolation)
619  QString iconPath = ":/icons/" + GUIUtil::getThemeName() + "/";
620  QString iconName = "";
621 
622  for(int i=0; ICON_MAPPING[i].url; ++i)
623  {
624  iconName = ICON_MAPPING[i].source;
625  ui->messagesWidget->document()->addResource(
626  QTextDocument::ImageResource,
627  QUrl(ICON_MAPPING[i].url),
628  QImage(iconPath + iconName).scaled(QSize(consoleFontSize*2, consoleFontSize*2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
629  }
630 
631  // Set default style sheet
632  QFontInfo fixedFontInfo(GUIUtil::fixedPitchFont());
633  ui->messagesWidget->document()->setDefaultStyleSheet(
634  QString(
635  "table { }"
636  "td.time { color: #808080; font-size: %2; padding-top: 3px; } "
637  "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } "
638  "td.cmd-request { color: #006060; } "
639  "td.cmd-error { color: red; } "
640  "b { color: #006060; } "
641  ).arg(fixedFontInfo.family(), QString("%1pt").arg(consoleFontSize))
642  );
643 
644  message(CMD_REPLY, (tr("Welcome to the Dash Core RPC console.") + "<br>" +
645  tr("Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.") + "<br>" +
646  tr("Type <b>help</b> for an overview of available commands.")), true);
647 }
648 
649 void RPCConsole::keyPressEvent(QKeyEvent *event)
650 {
651  if(windowType() != Qt::Widget && event->key() == Qt::Key_Escape)
652  {
653  close();
654  }
655 }
656 
657 void RPCConsole::message(int category, const QString &message, bool html)
658 {
659  QTime time = QTime::currentTime();
660  QString timeString = time.toString();
661  QString out;
662  out += "<table><tr><td class=\"time\" width=\"65\">" + timeString + "</td>";
663  out += "<td class=\"icon\" width=\"32\"><img src=\"" + categoryClass(category) + "\"></td>";
664  out += "<td class=\"message " + categoryClass(category) + "\" valign=\"middle\">";
665  if(html)
666  out += message;
667  else
668  out += GUIUtil::HtmlEscape(message, false);
669  out += "</td></tr></table>";
670  ui->messagesWidget->append(out);
671 }
672 
674 {
675  QString connections = QString::number(clientModel->getNumConnections()) + " (";
676  connections += tr("In:") + " " + QString::number(clientModel->getNumConnections(CONNECTIONS_IN)) + " / ";
677  connections += tr("Out:") + " " + QString::number(clientModel->getNumConnections(CONNECTIONS_OUT)) + ")";
678 
679  if(!clientModel->getNetworkActive()) {
680  connections += " (" + tr("Network activity disabled") + ")";
681  }
682 
683  ui->numberOfConnections->setText(connections);
684 }
685 
687 {
688  if (!clientModel)
689  return;
690 
692 }
693 
694 void RPCConsole::setNetworkActive(bool networkActive)
695 {
697 }
698 
699 void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers)
700 {
701  if (!headers) {
702  ui->numberOfBlocks->setText(QString::number(count));
703  ui->lastBlockTime->setText(blockDate.toString());
704  }
705 }
706 
707 void RPCConsole::setMasternodeCount(const QString &strMasternodes)
708 {
709  ui->masternodeCount->setText(strMasternodes);
710 }
711 
712 void RPCConsole::setMempoolSize(long numberOfTxs, size_t dynUsage)
713 {
714  ui->mempoolNumberTxs->setText(QString::number(numberOfTxs));
715 
716  if (dynUsage < 1000000)
717  ui->mempoolSize->setText(QString::number(dynUsage/1000.0, 'f', 2) + " KB");
718  else
719  ui->mempoolSize->setText(QString::number(dynUsage/1000000.0, 'f', 2) + " MB");
720 }
721 
723 {
724  QString cmd = ui->lineEdit->text();
725  ui->lineEdit->clear();
726 
727  if(!cmd.isEmpty())
728  {
729  message(CMD_REQUEST, cmd);
730  Q_EMIT cmdRequest(cmd);
731  // Remove command, if already in history
732  history.removeOne(cmd);
733  // Append command to history
734  history.append(cmd);
735  // Enforce maximum history size
736  while(history.size() > CONSOLE_HISTORY)
737  history.removeFirst();
738  // Set pointer to end of history
739  historyPtr = history.size();
740  // Scroll console view to end
741  scrollToEnd();
742  }
743 }
744 
746 {
747  historyPtr += offset;
748  if(historyPtr < 0)
749  historyPtr = 0;
750  if(historyPtr > history.size())
751  historyPtr = history.size();
752  QString cmd;
753  if(historyPtr < history.size())
754  cmd = history.at(historyPtr);
755  ui->lineEdit->setText(cmd);
756 }
757 
759 {
760  RPCExecutor *executor = new RPCExecutor();
761  executor->moveToThread(&thread);
762 
763  // Replies from executor object must go to this object
764  connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString)));
765  // Requests from this object must go to executor
766  connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString)));
767 
768  // On stopExecutor signal
769  // - quit the Qt event loop in the execution thread
770  connect(this, SIGNAL(stopExecutor()), &thread, SLOT(quit()));
771  // - queue executor for deletion (in execution thread)
772  connect(&thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection);
773 
774  // Default implementation of QThread::run() simply spins up an event loop in the thread,
775  // which is what we want.
776  thread.start();
777 }
778 
780 {
781  if (ui->tabWidget->widget(index) == ui->tab_console)
782  ui->lineEdit->setFocus();
783  else if (ui->tabWidget->widget(index) != ui->tab_peers)
785 }
786 
788 {
790 }
791 
793 {
794  QScrollBar *scrollbar = ui->messagesWidget->verticalScrollBar();
795  scrollbar->setValue(scrollbar->maximum());
796 }
797 
799 {
800  setTrafficGraphRange(static_cast<TrafficGraphData::GraphRange>(value));
801 }
802 
803 QString RPCConsole::FormatBytes(quint64 bytes)
804 {
805  if(bytes < 1024)
806  return QString(tr("%1 B")).arg(bytes);
807  if(bytes < 1024 * 1024)
808  return QString(tr("%1 KB")).arg(bytes / 1024);
809  if(bytes < 1024 * 1024 * 1024)
810  return QString(tr("%1 MB")).arg(bytes / 1024 / 1024);
811 
812  return QString(tr("%1 GB")).arg(bytes / 1024 / 1024 / 1024);
813 }
814 
816 {
819 }
820 
821 void RPCConsole::updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut)
822 {
823  ui->lblBytesIn->setText(FormatBytes(totalBytesIn));
824  ui->lblBytesOut->setText(FormatBytes(totalBytesOut));
825 }
826 
827 void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelection &deselected)
828 {
829  Q_UNUSED(deselected);
830 
831  if (!clientModel || !clientModel->getPeerTableModel() || selected.indexes().isEmpty())
832  return;
833 
834  const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.indexes().first().row());
835  if (stats)
836  updateNodeDetail(stats);
837 }
838 
840 {
841  QModelIndexList selected = ui->peerWidget->selectionModel()->selectedIndexes();
842  cachedNodeids.clear();
843  for(int i = 0; i < selected.size(); i++)
844  {
845  const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.at(i).row());
846  cachedNodeids.append(stats->nodeStats.nodeid);
847  }
848 }
849 
851 {
853  return;
854 
855  const CNodeCombinedStats *stats = NULL;
856  bool fUnselect = false;
857  bool fReselect = false;
858 
859  if (cachedNodeids.empty()) // no node selected yet
860  return;
861 
862  // find the currently selected row
863  int selectedRow = -1;
864  QModelIndexList selectedModelIndex = ui->peerWidget->selectionModel()->selectedIndexes();
865  if (!selectedModelIndex.isEmpty()) {
866  selectedRow = selectedModelIndex.first().row();
867  }
868 
869  // check if our detail node has a row in the table (it may not necessarily
870  // be at selectedRow since its position can change after a layout change)
871  int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeids.first());
872 
873  if (detailNodeRow < 0)
874  {
875  // detail node disappeared from table (node disconnected)
876  fUnselect = true;
877  }
878  else
879  {
880  if (detailNodeRow != selectedRow)
881  {
882  // detail node moved position
883  fUnselect = true;
884  fReselect = true;
885  }
886 
887  // get fresh stats on the detail node.
888  stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow);
889  }
890 
891  if (fUnselect && selectedRow >= 0) {
893  }
894 
895  if (fReselect)
896  {
897  for(int i = 0; i < cachedNodeids.size(); i++)
898  {
900  }
901  }
902 
903  if (stats)
904  updateNodeDetail(stats);
905 }
906 
908 {
909  // update the detail ui with latest node information
910  QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName) + " ");
911  peerAddrDetails += tr("(node id: %1)").arg(QString::number(stats->nodeStats.nodeid));
912  if (!stats->nodeStats.addrLocal.empty())
913  peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
914  ui->peerHeading->setText(peerAddrDetails);
918  ui->peerBytesSent->setText(FormatBytes(stats->nodeStats.nSendBytes));
919  ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes));
925  ui->peerVersion->setText(QString("%1").arg(QString::number(stats->nodeStats.nVersion)));
926  ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
927  ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound"));
928  ui->peerHeight->setText(QString("%1").arg(QString::number(stats->nodeStats.nStartingHeight)));
929  ui->peerWhitelisted->setText(stats->nodeStats.fWhitelisted ? tr("Yes") : tr("No"));
930 
931  // This check fails for example if the lock was busy and
932  // nodeStateStats couldn't be fetched.
933  if (stats->fNodeStateStatsAvailable) {
934  // Ban score is init to 0
935  ui->peerBanScore->setText(QString("%1").arg(stats->nodeStateStats.nMisbehavior));
936 
937  // Sync height is init to -1
938  if (stats->nodeStateStats.nSyncHeight > -1)
939  ui->peerSyncHeight->setText(QString("%1").arg(stats->nodeStateStats.nSyncHeight));
940  else
941  ui->peerSyncHeight->setText(tr("Unknown"));
942 
943  // Common height is init to -1
944  if (stats->nodeStateStats.nCommonHeight > -1)
945  ui->peerCommonHeight->setText(QString("%1").arg(stats->nodeStateStats.nCommonHeight));
946  else
947  ui->peerCommonHeight->setText(tr("Unknown"));
948  }
949 
950  ui->detailWidget->show();
951 }
952 
953 void RPCConsole::resizeEvent(QResizeEvent *event)
954 {
955  QWidget::resizeEvent(event);
956 }
957 
958 void RPCConsole::showEvent(QShowEvent *event)
959 {
960  QWidget::showEvent(event);
961 
963  return;
964 
965  // start PeerTableModel auto refresh
967 }
968 
969 void RPCConsole::hideEvent(QHideEvent *event)
970 {
971  QWidget::hideEvent(event);
972 
974  return;
975 
976  // stop PeerTableModel auto refresh
978 }
979 
980 void RPCConsole::showPeersTableContextMenu(const QPoint& point)
981 {
982  QModelIndex index = ui->peerWidget->indexAt(point);
983  if (index.isValid())
984  peersTableContextMenu->exec(QCursor::pos());
985 }
986 
987 void RPCConsole::showBanTableContextMenu(const QPoint& point)
988 {
989  QModelIndex index = ui->banlistWidget->indexAt(point);
990  if (index.isValid())
991  banTableContextMenu->exec(QCursor::pos());
992 }
993 
995 {
996  if(!g_connman)
997  return;
998 
999  // Get selected peer addresses
1000  QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->peerWidget, PeerTableModel::NetNodeId);
1001  for(int i = 0; i < nodes.count(); i++)
1002  {
1003  // Get currently selected peer address
1004  NodeId id = nodes.at(i).data().toInt();
1005  // Find the node, disconnect it and clear the selected node
1006  if(g_connman->DisconnectNode(id))
1008  }
1009 }
1010 
1012 {
1013  if (!clientModel || !g_connman)
1014  return;
1015 
1016  // Get selected peer addresses
1017  QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->peerWidget, PeerTableModel::NetNodeId);
1018  for(int i = 0; i < nodes.count(); i++)
1019  {
1020  // Get currently selected peer address
1021  NodeId id = nodes.at(i).data().toInt();
1022 
1023  // Get currently selected peer address
1024  int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(id);
1025  if(detailNodeRow < 0)
1026  return;
1027 
1028  // Find possible nodes, ban it and clear the selected node
1029  const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow);
1030  if(stats) {
1031  g_connman->Ban(stats->nodeStats.addr, BanReasonManuallyAdded, bantime);
1032  }
1033  }
1036 }
1037 
1039 {
1040  if (!clientModel)
1041  return;
1042 
1043  // Get selected ban addresses
1044  QList<QModelIndex> nodes = GUIUtil::getEntryData(ui->banlistWidget, BanTableModel::Address);
1045  for(int i = 0; i < nodes.count(); i++)
1046  {
1047  // Get currently selected ban address
1048  QString strNode = nodes.at(i).data().toString();
1049  CSubNet possibleSubnet;
1050 
1051  LookupSubNet(strNode.toStdString().c_str(), possibleSubnet);
1052  if (possibleSubnet.IsValid() && g_connman)
1053  {
1054  g_connman->Unban(possibleSubnet);
1056  }
1057  }
1058 }
1059 
1061 {
1062  ui->peerWidget->selectionModel()->clearSelection();
1063  cachedNodeids.clear();
1064  ui->detailWidget->hide();
1065  ui->peerHeading->setText(tr("Select a peer to view detailed information."));
1066 }
1067 
1069 {
1070  if (!clientModel)
1071  return;
1072 
1073  bool visible = clientModel->getBanTableModel()->shouldShow();
1074  ui->banlistWidget->setVisible(visible);
1075  ui->banHeading->setVisible(visible);
1076 }
1077 
1079 {
1080  ui->tabWidget->setCurrentIndex(tabType);
1081 }
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:547
QLabel * masternodeCount
QtRPCTimerBase(boost::function< void(void)> &func, int64_t millis)
Definition: rpcconsole.cpp:92
double dPingTime
Definition: net.h:611
QLabel * peerDirection
void on_sldGraphRange_valueChanged(int value)
Definition: rpcconsole.cpp:798
QLabel * peerSyncHeight
QThread thread
Definition: rpcconsole.h:165
double dPingWait
Definition: net.h:612
void peerSelected(const QItemSelection &selected, const QItemSelection &deselected)
Definition: rpcconsole.cpp:827
void setFontSize(int newSize)
Definition: rpcconsole.cpp:523
const QString SALVAGEWALLET("-salvagewallet")
void peerLayoutChanged()
Definition: rpcconsole.cpp:850
QPushButton * btn_zapwallettxes1
void updateNodeDetail(const CNodeCombinedStats *stats)
Definition: rpcconsole.cpp:907
void buildParameterlist(QString arg)
Definition: rpcconsole.cpp:585
void cmdRequest(const QString &command)
std::string addrName
Definition: net.h:601
virtual bool eventFilter(QObject *obj, QEvent *event)
Definition: rpcconsole.cpp:324
int historyPtr
Definition: rpcconsole.h:157
QLabel * numberOfBlocks
const PlatformStyle * platformStyle
Definition: rpcconsole.h:159
void startExecutor()
Definition: rpcconsole.cpp:758
void banSelectedNode(int bantime)
void setTabFocus(enum TabTypes tabType)
QLabel * peerPingWait
std::string addrLocal
Definition: net.h:614
QLabel * mempoolSize
void setMempoolSize(long numberOfTxs, size_t dynUsage)
Definition: rpcconsole.cpp:712
RPCConsole(const PlatformStyle *platformStyle, QWidget *parent)
Definition: rpcconsole.cpp:253
bool parseCommandLine(std::vector< std::string > &args, const std::string &strCommand)
Definition: rpcconsole.cpp:135
void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut)
Definition: rpcconsole.cpp:821
QWidget * tab_peers
QLabel * clientName
const QString REINDEX("-reindex")
void saveWindowGeometry(const QString &strSetting, QWidget *parent)
Definition: guiutil.cpp:875
const QString ZAPTXES2("-zapwallettxes=2")
void showPeersTableContextMenu(const QPoint &point)
Definition: rpcconsole.cpp:980
QTableView * banlistWidget
void on_lineEdit_returnPressed()
Definition: rpcconsole.cpp:722
QTableView * peerWidget
static QString categoryClass(int category)
Definition: rpcconsole.cpp:502
QLabel * peerPingTime
TrafficGraphWidget * trafficGraph
const struct @19 ICON_MAPPING[]
void showEvent(QShowEvent *event)
Definition: rpcconsole.cpp:958
const QString UPGRADEWALLET("-upgradewallet")
QLabel * wallet_path
void setNumBlocks(int count, const QDateTime &blockDate, double nVerificationProgress, bool headers)
Definition: rpcconsole.cpp:699
int getNumBlocks() const
Definition: clientmodel.cpp:94
QLineEdit * lineEdit
void restoreWindowGeometry(const QString &strSetting, const QSize &defaultSize, QWidget *parent)
Definition: guiutil.cpp:882
QLabel * numberOfConnections
void scrollToEnd()
Definition: rpcconsole.cpp:792
dictionary settings
void disconnectSelectedNode()
Definition: rpcconsole.cpp:994
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:280
void walletZaptxes2()
Definition: rpcconsole.cpp:567
void setClientModel(ClientModel *model)
Definition: rpcconsole.cpp:368
void setTrafficGraphRange(TrafficGraphData::GraphRange range)
Definition: rpcconsole.cpp:815
void handleRestart(QStringList args)
UniValue RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Definition: client.cpp:179
QCompleter * autoCompleter
Definition: rpcconsole.h:164
QPushButton * fontBiggerButton
std::string cleanSubVer
Definition: net.h:603
QMenu * banTableContextMenu
Definition: rpcconsole.h:162
QLabel * startupTime
Ui::RPCConsole * ui
Definition: rpcconsole.h:154
const char * url
Definition: rpcconsole.cpp:62
QWidget * tab_console
void showOrHideBanTableIfRequired()
QLabel * peerBytesRecv
void browseHistory(int offset)
Definition: rpcconsole.cpp:745
QLabel * label_berkeleyDBVersion
const CRPCTable tableRPC
Definition: server.cpp:614
const TrafficGraphData::GraphRange INITIAL_TRAFFIC_GRAPH_SETTING
Definition: rpcconsole.cpp:51
const char * source
Definition: rpcconsole.cpp:63
int getRowByNodeId(NodeId nodeid)
void updateNetworkState()
Definition: rpcconsole.cpp:673
void clearSelectedNode()
void resizeEvent(QResizeEvent *event)
Definition: rpcconsole.cpp:953
int64_t GetSystemTimeInSeconds()
Definition: utiltime.cpp:50
void hideEvent(QHideEvent *event)
Definition: rpcconsole.cpp:969
RPCTimerInterface * rpcTimerInterface
Definition: rpcconsole.h:160
QPushButton * btnClearTrafficGraph
int64_t nTimeOffset
Definition: net.h:600
const int CONSOLE_HISTORY
Definition: rpcconsole.cpp:47
const QString RESCAN("-rescan")
void on_tabWidget_currentChanged(int index)
Definition: rpcconsole.cpp:779
QPushButton * btn_salvagewallet
void reply(int category, const QString &command)
int nStartingHeight
Definition: net.h:605
QString getMasternodeCountString() const
Definition: clientmodel.cpp:82
QTabWidget * tabWidget
QPushButton * btn_upgradewallet
void peerLayoutAboutToChange()
Definition: rpcconsole.cpp:839
QLabel * peerSubversion
void setNetworkActive(bool networkActive)
Definition: rpcconsole.cpp:694
bool fWhitelisted
Definition: net.h:610
QPushButton * btn_rescan
QString formatTimeOffset(int64_t nTimeOffset)
Definition: guiutil.cpp:1023
QMenu * peersTableContextMenu
Definition: rpcconsole.h:161
QLabel * peerBytesSent
QString HtmlEscape(const QString &str, bool fMultiLine)
Definition: guiutil.cpp:261
bool fInbound
Definition: net.h:604
QString formatSubVersion() const
QWidget * detailWidget
CAddress addr
Definition: net.h:615
QLabel * peerServices
void showBanTableContextMenu(const QPoint &point)
Definition: rpcconsole.cpp:987
uint64_t nSendBytes
Definition: net.h:606
void request(const QString &command)
Definition: rpcconsole.cpp:205
CNodeStats nodeStats
QString dataDir() const
const QString ZAPTXES1("-zapwallettxes=1")
QPushButton * btn_zapwallettxes2
CNodeStateStats nodeStateStats
QPushButton * fontSmallerButton
void clear(bool clearHistory=true)
Definition: rpcconsole.cpp:606
static const int RangeMinutes[]
QLabel * networkName
QLabel * lastBlockTime
void keyPressEvent(QKeyEvent *)
Definition: rpcconsole.cpp:649
QLabel * peerLastRecv
version
Definition: setup.py:3
bool LookupSubNet(const char *pszName, CSubNet &ret)
Definition: netbase.cpp:640
QLabel * peerCommonHeight
QLabel * peerVersion
void openDebugLogfile()
Definition: guiutil.cpp:414
QLabel * berkeleyDBVersion
QPushButton * openDebugLogfileButton
QString formatFullVersion() const
void walletSalvage()
Definition: rpcconsole.cpp:549
bool IsValid() const
Definition: netaddress.cpp:698
bool getImagesOnButtons() const
Definition: platformstyle.h:21
QString formatClientStartupTime() const
bool getNetworkActive() const
Return true if network activity in core is enabled.
void fontSmaller()
Definition: rpcconsole.cpp:518
boost::function< void(void)> func
Definition: rpcconsole.cpp:104
QLabel * peerMinPing
int64_t nLastRecv
Definition: net.h:598
void RPCRegisterTimerInterface(RPCTimerInterface *iface)
Definition: server.cpp:592
quint64 getTotalBytesRecv() const
const char * Name()
Definition: rpcconsole.cpp:111
double dMinPing
Definition: net.h:613
int64_t nTimeConnected
Definition: net.h:599
void walletZaptxes1()
Definition: rpcconsole.cpp:561
void walletRescan()
Definition: rpcconsole.cpp:555
QLabel * peerHeading
ServiceFlags nServices
Definition: net.h:595
const CChainParams & Params()
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
const CNodeCombinedStats * getNodeStats(int idx)
QString getThemeName()
Definition: guiutil.cpp:902
int nVersion
Definition: net.h:602
int NodeId
Definition: net.h:94
QLabel * peerHeight
static QString FormatBytes(quint64 bytes)
Definition: rpcconsole.cpp:803
QPushButton * clearButton
void setMasternodeCount(const QString &strMasternodes)
Definition: rpcconsole.cpp:707
void walletReindex()
Definition: rpcconsole.cpp:579
int64_t nLastSend
Definition: net.h:597
void fontBigger()
Definition: rpcconsole.cpp:513
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:103
QList< QModelIndex > getEntryData(QAbstractItemView *view, int column)
Definition: guiutil.cpp:294
static int count
Definition: tests.c:41
QLabel * peerBanScore
int get_int() const
Definition: univalue.cpp:317
const char fontSizeSettingsKey[]
Definition: rpcconsole.cpp:49
NodeId nodeid
Definition: net.h:594
QString formatServicesStr(quint64 mask)
Definition: guiutil.cpp:986
void setNumConnections(int count)
Definition: rpcconsole.cpp:686
QString formatPingTime(double dPingTime)
Definition: guiutil.cpp:1018
double getVerificationProgress(const CBlockIndex *tip) const
void walletUpgrade()
Definition: rpcconsole.cpp:573
QLabel * clientUserAgent
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Definition: util.cpp:441
const QSize FONT_RANGE(4, 40)
QLabel * peerLastSend
RPCTimerBase * NewTimer(boost::function< void(void)> &func, int64_t millis)
Definition: rpcconsole.cpp:112
void setupUi(QWidget *RPCConsole)
QLabel * peerConnTime
QString formatDurationStr(int secs)
Definition: guiutil.cpp:966
QLabel * lblBytesIn
void on_openDebugLogfileButton_clicked()
Definition: rpcconsole.cpp:787
int consoleFontSize
Definition: rpcconsole.h:163
UniValue execute(const std::string &method, const UniValue &params) const
Definition: server.cpp:541
quint64 getTotalBytesSent() const
QLabel * banHeading
QLabel * mempoolNumberTxs
uint64_t nRecvBytes
Definition: net.h:608
std::vector< std::string > listCommands() const
Definition: server.cpp:570
QPushButton * btn_reindex
QDateTime getLastBlockDate() const
QLabel * timeoffset
void message(int category, const QString &message, bool html=false)
Definition: rpcconsole.cpp:657
void setClientModel(ClientModel *model)
QStringList history
Definition: rpcconsole.h:156
void stopExecutor()
QString clientName() const
QLabel * clientVersion
QList< NodeId > cachedNodeids
Definition: rpcconsole.h:158
void setGraphRangeMins(int value)
std::string get_str() const
Definition: univalue.cpp:310
QLabel * lblGraphRange
QLabel * lblBytesOut
void unbanSelectedNode()
ClientModel * clientModel
Definition: rpcconsole.h:155
BanTableModel * getBanTableModel()
result
Definition: rpcuser.py:37
QTextEdit * messagesWidget
void RPCUnregisterTimerInterface(RPCTimerInterface *iface)
Definition: server.cpp:597
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
Definition: clientmodel.cpp:66
QLabel * dataDir
PeerTableModel * getPeerTableModel()
QLabel * peerWhitelisted
QFont fixedPitchFont()
Definition: guiutil.cpp:97