5#include <bitcoin-build-config.h>
8#include <qt/forms/ui_debugwindow.h>
10#include <chainparams.h>
32#include <QAbstractButton>
33#include <QAbstractItemModel>
37#include <QKeySequence>
38#include <QLatin1String>
47#include <QStyledItemDelegate>
65 {
"cmd-request",
":/icons/tx_input"},
66 {
"cmd-reply",
":/icons/tx_output"},
67 {
"cmd-error",
":/icons/tx_output"},
68 {
"misc",
":/icons/tx_inout"},
75const QStringList historyFilter = QStringList()
77 <<
"createwalletdescriptor"
79 <<
"signmessagewithprivkey"
80 <<
"signrawtransactionwithkey"
82 <<
"walletpassphrasechange"
110 : QStyledItemDelegate(parent) {}
112 QString
displayText(
const QVariant& value,
const QLocale& locale)
const override
116 return value.toString() + QLatin1String(
" ");
120#include <qt/rpcconsole.moc>
144 std::vector< std::vector<std::string> > stack;
145 stack.emplace_back();
150 STATE_EATING_SPACES_IN_ARG,
151 STATE_EATING_SPACES_IN_BRACKETS,
156 STATE_ESCAPE_DOUBLEQUOTED,
157 STATE_COMMAND_EXECUTED,
158 STATE_COMMAND_EXECUTED_INNER
159 } state = STATE_EATING_SPACES;
162 unsigned nDepthInsideSensitive = 0;
163 size_t filter_begin_pos = 0, chpos;
164 std::vector<std::pair<size_t, size_t>> filter_ranges;
166 auto add_to_current_stack = [&](
const std::string& strArg) {
167 if (stack.back().empty() && (!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(strArg), Qt::CaseInsensitive)) {
168 nDepthInsideSensitive = 1;
169 filter_begin_pos = chpos;
173 stack.emplace_back();
178 auto close_out_params = [&]() {
179 if (nDepthInsideSensitive) {
180 if (!--nDepthInsideSensitive) {
182 filter_ranges.emplace_back(filter_begin_pos, chpos);
183 filter_begin_pos = 0;
189 std::string strCommandTerminated = strCommand;
190 if (strCommandTerminated.back() !=
'\n')
191 strCommandTerminated +=
"\n";
192 for (chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
194 char ch = strCommandTerminated[chpos];
197 case STATE_COMMAND_EXECUTED_INNER:
198 case STATE_COMMAND_EXECUTED:
200 bool breakParsing =
true;
203 case '[': curarg.clear(); state = STATE_COMMAND_EXECUTED_INNER;
break;
205 if (state == STATE_COMMAND_EXECUTED_INNER)
213 if (curarg.size() && fExecute)
219 const auto parsed{ToIntegral<size_t>(curarg)};
221 throw std::runtime_error(
"Invalid result query");
223 subelement = lastResult[parsed.value()];
228 throw std::runtime_error(
"Invalid result query");
229 lastResult = subelement;
232 state = STATE_COMMAND_EXECUTED;
236 breakParsing =
false;
242 if (lastResult.
isStr())
245 curarg = lastResult.
write(2);
251 add_to_current_stack(curarg);
257 state = STATE_EATING_SPACES;
264 case STATE_EATING_SPACES_IN_ARG:
265 case STATE_EATING_SPACES_IN_BRACKETS:
266 case STATE_EATING_SPACES:
269 case '"': state = STATE_DOUBLEQUOTED;
break;
270 case '\'': state = STATE_SINGLEQUOTED;
break;
271 case '\\': state = STATE_ESCAPE_OUTER;
break;
272 case '(':
case ')':
case '\n':
273 if (state == STATE_EATING_SPACES_IN_ARG)
274 throw std::runtime_error(
"Invalid Syntax");
275 if (state == STATE_ARGUMENT)
277 if (ch ==
'(' && stack.size() && stack.back().size() > 0)
279 if (nDepthInsideSensitive) {
280 ++nDepthInsideSensitive;
282 stack.emplace_back();
287 throw std::runtime_error(
"Invalid Syntax");
289 add_to_current_stack(curarg);
291 state = STATE_EATING_SPACES_IN_BRACKETS;
293 if ((ch ==
')' || ch ==
'\n') && stack.size() > 0)
298 UniValue params =
RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end()));
299 std::string method = stack.back()[0];
301 if (!wallet_name.isEmpty()) {
302 QByteArray encodedName = QUrl::toPercentEncoding(wallet_name);
303 uri =
"/wallet/"+std::string(encodedName.constData(), encodedName.length());
306 lastResult =
node->executeRpc(method, params, uri);
309 state = STATE_COMMAND_EXECUTED;
313 case ' ':
case ',':
case '\t':
314 if(state == STATE_EATING_SPACES_IN_ARG && curarg.empty() && ch ==
',')
315 throw std::runtime_error(
"Invalid Syntax");
317 else if(state == STATE_ARGUMENT)
319 add_to_current_stack(curarg);
322 if ((state == STATE_EATING_SPACES_IN_BRACKETS || state == STATE_ARGUMENT) && ch ==
',')
324 state = STATE_EATING_SPACES_IN_ARG;
327 state = STATE_EATING_SPACES;
329 default: curarg += ch; state = STATE_ARGUMENT;
332 case STATE_SINGLEQUOTED:
335 case '\'': state = STATE_ARGUMENT;
break;
336 default: curarg += ch;
339 case STATE_DOUBLEQUOTED:
342 case '"': state = STATE_ARGUMENT;
break;
343 case '\\': state = STATE_ESCAPE_DOUBLEQUOTED;
break;
344 default: curarg += ch;
347 case STATE_ESCAPE_OUTER:
348 curarg += ch; state = STATE_ARGUMENT;
350 case STATE_ESCAPE_DOUBLEQUOTED:
351 if(ch !=
'"' && ch !=
'\\') curarg +=
'\\';
352 curarg += ch; state = STATE_DOUBLEQUOTED;
356 if (pstrFilteredOut) {
357 if (STATE_COMMAND_EXECUTED == state) {
361 *pstrFilteredOut = strCommand;
362 for (
auto i = filter_ranges.rbegin(); i != filter_ranges.rend(); ++i) {
363 pstrFilteredOut->replace(i->first, i->second - i->first,
"(…)");
368 case STATE_COMMAND_EXECUTED:
369 if (lastResult.
isStr())
370 strResult = lastResult.
get_str();
372 strResult = lastResult.
write(2);
375 case STATE_EATING_SPACES:
387 std::string executableCommand =
command.toStdString() +
"\n";
390 if(executableCommand ==
"help-console\n") {
392 "This console accepts RPC commands using the standard syntax.\n"
393 " example: getblockhash 0\n\n"
395 "This console can also accept RPC commands using the parenthesized syntax.\n"
396 " example: getblockhash(0)\n\n"
398 "Commands may be nested when specified with the parenthesized syntax.\n"
399 " example: getblock(getblockhash(0) 1)\n\n"
401 "A space or a comma can be used to delimit arguments for either syntax.\n"
402 " example: getblockhash 0\n"
403 " getblockhash,0\n\n"
405 "Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n"
406 " example: getblock(getblockhash(0) 1)[tx]\n\n"
408 "Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n"
409 " example: getblock(getblockhash(0),1)[tx][0]\n\n")));
427 catch (
const std::runtime_error&)
432 catch (
const std::exception& e)
442 platformStyle(_platformStyle)
449 if (!restoreGeometry(settings.value(
"RPCConsoleWindowGeometry").toByteArray())) {
451 move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
453 ui->splitter->restoreState(settings.value(
"RPCConsoleWindowPeersTabSplitterSizes").toByteArray());
458 ui->splitter->restoreState(settings.value(
"RPCConsoleWidgetPeersTabSplitterSizes").toByteArray());
464 constexpr QChar nonbreaking_hyphen(8209);
467 tr(
"Inbound: initiated by peer"),
471 tr(
"Outbound Full Relay: default"),
474 tr(
"Outbound Block Relay: does not relay transactions or addresses"),
479 tr(
"Outbound Manual: added using RPC %1 or %2/%3 configuration options")
481 .arg(QString(nonbreaking_hyphen) +
"addnode")
482 .arg(QString(nonbreaking_hyphen) +
"connect"),
485 tr(
"Outbound Feeler: short-lived, for testing addresses"),
488 tr(
"Outbound Address Fetch: short-lived, for soliciting addresses"),
491 tr(
"Private broadcast: short-lived, for broadcasting privacy-sensitive transactions")};
492 const QString connection_types_list{
"<ul><li>" +
Join(
CONNECTION_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
493 ui->peerConnectionTypeLabel->setToolTip(
ui->peerConnectionTypeLabel->toolTip().arg(connection_types_list));
496 tr(
"detecting: peer could be v1 or v2"),
498 tr(
"v1: unencrypted, plaintext transport protocol"),
500 tr(
"v2: BIP324 encrypted transport protocol")};
501 const QString transport_types_list{
"<ul><li>" +
Join(
TRANSPORT_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
502 ui->peerTransportTypeLabel->setToolTip(
ui->peerTransportTypeLabel->toolTip().arg(transport_types_list));
503 const QString hb_list{
"<ul><li>\""
504 +
ts.
to +
"\" – " + tr(
"we selected the peer for high bandwidth relay") +
"</li><li>\""
505 +
ts.
from +
"\" – " + tr(
"the peer selected us for high bandwidth relay") +
"</li><li>\""
506 +
ts.
no +
"\" – " + tr(
"no high bandwidth relay selected") +
"</li></ul>"};
507 ui->peerHighBandwidthLabel->setToolTip(
ui->peerHighBandwidthLabel->toolTip().arg(hb_list));
508 ui->dataDir->setToolTip(
ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) +
"datadir"));
509 ui->blocksDir->setToolTip(
ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) +
"blocksdir"));
510 ui->openDebugLogfileButton->setToolTip(
ui->openDebugLogfileButton->toolTip().arg(CLIENT_NAME));
519 ui->fontBiggerButton->setShortcut(tr(
"Ctrl++"));
525 ui->fontSmallerButton->setShortcut(tr(
"Ctrl+-"));
532 ui->lineEdit->installEventFilter(
this);
533 ui->lineEdit->setMaxLength(16_MiB);
534 ui->messagesWidget->installEventFilter(
this);
537 connect(
ui->clearButton, &QAbstractButton::clicked, [
this] { clear(); });
543 ui->WalletSelector->setVisible(
false);
544 ui->WalletSelectorLabel->setVisible(
false);
563 settings.setValue(
"RPCConsoleWindowGeometry", saveGeometry());
564 settings.setValue(
"RPCConsoleWindowPeersTabSplitterSizes",
ui->splitter->saveState());
569 settings.setValue(
"RPCConsoleWidgetPeersTabSplitterSizes",
ui->splitter->saveState());
580 if(event->type() == QEvent::KeyPress)
582 QKeyEvent *keyevt =
static_cast<QKeyEvent*
>(event);
583 int key = keyevt->key();
584 Qt::KeyboardModifiers mod = keyevt->modifiers();
587 case Qt::Key_Up:
if(obj ==
ui->lineEdit) {
browseHistory(-1);
return true; }
break;
588 case Qt::Key_Down:
if(obj ==
ui->lineEdit) {
browseHistory(1);
return true; }
break;
590 case Qt::Key_PageDown:
591 if (obj ==
ui->lineEdit) {
592 QApplication::sendEvent(
ui->messagesWidget, keyevt);
600 QApplication::sendEvent(
ui->lineEdit, keyevt);
608 if(obj ==
ui->messagesWidget && (
609 (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) ||
610 ((mod & Qt::ControlModifier) && key == Qt::Key_V) ||
611 ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert)))
613 ui->lineEdit->setFocus();
614 QApplication::sendEvent(
ui->lineEdit, keyevt);
619 return QWidget::eventFilter(obj, event);
626 bool wallet_enabled{
false};
630 if (model && !wallet_enabled) {
636 ui->trafficGraph->setClientModel(model);
656 ui->peerWidget->verticalHeader()->hide();
657 ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
658 ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
659 ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
666 ui->peerWidget->horizontalHeader()->setSectionResizeMode(
PeerTableModel::Age, QHeaderView::ResizeToContents);
667 ui->peerWidget->horizontalHeader()->setStretchLastSection(
true);
686 connect(model->
getPeerTableModel(), &QAbstractItemModel::dataChanged, [
this] { updateDetailWidget(); });
690 ui->banlistWidget->verticalHeader()->hide();
691 ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
692 ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
693 ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
700 ui->banlistWidget->horizontalHeader()->setStretchLastSection(
true);
726 ui->networkName->setText(QString::fromStdString(
Params().GetChainTypeString()));
729 QStringList wordList;
731 for (
size_t i = 0; i < commandList.size(); ++i)
733 wordList << commandList[i].c_str();
734 wordList << (
"help " + commandList[i]).c_str();
737 wordList <<
"help-console";
740 autoCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel);
743 ui->lineEdit->setEnabled(
true);
757void RPCConsole::addWallet(
WalletModel *
const walletModel)
760 ui->WalletSelector->addItem(walletModel->
getDisplayName(), QVariant::fromValue(walletModel));
761 if (
ui->WalletSelector->count() == 2) {
763 ui->WalletSelector->setCurrentIndex(1);
765 if (
ui->WalletSelector->count() > 2) {
766 ui->WalletSelector->setVisible(
true);
767 ui->WalletSelectorLabel->setVisible(
true);
771void RPCConsole::removeWallet(
WalletModel *
const walletModel)
773 ui->WalletSelector->removeItem(
ui->WalletSelector->findData(QVariant::fromValue(walletModel)));
774 if (
ui->WalletSelector->count() == 2) {
775 ui->WalletSelector->setVisible(
false);
776 ui->WalletSelectorLabel->setVisible(
false);
780void RPCConsole::setCurrentWallet(
WalletModel*
const wallet_model)
782 QVariant
data = QVariant::fromValue(wallet_model);
783 ui->WalletSelector->setCurrentIndex(
ui->WalletSelector->findData(
data));
794 default:
return "misc";
817 QString str =
ui->messagesWidget->toHtml();
820 str.replace(QString(
"font-size:%1pt").arg(
consoleFontSize), QString(
"font-size:%1pt").arg(newSize));
827 float oldPosFactor = 1.0 /
ui->messagesWidget->verticalScrollBar()->maximum() *
ui->messagesWidget->verticalScrollBar()->value();
829 ui->messagesWidget->setHtml(str);
830 ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor *
ui->messagesWidget->verticalScrollBar()->maximum());
835 ui->messagesWidget->clear();
836 if (!keep_prompt)
ui->lineEdit->clear();
837 ui->lineEdit->setFocus();
843 ui->messagesWidget->document()->addResource(
844 QTextDocument::ImageResource,
855 ui->messagesWidget->document()->setDefaultStyleSheet(
858 "td.time { color: #808080; font-size: %2; padding-top: 3px; } "
859 "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } "
860 "td.cmd-request { color: #006060; } "
861 "td.cmd-error { color: red; } "
862 ".secwarning { color: red; }"
863 "b { color: #006060; } "
867 static const QString welcome_message =
871 tr(
"Welcome to the %1 RPC console.\n"
872 "Use up and down arrows to navigate history, and %2 to clear screen.\n"
873 "Use %3 and %4 to increase or decrease the font size.\n"
874 "Type %5 for an overview of available commands.\n"
875 "For more information on using this console, type %6.\n"
877 "%7WARNING: Scammers have been active, telling users to type"
878 " commands here, stealing their wallet contents. Do not use this console"
879 " without fully understanding the ramifications of a command.%8")
881 "<b>" +
ui->clearButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
882 "<b>" +
ui->fontBiggerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
883 "<b>" +
ui->fontSmallerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
885 "<b>help-console</b>",
886 "<span class=\"secwarning\">",
901 if (e->type() == QEvent::PaletteChange) {
908 ui->messagesWidget->document()->addResource(
909 QTextDocument::ImageResource,
915 QWidget::changeEvent(e);
920 QTime time = QTime::currentTime();
921 QString timeString = time.toString();
923 out +=
"<table><tr><td class=\"time\" width=\"65\">" + timeString +
"</td>";
924 out +=
"<td class=\"icon\" width=\"32\"><img src=\"" +
categoryClass(category) +
"\"></td>";
925 out +=
"<td class=\"message " +
categoryClass(category) +
"\" valign=\"middle\">";
930 out +=
"</td></tr></table>";
931 ui->messagesWidget->append(
out);
942 connections +=
" (" + tr(
"Network activity disabled") +
")";
945 ui->numberOfConnections->setText(connections);
947 QString local_addresses;
949 for (
const auto& [addr, info] : hosts) {
950 local_addresses += QString::fromStdString(addr.ToStringAddr());
951 if (!addr.IsI2P()) local_addresses +=
":" + QString::number(info.nPort);
952 local_addresses +=
", ";
954 local_addresses.chop(2);
955 if (local_addresses.isEmpty()) local_addresses = tr(
"None");
957 ui->localAddresses->setText(local_addresses);
976 ui->numberOfBlocks->setText(QString::number(
count));
977 ui->lastBlockTime->setText(blockDate.toString());
983 ui->mempoolNumberTxs->setText(QString::number(numberOfTxs));
985 const auto cur_usage_str = dynUsage < 1000000 ?
986 QObject::tr(
"%1 kB").arg(dynUsage / 1000.0, 0,
'f', 2) :
987 QObject::tr(
"%1 MB").arg(dynUsage / 1000000.0, 0,
'f', 2);
988 const auto max_usage_str = QObject::tr(
"%1 MB").arg(maxUsage / 1000000.0, 0,
'f', 2);
990 ui->mempoolSize->setText(cur_usage_str +
" / " + max_usage_str);
995 QString
cmd =
ui->lineEdit->text().trimmed();
1001 std::string strFilteredCmd;
1006 throw std::runtime_error(
"Invalid command line");
1008 }
catch (
const std::exception& e) {
1009 QMessageBox::critical(
this,
"Error", QString(
"Error: ") + QString::fromStdString(e.what()));
1014 if (
cmd == QLatin1String(
"stop")) {
1024 ui->lineEdit->clear();
1026 QString in_use_wallet_name;
1029 in_use_wallet_name = wallet_model ? wallet_model->
getWalletName() : QString();
1045 QMetaObject::invokeMethod(
m_executor, [
this,
cmd, in_use_wallet_name] {
1049 cmd = QString::fromStdString(strFilteredCmd);
1084 ui->lineEdit->setText(
cmd);
1095 ui->messagesWidget->undo();
1102 connect(&
thread, &QThread::finished,
m_executor, &RPCExecutor::deleteLater);
1114 if (
ui->tabWidget->widget(index) ==
ui->tab_console) {
1115 ui->lineEdit->setFocus();
1126 QScrollBar *scrollbar =
ui->messagesWidget->verticalScrollBar();
1127 scrollbar->setValue(scrollbar->maximum());
1132 const int multiplier = 5;
1133 int mins = value * multiplier;
1139 ui->trafficGraph->setGraphRange(std::chrono::minutes{mins});
1153 ui->peersTabRightPanel->hide();
1154 ui->peerHeading->setText(tr(
"Select a peer to view detailed information."));
1159 QString peerAddrDetails(QString::fromStdString(stats->nodeStats.m_addr_name) +
" ");
1160 peerAddrDetails += tr(
"(peer: %1)").arg(QString::number(stats->nodeStats.nodeid));
1161 if (!stats->nodeStats.addrLocal.empty())
1162 peerAddrDetails +=
"<br />" + tr(
"via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
1163 ui->peerHeading->setText(peerAddrDetails);
1164 QString bip152_hb_settings;
1165 if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings =
ts.
to;
1166 if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings.isEmpty() ?
ts.
from : QLatin1Char(
'/') +
ts.
from);
1167 if (bip152_hb_settings.isEmpty()) bip152_hb_settings =
ts.
no;
1168 ui->peerHighBandwidth->setText(bip152_hb_settings);
1170 const auto time_now{GetTime<std::chrono::seconds>()};
1172 ui->peerLastBlock->setText(
TimeDurationField(time_now, stats->nodeStats.m_last_block_time));
1180 ui->peerVersion->setText(stats->nodeStats.nVersion ? QString::number(stats->nodeStats.nVersion) :
ts.
na);
1181 ui->peerSubversion->setText(!stats->nodeStats.cleanSubVer.empty() ? QString::fromStdString(stats->nodeStats.cleanSubVer) :
ts.
na);
1183 ui->peerTransportType->setText(QString::fromStdString(
TransportTypeAsString(stats->nodeStats.m_transport_type)));
1185 ui->peerSessionIdLabel->setVisible(
true);
1186 ui->peerSessionId->setVisible(
true);
1187 ui->peerSessionId->setText(QString::fromStdString(stats->nodeStats.m_session_id));
1189 ui->peerSessionIdLabel->setVisible(
false);
1190 ui->peerSessionId->setVisible(
false);
1194 ui->peerPermissions->setText(
ts.
na);
1196 QStringList permissions;
1198 permissions.append(QString::fromStdString(permission));
1200 ui->peerPermissions->setText(permissions.join(
" & "));
1202 ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) :
ts.
na);
1206 if (stats->fNodeStateStatsAvailable) {
1210 if (stats->nodeStateStats.nSyncHeight > -1) {
1211 ui->peerSyncHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nSyncHeight));
1216 if (stats->nodeStateStats.nCommonHeight > -1) {
1217 ui->peerCommonHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nCommonHeight));
1222 ui->peerAddrRelayEnabled->setText(stats->nodeStateStats.m_addr_relay_enabled ?
ts.
yes :
ts.
no);
1223 ui->peerAddrProcessed->setText(QString::number(stats->nodeStateStats.m_addr_processed));
1224 ui->peerAddrRateLimited->setText(QString::number(stats->nodeStateStats.m_addr_rate_limited));
1225 ui->peerRelayTxes->setText(stats->nodeStateStats.m_relay_txs ?
ts.
yes :
ts.
no);
1229 ui->peersTabRightPanel->show();
1234 QWidget::resizeEvent(event);
1239 QWidget::showEvent(event);
1255 QWidget::hideEvent(event);
1266 QModelIndex index =
ui->peerWidget->indexAt(point);
1267 if (index.isValid())
1273 QModelIndex index =
ui->banlistWidget->indexAt(point);
1274 if (index.isValid())
1282 for(
int i = 0; i < nodes.count(); i++)
1285 NodeId id = nodes.at(i).data().toLongLong();
1301 m_node.
ban(stats->nodeStats.addr, bantime);
1317 bool unbanned{
false};
1318 for (
const auto& node_index : nodes) {
1319 unbanned |= ban_table_model->
unban(node_index);
1322 ban_table_model->refresh();
1328 ui->peerWidget->selectionModel()->clearSelection();
1339 ui->banlistWidget->setVisible(visible);
1340 ui->banHeading->setVisible(visible);
1345 ui->tabWidget->setCurrentIndex(
int(tabType));
1350 return ui->tabWidget->tabText(
int(tab_type));
1367 this->
ui->label_alerts->setVisible(!warnings.isEmpty());
1368 this->
ui->label_alerts->setText(warnings);
1376 const QString chainType = QString::fromStdString(
Params().GetChainTypeString());
1377 const QString title = tr(
"Node window - [%1]").arg(chainType);
1378 this->setWindowTitle(title);
const CChainParams & Params()
Return the currently selected parameters.
Qt model providing information about banned peers, similar to the "getpeerinfo" RPC call.
bool unban(const QModelIndex &index)
ChainType GetChainType() const
Return the chain type.
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.
std::map< CNetAddr, LocalServiceInfo > getNetLocalAddresses() const
PeerTableModel * getPeerTableModel()
PeerTableSortProxy * peerTableSortProxy()
void numConnectionsChanged(int count)
QString formatClientStartupTime() const
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
BanTableModel * getBanTableModel()
void numBlocksChanged(int count, const QDateTime &blockDate, double nVerificationProgress, SyncType header, SynchronizationState sync_state)
void alertsChanged(const QString &warnings)
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes, size_t mempoolMaxSizeInBytes)
QString formatFullVersion() const
QString formatSubVersion() const
void networkActiveChanged(bool networkActive)
interfaces::Node & node() const
static std::vector< std::string > ToStrings(NetPermissionFlags flags)
QString displayText(const QVariant &value, const QLocale &locale) const override
PeerIdViewDelegate(QObject *parent=nullptr)
Local Bitcoin RPC console.
static bool RPCExecuteCommandLine(interfaces::Node &node, std::string &strResult, const std::string &strCommand, std::string *const pstrFilteredOut=nullptr, const QString &wallet_name={})
QMenu * peersTableContextMenu
RPCConsole(interfaces::Node &node, const PlatformStyle *platformStyle, QWidget *parent)
struct RPCConsole::TranslatedStrings ts
void browseHistory(int offset)
Go forward or back in history.
QByteArray m_banlist_widget_header_state
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)
const PlatformStyle *const platformStyle
void setMempoolSize(long numberOfTxs, size_t dynUsage, size_t maxUsage)
Set size (number of transactions and memory usage) of the mempool in the UI.
void updateDetailWidget()
show detailed information on ui about selected node
void showEvent(QShowEvent *event) override
void resizeEvent(QResizeEvent *event) override
QString tabTitle(TabTypes tab_type) const
void updateNetworkState()
Update UI with latest network info from model.
void clear(bool keep_prompt=false)
void disconnectSelectedNode()
Disconnect a selected node on the Peers tab.
QString TimeDurationField(NodeClock::time_point now, NodeClock::time_point event) const
Format the duration between now and event as a string.
@ SUBVERSION_COLUMN_WIDTH
QCompleter * autoCompleter
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
virtual bool eventFilter(QObject *obj, QEvent *event) override
void on_openDebugLogfileButton_clicked()
open the debug.log from the current datadir
void showBanTableContextMenu(const QPoint &point)
Show custom context menu on Bans tab.
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)
QByteArray m_peer_widget_header_state
void changeEvent(QEvent *e) override
WalletModel * m_last_wallet_model
void showOrHideBanTableIfRequired()
Hides ban table if no bans are present.
QMenu * banTableContextMenu
static bool RPCParseCommandLine(interfaces::Node *node, std::string &strResult, const std::string &strCommand, bool fExecute, std::string *pstrFilteredOut=nullptr, const QString &wallet_name={})
Split shell command line into a list of arguments and optionally execute the command(s).
void reply(int category, const QString &command)
RPCExecutor(interfaces::Node &node)
interfaces::Node & m_node
void request(const QString &command, const QString &wallet_name)
void push_back(UniValue val)
const std::string & get_str() const
const UniValue & find_value(std::string_view key) const
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
Interface to Bitcoin wallet from Qt view code.
QString getDisplayName() const
static bool isWalletEnabled()
QString getWalletName() const
Top-level interface for a bitcoin node (bitcoind process).
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 bool getNetworkActive()=0
Get network active.
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 command lines arguments to params object when -named is disabled.
std::string TransportTypeAsString(TransportProtocolType transport_type)
Convert TransportProtocolType enum to a string value.
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.
QFont fixedPitchFont(bool use_embedded_font)
QString formatPingTime(NodeClock::duration ping_time)
Format a CNodeStats.m_last_ping_time/m_min_ping_time/m_ping_wait into a user-readable string if it ex...
QString formatBytes(uint64_t bytes)
void AddButtonShortcut(QAbstractButton *button, const QKeySequence &shortcut)
Connects an additional shortcut to a QAbstractButton.
void handleCloseWindowShortcut(QWidget *w)
QString formatDurationStr(std::chrono::nanoseconds dur)
Convert a duration into a QString with days, hours, mins, secs. This ignores sub-seconds.
void copyEntryData(const QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard.
QString ConnectionTypeToQString(ConnectionType conn_type, bool prepend_direction)
Convert enum ConnectionType to QString.
QString formatServicesStr(quint64 mask)
Format CNodeStats.nServices bitmask into a user-readable string.
QString formatTimeOffset(int64_t time_offset)
Format a CNodeStateStats.time_offset into a user-readable string.
bool IsEscapeOrBack(int key)
void ThreadRename(const std::string &)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
const std::vector< std::string > CONNECTION_TYPE_DOC
const std::vector< std::string > TRANSPORT_TYPE_DOC
const int INITIAL_TRAFFIC_GRAPH_MINS
const struct @8 ICON_MAPPING[]
const QSize FONT_RANGE(4, 40)
const int CONSOLE_HISTORY
static QString categoryClass(int category)
const char fontSizeSettingsKey[]
static time_point now() noexcept
Return current system time or mocked time, if set.