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:
- Preserve external_key_count and internal_key_count separately over the
account's lifetime.
- During recovery, call NextAddr(change=false) at least external_key_count
times.
- Call NextAddr(change=true) at least internal_key_count times.
- 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:
- Creates a preceding account so the target account has a non-trivial index.
- Funds an external address of the target account.
- Spends with FundPsbt, leaving value on an internal/change address.
- Records the target account's xpub and both branch counts.
- Restores the seed into a fresh wallet database and recreates the target
account at the same scope and index.
- Replays both address branches using their respective counts.
- Rescans and verifies that funds on both branches are detected and spendable.
Related PR: #11065
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:
account's lifetime.
times.
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:
account at the same scope and index.
Related PR: #11065