Skip to content

feat(swaps): native PeerSwap on-chain primitives (B1–B7) + bitcoind txid byte-order fix#3

Open
tonible14012002 wants to merge 8 commits into
lamtuanvu:custom-gossip-datafrom
tonible14012002:swaps
Open

feat(swaps): native PeerSwap on-chain primitives (B1–B7) + bitcoind txid byte-order fix#3
tonible14012002 wants to merge 8 commits into
lamtuanvu:custom-gossip-datafrom
tonible14012002:swaps

Conversation

@tonible14012002

Copy link
Copy Markdown

Summary

Adds the on-chain primitives the native PeerSwap engine (in the consumer econ-v1/nodemodules/ldk-node) builds on, all behind a new swaps cargo feature so the default build is byte-for-byte unaffected, plus a fix to the bitcoind chain backend that made swap confirmations unobservable.

Native swap primitives (B1–B7)

  • B1–B3 fundingcreate_swap_funding_tx (signed P2WSH HTLC opening, not broadcast), swap_list_confirmed_utxos, swap_sign_psbt (wallet/mod.rs).
  • B4 broadcastbroadcast_swap_tx over the bounded broadcast queue (tx_broadcaster.rs).
  • B5 reorg-aware per-txid confirmation trackingwatch_txid + get_tx_confirmationsTxStatus/ChainStatus + derive_tx_status, with swap_query_tx over whichever chain source is configured (Esplora/Electrum/Bitcoind) and fail-closed (NoChainSource) when it cannot answer (chain/mod.rs, chain/electrum.rs).
  • B6 feerateestimate_onchain_feerate → source-bearing FeerateQuote (fee_estimator.rs).
  • B7 discovery — swap-capability custom gossip plumbing (custom_gossip.rs).
  • Builder wiring + public surface (builder.rs, lib.rs).

Bug fix: swap_tx_confirmations queried the txid in reversed byte order

chain/bitcoind.rs passed consensus::encode::serialize_hex(txid) (internal little-endian bytes) to getrawtransaction, which expects the RPC/display (big-endian) txid. bitcoind answered -5 No such transaction, mapped to Ok(None) → NotFound, so the swap watcher never observed a confirmed opening tx on the bitcoind backend — the confirmation/CSV ladder never armed and swaps wedged. Fix: pass txid.to_string(). Proven on regtest (display txid = 10 confs; reversed = -5), after which a full swap-in ran to completion end-to-end.

Notes

  • Everything swap-related is gated behind #[cfg(feature = "swaps")]; without the feature this is a no-op.
  • This branch also carries the fork's prior customizations (custom gossip, onboarding/private-channel tweaks, channel-funding feerate target) that preceded the swap work.

🤖 Generated with Claude Code

lamtuanvu and others added 8 commits July 3, 2025 21:48
The ChannelFunding confirmation target resolved to a 12-block fee tier,
which during normal mempool congestion maps to a rate low enough that
funding transactions can sit unconfirmed for hours. The channel never
reaches channel_ready and the UI is stuck on `sync`.

Lower the target to ~3 blocks (mempool's "fast" tier) so funding txs are
mined promptly. The fee is still sourced from the chain source's
recommended estimates (esplora get_fee_estimates / electrum estimatefee /
bitcoind estimatesmartfee) — only the targeted confirmation window
changes, and only for funding transactions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…yte order

getrawtransaction wants the txid in RPC/display (big-endian) order (Txid Display),
but serialize_hex(txid) emits internal little-endian (reversed) bytes → bitcoind
returns -5, mapped to Ok(None)=NotFound. The native swap watcher therefore never
saw a confirmed opening tx on the bitcoind backend, so the CSV/confirmation ladder
never armed and swaps wedged at AWAIT_CONFIRM/AWAIT_CLAIM_PAYMENT. Fix: pass
txid.to_string() (display order). Proven on regtest (display txid=10 confs, reversed=-5).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…swaps` feature

Add the on-chain building blocks the native PeerSwap engine (modules/ldk-node in
the consumer) needs, all gated behind a new `swaps` cargo feature so the default
build is byte-for-byte unaffected:

- B1–B3 funding: create_swap_funding_tx (P2WSH HTLC opening, signed, not broadcast),
  swap_list_confirmed_utxos, swap_sign_psbt (wallet/mod.rs).
- B4 broadcast: broadcast_swap_tx over the bounded broadcast queue (tx_broadcaster.rs).
- B5 reorg-aware per-txid confirmation tracking: watch_txid + get_tx_confirmations
  → TxStatus/ChainStatus + derive_tx_status, with a swap_query_tx backed by whichever
  chain source is configured (Esplora/Electrum/Bitcoind) and FAIL-CLOSED
  (NoChainSource) when it cannot answer (chain/mod.rs, chain/electrum.rs).
- B6 feerate: estimate_onchain_feerate → source-bearing FeerateQuote so callers can
  refuse a stale/fallback estimate (fee_estimator.rs).
- B7 discovery: swap-capability custom gossip plumbing (custom_gossip.rs).
- Builder wiring (builder.rs), public surface (lib.rs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants