5#if defined(HAVE_CONFIG_H)
6#include <config/bitcoin-config.h>
11#include <chainparams.h>
18#include <qt/forms/ui_debugwindow.h>
55 {
"cmd-reply",
":/icons/tx_output"},
56 {
"cmd-error",
":/icons/tx_output"},
57 {
"misc",
":/icons/tx_inout"},
66 <<
"signmessagewithprivkey"
67 <<
"signrawtransactionwithkey"
69 <<
"walletpassphrasechange"
97 timer.setSingleShot(
true);
111 const char *
Name()
override {
return "Qt"; }
118#include <qt/rpcconsole.moc>
152 std::vector<std::vector<std::string>> stack;
153 stack.push_back(std::vector<std::string>());
176 Qt::CaseInsensitive)) {
182 stack.
push_back(std::vector<std::string>());
184 stack.back().push_back(
strArg);
229 throw std::runtime_error(
230 "Invalid result query");
239 throw std::runtime_error(
240 "Invalid result query");
301 throw std::runtime_error(
"Invalid Syntax");
304 if (
ch ==
'(' && stack.size() &&
305 stack.back().size() > 0) {
309 stack.push_back(std::vector<std::string>());
315 throw std::runtime_error(
"Invalid Syntax");
322 if ((
ch ==
')' ||
ch ==
'\n') && stack.size() > 0) {
329 std::vector<std::string>(
330 stack.back().begin() + 1,
331 stack.back().end()));
332 std::string method = stack.back()[0];
338 QUrl::toPercentEncoding(
360 throw std::runtime_error(
"Invalid Syntax");
405 if (
ch !=
'"' &&
ch !=
'\\') {
454 "This console accepts RPC commands using the standard "
456 " example: getblockhash 0\n\n"
458 "This console can also accept RPC commands using "
459 "parenthesized syntax.\n"
460 " example: getblockhash(0)\n\n"
462 "Commands may be nested when specified with the "
463 "parenthesized syntax.\n"
464 " example: getblock(getblockhash(0) 1)\n\n"
466 "A space or a comma can be used to delimit arguments "
467 "for either syntax.\n"
468 " example: getblockhash 0\n"
469 " getblockhash,0\n\n"
471 "Named results can be queried with a non-quoted key "
472 "string in brackets.\n"
473 " example: getblock(getblockhash(0) true)[tx]\n\n"
475 "Results without keys can be queried using an integer "
478 "getblock(getblockhash(0),true)[tx][0]\n\n")));
484 QString(
"Parse error: unbalanced ' or \""));
492 int code =
objError.find_value(
"code").getInt<
int>();
493 std::string message =
objError.find_value(
"message").get_str();
495 QString::fromStdString(message) +
" (code " +
496 QString::number(code) +
")");
497 }
catch (
const std::runtime_error &) {
501 QString::fromStdString(
objError.write()));
503 }
catch (
const std::exception &
e) {
505 QString(
"Error: ") + QString::fromStdString(
e.what()));
516 settings.value(
"RPCConsoleWindowGeometry").toByteArray())) {
524 tr(
"we selected the peer for high bandwidth relay") +
525 "</li><li>\"" +
tr(
"From") +
"\" – " +
526 tr(
"the peer selected us for high bandwidth relay") +
527 "</li><li>\"" +
tr(
"No") +
"\" – " +
528 tr(
"no high bandwidth relay selected") +
530 ui->peerHighBandwidthLabel->setToolTip(
531 ui->peerHighBandwidthLabel->toolTip().arg(
hb_list));
532 ui->dataDir->setToolTip(
534 ui->blocksDir->setToolTip(
ui->blocksDir->toolTip().arg(
536 ui->openDebugLogfileButton->setToolTip(
540 ui->openDebugLogfileButton->setIcon(
544 ui->fontBiggerButton->setIcon(
546 ui->fontSmallerButton->setIcon(
550 ui->lineEdit->installEventFilter(
this);
551 ui->lineEdit->setMaxLength(16 * 1024 * 1024);
552 ui->messagesWidget->installEventFilter(
this);
555 connect(
ui->fontBiggerButton, &QPushButton::clicked,
this,
557 connect(
ui->fontSmallerButton, &QPushButton::clicked,
this,
559 connect(
ui->btnClearTrafficGraph, &QPushButton::clicked,
ui->trafficGraph,
563 ui->WalletSelector->setVisible(
false);
564 ui->WalletSelectorLabel->setVisible(
false);
568 ui->berkeleyDBVersion->setText(
571 ui->label_berkeleyDBVersion->hide();
572 ui->berkeleyDBVersion->hide();
600 if (event->type() == QEvent::KeyPress) {
603 Qt::KeyboardModifiers
mod =
keyevt->modifiers();
606 if (
obj ==
ui->lineEdit) {
612 if (
obj ==
ui->lineEdit) {
618 case Qt::Key_PageDown:
619 if (
obj ==
ui->lineEdit) {
620 QApplication::postEvent(
ui->messagesWidget,
629 QApplication::postEvent(
ui->lineEdit,
638 if (
obj ==
ui->messagesWidget &&
640 key != Qt::Key_Tab) ||
641 ((
mod & Qt::ControlModifier) && key == Qt::Key_V) ||
642 ((
mod & Qt::ShiftModifier) && key == Qt::Key_Insert))) {
643 ui->lineEdit->setFocus();
644 QApplication::postEvent(
ui->lineEdit,
650 return QWidget::eventFilter(
obj, event);
655 double verification_progress) {
669 ui->trafficGraph->setClientModel(model);
696 ui->peerWidget->verticalHeader()->hide();
697 ui->peerWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
698 ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
699 ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
700 ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
706 ui->peerWidget->horizontalHeader()->setStretchLastSection(
true);
711 new QAction(
tr(
"Ban for") +
" " +
tr(
"1 &hour"),
this);
713 new QAction(
tr(
"Ban for") +
" " +
tr(
"1 &day"),
this);
715 new QAction(
tr(
"Ban for") +
" " +
tr(
"1 &week"),
this);
717 new QAction(
tr(
"Ban for") +
" " +
tr(
"1 &year"),
this);
737 connect(
ui->peerWidget, &QTableView::customContextMenuRequested,
this,
744 connect(
ui->peerWidget->selectionModel(),
745 &QItemSelectionModel::selectionChanged,
this,
753 &PeerTableModel::layoutAboutToBeChanged,
this,
758 ui->banlistWidget->verticalHeader()->hide();
759 ui->banlistWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
760 ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
761 ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
762 ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
767 ui->banlistWidget->horizontalHeader()->setStretchLastSection(
true);
777 connect(
ui->banlistWidget, &QTableView::customContextMenuRequested,
784 connect(
ui->banlistWidget, &QTableView::clicked,
this,
798 ui->networkName->setText(
799 QString::fromStdString(
Params().NetworkIDString()));
812 autoCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel);
815 ui->lineEdit->setEnabled(
true);
834 QVariant::fromValue(walletModel));
835 if (
ui->WalletSelector->count() == 2 && !
isVisible()) {
838 ui->WalletSelector->setCurrentIndex(1);
840 if (
ui->WalletSelector->count() > 2) {
841 ui->WalletSelector->setVisible(
true);
842 ui->WalletSelectorLabel->setVisible(
true);
847 ui->WalletSelector->removeItem(
848 ui->WalletSelector->findData(QVariant::fromValue(walletModel)));
849 if (
ui->WalletSelector->count() == 2) {
850 ui->WalletSelector->setVisible(
false);
851 ui->WalletSelectorLabel->setVisible(
false);
859 return "cmd-request";
889 QString str =
ui->messagesWidget->toHtml();
902 ui->messagesWidget->verticalScrollBar()->maximum() *
903 ui->messagesWidget->verticalScrollBar()->value();
905 ui->messagesWidget->setHtml(str);
906 ui->messagesWidget->verticalScrollBar()->setValue(
907 oldPosFactor *
ui->messagesWidget->verticalScrollBar()->maximum());
911 ui->messagesWidget->clear();
916 ui->lineEdit->clear();
917 ui->lineEdit->setFocus();
923 ui->messagesWidget->document()->addResource(
927 Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
932 ui->messagesWidget->document()->setDefaultStyleSheet(
934 "td.time { color: #808080; font-size: %2; padding-top: 3px; } "
935 "td.message { font-family: %1; font-size: %2; "
936 "white-space:pre-wrap; } "
937 "td.cmd-request { color: #006060; } "
938 "td.cmd-error { color: red; } "
939 ".secwarning { color: red; }"
940 "b { color: #006060; } ")
951 tr(
"Use up and down arrows to navigate history, and "
952 "%1 to clear screen.")
955 tr(
"Type %1 for an overview of available commands.")
956 .
arg(
"<b>help</b>") +
958 tr(
"For more information on using this console type %1.")
959 .
arg(
"<b>help-console</b>") +
960 "<br><span class=\"secwarning\"><br>" +
961 tr(
"WARNING: Scammers have been active, telling users to type "
962 "commands here, stealing their wallet contents. Do not use "
963 "this console without fully understanding the ramifications "
970 if (
windowType() != Qt::Widget && event->key() == Qt::Key_Escape) {
976 QTime time = QTime::currentTime();
979 out +=
"<table><tr><td class=\"time\" width=\"65\">" +
timeString +
"</td>";
980 out +=
"<td class=\"icon\" width=\"32\"><img src=\"" +
983 "\" valign=\"middle\">";
989 out +=
"</td></tr></table>";
990 ui->messagesWidget->append(out);
1006 connections +=
" (" +
tr(
"Network activity disabled") +
")";
1027 ui->numberOfBlocks->setText(QString::number(
count));
1033 ui->mempoolNumberTxs->setText(QString::number(
numberOfTxs));
1036 ui->mempoolSize->setText(QString::number(
dynUsage / 1000.0,
'f', 2) +
1039 ui->mempoolSize->setText(QString::number(
dynUsage / 1000000.0,
'f', 2) +
1047 if (!
cmd.isEmpty()) {
1055 throw std::runtime_error(
"Invalid command line");
1057 }
catch (
const std::exception &
e) {
1058 QMessageBox::critical(
this,
"Error",
1060 QString::fromStdString(
e.what()));
1064 ui->lineEdit->clear();
1078 tr(
"Executing command without any wallet"));
1124 ui->lineEdit->setText(
cmd);
1150 if (
ui->tabWidget->widget(index) ==
ui->tab_console) {
1151 ui->lineEdit->setFocus();
1171 ui->trafficGraph->setGraphRangeMins(
mins);
1172 ui->lblGraphRange->setText(
1184 ui->peerWidget->selectionModel()->selectedIndexes();
1186 for (
int i = 0; i <
selected.size(); i++) {
1208 int selectedRow = -1;
1210 ui->peerWidget->selectionModel()->selectedIndexes();
1237 ui->peerWidget->selectRow(
1254 ui->detailWidget->hide();
1255 ui->peerHeading->setText(
1256 tr(
"Select a peer to view detailed information."));
1284 ui->peerConnTime->setText(
1286 ui->peerLastBlock->setText(
1288 ui->peerLastTx->setText(
1290 ui->peerLastSend->setText(
1292 ui->peerLastRecv->setText(
1294 ui->peerBytesSent->setText(
1296 ui->peerBytesRecv->setText(
1298 ui->peerPingTime->setText(
1300 ui->peerMinPing->setText(
1302 ui->timeoffset->setText(
1305 ui->peerSubversion->setText(
1309 ui->peerNetwork->setText(
1312 ui->peerPermissions->setText(
tr(
"N/A"));
1321 ui->peerMappedAS->setText(
1329 ui->peerServices->setText(
1333 ui->peerSyncHeight->setText(
1336 ui->peerSyncHeight->setText(
tr(
"Unknown"));
1341 ui->peerCommonHeight->setText(
1344 ui->peerCommonHeight->setText(
tr(
"Unknown"));
1347 ui->peerHeight->setText(
1349 ui->peerPingWait->setText(
1355 ui->detailWidget->show();
1359 QWidget::resizeEvent(event);
1363 QWidget::showEvent(event);
1374 QWidget::hideEvent(event);
1386 if (index.isValid()) {
1393 if (index.isValid()) {
1402 for (
int i = 0; i < nodes.count(); i++) {
1404 NodeId id = nodes.at(i).data().toLongLong();
1420 for (
int i = 0; i < nodes.count(); i++) {
1422 NodeId id = nodes.at(i).data().toLongLong();
1451 for (
int i = 0; i < nodes.count(); i++) {
1464 ui->peerWidget->selectionModel()->clearSelection();
1480 ui->tabWidget->setCurrentIndex(
int(
tabType));
1484 return ui->tabWidget->tabText(
int(
tab_type));
1503 this->
ui->label_alerts->setVisible(!warnings.isEmpty());
1504 this->
ui->label_alerts->setText(warnings);
std::string BerkeleyDatabaseVersion()
const CChainParams & Params()
Return the currently selected parameters.
Model for Bitcoin network client.
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut)
QString blocksDir() const
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
PeerTableModel * getPeerTableModel()
int getNumConnections(NumConnections flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
void numConnectionsChanged(int count)
QString formatClientStartupTime() const
BanTableModel * getBanTableModel()
void numBlocksChanged(int count, const QDateTime &blockDate, double nVerificationProgress, SyncType header, SynchronizationState sync_state)
void alertsChanged(const QString &warnings)
QString formatFullVersion() const
QString formatSubVersion() const
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes)
void networkActiveChanged(bool networkActive)
interfaces::Node & node() const
static std::vector< std::string > ToStrings(NetPermissionFlags flags)
const CNodeCombinedStats * getNodeStats(int idx)
int getRowByNodeId(NodeId nodeid)
Class for handling RPC timers (used for e.g.
std::function< void()> func
QtRPCTimerBase(std::function< void()> &_func, int64_t millis)
const char * Name() override
Implementation name.
RPCTimerBase * NewTimer(std::function< void()> &func, int64_t millis) override
Factory function for timers.
Local Bitcoin RPC console.
QMenu * peersTableContextMenu
RPCConsole(interfaces::Node &node, const PlatformStyle *platformStyle, QWidget *parent)
void cmdRequest(const QString &command, const WalletModel *wallet_model)
void browseHistory(int offset)
Go forward or back in history.
RPCTimerInterface * rpcTimerInterface
QString TimeDurationField(std::chrono::seconds time_now, std::chrono::seconds time_at_event) const
Helper for the output of a time duration field.
void on_lineEdit_returnPressed()
void message(int category, const QString &msg)
Append the message to the message widget.
void setFontSize(int newSize)
void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut)
update traffic statistics
void setTrafficGraphRange(int mins)
static bool RPCParseCommandLine(interfaces::Node *node, std::string &strResult, const std::string &strCommand, bool fExecute, std::string *const pstrFilteredOut=nullptr, const WalletModel *wallet_model=nullptr)
Split shell command line into a list of arguments and optionally execute the command(s).
const PlatformStyle *const platformStyle
void updateDetailWidget()
show detailed information on ui about selected node
void showEvent(QShowEvent *event) override
void resizeEvent(QResizeEvent *event) override
static bool RPCExecuteCommandLine(interfaces::Node &node, std::string &strResult, const std::string &strCommand, std::string *const pstrFilteredOut=nullptr, const WalletModel *wallet_model=nullptr)
QString tabTitle(TabTypes tab_type) const
void updateNetworkState()
Update UI with latest network info from model.
void disconnectSelectedNode()
Disconnect a selected node on the Peers tab.
@ SUBVERSION_COLUMN_WIDTH
QCompleter * autoCompleter
void setMempoolSize(long numberOfTxs, size_t dynUsage)
Set size (number of transactions and memory usage) of the mempool in the UI.
void clear(bool clearHistory=true)
void hideEvent(QHideEvent *event) override
QKeySequence tabShortcut(TabTypes tab_type) const
void showPeersTableContextMenu(const QPoint &point)
Show custom context menu on Peers tab.
QList< NodeId > cachedNodeids
interfaces::Node & m_node
void unbanSelectedNode()
Unban a selected node on the Bans tab.
void updateAlerts(const QString &warnings)
void clearSelectedNode()
clear the selected node
void on_sldGraphRange_valueChanged(int value)
change the time range of the network traffic graph
void setNumConnections(int count)
Set number of connections shown in the UI.
void setNumBlocks(int count, const QDateTime &blockDate, double nVerificationProgress, SyncType synctype)
Set number of blocks and last block date shown in the UI.
ClientModel * clientModel
void banSelectedNode(int bantime)
Ban a selected node on the Peers tab.
void scrollToEnd()
Scroll console view to end.
void keyPressEvent(QKeyEvent *) override
void on_tabWidget_currentChanged(int index)
void setNetworkActive(bool networkActive)
Set network state shown in the UI.
QString cmdBeforeBrowsing
void addWallet(WalletModel *const walletModel)
virtual bool eventFilter(QObject *obj, QEvent *event) override
void on_openDebugLogfileButton_clicked()
open the debug.log from the current datadir
void removeWallet(WalletModel *const walletModel)
void showBanTableContextMenu(const QPoint &point)
Show custom context menu on Bans tab.
void peerLayoutAboutToChange()
Handle selection caching before update.
void setClientModel(ClientModel *model=nullptr, int bestblock_height=0, int64_t bestblock_date=0, double verification_progress=0.0)
void setTabFocus(enum TabTypes tabType)
set which tab has the focus (is visible)
WalletModel * m_last_wallet_model
void showOrHideBanTableIfRequired()
Hides ban table if no bans are present.
QMenu * banTableContextMenu
void peerLayoutChanged()
Handle updated peer information.
void reply(int category, const QString &command)
RPCExecutor(interfaces::Node &node)
interfaces::Node & m_node
void request(const QString &command, const WalletModel *wallet_model)
Opaque base class for timers returned by NewTimerFunc.
void push_back(UniValue val)
Interface to Bitcoin wallet from Qt view code.
QString getDisplayName() const
static bool isWalletEnabled()
Top-level interface for a bitcoin node (bitcoind process).
virtual void rpcSetTimerInterfaceIfUnset(RPCTimerInterface *iface)=0
Set RPC timer interface if unset.
virtual bool disconnectById(NodeId id)=0
Disconnect node by id.
virtual bool ban(const CNetAddr &net_addr, int64_t ban_time_offset)=0
Ban node.
virtual std::vector< std::string > listRpcCommands()=0
List rpc commands.
virtual void rpcUnsetTimerInterface(RPCTimerInterface *iface)=0
Unset RPC timer interface.
virtual bool getNetworkActive()=0
Get network active.
virtual bool unban(const CSubNet &ip)=0
Unban node.
virtual bool disconnectByAddress(const CNetAddr &net_addr)=0
Disconnect node by address.
UniValue RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
Convert positional arguments to command-specific RPC representation.
const Config & GetConfig()
QString NetworkToQString(Network net)
Convert enum Network to QString.
QString HtmlEscape(const QString &str, bool fMultiLine)
QList< QModelIndex > getEntryData(const QAbstractItemView *view, int column)
Return a field of the currently selected entry as a QString.
QString formatBytes(uint64_t bytes)
QString formatDurationStr(std::chrono::seconds dur)
Convert seconds into a QString with days, hours, mins, secs.
void handleCloseWindowShortcut(QWidget *w)
QString formatPingTime(std::chrono::microseconds ping_time)
Format a CNodeStats.m_last_ping_time into a user-readable string or display N/A, if 0.
QString formatTimeOffset(int64_t nTimeOffset)
Format a CNodeCombinedStats.nTimeOffset into a user-readable string.
QString formatServicesStr(quint64 mask)
Format CNodeStats.nServices bitmask into a user-readable string.
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
bool LookupSubNet(const std::string &strSubnet, CSubNet &ret, DNSLookupFn dns_lookup_function)
Parse and resolve a specified subnet string into the appropriate internal representation.
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
const struct @7 ICON_MAPPING[]
const int INITIAL_TRAFFIC_GRAPH_MINS
const QSize FONT_RANGE(4, 40)
const int CONSOLE_HISTORY
static QString categoryClass(int category)
const char fontSizeSettingsKey[]
int atoi(const std::string &str)
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
CNodeStateStats nodeStateStats
bool fNodeStateStatsAvailable
std::chrono::microseconds m_ping_wait
ServiceFlags their_services
std::chrono::microseconds m_last_ping_time
std::chrono::seconds m_last_recv
std::chrono::seconds m_last_send
std::chrono::seconds m_last_tx_time
std::chrono::microseconds m_min_ping_time
std::chrono::seconds m_connected
bool m_bip152_highbandwidth_from
bool m_bip152_highbandwidth_to
std::chrono::seconds m_last_block_time
NetPermissionFlags m_permissionFlags