diff --git a/src/common/args.cpp b/src/common/args.cpp index 7195c1cc097bc..4069fba1c9f03 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -359,6 +359,29 @@ std::optional ArgsManager::GetCommand() const return ret; } +bool ArgsManager::CheckCommandOptions(const std::string& command, std::vector* errors) const +{ + LOCK(cs_args); + + auto command_options = m_available_args.find(OptionsCategory::COMMAND_OPTIONS); + if (command_options == m_available_args.end()) return true; + + const std::set dummy; + auto command_args = m_command_args.find(command); + const std::set& valid_opts = (command_args == m_command_args.end() ? dummy : command_args->second); + + bool ok = true; + for (const auto& opts : command_options->second) { + if (!IsArgSet(opts.first)) continue; + if (valid_opts.count(opts.first)) continue; + if (errors != nullptr) { + errors->emplace_back(strprintf("The %s option cannot be used with the '%s' command.", opts.first, command)); + ok = false; + } + } + return ok; +} + std::vector ArgsManager::GetArgs(const std::string& strArg) const { std::vector result; diff --git a/src/common/args.h b/src/common/args.h index 1e48221d2adfc..11b387726be2f 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -214,6 +214,11 @@ class ArgsManager */ std::optional GetCommand() const; + /** + * Check for invalid command options + */ + bool CheckCommandOptions(const std::string& command, std::vector* errors = nullptr) const; + /** * Get blocks directory path * diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp index 10785ad3546fe..4dab9fbfb5e4b 100644 --- a/src/wallet/wallettool.cpp +++ b/src/wallet/wallettool.cpp @@ -112,21 +112,12 @@ static void WalletShowInfo(CWallet* wallet_instance) bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command) { - if (args.IsArgSet("-format") && command != "createfromdump") { - tfm::format(std::cerr, "The -format option can only be used with the \"createfromdump\" command.\n"); - return false; - } - if (args.IsArgSet("-dumpfile") && command != "dump" && command != "createfromdump") { - tfm::format(std::cerr, "The -dumpfile option can only be used with the \"dump\" and \"createfromdump\" commands.\n"); - return false; - } - if (args.IsArgSet("-descriptors") && command != "create") { - tfm::format(std::cerr, "The -descriptors option can only be used with the 'create' command.\n"); - return false; - } - if (args.IsArgSet("-legacy") && command != "create") { - tfm::format(std::cerr, "The -legacy option can only be used with the 'create' command.\n"); - return false; + { + std::vector details; + if (!args.CheckCommandOptions(command, &details)) { + tfm::format(std::cerr, "Error: Invalid arguments provided:\n%s\n", util::MakeUnorderedList(details)); + return false; + } } if (command == "create" && !args.IsArgSet("-wallet")) { tfm::format(std::cerr, "Wallet name must be provided when creating a new wallet.\n"); diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py index 784a769882918..719a391a24738 100755 --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -356,7 +356,7 @@ def test_dump_createfromdump(self): self.assert_raises_tool_error('Dump file {} does not exist.'.format(non_exist_dump), '-wallet=todump', '-dumpfile={}'.format(non_exist_dump), 'createfromdump') wallet_path = self.nodes[0].wallets_path / "todump2" self.assert_raises_tool_error('Failed to create database path \'{}\'. Database already exists.'.format(wallet_path), '-wallet=todump2', '-dumpfile={}'.format(wallet_dump), 'createfromdump') - self.assert_raises_tool_error("The -descriptors option can only be used with the 'create' command.", '-descriptors', '-wallet=todump2', '-dumpfile={}'.format(wallet_dump), 'createfromdump') + self.assert_raises_tool_error("Error: Invalid arguments provided:\n- The -descriptors option cannot be used with the 'createfromdump' command.", '-descriptors', '-wallet=todump2', '-dumpfile={}'.format(wallet_dump), 'createfromdump') self.log.info('Checking createfromdump') self.do_tool_createfromdump("load", "wallet.dump")