Skip to content

Conversation

@brunoerg
Copy link
Contributor

This PR adds fuzz coverage for the scriptpubkeyman migration (MigrateToDescriptor). Note that it's a test for the migration of the scriptpubkey manager, not for the whole migration process as tried in #29694, because:

  1. The wallet migration deals with DBs which is expensive for fuzzing (was getting around 3 exec/s);
  2. Mocking would require lots of refactors.

This target loads keys, HDChain (even inactive ones), watch only and might add tons of different scripts, then calls MigrateToDescriptor. It does not play with encrypted stuff because it would make the target super slow. Also, after the migration there are some assertions that would work as a regression test for #31452, for example.

@DrahtBot
Copy link
Contributor

DrahtBot commented May 27, 2025

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32624.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK marcofleon
Approach ACK w0xlt
Stale ACK maflcko

If your review is incorrectly listed, please copy-paste <!--meta-tag:bot-skip--> into the comment that the bot should ignore.

@brunoerg brunoerg force-pushed the 2025-05-fuzz-spkm-migration branch from 08b574d to 5f2fb4d Compare May 27, 2025 12:55
@brunoerg
Copy link
Contributor Author

08b574dde2c5f13a4c9dadcb9d8bded158c59623..5f2fb4dd333f8d1db27c78414afc84454e6ee4a5: Address #32624 (comment)

Copy link
Contributor

@w0xlt w0xlt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approach ACK

@brunoerg brunoerg requested a review from maflcko June 5, 2025 21:39
@brunoerg brunoerg force-pushed the 2025-05-fuzz-spkm-migration branch from 5f2fb4d to 73439a7 Compare June 16, 2025 17:11
@brunoerg brunoerg force-pushed the 2025-05-fuzz-spkm-migration branch from 73439a7 to 6d29c9a Compare June 17, 2025 16:12
@maflcko
Copy link
Member

maflcko commented Jun 17, 2025

lgtm ACK 6d29c9a6d1b4239a0844791d4a53599ae3a79cd0

@DrahtBot DrahtBot requested a review from w0xlt June 17, 2025 20:45
@achow101 achow101 requested review from achow101 and marcofleon and removed request for w0xlt October 22, 2025 15:12
@DrahtBot DrahtBot requested a review from w0xlt October 27, 2025 16:26
@maflcko maflcko closed this Oct 27, 2025
@maflcko maflcko reopened this Oct 27, 2025
@brunoerg brunoerg force-pushed the 2025-05-fuzz-spkm-migration branch from 6d29c9a to 6ced804 Compare October 27, 2025 17:06
@brunoerg
Copy link
Contributor Author

Force-pushed addressing #32624 (comment). Thanks, @marcofleon.

@brunoerg brunoerg force-pushed the 2025-05-fuzz-spkm-migration branch from 6ced804 to 6436ad7 Compare October 27, 2025 18:05
@brunoerg
Copy link
Contributor Author

There was one more case that I forgot to count in. We should consider the split chain support when verifying the result (desc_spkms). Force-pushed fixing it (6ced804 to 6436ad7).

Copy link
Contributor

@marcofleon marcofleon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some questions below.

Also, coverage report after about a day of fuzzing.

@brunoerg brunoerg force-pushed the 2025-05-fuzz-spkm-migration branch from 6436ad7 to 6227441 Compare November 13, 2025 19:40
@brunoerg
Copy link
Contributor Author

@brunoerg brunoerg force-pushed the 2025-05-fuzz-spkm-migration branch from 6227441 to 51917d9 Compare November 13, 2025 20:38
@marcofleon
Copy link
Contributor

Nice, lgtm ACK 51917d9

@DrahtBot DrahtBot requested a review from maflcko November 17, 2025 14:17
@brunoerg
Copy link
Contributor Author

@maflcko friendly review ping :)

Copy link
Contributor

@frankomosh frankomosh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few observations and questions below.


FUZZ_TARGET(spkm_migration, .init = initialize_spkm_migration)
{
SeedRandomStateForTest(SeedRand::ZEROS);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SeedRandomStateForTest(SeedRand::ZEROS) call appears to be unused in this target. Or is there something I am not seeing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean with unused? It is to avoid instability when it is using the global random state.

if (legacy_data.LoadWatchOnly(script_dest)) watch_only = true;

size_t added_script{0};
bool good_data{true};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'good_data' is only cleared when a custom script deserialization fails. other failures leave it true(like when AddCScript returns false).
Is it intentional to leave a potentially incomplete state in those other cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, see #28815.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not know that. Thanks for the context.

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)) {
Copy link
Contributor

@frankomosh frankomosh Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might be a small issue with how version is used in the assertion here. The version variable is initialized at line 244 and only assigned to the active HD chain when add_hd_chain is true (line 249). However, when add_inactive_hd_chain is true, the inactive chain gets its own version choice at line 257.

Challenge arises when add_hd_chain is false but add_inactive_hd_chain is true. In this scenario, condition (!add_hd_chain && add_inactive_hd_chain) would trigger added_chains *= 2, but this doesn't account for whether the inactive chain's version is actually VERSION_HD_CHAIN_SPLIT or not , as it just assumes any inactive chain should double the count.

If you consider or think that these sequence of events might cause assertion miscalculations then maybe a solution might be store and checking the inactive chain's version separately or checking hd_chain.nVersion directly after it's set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants