mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
make ParseOutputType return a std::optional<OutputType>
This commit is contained in:
parent
3308c61091
commit
32fa49a184
7 changed files with 40 additions and 36 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include <util/vector.h>
|
#include <util/vector.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";
|
static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";
|
||||||
|
@ -20,22 +21,18 @@ static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit";
|
||||||
static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";
|
static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";
|
||||||
static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m";
|
static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m";
|
||||||
|
|
||||||
bool ParseOutputType(const std::string& type, OutputType& output_type)
|
std::optional<OutputType> ParseOutputType(const std::string& type)
|
||||||
{
|
{
|
||||||
if (type == OUTPUT_TYPE_STRING_LEGACY) {
|
if (type == OUTPUT_TYPE_STRING_LEGACY) {
|
||||||
output_type = OutputType::LEGACY;
|
return OutputType::LEGACY;
|
||||||
return true;
|
|
||||||
} else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
|
} else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
|
||||||
output_type = OutputType::P2SH_SEGWIT;
|
return OutputType::P2SH_SEGWIT;
|
||||||
return true;
|
|
||||||
} else if (type == OUTPUT_TYPE_STRING_BECH32) {
|
} else if (type == OUTPUT_TYPE_STRING_BECH32) {
|
||||||
output_type = OutputType::BECH32;
|
return OutputType::BECH32;
|
||||||
return true;
|
|
||||||
} else if (type == OUTPUT_TYPE_STRING_BECH32M) {
|
} else if (type == OUTPUT_TYPE_STRING_BECH32M) {
|
||||||
output_type = OutputType::BECH32M;
|
return OutputType::BECH32M;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& FormatOutputType(OutputType type)
|
const std::string& FormatOutputType(OutputType type)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <script/standard.h>
|
#include <script/standard.h>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ static constexpr auto OUTPUT_TYPES = std::array{
|
||||||
OutputType::BECH32M,
|
OutputType::BECH32M,
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] bool ParseOutputType(const std::string& str, OutputType& output_type);
|
std::optional<OutputType> ParseOutputType(const std::string& str);
|
||||||
const std::string& FormatOutputType(OutputType type);
|
const std::string& FormatOutputType(OutputType type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#ifdef HAVE_MALLOC_INFO
|
#ifdef HAVE_MALLOC_INFO
|
||||||
|
@ -128,12 +129,13 @@ static RPCHelpMan createmultisig()
|
||||||
// Get the output type
|
// Get the output type
|
||||||
OutputType output_type = OutputType::LEGACY;
|
OutputType output_type = OutputType::LEGACY;
|
||||||
if (!request.params[2].isNull()) {
|
if (!request.params[2].isNull()) {
|
||||||
if (!ParseOutputType(request.params[2].get_str(), output_type)) {
|
std::optional<OutputType> parsed = ParseOutputType(request.params[2].get_str());
|
||||||
|
if (!parsed) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str()));
|
||||||
}
|
} else if (parsed.value() == OutputType::BECH32M) {
|
||||||
if (output_type == OutputType::BECH32M) {
|
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses");
|
||||||
}
|
}
|
||||||
|
output_type = parsed.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct using pay-to-script-hash:
|
// Construct using pay-to-script-hash:
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -46,11 +47,10 @@ FUZZ_TARGET(kitchen_sink)
|
||||||
|
|
||||||
const OutputType output_type = fuzzed_data_provider.PickValueInArray(OUTPUT_TYPES);
|
const OutputType output_type = fuzzed_data_provider.PickValueInArray(OUTPUT_TYPES);
|
||||||
const std::string& output_type_string = FormatOutputType(output_type);
|
const std::string& output_type_string = FormatOutputType(output_type);
|
||||||
OutputType output_type_parsed;
|
const std::optional<OutputType> parsed = ParseOutputType(output_type_string);
|
||||||
const bool parsed = ParseOutputType(output_type_string, output_type_parsed);
|
|
||||||
assert(parsed);
|
assert(parsed);
|
||||||
assert(output_type == output_type_parsed);
|
assert(output_type == parsed.value());
|
||||||
(void)ParseOutputType(fuzzed_data_provider.ConsumeRandomLengthString(64), output_type_parsed);
|
(void)ParseOutputType(fuzzed_data_provider.ConsumeRandomLengthString(64));
|
||||||
|
|
||||||
const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
|
const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
|
||||||
const std::vector<bool> bits = BytesToBits(bytes);
|
const std::vector<bool> bits = BytesToBits(bytes);
|
||||||
|
|
|
@ -66,8 +66,7 @@ FUZZ_TARGET(string)
|
||||||
(void)ParseNonRFCJSONValue(random_string_1);
|
(void)ParseNonRFCJSONValue(random_string_1);
|
||||||
} catch (const std::runtime_error&) {
|
} catch (const std::runtime_error&) {
|
||||||
}
|
}
|
||||||
OutputType output_type;
|
(void)ParseOutputType(random_string_1);
|
||||||
(void)ParseOutputType(random_string_1, output_type);
|
|
||||||
(void)RemovePrefix(random_string_1, random_string_2);
|
(void)RemovePrefix(random_string_1, random_string_2);
|
||||||
(void)ResolveErrMsg(random_string_1, random_string_2);
|
(void)ResolveErrMsg(random_string_1, random_string_2);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -266,12 +266,13 @@ static RPCHelpMan getnewaddress()
|
||||||
|
|
||||||
OutputType output_type = pwallet->m_default_address_type;
|
OutputType output_type = pwallet->m_default_address_type;
|
||||||
if (!request.params[1].isNull()) {
|
if (!request.params[1].isNull()) {
|
||||||
if (!ParseOutputType(request.params[1].get_str(), output_type)) {
|
std::optional<OutputType> parsed = ParseOutputType(request.params[1].get_str());
|
||||||
|
if (!parsed) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));
|
||||||
}
|
} else if (parsed.value() == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
|
||||||
if (output_type == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
|
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses");
|
||||||
}
|
}
|
||||||
|
output_type = parsed.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxDestination dest;
|
CTxDestination dest;
|
||||||
|
@ -313,12 +314,13 @@ static RPCHelpMan getrawchangeaddress()
|
||||||
|
|
||||||
OutputType output_type = pwallet->m_default_change_type.value_or(pwallet->m_default_address_type);
|
OutputType output_type = pwallet->m_default_change_type.value_or(pwallet->m_default_address_type);
|
||||||
if (!request.params[0].isNull()) {
|
if (!request.params[0].isNull()) {
|
||||||
if (!ParseOutputType(request.params[0].get_str(), output_type)) {
|
std::optional<OutputType> parsed = ParseOutputType(request.params[0].get_str());
|
||||||
|
if (!parsed) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
|
||||||
}
|
} else if (parsed.value() == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
|
||||||
if (output_type == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
|
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses");
|
||||||
}
|
}
|
||||||
|
output_type = parsed.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxDestination dest;
|
CTxDestination dest;
|
||||||
|
@ -1007,12 +1009,13 @@ static RPCHelpMan addmultisigaddress()
|
||||||
|
|
||||||
OutputType output_type = pwallet->m_default_address_type;
|
OutputType output_type = pwallet->m_default_address_type;
|
||||||
if (!request.params[3].isNull()) {
|
if (!request.params[3].isNull()) {
|
||||||
if (!ParseOutputType(request.params[3].get_str(), output_type)) {
|
std::optional<OutputType> parsed = ParseOutputType(request.params[3].get_str());
|
||||||
|
if (!parsed) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
|
||||||
}
|
} else if (parsed.value() == OutputType::BECH32M) {
|
||||||
if (output_type == OutputType::BECH32M) {
|
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Bech32m multisig addresses cannot be created with legacy wallets");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Bech32m multisig addresses cannot be created with legacy wallets");
|
||||||
}
|
}
|
||||||
|
output_type = parsed.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct using pay-to-script-hash:
|
// Construct using pay-to-script-hash:
|
||||||
|
@ -3133,11 +3136,11 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out,
|
||||||
if (options.exists("changeAddress") || options.exists("change_address")) {
|
if (options.exists("changeAddress") || options.exists("change_address")) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both change address and address type options");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both change address and address type options");
|
||||||
}
|
}
|
||||||
OutputType out_type;
|
if (std::optional<OutputType> parsed = ParseOutputType(options["change_type"].get_str())) {
|
||||||
if (!ParseOutputType(options["change_type"].get_str(), out_type)) {
|
coinControl.m_change_type.emplace(parsed.value());
|
||||||
|
} else {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
|
||||||
}
|
}
|
||||||
coinControl.m_change_type.emplace(out_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const UniValue include_watching_option = options.exists("include_watching") ? options["include_watching"] : options["includeWatching"];
|
const UniValue include_watching_option = options.exists("include_watching") ? options["include_watching"] : options["includeWatching"];
|
||||||
|
|
|
@ -2586,19 +2586,21 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain* chain, const std::st
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gArgs.GetArg("-addresstype", "").empty()) {
|
if (!gArgs.GetArg("-addresstype", "").empty()) {
|
||||||
if (!ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
|
std::optional<OutputType> parsed = ParseOutputType(gArgs.GetArg("-addresstype", ""));
|
||||||
|
if (!parsed) {
|
||||||
error = strprintf(_("Unknown address type '%s'"), gArgs.GetArg("-addresstype", ""));
|
error = strprintf(_("Unknown address type '%s'"), gArgs.GetArg("-addresstype", ""));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
walletInstance->m_default_address_type = parsed.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gArgs.GetArg("-changetype", "").empty()) {
|
if (!gArgs.GetArg("-changetype", "").empty()) {
|
||||||
OutputType out_type;
|
std::optional<OutputType> parsed = ParseOutputType(gArgs.GetArg("-changetype", ""));
|
||||||
if (!ParseOutputType(gArgs.GetArg("-changetype", ""), out_type)) {
|
if (!parsed) {
|
||||||
error = strprintf(_("Unknown change type '%s'"), gArgs.GetArg("-changetype", ""));
|
error = strprintf(_("Unknown change type '%s'"), gArgs.GetArg("-changetype", ""));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
walletInstance->m_default_change_type = out_type;
|
walletInstance->m_default_change_type = parsed.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gArgs.IsArgSet("-mintxfee")) {
|
if (gArgs.IsArgSet("-mintxfee")) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue