|
23 | 23 | #include <util/strencodings.h> |
24 | 24 | #include <util/string.h> |
25 | 25 | #include <util/threadnames.h> |
26 | | - |
| 26 | +#include <util/chaintype.h> |
27 | 27 | #include <univalue.h> |
28 | 28 |
|
29 | 29 | #include <QAbstractButton> |
@@ -95,12 +95,15 @@ public Q_SLOTS: |
95 | 95 |
|
96 | 96 | private: |
97 | 97 | interfaces::Node& m_node; |
| 98 | + bool executeConsoleGenerate(const std::vector<std::string>& parsed_command, const WalletModel* wallet_model, const bool exec_help = false); |
| 99 | + void executeConsoleHelpGenerate(); |
98 | 100 | bool executeConsoleHelpConsole(const std::vector<std::string>& parsed_command, const WalletModel* wallet_model, const bool exec_help = false); |
99 | 101 | bool executeConsoleOnlyCommand(const std::string& command, const WalletModel* wallet_model); |
100 | 102 | // std::map mapping strings to methods member of RPCExecutor class |
101 | 103 | // Keys must be strings with commands and (optionally) parameters in "canonical" form (separated by single space) |
102 | 104 | // Keys should match the beggining of user input commands (user commands can have more parameters than the key) |
103 | 105 | std::map<std::string, bool (RPCExecutor::*)(const std::vector<std::string>&, const WalletModel*, const bool)> m_method_map{ |
| 106 | + {"generate", &RPCExecutor::executeConsoleGenerate}, |
104 | 107 | {"help-console", &RPCExecutor::executeConsoleHelpConsole}}; |
105 | 108 | }; |
106 | 109 |
|
@@ -468,6 +471,73 @@ void RPCExecutor::request(const QString &command, const WalletModel* wallet_mode |
468 | 471 | } |
469 | 472 | } |
470 | 473 |
|
| 474 | +/** |
| 475 | + * @brief Executes the console-only command "generate". |
| 476 | + * @param parsed_command A vector of strings with command and parameters, usually generated by RPCExecutor::parseHelper |
| 477 | + * @param wallet_model WalletModel to use for the command |
| 478 | + * @return True if the command was executed, false otherwise. |
| 479 | + */ |
| 480 | +bool RPCExecutor::executeConsoleGenerate(const std::vector<std::string>& parsed_command, const WalletModel* wallet_model, const bool exec_help) |
| 481 | +{ |
| 482 | + // Initialize default parameters if missing |
| 483 | + const std::string nblocks{parsed_command.size() > 1 ? parsed_command[1] : "1"}; |
| 484 | + const std::string maxtries{parsed_command.size() > 2 ? parsed_command[2] : "1000000"}; |
| 485 | + |
| 486 | + // Handle some special cases... |
| 487 | + // Default to console help generate if more than 3 parameters or if "help generate" was called |
| 488 | + if (parsed_command.size() > 3 || exec_help) { |
| 489 | + executeConsoleHelpGenerate(); |
| 490 | + return true; |
| 491 | + } |
| 492 | + // Fail if we are on mainnet, to avoid generating addresses for blocks that will not be generated |
| 493 | + if (Params().GetChainType() == ChainType::MAIN) { |
| 494 | + Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Error: generate is not available on mainnet")); |
| 495 | + return true; |
| 496 | + } |
| 497 | + // Fail if parameters are not positive integers |
| 498 | + const auto nblocks_value{ToIntegral<int>(nblocks)}; |
| 499 | + const auto maxtries_value{ToIntegral<int>(maxtries)}; |
| 500 | + if (!nblocks_value || !maxtries_value || nblocks_value.value() <= 0 || maxtries_value.value() <= 0) { |
| 501 | + Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Error: parameters must be positive integers")); |
| 502 | + return true; |
| 503 | + } |
| 504 | + |
| 505 | + // Catch the console-only generate command with 2 or less parameters before RPC call is executed . |
| 506 | + std::string blocks; |
| 507 | + std::string address; |
| 508 | + if (!RPCConsole::RPCExecuteCommandLine(m_node, address, "getnewaddress\n", /*pstrFilteredOut=*/nullptr, wallet_model)) { |
| 509 | + Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Error: could not generate new address")); |
| 510 | + } else { |
| 511 | + if (!RPCConsole::RPCExecuteCommandLine(m_node, blocks, "generatetoaddress " + nblocks + " " + address + " " + maxtries + "\n", /*pstrFilteredOut=*/nullptr, wallet_model)) { |
| 512 | + Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Error: could not generate blocks")); |
| 513 | + } else { |
| 514 | + UniValue result{UniValue::VOBJ}; |
| 515 | + UniValue blocks_object{UniValue::VOBJ}; |
| 516 | + blocks_object.read(blocks); |
| 517 | + result.pushKV("address", address); |
| 518 | + result.pushKV("blocks", blocks_object); |
| 519 | + Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString("\n" + result.write(2) + "\n\n")); |
| 520 | + } |
| 521 | + } |
| 522 | + return true; |
| 523 | +} |
| 524 | + |
| 525 | +/** |
| 526 | + * @brief Executes the console-only command "help generate". |
| 527 | + */ |
| 528 | +void RPCExecutor::executeConsoleHelpGenerate() |
| 529 | +{ |
| 530 | + // Execute the console-only "help generate" command. |
| 531 | + Q_EMIT reply(RPCConsole::CMD_REPLY, |
| 532 | + QString("\n" |
| 533 | + "Generate blocks, equivalent to RPC getnewaddress followed by RPC generatetoaddress.\n" |
| 534 | + "Optional positive integer arguments are number of blocks to generate and maximum iterations to try.\n" |
| 535 | + "Equivalent to RPC generatetoaddress nblocks and maxtries arguments.\n" |
| 536 | + " example: generate\n" |
| 537 | + " example: generate 4\n" |
| 538 | + " example: generate 3 6000\n\n")); |
| 539 | +} |
| 540 | + |
471 | 541 | /** |
472 | 542 | * @brief Executes the console-only command "help-console". |
473 | 543 | * @param parsed_command A vector of strings with command and parameters, usually generated by RPCExecutor::parseHelper |
|
0 commit comments