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()
76 <<
"createwalletdescriptor"
78 <<
"signmessagewithprivkey"
79 <<
"signrawtransactionwithkey"
81 <<
"walletpassphrasechange"
109 : QStyledItemDelegate(parent) {}
111 QString
displayText(
const QVariant& value,
const QLocale& locale)
const override
115 return value.toString() + QLatin1String(
" ");
119#include <qt/rpcconsole.moc>
143 std::vector< std::vector<std::string> > stack;
144 stack.emplace_back();
149 STATE_EATING_SPACES_IN_ARG,
150 STATE_EATING_SPACES_IN_BRACKETS,
155 STATE_ESCAPE_DOUBLEQUOTED,
156 STATE_COMMAND_EXECUTED,
157 STATE_COMMAND_EXECUTED_INNER
158 } state = STATE_EATING_SPACES;
161 unsigned nDepthInsideSensitive = 0;
162 size_t filter_begin_pos = 0, chpos;
163 std::vector<std::pair<size_t, size_t>> filter_ranges;
165 auto add_to_current_stack = [&](
const std::string& strArg) {
166 if (stack.back().empty() && (!nDepthInsideSensitive) && historyFilter.contains(QString::fromStdString(strArg), Qt::CaseInsensitive)) {
167 nDepthInsideSensitive = 1;
168 filter_begin_pos = chpos;
172 stack.emplace_back();
177 auto close_out_params = [&]() {
178 if (nDepthInsideSensitive) {
179 if (!--nDepthInsideSensitive) {
181 filter_ranges.emplace_back(filter_begin_pos, chpos);
182 filter_begin_pos = 0;
188 std::string strCommandTerminated = strCommand;
189 if (strCommandTerminated.back() !=
'\n')
190 strCommandTerminated +=
"\n";
191 for (chpos = 0; chpos < strCommandTerminated.size(); ++chpos)
193 char ch = strCommandTerminated[chpos];
196 case STATE_COMMAND_EXECUTED_INNER:
197 case STATE_COMMAND_EXECUTED:
199 bool breakParsing =
true;
202 case '[': curarg.clear(); state = STATE_COMMAND_EXECUTED_INNER;
break;
204 if (state == STATE_COMMAND_EXECUTED_INNER)
212 if (curarg.size() && fExecute)
218 const auto parsed{ToIntegral<size_t>(curarg)};
220 throw std::runtime_error(
"Invalid result query");
222 subelement = lastResult[parsed.value()];
227 throw std::runtime_error(
"Invalid result query");
228 lastResult = subelement;
231 state = STATE_COMMAND_EXECUTED;
235 breakParsing =
false;
241 if (lastResult.
isStr())
244 curarg = lastResult.
write(2);
250 add_to_current_stack(curarg);
256 state = STATE_EATING_SPACES;
263 case STATE_EATING_SPACES_IN_ARG:
264 case STATE_EATING_SPACES_IN_BRACKETS:
265 case STATE_EATING_SPACES:
268 case '"': state = STATE_DOUBLEQUOTED;
break;
269 case '\'': state = STATE_SINGLEQUOTED;
break;
270 case '\\': state = STATE_ESCAPE_OUTER;
break;
271 case '(':
case ')':
case '\n':
272 if (state == STATE_EATING_SPACES_IN_ARG)
273 throw std::runtime_error(
"Invalid Syntax");
274 if (state == STATE_ARGUMENT)
276 if (ch ==
'(' && stack.size() && stack.back().size() > 0)
278 if (nDepthInsideSensitive) {
279 ++nDepthInsideSensitive;
281 stack.emplace_back();
286 throw std::runtime_error(
"Invalid Syntax");
288 add_to_current_stack(curarg);
290 state = STATE_EATING_SPACES_IN_BRACKETS;
292 if ((ch ==
')' || ch ==
'\n') && stack.size() > 0)
297 UniValue params =
RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end()));
298 std::string method = stack.back()[0];
300 if (!wallet_name.isEmpty()) {
301 QByteArray encodedName = QUrl::toPercentEncoding(wallet_name);
302 uri =
"/wallet/"+std::string(encodedName.constData(), encodedName.length());
305 lastResult =
node->executeRpc(method, params, uri);
308 state = STATE_COMMAND_EXECUTED;
312 case ' ':
case ',':
case '\t':
313 if(state == STATE_EATING_SPACES_IN_ARG && curarg.empty() && ch ==
',')
314 throw std::runtime_error(
"Invalid Syntax");
316 else if(state == STATE_ARGUMENT)
318 add_to_current_stack(curarg);
321 if ((state == STATE_EATING_SPACES_IN_BRACKETS || state == STATE_ARGUMENT) && ch ==
',')
323 state = STATE_EATING_SPACES_IN_ARG;
326 state = STATE_EATING_SPACES;
328 default: curarg += ch; state = STATE_ARGUMENT;
331 case STATE_SINGLEQUOTED:
334 case '\'': state = STATE_ARGUMENT;
break;
335 default: curarg += ch;
338 case STATE_DOUBLEQUOTED:
341 case '"': state = STATE_ARGUMENT;
break;
342 case '\\': state = STATE_ESCAPE_DOUBLEQUOTED;
break;
343 default: curarg += ch;
346 case STATE_ESCAPE_OUTER:
347 curarg += ch; state = STATE_ARGUMENT;
349 case STATE_ESCAPE_DOUBLEQUOTED:
350 if(ch !=
'"' && ch !=
'\\') curarg +=
'\\';
351 curarg += ch; state = STATE_DOUBLEQUOTED;
355 if (pstrFilteredOut) {
356 if (STATE_COMMAND_EXECUTED == state) {
360 *pstrFilteredOut = strCommand;
361 for (
auto i = filter_ranges.rbegin(); i != filter_ranges.rend(); ++i) {
362 pstrFilteredOut->replace(i->first, i->second - i->first,
"(…)");
367 case STATE_COMMAND_EXECUTED:
368 if (lastResult.
isStr())
369 strResult = lastResult.
get_str();
371 strResult = lastResult.
write(2);
374 case STATE_EATING_SPACES:
386 std::string executableCommand =
command.toStdString() +
"\n";
389 if(executableCommand ==
"help-console\n") {
391 "This console accepts RPC commands using the standard syntax.\n"
392 " example: getblockhash 0\n\n"
394 "This console can also accept RPC commands using the parenthesized syntax.\n"
395 " example: getblockhash(0)\n\n"
397 "Commands may be nested when specified with the parenthesized syntax.\n"
398 " example: getblock(getblockhash(0) 1)\n\n"
400 "A space or a comma can be used to delimit arguments for either syntax.\n"
401 " example: getblockhash 0\n"
402 " getblockhash,0\n\n"
404 "Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n"
405 " example: getblock(getblockhash(0) 1)[tx]\n\n"
407 "Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n"
408 " example: getblock(getblockhash(0),1)[tx][0]\n\n")));
426 catch (
const std::runtime_error&)
431 catch (
const std::exception& e)
441 platformStyle(_platformStyle)
448 if (!restoreGeometry(settings.value(
"RPCConsoleWindowGeometry").toByteArray())) {
450 move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
452 ui->splitter->restoreState(settings.value(
"RPCConsoleWindowPeersTabSplitterSizes").toByteArray());
457 ui->splitter->restoreState(settings.value(
"RPCConsoleWidgetPeersTabSplitterSizes").toByteArray());
463 constexpr QChar nonbreaking_hyphen(8209);
466 tr(
"Inbound: initiated by peer"),
470 tr(
"Outbound Full Relay: default"),
473 tr(
"Outbound Block Relay: does not relay transactions or addresses"),
478 tr(
"Outbound Manual: added using RPC %1 or %2/%3 configuration options")
480 .arg(QString(nonbreaking_hyphen) +
"addnode")
481 .arg(QString(nonbreaking_hyphen) +
"connect"),
484 tr(
"Outbound Feeler: short-lived, for testing addresses"),
487 tr(
"Outbound Address Fetch: short-lived, for soliciting addresses")};
488 const QString connection_types_list{
"<ul><li>" +
Join(
CONNECTION_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
489 ui->peerConnectionTypeLabel->setToolTip(
ui->peerConnectionTypeLabel->toolTip().arg(connection_types_list));
492 tr(
"detecting: peer could be v1 or v2"),
494 tr(
"v1: unencrypted, plaintext transport protocol"),
496 tr(
"v2: BIP324 encrypted transport protocol")};
497 const QString transport_types_list{
"<ul><li>" +
Join(
TRANSPORT_TYPE_DOC, QString(
"</li><li>")) +
"</li></ul>"};
498 ui->peerTransportTypeLabel->setToolTip(
ui->peerTransportTypeLabel->toolTip().arg(transport_types_list));
499 const QString hb_list{
"<ul><li>\""
500 +
ts.
to +
"\" – " + tr(
"we selected the peer for high bandwidth relay") +
"</li><li>\""
501 +
ts.
from +
"\" – " + tr(
"the peer selected us for high bandwidth relay") +
"</li><li>\""
502 +
ts.
no +
"\" – " + tr(
"no high bandwidth relay selected") +
"</li></ul>"};
503 ui->peerHighBandwidthLabel->setToolTip(
ui->peerHighBandwidthLabel->toolTip().arg(hb_list));
504 ui->dataDir->setToolTip(
ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) +
"datadir"));
505 ui->blocksDir->setToolTip(
ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) +
"blocksdir"));
506 ui->openDebugLogfileButton->setToolTip(
ui->openDebugLogfileButton->toolTip().arg(CLIENT_NAME));
515 ui->fontBiggerButton->setShortcut(tr(
"Ctrl++"));
521 ui->fontSmallerButton->setShortcut(tr(
"Ctrl+-"));
528 ui->lineEdit->installEventFilter(
this);
529 ui->lineEdit->setMaxLength(16 * 1024 * 1024);
530 ui->messagesWidget->installEventFilter(
this);
533 connect(
ui->clearButton, &QAbstractButton::clicked, [
this] { clear(); });
539 ui->WalletSelector->setVisible(
false);
540 ui->WalletSelectorLabel->setVisible(
false);
559 settings.setValue(
"RPCConsoleWindowGeometry", saveGeometry());
560 settings.setValue(
"RPCConsoleWindowPeersTabSplitterSizes",
ui->splitter->saveState());
565 settings.setValue(
"RPCConsoleWidgetPeersTabSplitterSizes",
ui->splitter->saveState());
576 if(event->type() == QEvent::KeyPress)
578 QKeyEvent *keyevt =
static_cast<QKeyEvent*
>(event);
579 int key = keyevt->key();
580 Qt::KeyboardModifiers mod = keyevt->modifiers();
583 case Qt::Key_Up:
if(obj ==
ui->lineEdit) {
browseHistory(-1);
return true; }
break;
584 case Qt::Key_Down:
if(obj ==
ui->lineEdit) {
browseHistory(1);
return true; }
break;
586 case Qt::Key_PageDown:
587 if (obj ==
ui->lineEdit) {
588 QApplication::sendEvent(
ui->messagesWidget, keyevt);
596 QApplication::sendEvent(
ui->lineEdit, keyevt);
604 if(obj ==
ui->messagesWidget && (
605 (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) ||
606 ((mod & Qt::ControlModifier) && key == Qt::Key_V) ||
607 ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert)))
609 ui->lineEdit->setFocus();
610 QApplication::sendEvent(
ui->lineEdit, keyevt);
615 return QWidget::eventFilter(obj, event);
622 bool wallet_enabled{
false};
626 if (model && !wallet_enabled) {
632 ui->trafficGraph->setClientModel(model);
652 ui->peerWidget->verticalHeader()->hide();
653 ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
654 ui->peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
655 ui->peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
662 ui->peerWidget->horizontalHeader()->setSectionResizeMode(
PeerTableModel::Age, QHeaderView::ResizeToContents);
663 ui->peerWidget->horizontalHeader()->setStretchLastSection(
true);
682 connect(model->
getPeerTableModel(), &QAbstractItemModel::dataChanged, [
this] { updateDetailWidget(); });
686 ui->banlistWidget->verticalHeader()->hide();
687 ui->banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
688 ui->banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
689 ui->banlistWidget->setContextMenuPolicy(Qt::CustomContextMenu);
696 ui->banlistWidget->horizontalHeader()->setStretchLastSection(
true);
722 ui->networkName->setText(QString::fromStdString(
Params().GetChainTypeString()));
725 QStringList wordList;
727 for (
size_t i = 0; i < commandList.size(); ++i)
729 wordList << commandList[i].c_str();
730 wordList << (
"help " + commandList[i]).c_str();
733 wordList <<
"help-console";
736 autoCompleter->setModelSorting(QCompleter::CaseSensitivelySortedModel);
739 ui->lineEdit->setEnabled(
true);
753void RPCConsole::addWallet(
WalletModel *
const walletModel)
756 ui->WalletSelector->addItem(walletModel->
getDisplayName(), QVariant::fromValue(walletModel));
757 if (
ui->WalletSelector->count() == 2) {
759 ui->WalletSelector->setCurrentIndex(1);
761 if (
ui->WalletSelector->count() > 2) {
762 ui->WalletSelector->setVisible(
true);
763 ui->WalletSelectorLabel->setVisible(
true);
767void RPCConsole::removeWallet(
WalletModel *
const walletModel)
769 ui->WalletSelector->removeItem(
ui->WalletSelector->findData(QVariant::fromValue(walletModel)));
770 if (
ui->WalletSelector->count() == 2) {
771 ui->WalletSelector->setVisible(
false);
772 ui->WalletSelectorLabel->setVisible(
false);
776void RPCConsole::setCurrentWallet(
WalletModel*
const wallet_model)
778 QVariant
data = QVariant::fromValue(wallet_model);
779 ui->WalletSelector->setCurrentIndex(
ui->WalletSelector->findData(
data));
790 default:
return "misc";
813 QString str =
ui->messagesWidget->toHtml();
816 str.replace(QString(
"font-size:%1pt").arg(
consoleFontSize), QString(
"font-size:%1pt").arg(newSize));
823 float oldPosFactor = 1.0 /
ui->messagesWidget->verticalScrollBar()->maximum() *
ui->messagesWidget->verticalScrollBar()->value();
825 ui->messagesWidget->setHtml(str);
826 ui->messagesWidget->verticalScrollBar()->setValue(oldPosFactor *
ui->messagesWidget->verticalScrollBar()->maximum());
831 ui->messagesWidget->clear();
832 if (!keep_prompt)
ui->lineEdit->clear();
833 ui->lineEdit->setFocus();
839 ui->messagesWidget->document()->addResource(
840 QTextDocument::ImageResource,
851 ui->messagesWidget->document()->setDefaultStyleSheet(
854 "td.time { color: #808080; font-size: %2; padding-top: 3px; } "
855 "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } "
856 "td.cmd-request { color: #006060; } "
857 "td.cmd-error { color: red; } "
858 ".secwarning { color: red; }"
859 "b { color: #006060; } "
863 static const QString welcome_message =
867 tr(
"Welcome to the %1 RPC console.\n"
868 "Use up and down arrows to navigate history, and %2 to clear screen.\n"
869 "Use %3 and %4 to increase or decrease the font size.\n"
870 "Type %5 for an overview of available commands.\n"
871 "For more information on using this console, type %6.\n"
873 "%7WARNING: Scammers have been active, telling users to type"
874 " commands here, stealing their wallet contents. Do not use this console"
875 " without fully understanding the ramifications of a command.%8")
877 "<b>" +
ui->clearButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
878 "<b>" +
ui->fontBiggerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
879 "<b>" +
ui->fontSmallerButton->shortcut().toString(QKeySequence::NativeText) +
"</b>",
881 "<b>help-console</b>",
882 "<span class=\"secwarning\">",
897 if (e->type() == QEvent::PaletteChange) {
904 ui->messagesWidget->document()->addResource(
905 QTextDocument::ImageResource,
911 QWidget::changeEvent(e);
916 QTime time = QTime::currentTime();
917 QString timeString = time.toString();
919 out +=
"<table><tr><td class=\"time\" width=\"65\">" + timeString +
"</td>";
920 out +=
"<td class=\"icon\" width=\"32\"><img src=\"" +
categoryClass(category) +
"\"></td>";
921 out +=
"<td class=\"message " +
categoryClass(category) +
"\" valign=\"middle\">";
926 out +=
"</td></tr></table>";
927 ui->messagesWidget->append(
out);
938 connections +=
" (" + tr(
"Network activity disabled") +
")";
941 ui->numberOfConnections->setText(connections);
943 QString local_addresses;
945 for (
const auto& [addr, info] : hosts) {
946 local_addresses += QString::fromStdString(addr.ToStringAddr());
947 if (!addr.IsI2P()) local_addresses +=
":" + QString::number(info.nPort);
948 local_addresses +=
", ";
950 local_addresses.chop(2);
951 if (local_addresses.isEmpty()) local_addresses = tr(
"None");
953 ui->localAddresses->setText(local_addresses);
972 ui->numberOfBlocks->setText(QString::number(
count));
973 ui->lastBlockTime->setText(blockDate.toString());
979 ui->mempoolNumberTxs->setText(QString::number(numberOfTxs));
981 const auto cur_usage_str = dynUsage < 1000000 ?
982 QObject::tr(
"%1 kB").arg(dynUsage / 1000.0, 0,
'f', 2) :
983 QObject::tr(
"%1 MB").arg(dynUsage / 1000000.0, 0,
'f', 2);
984 const auto max_usage_str = QObject::tr(
"%1 MB").arg(maxUsage / 1000000.0, 0,
'f', 2);
986 ui->mempoolSize->setText(cur_usage_str +
" / " + max_usage_str);
991 QString
cmd =
ui->lineEdit->text().trimmed();
997 std::string strFilteredCmd;
1002 throw std::runtime_error(
"Invalid command line");
1004 }
catch (
const std::exception& e) {
1005 QMessageBox::critical(
this,
"Error", QString(
"Error: ") + QString::fromStdString(e.what()));
1010 if (
cmd == QLatin1String(
"stop")) {
1020 ui->lineEdit->clear();
1022 QString in_use_wallet_name;
1025 in_use_wallet_name = wallet_model ? wallet_model->
getWalletName() : QString();
1041 QMetaObject::invokeMethod(
m_executor, [
this,
cmd, in_use_wallet_name] {
1045 cmd = QString::fromStdString(strFilteredCmd);
1080 ui->lineEdit->setText(
cmd);
1091 ui->messagesWidget->undo();
1098 connect(&
thread, &QThread::finished,
m_executor, &RPCExecutor::deleteLater);
1110 if (
ui->tabWidget->widget(index) ==
ui->tab_console) {
1111 ui->lineEdit->setFocus();
1122 QScrollBar *scrollbar =
ui->messagesWidget->verticalScrollBar();
1123 scrollbar->setValue(scrollbar->maximum());
1128 const int multiplier = 5;
1129 int mins = value * multiplier;
1135 ui->trafficGraph->setGraphRange(std::chrono::minutes{mins});
1149 ui->peersTabRightPanel->hide();
1150 ui->peerHeading->setText(tr(
"Select a peer to view detailed information."));
1155 QString peerAddrDetails(QString::fromStdString(stats->nodeStats.m_addr_name) +
" ");
1156 peerAddrDetails += tr(
"(peer: %1)").arg(QString::number(stats->nodeStats.nodeid));
1157 if (!stats->nodeStats.addrLocal.empty())
1158 peerAddrDetails +=
"<br />" + tr(
"via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
1159 ui->peerHeading->setText(peerAddrDetails);
1160 QString bip152_hb_settings;
1161 if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings =
ts.
to;
1162 if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings.isEmpty() ?
ts.
from : QLatin1Char(
'/') +
ts.
from);
1163 if (bip152_hb_settings.isEmpty()) bip152_hb_settings =
ts.
no;
1164 ui->peerHighBandwidth->setText(bip152_hb_settings);
1165 const auto time_now{GetTime<std::chrono::seconds>()};
1167 ui->peerLastBlock->setText(
TimeDurationField(time_now, stats->nodeStats.m_last_block_time));
1175 if (stats->nodeStats.nVersion) {
1176 ui->peerVersion->setText(QString::number(stats->nodeStats.nVersion));
1178 if (!stats->nodeStats.cleanSubVer.empty()) {
1179 ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
1182 ui->peerTransportType->setText(QString::fromStdString(
TransportTypeAsString(stats->nodeStats.m_transport_type)));
1184 ui->peerSessionIdLabel->setVisible(
true);
1185 ui->peerSessionId->setVisible(
true);
1186 ui->peerSessionId->setText(QString::fromStdString(stats->nodeStats.m_session_id));
1188 ui->peerSessionIdLabel->setVisible(
false);
1189 ui->peerSessionId->setVisible(
false);
1193 ui->peerPermissions->setText(
ts.
na);
1195 QStringList permissions;
1197 permissions.append(QString::fromStdString(permission));
1199 ui->peerPermissions->setText(permissions.join(
" & "));
1201 ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) :
ts.
na);
1205 if (stats->fNodeStateStatsAvailable) {
1209 if (stats->nodeStateStats.nSyncHeight > -1) {
1210 ui->peerSyncHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nSyncHeight));
1215 if (stats->nodeStateStats.nCommonHeight > -1) {
1216 ui->peerCommonHeight->setText(QString(
"%1").arg(stats->nodeStateStats.nCommonHeight));
1220 ui->peerHeight->setText(QString::number(stats->nodeStateStats.m_starting_height));
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.
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
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)
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 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[]