feat(swaps): native PeerSwap on-chain primitives (B1–B7) + bitcoind txid byte-order fix#3
Open
tonible14012002 wants to merge 8 commits into
Open
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the on-chain primitives the native PeerSwap engine (in the consumer
econ-v1/node→modules/ldk-node) builds on, all behind a newswapscargo 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)
create_swap_funding_tx(signed P2WSH HTLC opening, not broadcast),swap_list_confirmed_utxos,swap_sign_psbt(wallet/mod.rs).broadcast_swap_txover the bounded broadcast queue (tx_broadcaster.rs).watch_txid+get_tx_confirmations→TxStatus/ChainStatus+derive_tx_status, withswap_query_txover whichever chain source is configured (Esplora/Electrum/Bitcoind) and fail-closed (NoChainSource) when it cannot answer (chain/mod.rs,chain/electrum.rs).estimate_onchain_feerate→ source-bearingFeerateQuote(fee_estimator.rs).custom_gossip.rs).builder.rs,lib.rs).Bug fix:
swap_tx_confirmationsqueried the txid in reversed byte orderchain/bitcoind.rspassedconsensus::encode::serialize_hex(txid)(internal little-endian bytes) togetrawtransaction, which expects the RPC/display (big-endian) txid. bitcoind answered-5 No such transaction, mapped toOk(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: passtxid.to_string(). Proven on regtest (display txid = 10 confs; reversed = -5), after which a full swap-in ran to completion end-to-end.Notes
#[cfg(feature = "swaps")]; without the feature this is a no-op.🤖 Generated with Claude Code