55// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66// accordance with one or both of these licenses.
77
8+ use bitcoin:: secp256k1:: PublicKey ;
89use bitcoin:: Txid ;
910use lightning:: impl_writeable_tlv_based;
11+ use lightning:: impl_writeable_tlv_based_enum;
1012use lightning:: ln:: channelmanager:: PaymentId ;
13+ use lightning:: ln:: funding:: FundingContribution ;
14+ use lightning:: ln:: types:: ChannelId ;
1115
1216use crate :: data_store:: { StorableObject , StorableObjectUpdate } ;
1317use crate :: payment:: store:: PaymentDetailsUpdate ;
1418use crate :: payment:: PaymentDetails ;
1519
20+ /// Identifies which channel lifecycle event a [`FundingDetails`] record tracks.
21+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
22+ pub enum FundingPurpose {
23+ /// The funding transaction opens a channel.
24+ Establishment ,
25+ /// The funding transaction splices an already-open channel.
26+ Splice ,
27+ }
28+
29+ impl_writeable_tlv_based_enum ! ( FundingPurpose ,
30+ ( 0 , Establishment ) => { } ,
31+ ( 2 , Splice ) => { }
32+ ) ;
33+
34+ /// One broadcast of a funding transaction (channel open or splice) in which this node
35+ /// had a stake.
36+ ///
37+ /// When an RBF produces multiple candidates for the same [`FundingDetails`], each
38+ /// broadcast is recorded as its own [`FundingCandidate`] so that whichever candidate
39+ /// actually confirms can be identified and its contribution values restored onto the
40+ /// outer [`PaymentDetails`].
41+ ///
42+ /// `contribution` is set for dual-funded opens and splices, where the local node submits
43+ /// a [`FundingContribution`] describing its inputs, outputs, and fee share. It is `None`
44+ /// for single-funded opens, which have exactly one candidate and no alternative to swap
45+ /// to.
46+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
47+ pub struct FundingCandidate {
48+ /// Transaction ID of this broadcast.
49+ pub txid : Txid ,
50+ /// The contribution used to build this candidate, if any.
51+ pub contribution : Option < FundingContribution > ,
52+ }
53+
54+ impl_writeable_tlv_based ! ( FundingCandidate , {
55+ ( 0 , txid, required) ,
56+ ( 2 , contribution, option) ,
57+ } ) ;
58+
59+ /// Marks an on-chain payment as belonging to a channel's funding lifecycle (open or
60+ /// splice), and carries the per-candidate state needed to react to RBF replacements.
61+ ///
62+ /// The candidate whose `txid` matches the outer [`PaymentDetails`]`::kind.txid` is the
63+ /// one currently reflected by the payment's `amount_msat` and `fee_paid_msat`. On RBF, a
64+ /// new candidate is appended and becomes active.
65+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
66+ pub struct FundingDetails {
67+ /// The channel whose funding is being tracked.
68+ pub channel_id : ChannelId ,
69+ /// The channel's counterparty.
70+ pub counterparty_node_id : PublicKey ,
71+ /// Whether this funding is for a channel open or a splice.
72+ pub purpose : FundingPurpose ,
73+ /// Broadcast candidates, in the order they were observed.
74+ pub candidates : Vec < FundingCandidate > ,
75+ }
76+
77+ impl_writeable_tlv_based ! ( FundingDetails , {
78+ ( 0 , channel_id, required) ,
79+ ( 2 , counterparty_node_id, required) ,
80+ ( 4 , purpose, required) ,
81+ ( 6 , candidates, optional_vec) ,
82+ } ) ;
83+
1684/// Represents a pending payment
1785#[ derive( Clone , Debug , PartialEq , Eq ) ]
1886pub struct PendingPaymentDetails {
1987 /// The full payment details
2088 pub details : PaymentDetails ,
2189 /// Transaction IDs that have replaced or conflict with this payment.
2290 pub conflicting_txids : Vec < Txid > ,
91+ /// Set when the payment's transaction is a channel funding (open or splice). The
92+ /// record transitions to [`PaymentStatus::Succeeded`] on `ChannelReady` instead of
93+ /// after [`ANTI_REORG_DELAY`] confirmations.
94+ ///
95+ /// [`PaymentStatus::Succeeded`]: crate::payment::store::PaymentStatus::Succeeded
96+ /// [`ANTI_REORG_DELAY`]: lightning::chain::channelmonitor::ANTI_REORG_DELAY
97+ pub funding_details : Option < FundingDetails > ,
2398}
2499
25100impl PendingPaymentDetails {
26101 pub ( crate ) fn new ( details : PaymentDetails , conflicting_txids : Vec < Txid > ) -> Self {
27- Self { details, conflicting_txids }
102+ Self { details, conflicting_txids, funding_details : None }
103+ }
104+
105+ pub ( crate ) fn with_funding_details (
106+ details : PaymentDetails , conflicting_txids : Vec < Txid > , funding_details : FundingDetails ,
107+ ) -> Self {
108+ Self { details, conflicting_txids, funding_details : Some ( funding_details) }
28109 }
29110
30111 /// Convert to finalized payment for the main payment store
@@ -36,13 +117,15 @@ impl PendingPaymentDetails {
36117impl_writeable_tlv_based ! ( PendingPaymentDetails , {
37118 ( 0 , details, required) ,
38119 ( 2 , conflicting_txids, optional_vec) ,
120+ ( 4 , funding_details, option) ,
39121} ) ;
40122
41123#[ derive( Clone , Debug , PartialEq , Eq ) ]
42124pub ( crate ) struct PendingPaymentDetailsUpdate {
43125 pub id : PaymentId ,
44126 pub payment_update : Option < PaymentDetailsUpdate > ,
45127 pub conflicting_txids : Option < Vec < Txid > > ,
128+ pub funding_details : Option < Option < FundingDetails > > ,
46129}
47130
48131impl StorableObject for PendingPaymentDetails {
@@ -68,6 +151,13 @@ impl StorableObject for PendingPaymentDetails {
68151 }
69152 }
70153
154+ if let Some ( new_funding_details) = update. funding_details {
155+ if self . funding_details != new_funding_details {
156+ self . funding_details = new_funding_details;
157+ updated = true ;
158+ }
159+ }
160+
71161 updated
72162 }
73163
@@ -89,6 +179,11 @@ impl From<&PendingPaymentDetails> for PendingPaymentDetailsUpdate {
89179 } else {
90180 Some ( value. conflicting_txids . clone ( ) )
91181 } ;
92- Self { id : value. id ( ) , payment_update : Some ( value. details . to_update ( ) ) , conflicting_txids }
182+ Self {
183+ id : value. id ( ) ,
184+ payment_update : Some ( value. details . to_update ( ) ) ,
185+ conflicting_txids,
186+ funding_details : Some ( value. funding_details . clone ( ) ) ,
187+ }
93188 }
94189}
0 commit comments