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()
75 <<
"signmessagewithprivkey"
76 <<
"signrawtransactionwithkey"
78 <<
"walletpassphrasechange"
111 timer.setSingleShot(
true);
112 connect(&
timer, &QTimer::timeout, [
this]{
func(); });
125 const char *
Name()
override {
return "Qt"; }
137 : QStyledItemDelegate(parent) {}
139 QString
displayText(
const QVariant& value,
const QLocale& locale)
const override
143 return value.toString() + QLatin1String(
" ");
147#include <qt/rpcconsole.moc>
171 std::vector< std::vector<std::string> > stack;
172 stack.emplace_back();
177 STATE_EATING_SPACES_IN_ARG,
178 STATE_EATING_SPACES_IN_BRACKETS,
183 STATE_ESCAPE_DOUBLEQUOTED,
184 STATE_COMMAND_EXECUTED,
185 STATE_COMMAND_EXECUTED_INNER
186 } state = STATE_EATING_SPACES;
189 unsigned nDepthInsideSensitive = 0;
190 size_t filter_begin_pos = 0, chpos;
191 std::vector<std::pair<size_t, size_t>> filter_ranges;
193 auto add_to_current_stack = [&](
const std::string& strArg) {
194 if (stack.back().empty() && (!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(strArg), Qt::CaseInsensitive)) {
195 nDepthInsideSensitive = 1;
196 filter_begin_pos = chpos;
200 stack.emplace_back();
205 auto close_out_params = [&]() {
206 if (nDepthInsideSensitive) {
207 if (!--nDepthInsideSensitive) {
209 filter_ranges.emplace_back(filter_begin_pos, chpos);
210 filter_begin_pos = 0;
216 std::string strCommandTerminated = strCommand;
217 if (strCommandTerminated.back() !=
'\n')
218 strCommandTerminated +=
"\n";
219 for (chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
221 char ch = strCommandTerminated[chpos];
224 case STATE_COMMAND_EXECUTED_INNER:
225 case STATE_COMMAND_EXECUTED:
227 bool breakParsing =
true;
230 case '[': curarg.clear(); state = STATE_COMMAND_EXECUTED_INNER;
break;
232 if (state == STATE_COMMAND_EXECUTED_INNER)
240 if (curarg.size() && fExecute)
246 const auto parsed{ToIntegral<size_t>(curarg)};
248 throw std::runtime_error(
"Invalid result query");
250 subelement = lastResult[parsed.value()];
255 throw std::runtime_error(
"Invalid result query");
256 lastResult = subelement;
259 state = STATE_COMMAND_EXECUTED;
263 breakParsing =
false;
269 if (lastResult.
isStr())
272 curarg = lastResult.
write(2);
278 add_to_current_stack(curarg);
284 state = STATE_EATING_SPACES;
291 case STATE_EATING_SPACES_IN_ARG:
292 case STATE_EATING_SPACES_IN_BRACKETS:
293 case STATE_EATING_SPACES:
296 case '"': state = STATE_DOUBLEQUOTED;
break;
297 case '\'': state = STATE_SINGLEQUOTED;
break;
298 case '\\': state = STATE_ESCAPE_OUTER;
break;
299 case '(':
case ')':
case '\n':
300 if (state == STATE_EATING_SPACES_IN_ARG)
301 throw std::runtime_error(
"Invalid Syntax");
302 if (state == STATE_ARGUMENT)
304 if (ch ==
'(' && stack.size() && stack.back().size() > 0)
306 if (nDepthInsideSensitive) {
307 ++nDepthInsideSensitive;
309 stack.emplace_back();
314 throw std::runtime_error(
"Invalid Syntax");
316 add_to_current_stack(curarg);
318 state = STATE_EATING_SPACES_IN_BRACKETS;
320 if ((ch ==
')' || ch ==
'\n') && stack.size() > 0)
325 UniValue params =
RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end()));
326 std::string method = stack.back()[0];
328 if (!wallet_name.isEmpty()) {
329 QByteArray encodedName = QUrl::toPercentEncoding(wallet_name);
330 uri =
"/wallet/"+std::string(encodedName.constData(), encodedName.length());
333 lastResult =
node->executeRpc(method, params, uri);
336 state = STATE_COMMAND_EXECUTED;
340 case ' ':
case ',':
case '\t':
341 if(state == STATE_EATING_SPACES_IN_ARG && curarg.empty() && ch ==
',')
342 throw std::runtime_error(
"Invalid Syntax");
344 else if(state == STATE_ARGUMENT)
346 add_to_current_stack(curarg);
349 if ((state == STATE_EATING_SPACES_IN_BRACKETS || state == STATE_ARGUMENT) && ch ==
',')
351 state = STATE_EATING_SPACES_IN_ARG;
354 state = STATE_EATING_SPACES;
356 default: curarg += ch; state = STATE_ARGUMENT;
359 case STATE_SINGLEQUOTED:
362 case '\'': state = STATE_ARGUMENT;
break;
363 default: curarg += ch;
366 case STATE_DOUBLEQUOTED:
369 case '"': state = STATE_ARGUMENT;
break;
370 case '\\': state = STATE_ESCAPE_DOUBLEQUOTED;
break;
371 default: curarg += ch;
374 case STATE_ESCAPE_OUTER:
375 curarg += ch; state = STATE_ARGUMENT;
377 case STATE_ESCAPE_DOUBLEQUOTED:
378 if(ch !=
'"' && ch !=
'\\') curarg +=
'\\';
379 curarg += ch; state = STATE_DOUBLEQUOTED;
383 if (pstrFilteredOut) {
384 if (STATE_COMMAND_EXECUTED == state) {
388 *pstrFilteredOut = strCommand;
389 for (
auto i = filter_ranges.rbegin(); i != filter_ranges.rend(); ++i) {
390 pstrFilteredOut->replace(i->first, i->second - i->first,
"(…)");
395 case STATE_COMMAND_EXECUTED:
396 if (lastResult.
isStr())
397 strResult = lastResult.
get_str();
399 strResult = lastResult.
write(2);
402 case STATE_EATING_SPACES:
414 std::string executableCommand =
command.toStdString() +
"\n";
417 if(executableCommand ==
"help-console\n") {
419 "This console accepts RPC commands using the standard syntax.\n"
420 " example: getblockhash 0\n\n"
422 "This console can also accept RPC commands using the parenthesized syntax.\n"
423 " example: getblockhash(0)\n\n"
425 "Commands may be nested when specified with the parenthesized syntax.\n"
426 " example: getblock(getblockhash(0) 1)\n\n"
428 "A space or a comma can be used to delimit arguments for either syntax.\n"
429 " example: getblockhash 0\n"
430 " getblockhash,0\n\n"
432 "Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n"
433 " example: getblock(getblockhash(0) 1)[tx]\n\n"
435 "Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n"
436 " example: getblock(getblockhash(0),1)[tx][0]\n\n")));
454 catch (
const std::runtime_error&)
459 catch (
const std::exception& e)
469 platformStyle(_platformStyle)
476 if (!restoreGeometry(settings.value(
"RPCConsoleWindowGeometry").toByteArray())) {
478 move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
480 ui->splitter->restoreState(settings.value(
"RPCConsoleWindowPeersTabSplitterSizes").toByteArray());
485 ui->splitter->restoreState(settings.value(
"RPCConsoleWidgetPeersTabSplitterSizes").toByteArray());
491 constexpr QChar nonbreaking_hyphen(8209);
494 tr(
"Inbound: initiated by peer"),
498 tr(
"Outbound Full Relay: default"),
501 tr(
"Outbound Block Relay: does not relay transactions or addresses"),
506 tr(
"Outbound Manual: added using RPC %1 or %2/%3 configuration options")
508 .arg(QString(nonbreaking_hyphen) +
"addnode")
509 .arg(QString(nonbreaking_hyphen) +
"connect"),
512 tr(
"Outbound Feeler: short-lived, for testing addresses"),
515 tr(
"Outbound Address Fetch: short-lived, for soliciting addresses")};
516 const QString connection_types_list{
"<ul><li>" +
Join(
CONNECTION_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
517 ui->peerConnectionTypeLabel->setToolTip(
ui->peerConnectionTypeLabel->toolTip().arg(connection_types_list));
520 tr(
"detecting: peer could be v1 or v2"),
522 tr(
"v1: unencrypted, plaintext transport protocol"),
524 tr(
"v2: BIP324 encrypted transport protocol")};
525 const QString transport_types_list{
"<ul><li>" +
Join(
TRANSPORT_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
526 ui->peerTransportTypeLabel->setToolTip(
ui->peerTransportTypeLabel->toolTip().arg(transport_types_list));
527 const QString hb_list{
"<ul><li>\""
528 +
ts.
to +
"\" – " + tr(
"we selected the peer for high bandwidth relay") +
"</li><li>\""
529 +
ts.
from +
"\" – " + tr(
"the peer selected us for high bandwidth relay") +
"</li><li>\""
530 +
ts.
no +
"\" – " + tr(
"no high bandwidth relay selected") +
"</li></ul>"};
531 ui->peerHighBandwidthLabel->setToolTip(
ui->peerHighBandwidthLabel->toolTip().arg(hb_list));
532 ui->dataDir->setToolTip(
ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) +
"datadir"));
533 ui->blocksDir->setToolTip(
ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) +
"blocksdir"));
534 ui->openDebugLogfileButton->setToolTip(
ui->openDebugLogfileButton->toolTip().arg(CLIENT_NAME));
543 ui->fontBiggerButton->setShortcut(tr(
"Ctrl++"));
549 ui->fontSmallerButton->setShortcut(tr(
"Ctrl+-"));
556 ui->lineEdit->installEventFilter(
this);
557 ui->lineEdit->setMaxLength(16 * 1024 * 1024);
558 ui->messagesWidget->installEventFilter(
this);
561 connect(
ui->clearButton, &QAbstractButton::clicked, [
this] { clear(); });
567 ui->WalletSelector->setVisible(
false);
568 ui->WalletSelectorLabel->setVisible(
false);
593 settings.setValue(
"RPCConsoleWindowGeometry", saveGeometry());
594 settings.setValue(
"RPCConsoleWindowPeersTabSplitterSizes",
ui->splitter->saveState());
599 settings.setValue(
"RPCConsoleWidgetPeersTabSplitterSizes",
ui->splitter->saveState());
612 if(event->type() == QEvent::KeyPress)
614 QKeyEvent *keyevt =
static_cast<QKeyEvent*
>(event);
615 int key = keyevt->key();
616 Qt::KeyboardModifiers mod = keyevt->modifiers();
619 case Qt::Key_Up:
if(obj ==
ui->lineEdit) {
browseHistory(-1);
return true; }
break;
620 case Qt::Key_Down:
if(obj ==
ui->lineEdit) {
browseHistory(1);
return true; }
break;
622 case Qt::Key_PageDown:
623 if (obj ==
ui->lineEdit) {
624 QApplication::sendEvent(
ui->messagesWidget, keyevt);
632 QApplication::sendEvent(
ui->lineEdit, keyevt);
640 if(obj ==
ui->messagesWidget && (
641 (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) ||
642 ((mod & Qt::ControlModifier) && key == Qt::Key_V) ||
643 ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert)))
645 ui->lineEdit->setFocus();
646 QApplication::sendEvent(
ui->lineEdit, keyevt);
651 return QWidget::eventFilter(obj, event);
658 bool wallet_enabled{
false};
662 if (model && !wallet_enabled) {
668 ui->trafficGraph->setClientModel(model);
688 ui->peerWidget->verticalHeader()->hide();
689 ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
690 ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
691 ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
698 ui->peerWidget->horizontalHeader()->setSectionResizeMode(
PeerTableModel::Age, QHeaderView::ResizeToContents);
699 ui->peerWidget->horizontalHeader()->setStretchLastSection(
true);
718 connect(model->
getPeerTableModel(), &QAbstractItemModel::dataChanged, [
this] { updateDetailWidget(); });
722 ui->banlistWidget->verticalHeader()->hide();
723 ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
724 ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
725 ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
732 ui->banlistWidget->horizontalHeader()->setStretchLastSection(
true);
758 ui->networkName->setText(QString::fromStdString(
Params().GetChainTypeString()));
761 QStringList wordList;
763 for (
size_t i = 0; i < commandList.size(); ++i)
765 wordList << commandList[i].c_str();
766 wordList << (
"help " + commandList[i]).c_str();
769 wordList <<
"help-console";
772 autoCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel);
775 ui->lineEdit->setEnabled(
true);
789void RPCConsole::addWallet(
WalletModel *
const walletModel)
792 ui->WalletSelector->addItem(walletModel->
getDisplayName(), QVariant::fromValue(walletModel));
793 if (
ui->WalletSelector->count() == 2) {
795 ui->WalletSelector->setCurrentIndex(1);
797 if (
ui->WalletSelector->count() > 2) {
798 ui->WalletSelector->setVisible(
true);
799 ui->WalletSelectorLabel->setVisible(
true);
803void RPCConsole::removeWallet(
WalletModel *
const walletModel)
805 ui->WalletSelector->removeItem(
ui->WalletSelector->findData(QVariant::fromValue(walletModel)));
806 if (
ui->WalletSelector->count() == 2) {
807 ui->WalletSelector->setVisible(
false);
808 ui->WalletSelectorLabel->setVisible(
false);
812void RPCConsole::setCurrentWallet(
WalletModel*
const wallet_model)
814 QVariant
data = QVariant::fromValue(wallet_model);
815 ui->WalletSelector->setCurrentIndex(
ui->WalletSelector->findData(
data));
826 default:
return "misc";
849 QString str =
ui->messagesWidget->toHtml();
852 str.replace(QString(
"font-size:%1pt").arg(
consoleFontSize), QString(
"font-size:%1pt").arg(newSize));
859 float oldPosFactor = 1.0 /
ui->messagesWidget->verticalScrollBar()->maximum() *
ui->messagesWidget->verticalScrollBar()->value();
861 ui->messagesWidget->setHtml(str);
862 ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor *
ui->messagesWidget->verticalScrollBar()->maximum());
867 ui->messagesWidget->clear();
868 if (!keep_prompt)
ui->lineEdit->clear();
869 ui->lineEdit->setFocus();
875 ui->messagesWidget->document()->addResource(
876 QTextDocument::ImageResource,
887 ui->messagesWidget->document()->setDefaultStyleSheet(
890 "td.time { color: #808080; font-size: %2; padding-top: 3px; } "
891 "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } "
892 "td.cmd-request { color: #006060; } "
893 "td.cmd-error { color: red; } "
894 ".secwarning { color: red; }"
895 "b { color: #006060; } "
899 static const QString welcome_message =
903 tr(
"Welcome to the %1 RPC console.\n"
904 "Use up and down arrows to navigate history, and %2 to clear screen.\n"
905 "Use %3 and %4 to increase or decrease the font size.\n"
906 "Type %5 for an overview of available commands.\n"
907 "For more information on using this console, type %6.\n"
909 "%7WARNING: Scammers have been active, telling users to type"
910 " commands here, stealing their wallet contents. Do not use this console"
911 " without fully understanding the ramifications of a command.%8")
913 "<b>" +
ui->clearButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
914 "<b>" +
ui->fontBiggerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
915 "<b>" +
ui->fontSmallerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
917 "<b>help-console</b>",
918 "<span class=\"secwarning\">",
933 if (e->type() == QEvent::PaletteChange) {
940 ui->messagesWidget->document()->addResource(
941 QTextDocument::ImageResource,
947 QWidget::changeEvent(e);
952 QTime time = QTime::currentTime();
953 QString timeString = time.toString();
955 out +=
"<table><tr><td class=\"time\" width=\"65\">" + timeString +
"</td>";
956 out +=
"<td class=\"icon\" width=\"32\"><img src=\"" +
categoryClass(category) +
"\"></td>";
957 out +=
"<td class=\"message " +
categoryClass(category) +
"\" valign=\"middle\">";
962 out +=
"</td></tr></table>";
963 ui->messagesWidget->append(
out);
974 connections +=
" (" + tr(
"Network activity disabled") +
")";
977 ui->numberOfConnections->setText(connections);
979 QString local_addresses;
981 for (
const auto& [addr, info] : hosts) {
982 local_addresses += QString::fromStdString(addr.ToStringAddr());
983 if (!addr.IsI2P()) local_addresses +=
":" + QString::number(info.nPort);
984 local_addresses +=
", ";
986 local_addresses.chop(2);
987 if (local_addresses.isEmpty()) local_addresses = tr(
"None");
989 ui->localAddresses->setText(local_addresses);
1008 ui->numberOfBlocks->setText(QString::number(
count));
1009 ui->lastBlockTime->setText(blockDate.toString());
1015 ui->mempoolNumberTxs->setText(QString::number(numberOfTxs));
1017 const auto cur_usage_str = dynUsage < 1000000 ?
1018 QObject::tr(
"%1 kB").arg(dynUsage / 1000.0, 0,
'f', 2) :
1019 QObject::tr(
"%1 MB").arg(dynUsage / 1000000.0, 0,
'f', 2);
1020 const auto max_usage_str = QObject::tr(
"%1 MB").arg(maxUsage / 1000000.0, 0,
'f', 2);
1022 ui->mempoolSize->setText(cur_usage_str +
" / " + max_usage_str);
1027 QString
cmd =
ui->lineEdit->text().trimmed();
1029 if (
cmd.isEmpty()) {
1033 std::string strFilteredCmd;
1038 throw std::runtime_error(
"Invalid command line");
1040 }
catch (
const std::exception& e) {
1041 QMessageBox::critical(
this,
"Error", QString(
"Error: ") + QString::fromStdString(e.what()));
1046 if (
cmd == QLatin1String(
"stop")) {
1056 ui->lineEdit->clear();
1058 QString in_use_wallet_name;
1061 in_use_wallet_name = wallet_model ? wallet_model->
getWalletName() : QString();
1077 QMetaObject::invokeMethod(
m_executor, [
this,
cmd, in_use_wallet_name] {
1081 cmd = QString::fromStdString(strFilteredCmd);
1116 ui->lineEdit->setText(
cmd);
1127 ui->messagesWidget->undo();
1134 connect(&
thread, &QThread::finished,
m_executor, &RPCExecutor::deleteLater);
1146 if (
ui->tabWidget->widget(index) ==
ui->tab_console) {
1147 ui->lineEdit->setFocus();
1158 QScrollBar *scrollbar =
ui->messagesWidget->verticalScrollBar();
1159 scrollbar->setValue(scrollbar->maximum());
1164 const int multiplier = 5;
1165 int mins = value * multiplier;
1171 ui->trafficGraph->setGraphRange(std::chrono::minutes{mins});
1185 ui->peersTabRightPanel->hide();
1186 ui->peerHeading->setText(tr(
"Select a peer to view detailed information."));
1191 QString peerAddrDetails(QString::fromStdString(stats->nodeStats.m_addr_name) +
" ");
1192 peerAddrDetails += tr(
"(peer: %1)").arg(QString::number(stats->nodeStats.nodeid));
1193 if (!stats->nodeStats.addrLocal.empty())
1194 peerAddrDetails +=
"<br />" + tr(
"via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
1195 ui->peerHeading->setText(peerAddrDetails);
1196 QString bip152_hb_settings;
1197 if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings =
ts.
to;
1198 if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings.isEmpty() ?
ts.
from : QLatin1Char(
'/') +
ts.
from);
1199 if (bip152_hb_settings.isEmpty()) bip152_hb_settings =
ts.
no;
1200 ui->peerHighBandwidth->setText(bip152_hb_settings);
1201 const auto time_now{GetTime<std::chrono::seconds>()};
1203 ui->peerLastBlock->setText(
TimeDurationField(time_now, stats->nodeStats.m_last_block_time));
1211 if (stats->nodeStats.nVersion) {
1212 ui->peerVersion->setText(QString::number(stats->nodeStats.nVersion));
1214 if (!stats->nodeStats.cleanSubVer.empty()) {
1215 ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
1218 ui->peerTransportType->setText(QString::fromStdString(
TransportTypeAsString(stats->nodeStats.m_transport_type)));
1220 ui->peerSessionIdLabel->setVisible(
true);
1221 ui->peerSessionId->setVisible(
true);
1222 ui->peerSessionId->setText(QString::fromStdString(stats->nodeStats.m_session_id));
1224 ui->peerSessionIdLabel->setVisible(
false);
1225 ui->peerSessionId->setVisible(
false);
1229 ui->peerPermissions->setText(
ts.
na);
1231 QStringList permissions;
1233 permissions.append(QString::fromStdString(permission));
1235 ui->peerPermissions->setText(permissions.join(
" & "));
1237 ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) :
ts.
na);
1241 if (stats->fNodeStateStatsAvailable) {
1245 if (stats->nodeStateStats.nSyncHeight > -1) {
1246 ui->peerSyncHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nSyncHeight));
1251 if (stats->nodeStateStats.nCommonHeight > -1) {
1252 ui->peerCommonHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nCommonHeight));
1256 ui->peerHeight->setText(QString::number(stats->nodeStateStats.m_starting_height));
1258 ui->peerAddrRelayEnabled->setText(stats->nodeStateStats.m_addr_relay_enabled ?
ts.
yes :
ts.
no);
1259 ui->peerAddrProcessed->setText(QString::number(stats->nodeStateStats.m_addr_processed));
1260 ui->peerAddrRateLimited->setText(QString::number(stats->nodeStateStats.m_addr_rate_limited));
1261 ui->peerRelayTxes->setText(stats->nodeStateStats.m_relay_txs ?
ts.
yes :
ts.
no);
1265 ui->peersTabRightPanel->show();
1270 QWidget::resizeEvent(event);
1275 QWidget::showEvent(event);
1291 QWidget::hideEvent(event);
1302 QModelIndex index =
ui->peerWidget->indexAt(point);
1303 if (index.isValid())
1309 QModelIndex index =
ui->banlistWidget->indexAt(point);
1310 if (index.isValid())
1318 for(
int i = 0; i < nodes.count(); i++)
1321 NodeId id = nodes.at(i).data().toLongLong();
1337 m_node.
ban(stats->nodeStats.addr, bantime);
1353 bool unbanned{
false};
1354 for (
const auto& node_index : nodes) {
1355 unbanned |= ban_table_model->
unban(node_index);
1358 ban_table_model->refresh();
1364 ui->peerWidget->selectionModel()->clearSelection();
1375 ui->banlistWidget->setVisible(visible);
1376 ui->banHeading->setVisible(visible);
1381 ui->tabWidget->setCurrentIndex(
int(tabType));
1386 return ui->tabWidget->tabText(
int(tab_type));
1403 this->
ui->label_alerts->setVisible(!warnings.isEmpty());
1404 this->
ui->label_alerts->setText(warnings);
1412 const QString chainType = QString::fromStdString(
Params().GetChainTypeString());
1413 const QString title = tr(
"Node window - [%1]").arg(chainType);
1414 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.
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.
static bool RPCParseCommandLine(interfaces::Node *node, std::string &strResult, const std::string &strCommand, bool fExecute, std::string *const pstrFilteredOut=nullptr, const QString &wallet_name={})
Split shell command line into a list of arguments and optionally execute the command(s).
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)
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.
@ 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 QString &wallet_name)
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[]