5#include <bitcoin-build-config.h>
8#include <qt/forms/ui_debugwindow.h>
10#include <chainparams.h>
31#include <QAbstractButton>
32#include <QAbstractItemModel>
36#include <QKeySequence>
37#include <QLatin1String>
46#include <QStyledItemDelegate>
64 {
"cmd-request",
":/icons/tx_input"},
65 {
"cmd-reply",
":/icons/tx_output"},
66 {
"cmd-error",
":/icons/tx_output"},
67 {
"misc",
":/icons/tx_inout"},
74const QStringList historyFilter = QStringList()
78 <<
"signmessagewithprivkey"
79 <<
"signrawtransactionwithkey"
81 <<
"walletpassphrasechange"
114 timer.setSingleShot(
true);
115 connect(&
timer, &QTimer::timeout, [
this]{
func(); });
128 const char *
Name()
override {
return "Qt"; }
140 : QStyledItemDelegate(parent) {}
142 QString
displayText(
const QVariant& value,
const QLocale& locale)
const override
146 return value.toString() + QLatin1String(
" ");
150#include <qt/rpcconsole.moc>
174 std::vector< std::vector<std::string> > stack;
175 stack.emplace_back();
180 STATE_EATING_SPACES_IN_ARG,
181 STATE_EATING_SPACES_IN_BRACKETS,
186 STATE_ESCAPE_DOUBLEQUOTED,
187 STATE_COMMAND_EXECUTED,
188 STATE_COMMAND_EXECUTED_INNER
189 } state = STATE_EATING_SPACES;
192 unsigned nDepthInsideSensitive = 0;
193 size_t filter_begin_pos = 0, chpos;
194 std::vector<std::pair<size_t, size_t>> filter_ranges;
196 auto add_to_current_stack = [&](
const std::string& strArg) {
197 if (stack.back().empty() && (!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(strArg), Qt::CaseInsensitive)) {
198 nDepthInsideSensitive = 1;
199 filter_begin_pos = chpos;
203 stack.emplace_back();
208 auto close_out_params = [&]() {
209 if (nDepthInsideSensitive) {
210 if (!--nDepthInsideSensitive) {
212 filter_ranges.emplace_back(filter_begin_pos, chpos);
213 filter_begin_pos = 0;
219 std::string strCommandTerminated = strCommand;
220 if (strCommandTerminated.back() !=
'\n')
221 strCommandTerminated +=
"\n";
222 for (chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
224 char ch = strCommandTerminated[chpos];
227 case STATE_COMMAND_EXECUTED_INNER:
228 case STATE_COMMAND_EXECUTED:
230 bool breakParsing =
true;
233 case '[': curarg.clear(); state = STATE_COMMAND_EXECUTED_INNER;
break;
235 if (state == STATE_COMMAND_EXECUTED_INNER)
243 if (curarg.size() && fExecute)
249 const auto parsed{ToIntegral<size_t>(curarg)};
251 throw std::runtime_error(
"Invalid result query");
253 subelement = lastResult[parsed.value()];
258 throw std::runtime_error(
"Invalid result query");
259 lastResult = subelement;
262 state = STATE_COMMAND_EXECUTED;
266 breakParsing =
false;
272 if (lastResult.
isStr())
275 curarg = lastResult.
write(2);
281 add_to_current_stack(curarg);
287 state = STATE_EATING_SPACES;
294 case STATE_EATING_SPACES_IN_ARG:
295 case STATE_EATING_SPACES_IN_BRACKETS:
296 case STATE_EATING_SPACES:
299 case '"': state = STATE_DOUBLEQUOTED;
break;
300 case '\'': state = STATE_SINGLEQUOTED;
break;
301 case '\\': state = STATE_ESCAPE_OUTER;
break;
302 case '(':
case ')':
case '\n':
303 if (state == STATE_EATING_SPACES_IN_ARG)
304 throw std::runtime_error(
"Invalid Syntax");
305 if (state == STATE_ARGUMENT)
307 if (ch ==
'(' && stack.size() && stack.back().size() > 0)
309 if (nDepthInsideSensitive) {
310 ++nDepthInsideSensitive;
312 stack.emplace_back();
317 throw std::runtime_error(
"Invalid Syntax");
319 add_to_current_stack(curarg);
321 state = STATE_EATING_SPACES_IN_BRACKETS;
323 if ((ch ==
')' || ch ==
'\n') && stack.size() > 0)
328 UniValue params =
RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end()));
329 std::string method = stack.back()[0];
333 QByteArray encodedName = QUrl::toPercentEncoding(wallet_model->
getWalletName());
334 uri =
"/wallet/"+std::string(encodedName.constData(), encodedName.length());
338 lastResult =
node->executeRpc(method, params, uri);
341 state = STATE_COMMAND_EXECUTED;
345 case ' ':
case ',':
case '\t':
346 if(state == STATE_EATING_SPACES_IN_ARG && curarg.empty() && ch ==
',')
347 throw std::runtime_error(
"Invalid Syntax");
349 else if(state == STATE_ARGUMENT)
351 add_to_current_stack(curarg);
354 if ((state == STATE_EATING_SPACES_IN_BRACKETS || state == STATE_ARGUMENT) && ch ==
',')
356 state = STATE_EATING_SPACES_IN_ARG;
359 state = STATE_EATING_SPACES;
361 default: curarg += ch; state = STATE_ARGUMENT;
364 case STATE_SINGLEQUOTED:
367 case '\'': state = STATE_ARGUMENT;
break;
368 default: curarg += ch;
371 case STATE_DOUBLEQUOTED:
374 case '"': state = STATE_ARGUMENT;
break;
375 case '\\': state = STATE_ESCAPE_DOUBLEQUOTED;
break;
376 default: curarg += ch;
379 case STATE_ESCAPE_OUTER:
380 curarg += ch; state = STATE_ARGUMENT;
382 case STATE_ESCAPE_DOUBLEQUOTED:
383 if(ch !=
'"' && ch !=
'\\') curarg +=
'\\';
384 curarg += ch; state = STATE_DOUBLEQUOTED;
388 if (pstrFilteredOut) {
389 if (STATE_COMMAND_EXECUTED == state) {
393 *pstrFilteredOut = strCommand;
394 for (
auto i = filter_ranges.rbegin(); i != filter_ranges.rend(); ++i) {
395 pstrFilteredOut->replace(i->first, i->second - i->first,
"(…)");
400 case STATE_COMMAND_EXECUTED:
401 if (lastResult.
isStr())
402 strResult = lastResult.
get_str();
404 strResult = lastResult.
write(2);
407 case STATE_EATING_SPACES:
419 std::string executableCommand =
command.toStdString() +
"\n";
422 if(executableCommand ==
"help-console\n") {
424 "This console accepts RPC commands using the standard syntax.\n"
425 " example: getblockhash 0\n\n"
427 "This console can also accept RPC commands using the parenthesized syntax.\n"
428 " example: getblockhash(0)\n\n"
430 "Commands may be nested when specified with the parenthesized syntax.\n"
431 " example: getblock(getblockhash(0) 1)\n\n"
433 "A space or a comma can be used to delimit arguments for either syntax.\n"
434 " example: getblockhash 0\n"
435 " getblockhash,0\n\n"
437 "Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n"
438 " example: getblock(getblockhash(0) 1)[tx]\n\n"
440 "Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n"
441 " example: getblock(getblockhash(0),1)[tx][0]\n\n")));
459 catch (
const std::runtime_error&)
464 catch (
const std::exception& e)
474 platformStyle(_platformStyle)
481 if (!restoreGeometry(settings.value(
"RPCConsoleWindowGeometry").toByteArray())) {
483 move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
485 ui->splitter->restoreState(settings.value(
"RPCConsoleWindowPeersTabSplitterSizes").toByteArray());
490 ui->splitter->restoreState(settings.value(
"RPCConsoleWidgetPeersTabSplitterSizes").toByteArray());
496 constexpr QChar nonbreaking_hyphen(8209);
499 tr(
"Inbound: initiated by peer"),
503 tr(
"Outbound Full Relay: default"),
506 tr(
"Outbound Block Relay: does not relay transactions or addresses"),
511 tr(
"Outbound Manual: added using RPC %1 or %2/%3 configuration options")
513 .arg(QString(nonbreaking_hyphen) +
"addnode")
514 .arg(QString(nonbreaking_hyphen) +
"connect"),
517 tr(
"Outbound Feeler: short-lived, for testing addresses"),
520 tr(
"Outbound Address Fetch: short-lived, for soliciting addresses")};
521 const QString connection_types_list{
"<ul><li>" +
Join(
CONNECTION_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
522 ui->peerConnectionTypeLabel->setToolTip(
ui->peerConnectionTypeLabel->toolTip().arg(connection_types_list));
525 tr(
"detecting: peer could be v1 or v2"),
527 tr(
"v1: unencrypted, plaintext transport protocol"),
529 tr(
"v2: BIP324 encrypted transport protocol")};
530 const QString transport_types_list{
"<ul><li>" +
Join(
TRANSPORT_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
531 ui->peerTransportTypeLabel->setToolTip(
ui->peerTransportTypeLabel->toolTip().arg(transport_types_list));
532 const QString hb_list{
"<ul><li>\""
533 +
ts.
to +
"\" – " + tr(
"we selected the peer for high bandwidth relay") +
"</li><li>\""
534 +
ts.
from +
"\" – " + tr(
"the peer selected us for high bandwidth relay") +
"</li><li>\""
535 +
ts.
no +
"\" – " + tr(
"no high bandwidth relay selected") +
"</li></ul>"};
536 ui->peerHighBandwidthLabel->setToolTip(
ui->peerHighBandwidthLabel->toolTip().arg(hb_list));
537 ui->dataDir->setToolTip(
ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) +
"datadir"));
538 ui->blocksDir->setToolTip(
ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) +
"blocksdir"));
539 ui->openDebugLogfileButton->setToolTip(
ui->openDebugLogfileButton->toolTip().arg(CLIENT_NAME));
548 ui->fontBiggerButton->setShortcut(tr(
"Ctrl++"));
554 ui->fontSmallerButton->setShortcut(tr(
"Ctrl+-"));
561 ui->lineEdit->installEventFilter(
this);
562 ui->lineEdit->setMaxLength(16 * 1024 * 1024);
563 ui->messagesWidget->installEventFilter(
this);
566 connect(
ui->clearButton, &QAbstractButton::clicked, [
this] { clear(); });
572 ui->WalletSelector->setVisible(
false);
573 ui->WalletSelectorLabel->setVisible(
false);
598 settings.setValue(
"RPCConsoleWindowGeometry", saveGeometry());
599 settings.setValue(
"RPCConsoleWindowPeersTabSplitterSizes",
ui->splitter->saveState());
604 settings.setValue(
"RPCConsoleWidgetPeersTabSplitterSizes",
ui->splitter->saveState());
617 if(event->type() == QEvent::KeyPress)
619 QKeyEvent *keyevt =
static_cast<QKeyEvent*
>(event);
620 int key = keyevt->key();
621 Qt::KeyboardModifiers mod = keyevt->modifiers();
624 case Qt::Key_Up:
if(obj ==
ui->lineEdit) {
browseHistory(-1);
return true; }
break;
625 case Qt::Key_Down:
if(obj ==
ui->lineEdit) {
browseHistory(1);
return true; }
break;
627 case Qt::Key_PageDown:
628 if (obj ==
ui->lineEdit) {
629 QApplication::sendEvent(
ui->messagesWidget, keyevt);
637 QApplication::sendEvent(
ui->lineEdit, keyevt);
645 if(obj ==
ui->messagesWidget && (
646 (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) ||
647 ((mod & Qt::ControlModifier) && key == Qt::Key_V) ||
648 ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert)))
650 ui->lineEdit->setFocus();
651 QApplication::sendEvent(
ui->lineEdit, keyevt);
656 return QWidget::eventFilter(obj, event);
663 bool wallet_enabled{
false};
667 if (model && !wallet_enabled) {
673 ui->trafficGraph->setClientModel(model);
693 ui->peerWidget->verticalHeader()->hide();
694 ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
695 ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
696 ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
703 ui->peerWidget->horizontalHeader()->setSectionResizeMode(
PeerTableModel::Age, QHeaderView::ResizeToContents);
704 ui->peerWidget->horizontalHeader()->setStretchLastSection(
true);
723 connect(model->
getPeerTableModel(), &QAbstractItemModel::dataChanged, [
this] { updateDetailWidget(); });
727 ui->banlistWidget->verticalHeader()->hide();
728 ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
729 ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
730 ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
737 ui->banlistWidget->horizontalHeader()->setStretchLastSection(
true);
763 ui->networkName->setText(QString::fromStdString(
Params().GetChainTypeString()));
766 QStringList wordList;
768 for (
size_t i = 0; i < commandList.size(); ++i)
770 wordList << commandList[i].c_str();
771 wordList << (
"help " + commandList[i]).c_str();
774 wordList <<
"help-console";
777 autoCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel);
780 ui->lineEdit->setEnabled(
true);
794void RPCConsole::addWallet(
WalletModel *
const walletModel)
797 ui->WalletSelector->addItem(walletModel->
getDisplayName(), QVariant::fromValue(walletModel));
798 if (
ui->WalletSelector->count() == 2) {
800 ui->WalletSelector->setCurrentIndex(1);
802 if (
ui->WalletSelector->count() > 2) {
803 ui->WalletSelector->setVisible(
true);
804 ui->WalletSelectorLabel->setVisible(
true);
808void RPCConsole::removeWallet(
WalletModel *
const walletModel)
810 ui->WalletSelector->removeItem(
ui->WalletSelector->findData(QVariant::fromValue(walletModel)));
811 if (
ui->WalletSelector->count() == 2) {
812 ui->WalletSelector->setVisible(
false);
813 ui->WalletSelectorLabel->setVisible(
false);
817void RPCConsole::setCurrentWallet(
WalletModel*
const wallet_model)
819 QVariant
data = QVariant::fromValue(wallet_model);
820 ui->WalletSelector->setCurrentIndex(
ui->WalletSelector->findData(
data));
831 default:
return "misc";
854 QString str =
ui->messagesWidget->toHtml();
857 str.replace(QString(
"font-size:%1pt").arg(
consoleFontSize), QString(
"font-size:%1pt").arg(newSize));
864 float oldPosFactor = 1.0 /
ui->messagesWidget->verticalScrollBar()->maximum() *
ui->messagesWidget->verticalScrollBar()->value();
866 ui->messagesWidget->setHtml(str);
867 ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor *
ui->messagesWidget->verticalScrollBar()->maximum());
872 ui->messagesWidget->clear();
873 if (!keep_prompt)
ui->lineEdit->clear();
874 ui->lineEdit->setFocus();
880 ui->messagesWidget->document()->addResource(
881 QTextDocument::ImageResource,
892 ui->messagesWidget->document()->setDefaultStyleSheet(
895 "td.time { color: #808080; font-size: %2; padding-top: 3px; } "
896 "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } "
897 "td.cmd-request { color: #006060; } "
898 "td.cmd-error { color: red; } "
899 ".secwarning { color: red; }"
900 "b { color: #006060; } "
904 static const QString welcome_message =
908 tr(
"Welcome to the %1 RPC console.\n"
909 "Use up and down arrows to navigate history, and %2 to clear screen.\n"
910 "Use %3 and %4 to increase or decrease the font size.\n"
911 "Type %5 for an overview of available commands.\n"
912 "For more information on using this console, type %6.\n"
914 "%7WARNING: Scammers have been active, telling users to type"
915 " commands here, stealing their wallet contents. Do not use this console"
916 " without fully understanding the ramifications of a command.%8")
918 "<b>" +
ui->clearButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
919 "<b>" +
ui->fontBiggerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
920 "<b>" +
ui->fontSmallerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
922 "<b>help-console</b>",
923 "<span class=\"secwarning\">",
938 if (e->type() == QEvent::PaletteChange) {
945 ui->messagesWidget->document()->addResource(
946 QTextDocument::ImageResource,
952 QWidget::changeEvent(e);
957 QTime time = QTime::currentTime();
958 QString timeString = time.toString();
960 out +=
"<table><tr><td class=\"time\" width=\"65\">" + timeString +
"</td>";
961 out +=
"<td class=\"icon\" width=\"32\"><img src=\"" +
categoryClass(category) +
"\"></td>";
962 out +=
"<td class=\"message " +
categoryClass(category) +
"\" valign=\"middle\">";
967 out +=
"</td></tr></table>";
968 ui->messagesWidget->append(
out);
979 connections +=
" (" + tr(
"Network activity disabled") +
")";
982 ui->numberOfConnections->setText(connections);
984 QString local_addresses;
986 for (
const auto& [addr, info] : hosts) {
987 local_addresses += QString::fromStdString(addr.ToStringAddr());
988 if (!addr.IsI2P()) local_addresses +=
":" + QString::number(info.nPort);
989 local_addresses +=
", ";
991 local_addresses.chop(2);
992 if (local_addresses.isEmpty()) local_addresses = tr(
"None");
994 ui->localAddresses->setText(local_addresses);
1013 ui->numberOfBlocks->setText(QString::number(
count));
1014 ui->lastBlockTime->setText(blockDate.toString());
1020 ui->mempoolNumberTxs->setText(QString::number(numberOfTxs));
1022 const auto cur_usage_str = dynUsage < 1000000 ?
1023 QObject::tr(
"%1 kB").arg(dynUsage / 1000.0, 0,
'f', 2) :
1024 QObject::tr(
"%1 MB").arg(dynUsage / 1000000.0, 0,
'f', 2);
1025 const auto max_usage_str = QObject::tr(
"%1 MB").arg(maxUsage / 1000000.0, 0,
'f', 2);
1027 ui->mempoolSize->setText(cur_usage_str +
" / " + max_usage_str);
1032 QString
cmd =
ui->lineEdit->text().trimmed();
1034 if (
cmd.isEmpty()) {
1038 std::string strFilteredCmd;
1043 throw std::runtime_error(
"Invalid command line");
1045 }
catch (
const std::exception& e) {
1046 QMessageBox::critical(
this,
"Error", QString(
"Error: ") + QString::fromStdString(e.what()));
1051 if (
cmd == QLatin1String(
"stop")) {
1061 ui->lineEdit->clear();
1065 wallet_model =
ui->WalletSelector->currentData().value<
WalletModel*>();
1082 QMetaObject::invokeMethod(
m_executor, [
this,
cmd, wallet_model] {
1086 cmd = QString::fromStdString(strFilteredCmd);
1121 ui->lineEdit->setText(
cmd);
1132 ui->messagesWidget->undo();
1139 connect(&
thread, &QThread::finished,
m_executor, &RPCExecutor::deleteLater);
1151 if (
ui->tabWidget->widget(index) ==
ui->tab_console) {
1152 ui->lineEdit->setFocus();
1163 QScrollBar *scrollbar =
ui->messagesWidget->verticalScrollBar();
1164 scrollbar->setValue(scrollbar->maximum());
1169 const int multiplier = 5;
1170 int mins = value * multiplier;
1176 ui->trafficGraph->setGraphRange(std::chrono::minutes{mins});
1190 ui->peersTabRightPanel->hide();
1191 ui->peerHeading->setText(tr(
"Select a peer to view detailed information."));
1196 QString peerAddrDetails(QString::fromStdString(stats->nodeStats.m_addr_name) +
" ");
1197 peerAddrDetails += tr(
"(peer: %1)").arg(QString::number(stats->nodeStats.nodeid));
1198 if (!stats->nodeStats.addrLocal.empty())
1199 peerAddrDetails +=
"<br />" + tr(
"via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
1200 ui->peerHeading->setText(peerAddrDetails);
1201 QString bip152_hb_settings;
1202 if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings =
ts.
to;
1203 if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings.isEmpty() ?
ts.
from : QLatin1Char(
'/') +
ts.
from);
1204 if (bip152_hb_settings.isEmpty()) bip152_hb_settings =
ts.
no;
1205 ui->peerHighBandwidth->setText(bip152_hb_settings);
1206 const auto time_now{GetTime<std::chrono::seconds>()};
1208 ui->peerLastBlock->setText(
TimeDurationField(time_now, stats->nodeStats.m_last_block_time));
1216 if (stats->nodeStats.nVersion) {
1217 ui->peerVersion->setText(QString::number(stats->nodeStats.nVersion));
1219 if (!stats->nodeStats.cleanSubVer.empty()) {
1220 ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
1223 ui->peerTransportType->setText(QString::fromStdString(
TransportTypeAsString(stats->nodeStats.m_transport_type)));
1225 ui->peerSessionIdLabel->setVisible(
true);
1226 ui->peerSessionId->setVisible(
true);
1227 ui->peerSessionId->setText(QString::fromStdString(stats->nodeStats.m_session_id));
1229 ui->peerSessionIdLabel->setVisible(
false);
1230 ui->peerSessionId->setVisible(
false);
1234 ui->peerPermissions->setText(
ts.
na);
1236 QStringList permissions;
1238 permissions.append(QString::fromStdString(permission));
1240 ui->peerPermissions->setText(permissions.join(
" & "));
1242 ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) :
ts.
na);
1246 if (stats->fNodeStateStatsAvailable) {
1250 if (stats->nodeStateStats.nSyncHeight > -1) {
1251 ui->peerSyncHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nSyncHeight));
1256 if (stats->nodeStateStats.nCommonHeight > -1) {
1257 ui->peerCommonHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nCommonHeight));
1261 ui->peerHeight->setText(QString::number(stats->nodeStateStats.m_starting_height));
1263 ui->peerAddrRelayEnabled->setText(stats->nodeStateStats.m_addr_relay_enabled ?
ts.
yes :
ts.
no);
1264 ui->peerAddrProcessed->setText(QString::number(stats->nodeStateStats.m_addr_processed));
1265 ui->peerAddrRateLimited->setText(QString::number(stats->nodeStateStats.m_addr_rate_limited));
1266 ui->peerRelayTxes->setText(stats->nodeStateStats.m_relay_txs ?
ts.
yes :
ts.
no);
1270 ui->peersTabRightPanel->show();
1275 QWidget::resizeEvent(event);
1280 QWidget::showEvent(event);
1296 QWidget::hideEvent(event);
1307 QModelIndex index =
ui->peerWidget->indexAt(point);
1308 if (index.isValid())
1314 QModelIndex index =
ui->banlistWidget->indexAt(point);
1315 if (index.isValid())
1323 for(
int i = 0; i < nodes.count(); i++)
1326 NodeId id = nodes.at(i).data().toLongLong();
1342 m_node.
ban(stats->nodeStats.addr, bantime);
1358 bool unbanned{
false};
1359 for (
const auto& node_index : nodes) {
1360 unbanned |= ban_table_model->
unban(node_index);
1363 ban_table_model->refresh();
1369 ui->peerWidget->selectionModel()->clearSelection();
1380 ui->banlistWidget->setVisible(visible);
1381 ui->banHeading->setVisible(visible);
1386 ui->tabWidget->setCurrentIndex(
int(tabType));
1391 return ui->tabWidget->tabText(
int(tab_type));
1408 this->
ui->label_alerts->setVisible(!warnings.isEmpty());
1409 this->
ui->label_alerts->setText(warnings);
1417 const QString chainType = QString::fromStdString(
Params().GetChainTypeString());
1418 const QString title = tr(
"Node window - [%1]").arg(chainType);
1419 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)
Class for handling RPC timers (used for e.g.
std::function< void()> func
QtRPCTimerBase(std::function< void()> &_func, int64_t millis)
~QtRPCTimerBase()=default
const char * Name() override
Implementation name.
RPCTimerBase * NewTimer(std::function< void()> &func, int64_t millis) override
Factory function for timers.
~QtRPCTimerInterface()=default
Local Bitcoin RPC console.
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
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 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
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 clear(bool keep_prompt=false)
void disconnectSelectedNode()
Disconnect a selected node on the Peers tab.
@ 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
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)
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 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 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.
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 formatBytes(uint64_t bytes)
QString formatDurationStr(std::chrono::seconds dur)
Convert seconds into a QString with days, hours, mins, secs.
void AddButtonShortcut(QAbstractButton *button, const QKeySequence &shortcut)
Connects an additional shortcut to a QAbstractButton.
void handleCloseWindowShortcut(QWidget *w)
void copyEntryData(const QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard.
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 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[]