wallet migration, fuzz: Migrate hd seed once

If a wallet has multiple HD chains that have the same seed, we should
only migrate that seed a single time.

This fixes a fuzz crash that occurs once the return value of
AddDescriptorKeyWithDB is checked during descriptor construction.
This commit is contained in:
Ava Chow
2026-04-29 14:13:28 -07:00
parent 1a1f584360
commit 0301c758ea
3 changed files with 11 additions and 4 deletions

View File

@@ -619,10 +619,10 @@ std::optional<MigrationData> LegacyDataSPKM::MigrateToDescriptor()
}
// Handle HD keys by using the CHDChains
std::vector<CHDChain> chains;
chains.push_back(m_hd_chain);
std::set<CHDChain> chains;
chains.insert(m_hd_chain);
for (const auto& chain_pair : m_inactive_hd_chains) {
chains.push_back(chain_pair.second);
chains.insert(chain_pair.second);
}
bool can_support_hd_split_feature = m_hd_chain.nVersion >= CHDChain::VERSION_HD_CHAIN_SPLIT;

View File

@@ -229,6 +229,7 @@ FUZZ_TARGET(spkm_migration, .init = initialize_spkm_migration)
if (legacy_data.LoadKey(key, pub_key) && std::find(keys.begin(), keys.end(), key) == keys.end()) keys.push_back(key);
}
size_t added_chains = 0;
bool add_hd_chain{fuzzed_data_provider.ConsumeBool() && !keys.empty()};
CHDChain hd_chain;
auto version{fuzzed_data_provider.ConsumeBool() ? CHDChain::VERSION_HD_CHAIN_SPLIT : CHDChain::VERSION_HD_BASE};
@@ -238,14 +239,17 @@ FUZZ_TARGET(spkm_migration, .init = initialize_spkm_migration)
hd_chain.nVersion = version;
hd_chain.seed_id = hd_key.GetPubKey().GetID();
legacy_data.LoadHDChain(hd_chain);
added_chains++;
}
bool add_inactive_hd_chain{fuzzed_data_provider.ConsumeBool() && !keys.empty()};
if (add_inactive_hd_chain) {
hd_key = PickValue(fuzzed_data_provider, keys);
hd_chain.nVersion = fuzzed_data_provider.ConsumeBool() ? CHDChain::VERSION_HD_CHAIN_SPLIT : CHDChain::VERSION_HD_BASE;
bool dup_chain = hd_chain.seed_id == hd_key.GetPubKey().GetID();
hd_chain.seed_id = hd_key.GetPubKey().GetID();
legacy_data.AddInactiveHDChain(hd_chain);
if (!dup_chain) added_chains++;
}
bool watch_only = false;
@@ -323,7 +327,6 @@ FUZZ_TARGET(spkm_migration, .init = initialize_spkm_migration)
auto result{legacy_data.MigrateToDescriptor()};
assert(result);
size_t added_chains{static_cast<size_t>(add_hd_chain) + static_cast<size_t>(add_inactive_hd_chain)};
if ((add_hd_chain && version >= CHDChain::VERSION_HD_CHAIN_SPLIT) || (!add_hd_chain && add_inactive_hd_chain)) {
added_chains *= 2;
}

View File

@@ -126,6 +126,10 @@ public:
{
return seed_id == chain.seed_id;
}
bool operator<(const CHDChain& chain) const
{
return seed_id < chain.seed_id;
}
};
class CKeyMetadata