Skip to content

Add splice details to TransactionType::Splice#4570

Open
jkczyz wants to merge 2 commits intolightningdevkit:mainfrom
jkczyz:2026-04-splice-transaction-type
Open

Add splice details to TransactionType::Splice#4570
jkczyz wants to merge 2 commits intolightningdevkit:mainfrom
jkczyz:2026-04-splice-transaction-type

Conversation

@jkczyz
Copy link
Copy Markdown
Contributor

@jkczyz jkczyz commented Apr 17, 2026

Surface splice broadcast metadata downstream, so consumers (notably LDK Node) can reconcile PaymentDetails / PendingPaymentDetails directly from the broadcaster callback.

  • TransactionType::Splice now carries contribution: Option<FundingContribution> — our local contribution for this round, and replaced_txid: Option<Txid> — the prior negotiated candidate being replaced on RBF. The alternative (reacting to SplicePending) is worse: that event races with BDK wallet sync and doesn't carry the replaced txid.
  • FundingContribution gains public getters for estimated_fee, inputs, and max_feerate; feerate is elevated from pub(super) to pub. Combined with existing value_added, outputs, change_output, this exposes everything a downstream consumer needs without reaching into the raw transaction.

The Hash derive on TransactionType is dropped (unused in the workspace; FundingContribution transitively contains ConfirmedUtxo which lacks Hash).

jkczyz and others added 2 commits April 17, 2026 10:12
`TransactionType::Splice` now carries the local contribution to the
splice and, for RBF, the txid of the prior negotiated candidate being
replaced. This lets LDK Node update its `PaymentDetails` and
`PendingPaymentDetails` from the broadcast callback without re-deriving
the contribution from the raw transaction or tracking RBF chains
itself.

Driving these updates from the `SplicePending` event instead is more
complicated because that event races with BDK wallet syncing and
doesn't carry the replaced txid; the broadcast callback is a cleaner
integration point.

The `Hash` derive on `TransactionType` is dropped since it isn't used
anywhere in the workspace and `FundingContribution` (now embedded)
transitively contains `ConfirmedUtxo`, which doesn't derive `Hash`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add public getters for `estimated_fee`, `inputs`, and `max_feerate`, and
elevate `feerate` from `pub(super)` to `pub`. Together with the existing
`value_added`, `outputs`, and `change_output`, this gives downstream
consumers of `TransactionType::Splice` (notably LDK Node, which updates
`PaymentDetails` from the broadcast callback) the data they need
without reaching into the raw transaction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ldk-reviews-bot
Copy link
Copy Markdown

ldk-reviews-bot commented Apr 17, 2026

👋 Thanks for assigning @wpaulino as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz jkczyz requested review from TheBlueMatt and wpaulino April 17, 2026 21:14
@ldk-claude-review-bot
Copy link
Copy Markdown
Collaborator

I've thoroughly reviewed every file and hunk in the diff. Here is my assessment:

No issues found.

The core logic is correct:

  • replaced_txid (channel.rs:9361-9364): Uses checked_sub(2) on the negotiated_candidates length after the current candidate has already been pushed (line 9338), correctly yielding the second-to-last entry's txid (the one being replaced). Returns None for the first splice (length 1), Some(prev_txid) for RBFs.

  • contribution (channel.rs:9365): contributions.last().cloned() correctly returns the current round's contribution. The invariant that once contributions is non-empty, every subsequent completed round pushes a new entry is maintained by the tx_init_rbf flow (lines 13093-13125) and the abort cleanup in reset_pending_splice_state (line 7293).

  • Hash derive removal: Justified since FundingContribution transitively contains ConfirmedUtxo which lacks Hash, and Hash was unused on TransactionType anywhere in the workspace.

  • New public getters (estimated_fee, inputs, feerate, max_feerate): Visibility is consistent with the already-public value_added, outputs, and change_output getters. Types in the return positions (FundingTxInput, FeeRate, Amount) are all public.

  • Test coverage: Comprehensive — covers first splice (None), single RBF (Some(first)), sequential RBFs (Some(prev)), tiebreak scenarios, acceptor-only and initiator-only contributions.

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