aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorRussell Yanofsky <russ@yanofsky.org>2018-03-19 15:57:11 -0400
committerRussell Yanofsky <russ@yanofsky.org>2018-04-05 12:19:35 -0400
commit1e46d8ae897aded3367a2dd63a76991882d170fa (patch)
treeb3738f95b2c05a6e712576a9c6d08a128391fe65 /src/wallet
parent5f0c6a7b0e47e03f848dc992d37fe209dd9c6975 (diff)
Get rid of ambiguous OutputType::NONE value
Based on suggestion by Pieter Wuille <pieter.wuille@gmail.com> at https://github.com/bitcoin/bitcoin/pull/12119#issuecomment-357982763 After #12119, the NONE output type was overloaded to refer to either an output type that couldn't be parsed, or to an automatic change output mode. This change drops the NONE enum and uses a simple bool indicate parse failure, and a new CHANGE_AUTO enum to refer the change output type. This change is almost a pure refactoring except it makes RPCs reject empty string ("") address types instead of treating them like they were unset. This simplifies the parsing code a little bit and could prevent RPC usage mistakes. It's noted in the release notes.
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/rpcwallet.cpp15
-rw-r--r--src/wallet/wallet.cpp28
-rw-r--r--src/wallet/wallet.h15
3 files changed, 30 insertions, 28 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index c34b166a41..f669921750 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -164,8 +164,7 @@ UniValue getnewaddress(const JSONRPCRequest& request)
OutputType output_type = pwallet->m_default_address_type;
if (!request.params[1].isNull()) {
- output_type = ParseOutputType(request.params[1].get_str(), pwallet->m_default_address_type);
- if (output_type == OutputType::NONE) {
+ if (!ParseOutputType(request.params[1].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[1].get_str()));
}
}
@@ -259,10 +258,9 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request)
pwallet->TopUpKeyPool();
}
- OutputType output_type = pwallet->m_default_change_type != OutputType::NONE ? pwallet->m_default_change_type : pwallet->m_default_address_type;
+ OutputType output_type = pwallet->m_default_change_type != OutputType::CHANGE_AUTO ? pwallet->m_default_change_type : pwallet->m_default_address_type;
if (!request.params[0].isNull()) {
- output_type = ParseOutputType(request.params[0].get_str(), output_type);
- if (output_type == OutputType::NONE) {
+ if (!ParseOutputType(request.params[0].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[0].get_str()));
}
}
@@ -1226,8 +1224,7 @@ UniValue addmultisigaddress(const JSONRPCRequest& request)
OutputType output_type = pwallet->m_default_address_type;
if (!request.params[3].isNull()) {
- output_type = ParseOutputType(request.params[3].get_str(), output_type);
- if (output_type == OutputType::NONE) {
+ if (!ParseOutputType(request.params[3].get_str(), output_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown address type '%s'", request.params[3].get_str()));
}
}
@@ -3180,8 +3177,8 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
if (options.exists("changeAddress")) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both changeAddress and address_type options");
}
- coinControl.m_change_type = ParseOutputType(options["change_type"].get_str(), pwallet->m_default_change_type);
- if (coinControl.m_change_type == OutputType::NONE) {
+ coinControl.m_change_type = pwallet->m_default_change_type;
+ if (!ParseOutputType(options["change_type"].get_str(), *coinControl.m_change_type)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
}
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index dbc1760c80..965eb067cc 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2648,7 +2648,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vector<CRecipient>& vecSend)
{
// If -changetype is specified, always use that change type.
- if (change_type != OutputType::NONE) {
+ if (change_type != OutputType::CHANGE_AUTO) {
return change_type;
}
@@ -4022,16 +4022,12 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
}
}
- walletInstance->m_default_address_type = ParseOutputType(gArgs.GetArg("-addresstype", ""), DEFAULT_ADDRESS_TYPE);
- if (walletInstance->m_default_address_type == OutputType::NONE) {
+ if (!gArgs.GetArg("-addresstype", "").empty() && !ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
InitError(strprintf("Unknown address type '%s'", gArgs.GetArg("-addresstype", "")));
return nullptr;
}
- // If changetype is set in config file or parameter, check that it's valid.
- // Default to OutputType::NONE if not set.
- walletInstance->m_default_change_type = ParseOutputType(gArgs.GetArg("-changetype", ""), OutputType::NONE);
- if (walletInstance->m_default_change_type == OutputType::NONE && !gArgs.GetArg("-changetype", "").empty()) {
+ if (!gArgs.GetArg("-changetype", "").empty() && !ParseOutputType(gArgs.GetArg("-changetype", ""), walletInstance->m_default_change_type)) {
InitError(strprintf("Unknown change type '%s'", gArgs.GetArg("-changetype", "")));
return nullptr;
}
@@ -4219,19 +4215,19 @@ static const std::string OUTPUT_TYPE_STRING_LEGACY = "legacy";
static const std::string OUTPUT_TYPE_STRING_P2SH_SEGWIT = "p2sh-segwit";
static const std::string OUTPUT_TYPE_STRING_BECH32 = "bech32";
-OutputType ParseOutputType(const std::string& type, OutputType default_type)
+bool ParseOutputType(const std::string& type, OutputType& output_type)
{
- if (type.empty()) {
- return default_type;
- } else if (type == OUTPUT_TYPE_STRING_LEGACY) {
- return OutputType::LEGACY;
+ if (type == OUTPUT_TYPE_STRING_LEGACY) {
+ output_type = OutputType::LEGACY;
+ return true;
} else if (type == OUTPUT_TYPE_STRING_P2SH_SEGWIT) {
- return OutputType::P2SH_SEGWIT;
+ output_type = OutputType::P2SH_SEGWIT;
+ return true;
} else if (type == OUTPUT_TYPE_STRING_BECH32) {
- return OutputType::BECH32;
- } else {
- return OutputType::NONE;
+ output_type = OutputType::BECH32;
+ return true;
}
+ return false;
}
const std::string& FormatOutputType(OutputType type)
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 898c32c708..1d85fbcea1 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -99,15 +99,24 @@ enum WalletFeature
};
enum class OutputType {
- NONE,
LEGACY,
P2SH_SEGWIT,
BECH32,
+
+ /**
+ * Special output type for change outputs only. Automatically choose type
+ * based on address type setting and the types other of non-change outputs
+ * (see -changetype option documentation and implementation in
+ * CWallet::TransactionChangeType for details).
+ */
+ CHANGE_AUTO,
};
//! Default for -addresstype
constexpr OutputType DEFAULT_ADDRESS_TYPE{OutputType::P2SH_SEGWIT};
+//! Default for -changetype
+constexpr OutputType DEFAULT_CHANGE_TYPE{OutputType::CHANGE_AUTO};
/** A key pool entry */
class CKeyPool
@@ -988,7 +997,7 @@ public:
static CFeeRate fallbackFee;
static CFeeRate m_discard_rate;
OutputType m_default_address_type{DEFAULT_ADDRESS_TYPE};
- OutputType m_default_change_type{OutputType::NONE}; // Default to OutputType::NONE if not set by -changetype
+ OutputType m_default_change_type{DEFAULT_CHANGE_TYPE};
bool NewKeyPool();
size_t KeypoolCountExternalKeys();
@@ -1232,7 +1241,7 @@ public:
}
};
-OutputType ParseOutputType(const std::string& str, OutputType default_type);
+bool ParseOutputType(const std::string& str, OutputType& output_type);
const std::string& FormatOutputType(OutputType type);
/**