refactor: wallet: return util::Result from GetReservedDestination methods

This commit is contained in:
Sebastian Falbesoner 2022-07-20 19:06:57 +02:00
parent 006740b6f6
commit 76b3c37fcb
5 changed files with 26 additions and 40 deletions

View File

@ -292,26 +292,22 @@ bool LegacyScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, WalletBat
return true; return true;
} }
bool LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) util::Result<CTxDestination> LegacyScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool)
{ {
if (LEGACY_OUTPUT_TYPES.count(type) == 0) { if (LEGACY_OUTPUT_TYPES.count(type) == 0) {
error = _("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types"); return util::Error{_("Error: Legacy wallets only support the \"legacy\", \"p2sh-segwit\", and \"bech32\" address types")};
return false;
} }
assert(type != OutputType::BECH32M); assert(type != OutputType::BECH32M);
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
if (!CanGetAddresses(internal)) { if (!CanGetAddresses(internal)) {
error = _("Error: Keypool ran out, please call keypoolrefill first"); return util::Error{_("Error: Keypool ran out, please call keypoolrefill first")};
return false;
} }
if (!ReserveKeyFromKeyPool(index, keypool, internal)) { if (!ReserveKeyFromKeyPool(index, keypool, internal)) {
error = _("Error: Keypool ran out, please call keypoolrefill first"); return util::Error{_("Error: Keypool ran out, please call keypoolrefill first")};
return false;
} }
address = GetDestinationForKey(keypool.vchPubKey, type); return GetDestinationForKey(keypool.vchPubKey, type);
return true;
} }
bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal) bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal)
@ -1760,17 +1756,12 @@ bool DescriptorScriptPubKeyMan::Encrypt(const CKeyingMaterial& master_key, Walle
return true; return true;
} }
bool DescriptorScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) util::Result<CTxDestination> DescriptorScriptPubKeyMan::GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool)
{ {
LOCK(cs_desc_man); LOCK(cs_desc_man);
auto op_dest = GetNewDestination(type); auto op_dest = GetNewDestination(type);
index = m_wallet_descriptor.next_index - 1; index = m_wallet_descriptor.next_index - 1;
if (op_dest) { return op_dest;
address = *op_dest;
} else {
error = util::ErrorString(op_dest);
}
return bool(op_dest);
} }
void DescriptorScriptPubKeyMan::ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) void DescriptorScriptPubKeyMan::ReturnDestination(int64_t index, bool internal, const CTxDestination& addr)

View File

@ -179,7 +179,7 @@ public:
virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; } 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 Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; }
virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) { return false; } virtual util::Result<CTxDestination> GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) { return util::Error{Untranslated("Not supported")}; }
virtual void KeepDestination(int64_t index, const OutputType& type) {} virtual void KeepDestination(int64_t index, const OutputType& type) {}
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {} virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
@ -366,7 +366,7 @@ public:
bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override; bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override; bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) override; util::Result<CTxDestination> GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) override;
void KeepDestination(int64_t index, const OutputType& type) override; void KeepDestination(int64_t index, const OutputType& type) override;
void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override; void ReturnDestination(int64_t index, bool internal, const CTxDestination&) override;
@ -574,7 +574,7 @@ public:
bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override; bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) override;
bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override; bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) override;
bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) override; util::Result<CTxDestination> GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) override;
void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) 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 // Tops up the descriptor cache and m_map_script_pub_keys. The cache is stored in the wallet file

View File

@ -812,11 +812,13 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
// Reserve a new key pair from key pool. If it fails, provide a dummy // Reserve a new key pair from key pool. If it fails, provide a dummy
// destination in case we don't need change. // destination in case we don't need change.
CTxDestination dest; CTxDestination dest;
bilingual_str dest_err; auto op_dest = reservedest.GetReservedDestination(true);
if (!reservedest.GetReservedDestination(dest, true, dest_err)) { if (!op_dest) {
error = _("Transaction needs a change address, but we can't generate it.") + Untranslated(" ") + dest_err; error = _("Transaction needs a change address, but we can't generate it.") + Untranslated(" ") + util::ErrorString(op_dest);
} else {
dest = *op_dest;
scriptChange = GetScriptForDestination(dest);
} }
scriptChange = GetScriptForDestination(dest);
// A valid destination implies a change script (and // A valid destination implies a change script (and
// vice-versa). An empty change script will abort later, if the // vice-versa). An empty change script will abort later, if the
// change keypool ran out, but change is required. // change keypool ran out, but change is required.

View File

@ -2351,15 +2351,11 @@ util::Result<CTxDestination> CWallet::GetNewChangeDestination(const OutputType t
{ {
LOCK(cs_wallet); LOCK(cs_wallet);
CTxDestination dest;
bilingual_str error;
ReserveDestination reservedest(this, type); ReserveDestination reservedest(this, type);
if (!reservedest.GetReservedDestination(dest, true, error)) { auto op_dest = reservedest.GetReservedDestination(true);
return util::Error{error}; if (op_dest) reservedest.KeepDestination();
}
reservedest.KeepDestination(); return op_dest;
return dest;
} }
std::optional<int64_t> CWallet::GetOldestKeyPoolTime() const std::optional<int64_t> CWallet::GetOldestKeyPoolTime() const
@ -2429,27 +2425,24 @@ std::set<std::string> CWallet::ListAddrBookLabels(const std::string& purpose) co
return label_set; return label_set;
} }
bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool internal, bilingual_str& error) util::Result<CTxDestination> ReserveDestination::GetReservedDestination(bool internal)
{ {
m_spk_man = pwallet->GetScriptPubKeyMan(type, internal); m_spk_man = pwallet->GetScriptPubKeyMan(type, internal);
if (!m_spk_man) { if (!m_spk_man) {
error = strprintf(_("Error: No %s addresses available."), FormatOutputType(type)); return util::Error{strprintf(_("Error: No %s addresses available."), FormatOutputType(type))};
return false;
} }
if (nIndex == -1) if (nIndex == -1)
{ {
m_spk_man->TopUp(); m_spk_man->TopUp();
CKeyPool keypool; CKeyPool keypool;
if (!m_spk_man->GetReservedDestination(type, internal, address, nIndex, keypool, error)) { auto op_address = m_spk_man->GetReservedDestination(type, internal, nIndex, keypool);
return false; if (!op_address) return op_address;
} address = *op_address;
fInternal = keypool.fInternal; fInternal = keypool.fInternal;
} }
dest = address; return address;
return true;
} }
void ReserveDestination::KeepDestination() void ReserveDestination::KeepDestination()

View File

@ -189,7 +189,7 @@ public:
} }
//! Reserve an address //! Reserve an address
bool GetReservedDestination(CTxDestination& pubkey, bool internal, bilingual_str& error); util::Result<CTxDestination> GetReservedDestination(bool internal);
//! Return reserved address //! Return reserved address
void ReturnDestination(); void ReturnDestination();
//! Keep the address. Do not return it's key to the keypool when this object goes out of scope //! Keep the address. Do not return it's key to the keypool when this object goes out of scope