-
Notifications
You must be signed in to change notification settings - Fork 266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Debug Console implementation of generate method #692
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,8 +96,33 @@ public Q_SLOTS: | |
|
||
private: | ||
interfaces::Node& m_node; | ||
bool executeConsoleHelpConsole(const std::vector<std::string>& parsed_command, const WalletModel* wallet_model, const bool exec_help = false); | ||
bool executeConsoleOnlyCommand(const std::string& command, const WalletModel* wallet_model); | ||
// std::map mapping strings to methods member of RPCExecutor class | ||
// Keys must be strings with commands and (optionally) parameters in "canonical" form (separated by single space) | ||
// Keys should match the beggining of user input commands (user commands can have more parameters than the key) | ||
std::map<std::string, bool (RPCExecutor::*)(const std::vector<std::string>&, const WalletModel*, const bool)> m_method_map{ | ||
{"help-console", &RPCExecutor::executeConsoleHelpConsole}}; | ||
}; | ||
|
||
/** | ||
* Small and fast parser supporting console command syntax, with limited functionality. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function iterates over the entire input command string twice. It isn't really "fast". |
||
* Splits a command line string into a vector with command at position 0, and parameters after | ||
* | ||
* @param[in] strCommand Command line to parse | ||
* | ||
* @return a vector of strings with command and parameters | ||
*/ | ||
std::vector<std::string> parseHelper(const std::string& strCommand) | ||
{ | ||
// Split while recognizing the several characters that can be used as separators in the GUI console | ||
std::vector<std::string> vec{SplitString(strCommand, " (),")}; | ||
hernanmarino marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Remove empty strings produced by consecutive separators | ||
auto should_remove{[](const std::string& str) { return str.empty(); }}; | ||
vec.erase(std::remove_if(vec.begin(), vec.end(), should_remove), vec.end()); | ||
return vec; | ||
} | ||
|
||
/** Class for handling RPC timers | ||
* (used for e.g. re-locking the wallet after a timeout) | ||
*/ | ||
|
@@ -415,35 +440,15 @@ void RPCExecutor::request(const QString &command, const WalletModel* wallet_mode | |
std::string result; | ||
std::string executableCommand = command.toStdString() + "\n"; | ||
|
||
// Catch the console-only-help command before RPC call is executed and reply with help text as-if a RPC reply. | ||
if(executableCommand == "help-console\n") { | ||
Q_EMIT reply(RPCConsole::CMD_REPLY, QString(("\n" | ||
"This console accepts RPC commands using the standard syntax.\n" | ||
" example: getblockhash 0\n\n" | ||
|
||
"This console can also accept RPC commands using the parenthesized syntax.\n" | ||
" example: getblockhash(0)\n\n" | ||
|
||
"Commands may be nested when specified with the parenthesized syntax.\n" | ||
" example: getblock(getblockhash(0) 1)\n\n" | ||
|
||
"A space or a comma can be used to delimit arguments for either syntax.\n" | ||
" example: getblockhash 0\n" | ||
" getblockhash,0\n\n" | ||
|
||
"Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n" | ||
" example: getblock(getblockhash(0) 1)[tx]\n\n" | ||
|
||
"Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n" | ||
" example: getblock(getblockhash(0),1)[tx][0]\n\n"))); | ||
return; | ||
} | ||
if (!RPCConsole::RPCExecuteCommandLine(m_node, result, executableCommand, nullptr, wallet_model)) { | ||
Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \"")); | ||
return; | ||
// Attempt to execute console-only commands | ||
if (!RPCExecutor::executeConsoleOnlyCommand(command.toStdString(), wallet_model)) { | ||
// Send to the RPC command parser if not console-only | ||
if (!RPCConsole::RPCExecuteCommandLine(m_node, result, executableCommand, nullptr, wallet_model)) { | ||
Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \"")); | ||
return; | ||
} | ||
Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(result)); | ||
Comment on lines
+447
to
+453
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an indentation issue here. |
||
} | ||
|
||
Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(result)); | ||
} | ||
catch (UniValue& objError) | ||
{ | ||
|
@@ -464,6 +469,59 @@ void RPCExecutor::request(const QString &command, const WalletModel* wallet_mode | |
} | ||
} | ||
|
||
/** | ||
* @brief Executes the console-only command "help-console". | ||
* @param parsed_command A vector of strings with command and parameters, usually generated by RPCExecutor::parseHelper | ||
* @param wallet_model WalletModel to use for the command | ||
* @return True if the command was executed, false otherwise. | ||
*/ | ||
bool RPCExecutor::executeConsoleHelpConsole(const std::vector<std::string>& parsed_command, const WalletModel* wallet_model, const bool exec_help) | ||
{ | ||
// Reply with help text as-if a RPC reply. | ||
Q_EMIT reply(RPCConsole::CMD_REPLY, | ||
QString("\n" | ||
"This console accepts RPC commands using the standard syntax.\n" | ||
" example: getblockhash 0\n\n" | ||
"This console can also accept RPC commands using the parenthesized syntax.\n" | ||
" example: getblockhash(0)\n\n" | ||
"Commands may be nested when specified with the parenthesized syntax.\n" | ||
" example: getblock(getblockhash(0) 1)\n\n" | ||
"A space or a comma can be used to delimit arguments for either syntax.\n" | ||
" example: getblockhash 0\n" | ||
" getblockhash,0\n\n" | ||
"Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n" | ||
" example: getblock(getblockhash(0) 1)[tx]\n\n" | ||
"Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n" | ||
" example: getblock(getblockhash(0),1)[tx][0]\n\n")); | ||
return true; | ||
} | ||
|
||
/** | ||
* Catches console-only command before a RPC call is executed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't be here. The function's docstrings shouldn't explain the caller workflow behavior. |
||
* | ||
* @param[in] command Command line to execute | ||
* @param[in] wallet_model Wallet model to use | ||
* @return true if command was handled by this method (even on errors), false otherwise | ||
* | ||
*/ | ||
bool RPCExecutor::executeConsoleOnlyCommand(const std::string& command, const WalletModel* wallet_model) | ||
hernanmarino marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
// Parse command line into a vector of strings | ||
const std::vector<std::string> parsed_command{parseHelper(command)}; | ||
|
||
if (parsed_command.empty()) return false; | ||
|
||
std::string method = parsed_command[0]; | ||
bool exec_help = false; | ||
if (method == "help" && parsed_command.size() > 1) { | ||
exec_help = true; | ||
method = parsed_command[1]; | ||
} | ||
auto it_method = m_method_map.find(method); | ||
if (it_method == m_method_map.end()) return false; // method not found | ||
return (this->*(it_method->second))(parsed_command, wallet_model, exec_help); | ||
} | ||
|
||
RPCConsole::RPCConsole(interfaces::Node& node, const PlatformStyle *_platformStyle, QWidget *parent) : | ||
QWidget(parent), | ||
m_node(node), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case you retouch this; these functions should return a
util::Result<QString>
instead of a boolean. This way, the returned string can be emitted at the caller side (same as it is done for the RPC commands). This will improve the existing structure that has all functions returning true on all code paths.