Skip to content

asset-lock lock-waiters never observe the InstantSend record upgrade — self-broadcast fundings degrade to ChainLock finality (regression: rust-dashcore b056d07c..1f5dd24f) #4417

Description

@bfoss765

Summary

Self-broadcast asset-lock flows (shield-from-wallet Type-18, L1 invite funding, identity funding) obtain their asset-lock proof via wait_for_proof (rs-platform-wallet asset_lock/sync/proof.rs), which decides Instant-vs-Chain by reading the funding transaction record's context. On current pins, the waiter never observes the record's InstantSend context upgrade, even though the upgrade demonstrably runs — so every such flow silently degrades from ~5s (InstantSend proof) to ChainLock finality (2.5–3+ min on testnet).

Field evidence (2026-08-18, testnet, Samsung S21, all timings from on-device SDK logs)

Instrumented run on the current stack (platform integration/v42-keystore-gu1 + rust-dashcore 1f5dd24f), tx 88d4dd84…:

21:04:57.775Z  broadcast accepted; record created context=mempool
21:04:59.273Z  InstantLock signature VERIFIED (+1.5s); SyncEvent InstantLockReceived (validated=true)
21:04:59.273Z  WalletEvent TransactionInstantLocked — the record-upgrade loop ran
21:04:58 → 21:09:58Z  wait_for_proof runs its FULL 300s IS-preference window without ever
               observing InstantSend context (its closing "IS-lock did not propagate within
               300s" warning is factually wrong — it propagated and verified in 1.5s)
21:10:48Z  completes via the reconstruction path (total 5m50s)

ChainLock events woke the waiter repeatedly inside the window; each re-read still returned a pre-InstantSend context — so this is not a missed-wakeup race; the waiter's record view does not receive the islock promotion (block-processing updates ARE visible to it — the record's height is). A second slow run also logged Building ChainLock proof … per-record promotion missed by SPV catch-up cascade, i.e. the ChainLock leg of the same visibility divergence.

The upgrade itself exists and runs in every era: process_instant_send_lockmark_instant_send_utxos (key-wallet wallet_info_interface.rs) upgrades the record in every account via update_context(TransactionContext::InstantSend(..)) — byte-identical across all pins tested.

Four-build A/B bisect (same device, same wallet upgraded in place, same testnet hour)

app build stack shield proof time
qa-11.10.79 v4.1 platform + rust e99959ce 5.0 s
qa-11.10.81 v4.2 platform fold + rust b056d07c 7.1 s
qa-11.10.84 same platform lineage + rust 1f5dd24f 2 m 05 s
qa-11.10.99 current 5 m 50 s (worst observed)

.81 fast / .84 slow with the same platform lineage ⇒ the platform v4.2 fold is exonerated; the regression is introduced by the rust-dashcore repin b056d07c..1f5dd24f (2026-08-11, 14 commits): #941, #943, #944, #946, #947 (fold), #949, #952, #953 + fold-support commits. First-pass triage: #949's key-wallet hunk only adds scan_script_pubkeys (does not touch the islock path); #941/#943/#953 are networking; strongest remaining candidates are #944 (asset lock funded from a caller-chosen account list — changes funding/record filing across accounts) and the #946/#947 fold.

Also relevant: the FFI persister cannot represent the InstantSend context (rs-platform-wallet-ffi/src/core_wallet_types.rs islock TODO), so on Android the in-memory record view is the only possible source of an Instant proof — persistence cannot paper over the divergence.

Mitigation already applied

fix/asset-lock-proof-bounded-repoll (platform): both lock-waiters now cap each iteration's sleep at 1s and re-read the record, making them correct under every wake/visibility ordering (worst-case miss = 1s, not a chainlock). This restores ~5s flows but is a mitigation, not the root fix.

Ask

Root-cause why the waiter's record view (funding_tx_record via get_wallet_info) stops receiving islock (and sometimes chainlock) context promotions on b056d07c..1f5dd24f — which of the record-filing / account-enumeration / manager-view changes in that window causes the divergence — and fix at the source. Repro is deterministic: any self-broadcast shield on a current testnet build, comparing InstantLock signature verified timestamps against wait_for_proof resolution.

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