aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2021-06-12 21:36:05 -0400
committerAndrew Chow <achow101-github@achow101.com>2021-06-22 21:57:04 -0400
commit754f134a50cc56cdf0baf996d909c992770fcc97 (patch)
tree6254beb3d43175e1383014a1f80daa10c60b42cc /src
parent87a0e7a3b7c0ffd545e537bd497cdc3e67d045f6 (diff)
wallet: Add error message to GetReservedDestination
Adds an error output parameter to all GetReservedDestination functions so that callers can get the actual reason that a change address could not be fetched. This more closely matches GetNewDestination. This allows for more granular error messages, such as one that indicates that bech32m addresses cannot be generated yet.
Diffstat (limited to 'src')
-rw-r--r--src/wallet/scriptpubkeyman.cpp8
-rw-r--r--src/wallet/scriptpubkeyman.h6
-rw-r--r--src/wallet/spend.cpp5
-rw-r--r--src/wallet/wallet.cpp10
-rw-r--r--src/wallet/wallet.h2
5 files changed, 17 insertions, 14 deletions
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index 2f7729a901..44c3912544 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -295,19 +295,22 @@ bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBat
return true;
}
-bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
+bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error)
{
if (LEGACY_OUTPUT_TYPES.count(type) == 0) {
+ error = _("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types").translated;
return false;
}
assert(type != OutputType::BECH32M);
LOCK(cs_KeyStore);
if (!CanGetAddresses(internal)) {
+ error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
return false;
}
if (!ReserveKeyFromKeyPool(index, keypool, internal)) {
+ error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
return false;
}
address = GetDestinationForKey(keypool.vchPubKey, type);
@@ -1720,10 +1723,9 @@ bool DescriptorScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, Walle
return true;
}
-bool DescriptorScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool)
+bool DescriptorScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error)
{
LOCK(cs_desc_man);
- std::string error;
bool result = GetNewDestination(type, address, error);
index = m_wallet_descriptor.next_index - 1;
return result;
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index 3c6a29e5d1..b2ca354b0a 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -181,7 +181,7 @@ public:
virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; }
virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; }
- virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) { return false; }
+ virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) { return false; }
virtual void KeepDestination(int64_t index, const OutputType& type) {}
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
@@ -364,7 +364,7 @@ public:
bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
- bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) override;
+ bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) override;
void KeepDestination(int64_t index, const OutputType& type) override;
void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override;
@@ -573,7 +573,7 @@ public:
bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
- bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) override;
+ bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, std::string& error) override;
void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) override;
// Tops up the descriptor cache and m_map_script_pub_keys. The cache is stored in the wallet file
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index c8ded4c51e..6a8df437ae 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -618,8 +618,9 @@ bool CWallet::CreateTransactionInternal(
// Reserve a new key pair from key pool. If it fails, provide a dummy
// destination in case we don't need change.
CTxDestination dest;
- if (!reservedest.GetReservedDestination(dest, true)) {
- error = _("Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.");
+ std::string dest_err;
+ if (!reservedest.GetReservedDestination(dest, true, dest_err)) {
+ error = strprintf(_("Transaction needs a change address, but we can't generate it. %s"), dest_err);
}
scriptChange = GetScriptForDestination(dest);
// A valid destination implies a change script (and
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 0f69302697..c2586b60b8 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2118,7 +2118,7 @@ bool CWallet::GetNewDestination(const OutputType type, const std::string label,
spk_man->TopUp();
result = spk_man->GetNewDestination(type, dest, error);
} else {
- error = strprintf("Error: No %s addresses available.", FormatOutputType(type));
+ error = strprintf(_("Error: No %s addresses available."), FormatOutputType(type)).translated;
}
if (result) {
SetAddressBook(dest, label, "receive");
@@ -2133,8 +2133,7 @@ bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& des
error.clear();
ReserveDestination reservedest(this, type);
- if (!reservedest.GetReservedDestination(dest, true)) {
- error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
+ if (!reservedest.GetReservedDestination(dest, true, error)) {
return false;
}
@@ -2181,10 +2180,11 @@ std::set<CTxDestination> CWallet::GetLabelAddresses(const std::string& label) co
return result;
}
-bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool internal)
+bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool internal, std::string& error)
{
m_spk_man = pwallet->GetScriptPubKeyMan(type, internal);
if (!m_spk_man) {
+ error = strprintf(_("Error: No %s addresses available."), FormatOutputType(type)).translated;
return false;
}
@@ -2194,7 +2194,7 @@ bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool inter
m_spk_man->TopUp();
CKeyPool keypool;
- if (!m_spk_man->GetReservedDestination(type, internal, address, nIndex, keypool)) {
+ if (!m_spk_man->GetReservedDestination(type, internal, address, nIndex, keypool, error)) {
return false;
}
fInternal = keypool.fInternal;
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 66f39edb4d..b63938c5f1 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -181,7 +181,7 @@ public:
}
//! Reserve an address
- bool GetReservedDestination(CTxDestination& pubkey, bool internal);
+ bool GetReservedDestination(CTxDestination& pubkey, bool internal, std::string& error);
//! Return reserved address
void ReturnDestination();
//! Keep the address. Do not return it's key to the keypool when this object goes out of scope