Changeset View
Changeset View
Standalone View
Standalone View
src/qt/rpcconsole.cpp
// Copyright (c) 2011-2016 The Bitcoin Core developers | // Copyright (c) 2011-2019 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#if defined(HAVE_CONFIG_H) | #if defined(HAVE_CONFIG_H) | ||||
#include <config/bitcoin-config.h> | #include <config/bitcoin-config.h> | ||||
#endif | #endif | ||||
#include <qt/rpcconsole.h> | #include <qt/rpcconsole.h> | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
/* Object for executing console RPC commands in a separate thread. | /* Object for executing console RPC commands in a separate thread. | ||||
*/ | */ | ||||
class RPCExecutor : public QObject { | class RPCExecutor : public QObject { | ||||
Q_OBJECT | Q_OBJECT | ||||
public: | public: | ||||
RPCExecutor(interfaces::Node &node) : m_node(node) {} | RPCExecutor(interfaces::Node &node) : m_node(node) {} | ||||
public Q_SLOTS: | public Q_SLOTS: | ||||
void request(const QString &command, const QString &walletID); | void request(const QString &command, const WalletModel *wallet_model); | ||||
Q_SIGNALS: | Q_SIGNALS: | ||||
void reply(int category, const QString &command); | void reply(int category, const QString &command); | ||||
private: | private: | ||||
interfaces::Node &m_node; | interfaces::Node &m_node; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
* data | * data | ||||
*/ | */ | ||||
bool RPCConsole::RPCParseCommandLine(interfaces::Node *node, | bool RPCConsole::RPCParseCommandLine(interfaces::Node *node, | ||||
std::string &strResult, | std::string &strResult, | ||||
const std::string &strCommand, | const std::string &strCommand, | ||||
const bool fExecute, | const bool fExecute, | ||||
std::string *const pstrFilteredOut, | std::string *const pstrFilteredOut, | ||||
const std::string *walletID) { | const WalletModel *wallet_model) { | ||||
std::vector<std::vector<std::string>> stack; | std::vector<std::vector<std::string>> stack; | ||||
stack.push_back(std::vector<std::string>()); | stack.push_back(std::vector<std::string>()); | ||||
enum CmdParseState { | enum CmdParseState { | ||||
STATE_EATING_SPACES, | STATE_EATING_SPACES, | ||||
STATE_EATING_SPACES_IN_ARG, | STATE_EATING_SPACES_IN_ARG, | ||||
STATE_EATING_SPACES_IN_BRACKETS, | STATE_EATING_SPACES_IN_BRACKETS, | ||||
STATE_ARGUMENT, | STATE_ARGUMENT, | ||||
▲ Show 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | for (chpos = 0; chpos < strCommandTerminated.size(); ++chpos) { | ||||
stack.back()[0], | stack.back()[0], | ||||
std::vector<std::string>( | std::vector<std::string>( | ||||
stack.back().begin() + 1, | stack.back().begin() + 1, | ||||
stack.back().end())); | stack.back().end())); | ||||
std::string method = stack.back()[0]; | std::string method = stack.back()[0]; | ||||
std::string uri; | std::string uri; | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
if (walletID) { | if (wallet_model) { | ||||
QByteArray encodedName = | QByteArray encodedName = | ||||
QUrl::toPercentEncoding( | QUrl::toPercentEncoding( | ||||
QString::fromStdString(*walletID)); | wallet_model->getWalletName()); | ||||
uri = "/wallet/" + | uri = "/wallet/" + | ||||
std::string(encodedName.constData(), | std::string(encodedName.constData(), | ||||
encodedName.length()); | encodedName.length()); | ||||
} | } | ||||
#endif | #endif | ||||
GlobalConfig config; | GlobalConfig config; | ||||
assert(node); | assert(node); | ||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | switch (state) { | ||||
case STATE_ARGUMENT: | case STATE_ARGUMENT: | ||||
case STATE_EATING_SPACES: | case STATE_EATING_SPACES: | ||||
return true; | return true; | ||||
default: // ERROR to end in one of the other states | default: // ERROR to end in one of the other states | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
void RPCExecutor::request(const QString &command, const QString &walletID) { | void RPCExecutor::request(const QString &command, | ||||
const WalletModel *wallet_model) { | |||||
try { | try { | ||||
std::string result; | std::string result; | ||||
std::string executableCommand = command.toStdString() + "\n"; | std::string executableCommand = command.toStdString() + "\n"; | ||||
// Catch the console-only-help command before RPC call is executed and | // Catch the console-only-help command before RPC call is executed and | ||||
// reply with help text as-if a RPC reply. | // reply with help text as-if a RPC reply. | ||||
if (executableCommand == "help-console\n") { | if (executableCommand == "help-console\n") { | ||||
Q_EMIT reply( | Q_EMIT reply( | ||||
Show All 21 Lines | try { | ||||
" example: getblock(getblockhash(0) true)[tx]\n\n" | " example: getblock(getblockhash(0) true)[tx]\n\n" | ||||
"Results without keys can be queried using an integer " | "Results without keys can be queried using an integer " | ||||
"in brackets.\n" | "in brackets.\n" | ||||
" example: " | " example: " | ||||
"getblock(getblockhash(0),true)[tx][0]\n\n"))); | "getblock(getblockhash(0),true)[tx][0]\n\n"))); | ||||
return; | return; | ||||
} | } | ||||
std::string wallet_id = walletID.toStdString(); | |||||
if (!RPCConsole::RPCExecuteCommandLine( | if (!RPCConsole::RPCExecuteCommandLine( | ||||
m_node, result, executableCommand, nullptr, | m_node, result, executableCommand, nullptr, wallet_model)) { | ||||
walletID.isNull() ? nullptr : &wallet_id)) { | |||||
Q_EMIT reply(RPCConsole::CMD_ERROR, | Q_EMIT reply(RPCConsole::CMD_ERROR, | ||||
QString("Parse error: unbalanced ' or \"")); | QString("Parse error: unbalanced ' or \"")); | ||||
return; | return; | ||||
} | } | ||||
Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(result)); | Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(result)); | ||||
} catch (UniValue &objError) { | } catch (UniValue &objError) { | ||||
// Nice formatting for standard-format error | // Nice formatting for standard-format error | ||||
▲ Show 20 Lines • Show All 319 Lines • ▼ Show 20 Lines | if (!model) { | ||||
// called. Make sure we clean up the executor thread | // called. Make sure we clean up the executor thread | ||||
Q_EMIT stopExecutor(); | Q_EMIT stopExecutor(); | ||||
thread.wait(); | thread.wait(); | ||||
} | } | ||||
} | } | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
void RPCConsole::addWallet(WalletModel *const walletModel) { | void RPCConsole::addWallet(WalletModel *const walletModel) { | ||||
const QString name = walletModel->getWalletName(); | // use name for text and wallet model for internal data object (to allow to | ||||
// use name for text and internal data object (to allow to move to a wallet | // move to a wallet id later) | ||||
// id later) | ui->WalletSelector->addItem(walletModel->getDisplayName(), | ||||
QString display_name = | QVariant::fromValue(walletModel)); | ||||
name.isEmpty() ? "[" + tr("default wallet") + "]" : name; | |||||
ui->WalletSelector->addItem(display_name, name); | |||||
if (ui->WalletSelector->count() == 2 && !isVisible()) { | if (ui->WalletSelector->count() == 2 && !isVisible()) { | ||||
// First wallet added, set to default so long as the window isn't | // First wallet added, set to default so long as the window isn't | ||||
// presently visible (and potentially in use) | // presently visible (and potentially in use) | ||||
ui->WalletSelector->setCurrentIndex(1); | ui->WalletSelector->setCurrentIndex(1); | ||||
} | } | ||||
if (ui->WalletSelector->count() > 2) { | if (ui->WalletSelector->count() > 2) { | ||||
ui->WalletSelector->setVisible(true); | ui->WalletSelector->setVisible(true); | ||||
ui->WalletSelectorLabel->setVisible(true); | ui->WalletSelectorLabel->setVisible(true); | ||||
} | } | ||||
} | } | ||||
void RPCConsole::removeWallet(WalletModel *const walletModel) { | void RPCConsole::removeWallet(WalletModel *const walletModel) { | ||||
const QString name = walletModel->getWalletName(); | ui->WalletSelector->removeItem( | ||||
ui->WalletSelector->removeItem(ui->WalletSelector->findData(name)); | ui->WalletSelector->findData(QVariant::fromValue(walletModel))); | ||||
if (ui->WalletSelector->count() == 2) { | if (ui->WalletSelector->count() == 2) { | ||||
ui->WalletSelector->setVisible(false); | ui->WalletSelector->setVisible(false); | ||||
ui->WalletSelectorLabel->setVisible(false); | ui->WalletSelectorLabel->setVisible(false); | ||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
static QString categoryClass(int category) { | static QString categoryClass(int category) { | ||||
▲ Show 20 Lines • Show All 200 Lines • ▼ Show 20 Lines | if (!cmd.isEmpty()) { | ||||
QString::fromStdString(e.what())); | QString::fromStdString(e.what())); | ||||
return; | return; | ||||
} | } | ||||
ui->lineEdit->clear(); | ui->lineEdit->clear(); | ||||
cmdBeforeBrowsing = QString(); | cmdBeforeBrowsing = QString(); | ||||
QString walletID; | WalletModel *wallet_model{nullptr}; | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
const int wallet_index = ui->WalletSelector->currentIndex(); | const int wallet_index = ui->WalletSelector->currentIndex(); | ||||
if (wallet_index > 0) { | if (wallet_index > 0) { | ||||
walletID = (QString)ui->WalletSelector->itemData(wallet_index) | wallet_model = ui->WalletSelector->itemData(wallet_index) | ||||
.value<QString>(); | .value<WalletModel *>(); | ||||
} | } | ||||
if (m_last_wallet_id != walletID) { | if (m_last_wallet_model != wallet_model) { | ||||
if (walletID.isNull()) { | if (wallet_model) { | ||||
message(CMD_REQUEST, tr("Executing command using \"%1\" wallet") | |||||
.arg(wallet_model->getWalletName())); | |||||
} else { | |||||
message(CMD_REQUEST, | message(CMD_REQUEST, | ||||
tr("Executing command without any wallet")); | tr("Executing command without any wallet")); | ||||
} else { | |||||
message( | |||||
CMD_REQUEST, | |||||
tr("Executing command using \"%1\" wallet").arg(walletID)); | |||||
} | } | ||||
m_last_wallet_id = walletID; | m_last_wallet_model = wallet_model; | ||||
} | } | ||||
#endif | #endif | ||||
message(CMD_REQUEST, QString::fromStdString(strFilteredCmd)); | message(CMD_REQUEST, QString::fromStdString(strFilteredCmd)); | ||||
Q_EMIT cmdRequest(cmd, walletID); | Q_EMIT cmdRequest(cmd, m_last_wallet_model); | ||||
cmd = QString::fromStdString(strFilteredCmd); | cmd = QString::fromStdString(strFilteredCmd); | ||||
// Remove command, if already in history | // Remove command, if already in history | ||||
history.removeOne(cmd); | history.removeOne(cmd); | ||||
// Append command to history | // Append command to history | ||||
history.append(cmd); | history.append(cmd); | ||||
// Enforce maximum history size | // Enforce maximum history size | ||||
▲ Show 20 Lines • Show All 366 Lines • Show Last 20 Lines |