@@ -11,7 +11,7 @@ use lightning::ln::channelmanager::PaymentId;
1111
1212use crate :: data_store:: { StorableObject , StorableObjectUpdate } ;
1313use crate :: payment:: store:: PaymentDetailsUpdate ;
14- use crate :: payment:: PaymentDetails ;
14+ use crate :: payment:: { PaymentDetails , PaymentKind } ;
1515
1616/// Represents a pending payment
1717#[ derive( Clone , Debug , PartialEq , Eq ) ]
@@ -26,11 +26,6 @@ impl PendingPaymentDetails {
2626 pub ( crate ) fn new ( details : PaymentDetails , conflicting_txids : Vec < Txid > ) -> Self {
2727 Self { details, conflicting_txids }
2828 }
29-
30- /// Convert to finalized payment for the main payment store
31- pub fn into_payment_details ( self ) -> PaymentDetails {
32- self . details
33- }
3429}
3530
3631impl_writeable_tlv_based ! ( PendingPaymentDetails , {
@@ -68,6 +63,12 @@ impl StorableObject for PendingPaymentDetails {
6863 }
6964 }
7065
66+ if let PaymentKind :: Onchain { txid, .. } = & self . details . kind {
67+ let conflicts_len = self . conflicting_txids . len ( ) ;
68+ self . conflicting_txids . retain ( |conflicting_txid| conflicting_txid != txid) ;
69+ updated |= self . conflicting_txids . len ( ) != conflicts_len;
70+ }
71+
7172 updated
7273 }
7374
@@ -92,3 +93,50 @@ impl From<&PendingPaymentDetails> for PendingPaymentDetailsUpdate {
9293 Self { id : value. id ( ) , payment_update : Some ( value. details . to_update ( ) ) , conflicting_txids }
9394 }
9495}
96+
97+ #[ cfg( test) ]
98+ mod tests {
99+ use bitcoin:: hashes:: Hash ;
100+
101+ use super :: * ;
102+ use crate :: payment:: { ConfirmationStatus , PaymentDirection , PaymentKind , PaymentStatus } ;
103+
104+ fn test_txid ( byte : u8 ) -> Txid {
105+ Txid :: from_byte_array ( [ byte; 32 ] )
106+ }
107+
108+ fn pending_onchain_payment ( payment_id : PaymentId , txid : Txid ) -> PaymentDetails {
109+ PaymentDetails :: new (
110+ payment_id,
111+ PaymentKind :: Onchain { txid, status : ConfirmationStatus :: Unconfirmed } ,
112+ Some ( 1_000 ) ,
113+ Some ( 100 ) ,
114+ PaymentDirection :: Outbound ,
115+ PaymentStatus :: Pending ,
116+ )
117+ }
118+
119+ #[ test]
120+ fn pending_onchain_conflicts_exclude_current_txid_after_txid_rotation ( ) {
121+ let original_txid = test_txid ( 1 ) ;
122+ let replacement_txid = test_txid ( 2 ) ;
123+ let payment_id = PaymentId ( original_txid. to_byte_array ( ) ) ;
124+
125+ let mut pending_payment = PendingPaymentDetails :: new (
126+ pending_onchain_payment ( payment_id, replacement_txid) ,
127+ vec ! [ original_txid] ,
128+ ) ;
129+ let update = PendingPaymentDetails :: new (
130+ pending_onchain_payment ( payment_id, original_txid) ,
131+ Vec :: new ( ) ,
132+ )
133+ . to_update ( ) ;
134+
135+ assert ! ( pending_payment. update( update) ) ;
136+ assert_eq ! (
137+ pending_payment. conflicting_txids,
138+ Vec :: <Txid >:: new( ) ,
139+ "current txid must not remain in its own conflict list"
140+ ) ;
141+ }
142+ }
0 commit comments