Skip to content

platform-wallet: restore scan does not own CoinJoin-derivation change — CoinJoin-funded sends display at gross input value #4474

Description

@bfoss765

Observed

On a restored mainnet wallet (Android host, kotlin-sdk v42int AAR line): a historical send that spent a single denominated CoinJoin input (10.0001 DASH, the largest denomination) paying ~3.4 with ~6.6 change back displays as a 10 DASH send. The stored transactions record's net amount equals the gross input value.

Mechanism

The restore deep scan's ownership/watch set does not include the CoinJoin derivation chains. Change from a CoinJoin-funded send goes to a CoinJoin-chain address, which the scan attributes as foreign, so the record is born with net = −(sum of inputs) instead of −(payment + fee). The record's direction class is correct (OUTGOING), so class-level reconciliation on the host never revisits it — the wrong net is durable.

Relationship to the known restore persistence gap

This is the display variant of the same ownership gap already tracked for the pending persistence fix: the store also drops unspent CoinJoin-change outputs on restore (the balance variant). Both variants should close at the same layer — the restore scan's ownership set must include CoinJoin derivations — plus a heal/backfill pass for already-restored stores whose records were born with gross nets. Note the Android host ships a class-level reattribution walker that persists its corrections durably; an SDK-side heal needs to compose with (not fight) those persisted host corrections.

Acceptance

After restore-from-seed of a wallet with CoinJoin history:

  1. sends funded by denominated inputs net to payment + fee (change attributed owned);
  2. unspent CoinJoin change is present in balance;
  3. a reconciliation pass corrects born-wrong nets in existing restored stores.

Coordination note: #4406 is currently active on the swept-transaction persistence seam — worth aligning so the two don't collide.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions