Skip to content

Commit 4f1a75b

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#22621: make ParseOutputType return a std::optional<OutputType>
32fa49a make ParseOutputType return a std::optional<OutputType> (fanquake) Pull request description: Similar to #22220. Skipped using `auto` here for the same reasons outlined in that PR. ACKs for top commit: jnewbery: utACK 32fa49a jonatack: Code review ACK 32fa49a and debian clang 13 debug build is clean / unit tests locally are green MarcoFalke: review ACK 32fa49a 🍢 Tree-SHA512: 7752193117669b800889226185d49d164395697853828f8acb568f07651789bc5b2cddc45555957450353886e46b9a1e13c77a5e730a14c6ee621fabc8dc3d10
2 parents 2b06af1 + 32fa49a commit 4f1a75b

File tree

7 files changed

+40
-36
lines changed

7 files changed

+40
-36
lines changed

src/outputtype.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,26 @@
1313
#include <util/vector.h>
1414

1515
#include <assert.h>
16+
#include <optional>
1617
#include <string>
1718

1819
static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";
1920
static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit";
2021
static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";
2122
static const std::string OUTPUT_TYPE_STRING_BECH32M = "bech32m";
2223

23-
bool ParseOutputType(const std::string& type, OutputType& output_type)
24+
std::optional<OutputType> ParseOutputType(const std::string& type)
2425
{
2526
if (type == OUTPUT_TYPE_STRING_LEGACY) {
26-
output_type = OutputType::LEGACY;
27-
return true;
27+
return OutputType::LEGACY;
2828
} else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
29-
output_type = OutputType::P2SH_SEGWIT;
30-
return true;
29+
return OutputType::P2SH_SEGWIT;
3130
} else if (type == OUTPUT_TYPE_STRING_BECH32) {
32-
output_type = OutputType::BECH32;
33-
return true;
31+
return OutputType::BECH32;
3432
} else if (type == OUTPUT_TYPE_STRING_BECH32M) {
35-
output_type = OutputType::BECH32M;
36-
return true;
33+
return OutputType::BECH32M;
3734
}
38-
return false;
35+
return std::nullopt;
3936
}
4037

4138
const std::string& FormatOutputType(OutputType type)

src/outputtype.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <script/standard.h>
1212

1313
#include <array>
14+
#include <optional>
1415
#include <string>
1516
#include <vector>
1617

@@ -28,7 +29,7 @@ static constexpr auto OUTPUT_TYPES = std::array{
2829
OutputType::BECH32M,
2930
};
3031

31-
[[nodiscard]] bool ParseOutputType(const std::string& str, OutputType& output_type);
32+
std::optional<OutputType> ParseOutputType(const std::string& str);
3233
const std::string& FormatOutputType(OutputType type);
3334

3435
/**

src/rpc/misc.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <util/strencodings.h>
2525
#include <util/system.h>
2626

27+
#include <optional>
2728
#include <stdint.h>
2829
#include <tuple>
2930
#ifdef HAVE_MALLOC_INFO
@@ -128,12 +129,13 @@ static RPCHelpMan createmultisig()
128129
// Get the output type
129130
OutputType output_type = OutputType::LEGACY;
130131
if (!request.params[2].isNull()) {
131-
if (!ParseOutputType(request.params[2].get_str(), output_type)) {
132+
std::optional<OutputType> parsed = ParseOutputType(request.params[2].get_str());
133+
if (!parsed) {
132134
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[2].get_str()));
133-
}
134-
if (output_type == OutputType::BECH32M) {
135+
} else if (parsed.value() == OutputType::BECH32M) {
135136
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "createmultisig cannot create bech32m multisig addresses");
136137
}
138+
output_type = parsed.value();
137139
}
138140

139141
// Construct using pay-to-script-hash:

src/test/fuzz/kitchen_sink.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <array>
1515
#include <cstdint>
16+
#include <optional>
1617
#include <vector>
1718

1819
namespace {
@@ -46,11 +47,10 @@ FUZZ_TARGET(kitchen_sink)
4647

4748
const OutputType output_type = fuzzed_data_provider.PickValueInArray(OUTPUT_TYPES);
4849
const std::string& output_type_string = FormatOutputType(output_type);
49-
OutputType output_type_parsed;
50-
const bool parsed = ParseOutputType(output_type_string, output_type_parsed);
50+
const std::optional<OutputType> parsed = ParseOutputType(output_type_string);
5151
assert(parsed);
52-
assert(output_type == output_type_parsed);
53-
(void)ParseOutputType(fuzzed_data_provider.ConsumeRandomLengthString(64), output_type_parsed);
52+
assert(output_type == parsed.value());
53+
(void)ParseOutputType(fuzzed_data_provider.ConsumeRandomLengthString(64));
5454

5555
const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
5656
const std::vector<bool> bits = BytesToBits(bytes);

src/test/fuzz/string.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ FUZZ_TARGET(string)
6666
(void)ParseNonRFCJSONValue(random_string_1);
6767
} catch (const std::runtime_error&) {
6868
}
69-
OutputType output_type;
70-
(void)ParseOutputType(random_string_1, output_type);
69+
(void)ParseOutputType(random_string_1);
7170
(void)RemovePrefix(random_string_1, random_string_2);
7271
(void)ResolveErrMsg(random_string_1, random_string_2);
7372
try {

src/wallet/rpcwallet.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,13 @@ static RPCHelpMan getnewaddress()
266266

267267
OutputType output_type = pwallet->m_default_address_type;
268268
if (!request.params[1].isNull()) {
269-
if (!ParseOutputType(request.params[1].get_str(), output_type)) {
269+
std::optional<OutputType> parsed = ParseOutputType(request.params[1].get_str());
270+
if (!parsed) {
270271
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));
271-
}
272-
if (output_type == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
272+
} else if (parsed.value() == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
273273
throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses");
274274
}
275+
output_type = parsed.value();
275276
}
276277

277278
CTxDestination dest;
@@ -313,12 +314,13 @@ static RPCHelpMan getrawchangeaddress()
313314

314315
OutputType output_type = pwallet->m_default_change_type.value_or(pwallet->m_default_address_type);
315316
if (!request.params[0].isNull()) {
316-
if (!ParseOutputType(request.params[0].get_str(), output_type)) {
317+
std::optional<OutputType> parsed = ParseOutputType(request.params[0].get_str());
318+
if (!parsed) {
317319
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
318-
}
319-
if (output_type == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
320+
} else if (parsed.value() == OutputType::BECH32M && pwallet->GetLegacyScriptPubKeyMan()) {
320321
throw JSONRPCError(RPC_INVALID_PARAMETER, "Legacy wallets cannot provide bech32m addresses");
321322
}
323+
output_type = parsed.value();
322324
}
323325

324326
CTxDestination dest;
@@ -1007,12 +1009,13 @@ static RPCHelpMan addmultisigaddress()
10071009

10081010
OutputType output_type = pwallet->m_default_address_type;
10091011
if (!request.params[3].isNull()) {
1010-
if (!ParseOutputType(request.params[3].get_str(), output_type)) {
1012+
std::optional<OutputType> parsed = ParseOutputType(request.params[3].get_str());
1013+
if (!parsed) {
10111014
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
1012-
}
1013-
if (output_type == OutputType::BECH32M) {
1015+
} else if (parsed.value() == OutputType::BECH32M) {
10141016
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Bech32m multisig addresses cannot be created with legacy wallets");
10151017
}
1018+
output_type = parsed.value();
10161019
}
10171020

10181021
// Construct using pay-to-script-hash:
@@ -3133,11 +3136,11 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out,
31333136
if (options.exists("changeAddress") || options.exists("change_address")) {
31343137
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both change address and address type options");
31353138
}
3136-
OutputType out_type;
3137-
if (!ParseOutputType(options["change_type"].get_str(), out_type)) {
3139+
if (std::optional<OutputType> parsed = ParseOutputType(options["change_type"].get_str())) {
3140+
coinControl.m_change_type.emplace(parsed.value());
3141+
} else {
31383142
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
31393143
}
3140-
coinControl.m_change_type.emplace(out_type);
31413144
}
31423145

31433146
const UniValue include_watching_option = options.exists("include_watching") ? options["include_watching"] : options["includeWatching"];

src/wallet/wallet.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,19 +2586,21 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain* chain, const std::st
25862586
}
25872587

25882588
if (!gArgs.GetArg("-addresstype", "").empty()) {
2589-
if (!ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
2589+
std::optional<OutputType> parsed = ParseOutputType(gArgs.GetArg("-addresstype", ""));
2590+
if (!parsed) {
25902591
error = strprintf(_("Unknown address type '%s'"), gArgs.GetArg("-addresstype", ""));
25912592
return nullptr;
25922593
}
2594+
walletInstance->m_default_address_type = parsed.value();
25932595
}
25942596

25952597
if (!gArgs.GetArg("-changetype", "").empty()) {
2596-
OutputType out_type;
2597-
if (!ParseOutputType(gArgs.GetArg("-changetype", ""), out_type)) {
2598+
std::optional<OutputType> parsed = ParseOutputType(gArgs.GetArg("-changetype", ""));
2599+
if (!parsed) {
25982600
error = strprintf(_("Unknown change type '%s'"), gArgs.GetArg("-changetype", ""));
25992601
return nullptr;
26002602
}
2601-
walletInstance->m_default_change_type = out_type;
2603+
walletInstance->m_default_change_type = parsed.value();
26022604
}
26032605

26042606
if (gArgs.IsArgSet("-mintxfee")) {

0 commit comments

Comments
 (0)