|
|
@ -354,15 +354,22 @@ bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t i
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
|
|
|
|
std::vector<WalletDestination> LegacyScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LOCK(cs_KeyStore);
|
|
|
|
LOCK(cs_KeyStore);
|
|
|
|
|
|
|
|
std::vector<WalletDestination> result;
|
|
|
|
// extract addresses and check if they match with an unused keypool key
|
|
|
|
// extract addresses and check if they match with an unused keypool key
|
|
|
|
for (const auto& keyid : GetAffectedKeys(script, *this)) {
|
|
|
|
for (const auto& keyid : GetAffectedKeys(script, *this)) {
|
|
|
|
std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
|
|
|
|
std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
|
|
|
|
if (mi != m_pool_key_to_index.end()) {
|
|
|
|
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__);
|
|
|
|
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()) {
|
|
|
|
if (!TopUp()) {
|
|
|
|
WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
|
|
|
|
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()
|
|
|
|
void LegacyScriptPubKeyMan::UpgradeKeyMetadata()
|
|
|
@ -1427,7 +1436,7 @@ void LegacyScriptPubKeyMan::LearnAllRelatedScripts(const CPubKey& key)
|
|
|
|
LearnRelatedScripts(key, OutputType::P2SH_SEGWIT);
|
|
|
|
LearnRelatedScripts(key, OutputType::P2SH_SEGWIT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id)
|
|
|
|
std::vector<CKeyPool> LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
AssertLockHeld(cs_KeyStore);
|
|
|
|
AssertLockHeld(cs_KeyStore);
|
|
|
|
bool internal = setInternalKeyPool.count(keypool_id);
|
|
|
|
bool internal = setInternalKeyPool.count(keypool_id);
|
|
|
@ -1435,6 +1444,7 @@ void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id)
|
|
|
|
std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
|
|
|
|
std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : (set_pre_split_keypool.empty() ? &setExternalKeyPool : &set_pre_split_keypool);
|
|
|
|
auto it = setKeyPool->begin();
|
|
|
|
auto it = setKeyPool->begin();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<CKeyPool> result;
|
|
|
|
WalletBatch batch(m_storage.GetDatabase());
|
|
|
|
WalletBatch batch(m_storage.GetDatabase());
|
|
|
|
while (it != std::end(*setKeyPool)) {
|
|
|
|
while (it != std::end(*setKeyPool)) {
|
|
|
|
const int64_t& index = *(it);
|
|
|
|
const int64_t& index = *(it);
|
|
|
@ -1448,7 +1458,10 @@ void LegacyScriptPubKeyMan::MarkReserveKeysAsUsed(int64_t keypool_id)
|
|
|
|
batch.ErasePool(index);
|
|
|
|
batch.ErasePool(index);
|
|
|
|
WalletLogPrintf("keypool index %d removed\n", index);
|
|
|
|
WalletLogPrintf("keypool index %d removed\n", index);
|
|
|
|
it = setKeyPool->erase(it);
|
|
|
|
it = setKeyPool->erase(it);
|
|
|
|
|
|
|
|
result.push_back(std::move(keypool));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& provider)
|
|
|
|
std::vector<CKeyID> GetAffectedKeys(const CScript& spk, const SigningProvider& provider)
|
|
|
@ -1820,19 +1833,32 @@ bool DescriptorScriptPubKeyMan::TopUp(unsigned int size)
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DescriptorScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
|
|
|
|
std::vector<WalletDestination> DescriptorScriptPubKeyMan::MarkUnusedAddresses(const CScript& script)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LOCK(cs_desc_man);
|
|
|
|
LOCK(cs_desc_man);
|
|
|
|
|
|
|
|
std::vector<WalletDestination> result;
|
|
|
|
if (IsMine(script)) {
|
|
|
|
if (IsMine(script)) {
|
|
|
|
int32_t index = m_map_script_pub_keys[script];
|
|
|
|
int32_t index = m_map_script_pub_keys[script];
|
|
|
|
if (index >= m_wallet_descriptor.next_index) {
|
|
|
|
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);
|
|
|
|
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<FlatSigningProvider>();
|
|
|
|
|
|
|
|
std::vector<CScript> 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()) {
|
|
|
|
if (!TopUp()) {
|
|
|
|
WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
|
|
|
|
WalletLogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DescriptorScriptPubKeyMan::AddDescriptorKey(const CKey& key, const CPubKey &pubkey)
|
|
|
|
void DescriptorScriptPubKeyMan::AddDescriptorKey(const CKey& key, const CPubKey &pubkey)
|
|
|
|