Skip to content

On-chain send reports success before broadcast is attempted; failed broadcast leaves inputs marked spent #1143

Description

@coreyphillips

Severity: Medium (fund-stranding / UX integrity)

Wallet::send_to_address in ldk-node builds, signs, and persists the transaction, then calls broadcast_transactions and unconditionally returns Ok(txid) (ldk-node/src/wallet/mod.rs:1915). The broadcaster is a fire-and-forget try_send onto a 50-slot queue; a full queue is only logged (ldk-node/src/tx_broadcaster.rs:47-52). The queue consumer POSTs each tx to esplora and only logs failures (timeouts, 5xx, non-"already known" 400s), with no retry and no error path back to the caller (ldk-node/src/chain/esplora.rs:482-551).

The app therefore shows the success state as soon as Ok(txid) returns, whether or not the tx reached the network. If it never propagates, the tx stays in the wallet store with its inputs spent and the funds appear locked. The only downstream signal is OnchainTransactionEvicted on a later sync (AppViewModel.kt:1059 -> ActivityRepo.kt:262: toast + activity removed). There are no cancelTx or rebroadcast call sites in the app, and ldk-node never re-broadcasts unconfirmed wallet transactions. The same queue also carries RBF bumps and CPFP accelerations.

Steps to reproduce:

  1. Send an on-chain payment while the configured esplora endpoint is unreachable (cut connectivity right after confirm, or point the app at a dead esplora URL on regtest).
  2. The app shows success with a txid; the tx never appears on chain.
  3. Balance stays reduced until a later sync evicts the tx.

Suggested fix:

  • Make broadcast_transactions return a result the payment call can await, or have the queue consumer emit a per-txid success/failure event.
  • Periodically re-broadcast unconfirmed wallet transactions.
  • When OnchainTransactionEvicted fires for a user-initiated send, offer "retry broadcast" and "cancel (RBF-to-self)" actions in the UI.

Sibling issue: synonymdev/bitkit-ios#660 (same root cause in ldk-node).

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