Skip to content

walletrpc: fix XCreateAccount branch recovery #11087

Description

@yyforyongyu

Description

The manual recovery procedure introduced with XCreateAccount in #11065 does
not distinguish between the account's external and internal address branches.

Account tracks external_key_count and internal_key_count separately, while
NextAddr selects the branch with its change field. Since change defaults to
false, replaying a single aggregate address count derives only external
addresses. Internal/change scripts can therefore remain unknown to the restored
wallet even after a transaction rescan.

This is especially relevant after using FundPsbt, because the account's
remaining balance may be held on an internal change address. The keys and funds
remain derivable from the seed, but following the current procedure can leave
that balance invisible.

Original review discussion:
#11065 (comment)

Expected behavior

The recovery procedure and CLI warning should make it explicit that users must:

  1. Preserve external_key_count and internal_key_count separately over the
    account's lifetime.
  2. During recovery, call NextAddr(change=false) at least external_key_count
    times.
  3. Call NextAddr(change=true) at least internal_key_count times.
  4. Rescan only after both branches have been derived.

Recording only the derivation path when the account is created is insufficient,
because both counters are initially zero and increase as the account is used.

Test coverage

Add an end-to-end recovery test that:

  1. Creates a preceding account so the target account has a non-trivial index.
  2. Funds an external address of the target account.
  3. Spends with FundPsbt, leaving value on an internal/change address.
  4. Records the target account's xpub and both branch counts.
  5. Restores the seed into a fresh wallet database and recreates the target
    account at the same scope and index.
  6. Replays both address branches using their respective counts.
  7. Rescans and verifies that funds on both branches are detected and spendable.

Related PR: #11065

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions