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 bool command_parsed =
false;
163 unsigned nDepthInsideSensitive = 0;
164 size_t filter_begin_pos = 0, chpos;
165 std::vector<std::pair<size_t, size_t>> filter_ranges;
167 auto add_to_current_stack = [&](
const std::string& strArg) {
168 if (stack.back().empty() && (!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(strArg), Qt::CaseInsensitive)) {
169 nDepthInsideSensitive = 1;
170 filter_begin_pos = chpos;
174 stack.emplace_back();
179 auto close_out_params = [&]() {
180 if (nDepthInsideSensitive) {
181 if (!--nDepthInsideSensitive) {
183 filter_ranges.emplace_back(filter_begin_pos, chpos);
184 filter_begin_pos = 0;
190 std::string strCommandTerminated = strCommand;
191 if (strCommandTerminated.back() !=
'\n')
192 strCommandTerminated +=
"\n";
193 for (chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
195 char ch = strCommandTerminated[chpos];
198 case STATE_COMMAND_EXECUTED_INNER:
199 case STATE_COMMAND_EXECUTED:
201 bool breakParsing =
true;
204 case '[': curarg.clear(); state = STATE_COMMAND_EXECUTED_INNER;
break;
206 if (state == STATE_COMMAND_EXECUTED_INNER)
214 if (curarg.size() && fExecute)
220 const auto parsed{ToIntegral<size_t>(curarg)};
222 throw std::runtime_error(
"Invalid result query");
224 subelement = lastResult[parsed.value()];
229 throw std::runtime_error(
"Invalid result query");
230 lastResult = subelement;
233 state = STATE_COMMAND_EXECUTED;
237 breakParsing =
false;
243 if (lastResult.
isStr())
246 curarg = lastResult.
write(2);
252 add_to_current_stack(curarg);
258 state = STATE_EATING_SPACES;
265 case STATE_EATING_SPACES_IN_ARG:
266 case STATE_EATING_SPACES_IN_BRACKETS:
267 case STATE_EATING_SPACES:
270 case '"': state = STATE_DOUBLEQUOTED;
break;
271 case '\'': state = STATE_SINGLEQUOTED;
break;
272 case '\\': state = STATE_ESCAPE_OUTER;
break;
273 case '(':
case ')':
case '\n':
274 if (state == STATE_EATING_SPACES_IN_ARG)
275 throw std::runtime_error(
"Invalid Syntax");
276 if (state == STATE_ARGUMENT)
278 if (ch ==
'(' && stack.size() && stack.back().size() > 0)
280 if (nDepthInsideSensitive) {
281 ++nDepthInsideSensitive;
283 stack.emplace_back();
288 throw std::runtime_error(
"Invalid Syntax");
290 add_to_current_stack(curarg);
292 state = STATE_EATING_SPACES_IN_BRACKETS;
294 if ((ch ==
')' || ch ==
'\n') && stack.size() > 0 && stack.back().size() > 0)
299 UniValue params =
RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end()));
300 std::string method = stack.back()[0];
302 if (!wallet_name.isEmpty()) {
303 QByteArray encodedName = QUrl::toPercentEncoding(wallet_name);
304 uri =
"/wallet/"+std::string(encodedName.constData(), encodedName.length());
307 lastResult =
node->executeRpc(method, params, uri);
310 command_parsed =
true;
311 state = STATE_COMMAND_EXECUTED;
315 case ' ':
case ',':
case '\t':
316 if(state == STATE_EATING_SPACES_IN_ARG && curarg.empty() && ch ==
',')
317 throw std::runtime_error(
"Invalid Syntax");
319 else if(state == STATE_ARGUMENT)
321 add_to_current_stack(curarg);
324 if ((state == STATE_EATING_SPACES_IN_BRACKETS || state == STATE_ARGUMENT) && ch ==
',')
326 state = STATE_EATING_SPACES_IN_ARG;
329 state = STATE_EATING_SPACES;
331 default: curarg += ch; state = STATE_ARGUMENT;
334 case STATE_SINGLEQUOTED:
337 case '\'': state = STATE_ARGUMENT;
break;
338 default: curarg += ch;
341 case STATE_DOUBLEQUOTED:
344 case '"': state = STATE_ARGUMENT;
break;
345 case '\\': state = STATE_ESCAPE_DOUBLEQUOTED;
break;
346 default: curarg += ch;
349 case STATE_ESCAPE_OUTER:
350 curarg += ch; state = STATE_ARGUMENT;
352 case STATE_ESCAPE_DOUBLEQUOTED:
353 if(ch !=
'"' && ch !=
'\\') curarg +=
'\\';
354 curarg += ch; state = STATE_DOUBLEQUOTED;
358 if (pstrFilteredOut) {
359 if (STATE_COMMAND_EXECUTED == state) {
363 *pstrFilteredOut = strCommand;
364 for (
auto i = filter_ranges.rbegin(); i != filter_ranges.rend(); ++i) {
365 pstrFilteredOut->replace(i->first, i->second - i->first,
"(…)");
370 case STATE_COMMAND_EXECUTED:
371 if (lastResult.
isStr())
372 strResult = lastResult.
get_str();
374 strResult = lastResult.
write(2);
378 case STATE_EATING_SPACES:
381 return command_parsed;
392 std::string executableCommand =
command.toStdString() +
"\n";
395 if(executableCommand ==
"help-console\n") {
397 "This console accepts RPC commands using the standard syntax.\n"
398 " example: getblockhash 0\n\n"
400 "This console can also accept RPC commands using the parenthesized syntax.\n"
401 " example: getblockhash(0)\n\n"
403 "Commands may be nested when specified with the parenthesized syntax.\n"
404 " example: getblock(getblockhash(0) 1)\n\n"
406 "A space or a comma can be used to delimit arguments for either syntax.\n"
407 " example: getblockhash 0\n"
408 " getblockhash,0\n\n"
410 "Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n"
411 " example: getblock(getblockhash(0) 1)[tx]\n\n"
413 "Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n"
414 " example: getblock(getblockhash(0),1)[tx][0]\n\n")));
432 catch (
const std::runtime_error&)
437 catch (
const std::exception& e)
447 platformStyle(_platformStyle)
454 if (!restoreGeometry(settings.value(
"RPCConsoleWindowGeometry").toByteArray())) {
456 move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
458 ui->splitter->restoreState(settings.value(
"RPCConsoleWindowPeersTabSplitterSizes").toByteArray());
463 ui->splitter->restoreState(settings.value(
"RPCConsoleWidgetPeersTabSplitterSizes").toByteArray());
469 constexpr QChar nonbreaking_hyphen(8209);
472 tr(
"Inbound: initiated by peer"),
476 tr(
"Outbound Full Relay: default"),
479 tr(
"Outbound Block Relay: does not relay transactions or addresses"),
484 tr(
"Outbound Manual: added using RPC %1 or %2/%3 configuration options")
486 .arg(QString(nonbreaking_hyphen) +
"addnode")
487 .arg(QString(nonbreaking_hyphen) +
"connect"),
490 tr(
"Outbound Feeler: short-lived, for testing addresses"),
493 tr(
"Outbound Address Fetch: short-lived, for soliciting addresses"),
496 tr(
"Private broadcast: short-lived, for broadcasting privacy-sensitive transactions")};
497 const QString connection_types_list{
"<ul><li>" +
Join(
CONNECTION_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
498 ui->peerConnectionTypeLabel->setToolTip(
ui->peerConnectionTypeLabel->toolTip().arg(connection_types_list));
501 tr(
"detecting: peer could be v1 or v2"),
503 tr(
"v1: unencrypted, plaintext transport protocol"),
505 tr(
"v2: BIP324 encrypted transport protocol")};
506 const QString transport_types_list{
"<ul><li>" +
Join(
TRANSPORT_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
507 ui->peerTransportTypeLabel->setToolTip(
ui->peerTransportTypeLabel->toolTip().arg(transport_types_list));
508 const QString hb_list{
"<ul><li>\""
509 +
ts.
to +
"\" – " + tr(
"we selected the peer for high bandwidth relay") +
"</li><li>\""
510 +
ts.
from +
"\" – " + tr(
"the peer selected us for high bandwidth relay") +
"</li><li>\""
511 +
ts.
no +
"\" – " + tr(
"no high bandwidth relay selected") +
"</li></ul>"};
512 ui->peerHighBandwidthLabel->setToolTip(
ui->peerHighBandwidthLabel->toolTip().arg(hb_list));
513 ui->dataDir->setToolTip(
ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) +
"datadir"));
514 ui->blocksDir->setToolTip(
ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) +
"blocksdir"));
515 ui->openDebugLogfileButton->setToolTip(
ui->openDebugLogfileButton->toolTip().arg(CLIENT_NAME));
524 ui->fontBiggerButton->setShortcut(tr(
"Ctrl++"));
530 ui->fontSmallerButton->setShortcut(tr(
"Ctrl+-"));
537 ui->lineEdit->installEventFilter(
this);
538 ui->lineEdit->setMaxLength(16_MiB);
539 ui->messagesWidget->installEventFilter(
this);
542 connect(
ui->clearButton, &QAbstractButton::clicked, [
this] { clear(); });
548 ui->WalletSelector->setVisible(
false);
549 ui->WalletSelectorLabel->setVisible(
false);
568 settings.setValue(
"RPCConsoleWindowGeometry", saveGeometry());
569 settings.setValue(
"RPCConsoleWindowPeersTabSplitterSizes",
ui->splitter->saveState());
574 settings.setValue(
"RPCConsoleWidgetPeersTabSplitterSizes",
ui->splitter->saveState());
585 if(event->type() == QEvent::KeyPress)
587 QKeyEvent *keyevt =
static_cast<QKeyEvent*
>(event);
588 int key = keyevt->key();
589 Qt::KeyboardModifiers mod = keyevt->modifiers();
592 case Qt::Key_Up:
if(obj ==
ui->lineEdit) {
browseHistory(-1);
return true; }
break;
593 case Qt::Key_Down:
if(obj ==
ui->lineEdit) {
browseHistory(1);
return true; }
break;
595 case Qt::Key_PageDown:
596 if (obj ==
ui->lineEdit) {
597 QApplication::sendEvent(
ui->messagesWidget, keyevt);
605 QApplication::sendEvent(
ui->lineEdit, keyevt);
613 if(obj ==
ui->messagesWidget && (
614 (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) ||
615 ((mod & Qt::ControlModifier) && key == Qt::Key_V) ||
616 ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert)))
618 ui->lineEdit->setFocus();
619 QApplication::sendEvent(
ui->lineEdit, keyevt);
624 return QWidget::eventFilter(obj, event);
631 bool wallet_enabled{
false};
635 if (model && !wallet_enabled) {
641 ui->trafficGraph->setClientModel(model);
661 ui->peerWidget->verticalHeader()->hide();
662 ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
663 ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
664 ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
671 ui->peerWidget->horizontalHeader()->setSectionResizeMode(
PeerTableModel::Age, QHeaderView::ResizeToContents);
672 ui->peerWidget->horizontalHeader()->setStretchLastSection(
true);
691 connect(model->
getPeerTableModel(), &QAbstractItemModel::dataChanged, [
this] { updateDetailWidget(); });
695 ui->banlistWidget->verticalHeader()->hide();
696 ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
697 ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
698 ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
705 ui->banlistWidget->horizontalHeader()->setStretchLastSection(
true);
731 ui->networkName->setText(QString::fromStdString(
Params().GetChainTypeString()));
734 QStringList wordList;
736 for (
size_t i = 0; i < commandList.size(); ++i)
738 wordList << commandList[i].c_str();
739 wordList << (
"help " + commandList[i]).c_str();
742 wordList <<
"help-console";
745 autoCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel);
748 ui->lineEdit->setEnabled(
true);
762void RPCConsole::addWallet(
WalletModel *
const walletModel)
765 ui->WalletSelector->addItem(walletModel->
getDisplayName(), QVariant::fromValue(walletModel));
766 if (
ui->WalletSelector->count() == 2) {
768 ui->WalletSelector->setCurrentIndex(1);
770 if (
ui->WalletSelector->count() > 2) {
771 ui->WalletSelector->setVisible(
true);
772 ui->WalletSelectorLabel->setVisible(
true);
776void RPCConsole::removeWallet(
WalletModel *
const walletModel)
778 ui->WalletSelector->removeItem(
ui->WalletSelector->findData(QVariant::fromValue(walletModel)));
779 if (
ui->WalletSelector->count() == 2) {
780 ui->WalletSelector->setVisible(
false);
781 ui->WalletSelectorLabel->setVisible(
false);
785void RPCConsole::setCurrentWallet(
WalletModel*
const wallet_model)
787 QVariant
data = QVariant::fromValue(wallet_model);
788 ui->WalletSelector->setCurrentIndex(
ui->WalletSelector->findData(
data));
799 default:
return "misc";
822 QString str =
ui->messagesWidget->toHtml();
825 str.replace(QString(
"font-size:%1pt").arg(
consoleFontSize), QString(
"font-size:%1pt").arg(newSize));
832 float oldPosFactor = 1.0 /
ui->messagesWidget->verticalScrollBar()->maximum() *
ui->messagesWidget->verticalScrollBar()->value();
834 ui->messagesWidget->setHtml(str);
835 ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor *
ui->messagesWidget->verticalScrollBar()->maximum());
840 ui->messagesWidget->clear();
841 if (!keep_prompt)
ui->lineEdit->clear();
842 ui->lineEdit->setFocus();
848 ui->messagesWidget->document()->addResource(
849 QTextDocument::ImageResource,
860 ui->messagesWidget->document()->setDefaultStyleSheet(
863 "td.time { color: #808080; font-size: %2; padding-top: 3px; } "
864 "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } "
865 "td.cmd-request { color: #006060; } "
866 "td.cmd-error { color: red; } "
867 ".secwarning { color: red; }"
868 "b { color: #006060; } "
872 static const QString welcome_message =
876 tr(
"Welcome to the %1 RPC console.\n"
877 "Use up and down arrows to navigate history, and %2 to clear screen.\n"
878 "Use %3 and %4 to increase or decrease the font size.\n"
879 "Type %5 for an overview of available commands.\n"
880 "For more information on using this console, type %6.\n"
882 "%7WARNING: Scammers have been active, telling users to type"
883 " commands here, stealing their wallet contents. Do not use this console"
884 " without fully understanding the ramifications of a command.%8")
886 "<b>" +
ui->clearButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
887 "<b>" +
ui->fontBiggerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
888 "<b>" +
ui->fontSmallerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
890 "<b>help-console</b>",
891 "<span class=\"secwarning\">",
906 if (e->type() == QEvent::PaletteChange) {
913 ui->messagesWidget->document()->addResource(
914 QTextDocument::ImageResource,
920 QWidget::changeEvent(e);
925 QTime time = QTime::currentTime();
926 QString timeString = time.toString();
928 out +=
"<table><tr><td class=\"time\" width=\"65\">" + timeString +
"</td>";
929 out +=
"<td class=\"icon\" width=\"32\"><img src=\"" +
categoryClass(category) +
"\"></td>";
930 out +=
"<td class=\"message " +
categoryClass(category) +
"\" valign=\"middle\">";
935 out +=
"</td></tr></table>";
936 ui->messagesWidget->append(
out);
947 connections +=
" (" + tr(
"Network activity disabled") +
")";
950 ui->numberOfConnections->setText(connections);
952 QString local_addresses;
954 for (
const auto& [addr, info] : hosts) {
955 local_addresses += QString::fromStdString(addr.ToStringAddr());
956 if (!addr.IsI2P()) local_addresses +=
":" + QString::number(info.nPort);
957 local_addresses +=
", ";
959 local_addresses.chop(2);
960 if (local_addresses.isEmpty()) local_addresses = tr(
"None");
962 ui->localAddresses->setText(local_addresses);
981 ui->numberOfBlocks->setText(QString::number(
count));
982 ui->lastBlockTime->setText(blockDate.toString());
988 ui->mempoolNumberTxs->setText(QString::number(numberOfTxs));
990 const auto cur_usage_str = dynUsage < 1000000 ?
991 QObject::tr(
"%1 kB").arg(dynUsage / 1000.0, 0,
'f', 2) :
992 QObject::tr(
"%1 MB").arg(dynUsage / 1000000.0, 0,
'f', 2);
993 const auto max_usage_str = QObject::tr(
"%1 MB").arg(maxUsage / 1000000.0, 0,
'f', 2);
995 ui->mempoolSize->setText(cur_usage_str +
" / " + max_usage_str);
1000 QString
cmd =
ui->lineEdit->text().trimmed();
1002 if (
cmd.isEmpty()) {
1006 std::string strFilteredCmd;
1011 throw std::runtime_error(
"Invalid command line");
1013 }
catch (
const std::exception& e) {
1014 QMessageBox::critical(
this,
"Error", QString(
"Error: ") + QString::fromStdString(e.what()));
1019 if (
cmd == QLatin1String(
"stop")) {
1029 ui->lineEdit->clear();
1031 QString in_use_wallet_name;
1034 in_use_wallet_name = wallet_model ? wallet_model->
getWalletName() : QString();
1050 QMetaObject::invokeMethod(
m_executor, [
this,
cmd, in_use_wallet_name] {
1054 cmd = QString::fromStdString(strFilteredCmd);
1089 ui->lineEdit->setText(
cmd);
1100 ui->messagesWidget->undo();
1107 connect(&
thread, &QThread::finished,
m_executor, &RPCExecutor::deleteLater);
1119 if (
ui->tabWidget->widget(index) ==
ui->tab_console) {
1120 ui->lineEdit->setFocus();
1131 QScrollBar *scrollbar =
ui->messagesWidget->verticalScrollBar();
1132 scrollbar->setValue(scrollbar->maximum());
1137 const int multiplier = 5;
1138 int mins = value * multiplier;
1144 ui->trafficGraph->setGraphRange(std::chrono::minutes{mins});
1158 ui->peersTabRightPanel->hide();
1159 ui->peerHeading->setText(tr(
"Select a peer to view detailed information."));
1164 QString peerAddrDetails(QString::fromStdString(stats->nodeStats.m_addr_name) +
" ");
1165 peerAddrDetails += tr(
"(peer: %1)").arg(QString::number(stats->nodeStats.nodeid));
1166 if (!stats->nodeStats.addrLocal.empty())
1167 peerAddrDetails +=
"<br />" + tr(
"via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
1168 ui->peerHeading->setText(peerAddrDetails);
1169 QString bip152_hb_settings;
1170 if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings =
ts.
to;
1171 if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings.isEmpty() ?
ts.
from : QLatin1Char(
'/') +
ts.
from);
1172 if (bip152_hb_settings.isEmpty()) bip152_hb_settings =
ts.
no;
1173 ui->peerHighBandwidth->setText(bip152_hb_settings);
1175 const auto time_now{GetTime<std::chrono::seconds>()};
1177 ui->peerLastBlock->setText(
TimeDurationField(time_now, stats->nodeStats.m_last_block_time));
1185 ui->peerVersion->setText(stats->nodeStats.nVersion ? QString::number(stats->nodeStats.nVersion) :
ts.
na);
1186 ui->peerSubversion->setText(!stats->nodeStats.cleanSubVer.empty() ? QString::fromStdString(stats->nodeStats.cleanSubVer) :
ts.
na);
1188 ui->peerTransportType->setText(QString::fromStdString(
TransportTypeAsString(stats->nodeStats.m_transport_type)));
1190 ui->peerSessionIdLabel->setVisible(
true);
1191 ui->peerSessionId->setVisible(
true);
1192 ui->peerSessionId->setText(QString::fromStdString(stats->nodeStats.m_session_id));
1194 ui->peerSessionIdLabel->setVisible(
false);
1195 ui->peerSessionId->setVisible(
false);
1199 ui->peerPermissions->setText(
ts.
na);
1201 QStringList permissions;
1203 permissions.append(QString::fromStdString(permission));
1205 ui->peerPermissions->setText(permissions.join(
" & "));
1207 ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) :
ts.
na);
1211 if (stats->fNodeStateStatsAvailable) {
1215 if (stats->nodeStateStats.nSyncHeight > -1) {
1216 ui->peerSyncHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nSyncHeight));
1221 if (stats->nodeStateStats.nCommonHeight > -1) {
1222 ui->peerCommonHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nCommonHeight));
1227 ui->peerAddrRelayEnabled->setText(stats->nodeStateStats.m_addr_relay_enabled ?
ts.
yes :
ts.
no);
1228 ui->peerAddrProcessed->setText(QString::number(stats->nodeStateStats.m_addr_processed));
1229 ui->peerAddrRateLimited->setText(QString::number(stats->nodeStateStats.m_addr_rate_limited));
1230 ui->peerRelayTxes->setText(stats->nodeStateStats.m_relay_txs ?
ts.
yes :
ts.
no);
1234 ui->peersTabRightPanel->show();
1239 QWidget::resizeEvent(event);
1244 QWidget::showEvent(event);
1260 QWidget::hideEvent(event);
1271 QModelIndex index =
ui->peerWidget->indexAt(point);
1272 if (index.isValid())
1278 QModelIndex index =
ui->banlistWidget->indexAt(point);
1279 if (index.isValid())
1287 for(
int i = 0; i < nodes.count(); i++)
1290 NodeId id = nodes.at(i).data().toLongLong();
1306 m_node.
ban(stats->nodeStats.addr, bantime);
1322 bool unbanned{
false};
1323 for (
const auto& node_index : nodes) {
1324 unbanned |= ban_table_model->
unban(node_index);
1327 ban_table_model->refresh();
1333 ui->peerWidget->selectionModel()->clearSelection();
1344 ui->banlistWidget->setVisible(visible);
1345 ui->banHeading->setVisible(visible);
1350 ui->tabWidget->setCurrentIndex(
int(tabType));
1355 return ui->tabWidget->tabText(
int(tab_type));
1372 this->
ui->label_alerts->setVisible(!warnings.isEmpty());
1373 this->
ui->label_alerts->setText(warnings);
1381 const QString chainType = QString::fromStdString(
Params().GetChainTypeString());
1382 const QString title = tr(
"Node window - [%1]").arg(chainType);
1383 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.
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
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.