From c1b99c088c54eb101c0a28a67237965576ccf5ad Mon Sep 17 00:00:00 2001 From: S3RK <1466284+S3RK@users.noreply.github.com> Date: Wed, 8 Sep 2021 10:00:18 +0200 Subject: Return used destinations from ScriptPubKeyMan::MarkUnusedAddresses --- src/wallet/scriptpubkeyman.cpp | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'src/wallet/scriptpubkeyman.cpp') diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index fdfb36bb0a..2894ff7c61 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -354,15 +354,22 @@ bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t i return true; } -void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script) +std::vector LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script) { LOCK(cs_KeyStore); + std::vector result; // extract addresses and check if they match with an unused keypool key for (const auto& keyid : GetAffectedKeys(script, *this)) { std::map::const_iterator mi = m_pool_key_to_index.find(keyid); if (mi != m_pool_key_to_index.end()) { WalletLogPrintf("%s: Detected a used keypool key, mark all keypool keys up to this key as used\n", __func__); - MarkReserveKeysAsUsed(mi->second); + for (const auto& keypool : MarkReserveKeysAsUsed(mi->second)) { + // derive all possible destinations as any of them could have been used + for (const auto& type : LEGACY_OUTPUT_TYPES) { + const auto& dest = GetDestinationForKey(keypool.vchPubKey, type); + result.push_back({dest, keypool.fInternal}); + } + } if (!TopUp()) { WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__); @@ -384,6 +391,8 @@ void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script) } } } + + return result; } void LegacyScriptPubKeyMan::UpgradeKeyMetadata() @@ -1427,7 +1436,7 @@ void LegacyScriptPubKeyMan::LearnAllRelatedScripts(const CPubKey& key) LearnRelatedScripts(key, OutputType::P2SH_SEGWIT); } -void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id) +std::vector LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id) { AssertLockHeld(cs_KeyStore); bool internal = setInternalKeyPool.count(keypool_id); @@ -1435,6 +1444,7 @@ void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id) std::set *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool); auto it = setKeyPool->begin(); + std::vector result; WalletBatch batch(m_storage.GetDatabase()); while (it != std::end(*setKeyPool)) { const int64_t& index = *(it); @@ -1448,7 +1458,10 @@ void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id) batch.ErasePool(index); WalletLogPrintf("keypool index %d removed\n", index); it = setKeyPool->erase(it); + result.push_back(std::move(keypool)); } + + return result; } std::vector GetAffectedKeys(const CScript& spk, const SigningProvider& provider) @@ -1820,19 +1833,32 @@ bool DescriptorScriptPubKeyMan::TopUp(unsigned int size) return true; } -void DescriptorScriptPubKeyMan::MarkUnusedAddresses(const CScript& script) +std::vector DescriptorScriptPubKeyMan::MarkUnusedAddresses(const CScript& script) { LOCK(cs_desc_man); + std::vector result; if (IsMine(script)) { int32_t index = m_map_script_pub_keys[script]; if (index >= m_wallet_descriptor.next_index) { WalletLogPrintf("%s: Detected a used keypool item at index %d, mark all keypool items up to this item as used\n", __func__, index); - m_wallet_descriptor.next_index = index + 1; + auto out_keys = std::make_unique(); + std::vector scripts_temp; + while (index >= m_wallet_descriptor.next_index) { + if (!m_wallet_descriptor.descriptor->ExpandFromCache(m_wallet_descriptor.next_index, m_wallet_descriptor.cache, scripts_temp, *out_keys)) { + throw std::runtime_error(std::string(__func__) + ": Unable to expand descriptor from cache"); + } + CTxDestination dest; + ExtractDestination(scripts_temp[0], dest); + result.push_back({dest, std::nullopt}); + m_wallet_descriptor.next_index++; + } } if (!TopUp()) { WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__); } } + + return result; } void DescriptorScriptPubKeyMan::AddDescriptorKey(const CKey& key, const CPubKey &pubkey) -- cgit v1.2.3