@@ -84,6 +84,28 @@ pub enum Event {
8484 /// The value, in thousandths of a satoshi, that has been received.
8585 amount_msat : u64 ,
8686 } ,
87+ /// A payment for a previously-registered payment hash has been received.
88+ ///
89+ /// This needs to be manually claimed by supplying the correct preimage to [`claim_for_hash`].
90+ ///
91+ /// If the the provided parameters don't match the expectations or the preimage can't be
92+ /// retrieved in time, should be failed-back via [`fail_for_hash`].
93+ ///
94+ /// Note claiming will necessarily fail after the `claim_deadline` has been reached.
95+ ///
96+ /// [`claim_for_hash`]: crate::payment::Bolt11Payment::claim_for_hash
97+ /// [`fail_for_hash`]: crate::payment::Bolt11Payment::fail_for_hash
98+ PaymentClaimable {
99+ /// A local identifier used to track the payment.
100+ payment_id : PaymentId ,
101+ /// The hash of the payment.
102+ payment_hash : PaymentHash ,
103+ /// The value, in thousandths of a satoshi, that is claimable.
104+ claimable_amount_msat : u64 ,
105+ /// The block height at which this payment will be failed back and will no longer be
106+ /// eligible for claiming.
107+ claim_deadline : Option < u32 > ,
108+ } ,
87109 /// A channel has been created and is pending confirmation on-chain.
88110 ChannelPending {
89111 /// The `channel_id` of the channel.
@@ -156,6 +178,12 @@ impl_writeable_tlv_based_enum!(Event,
156178 ( 1 , counterparty_node_id, option) ,
157179 ( 2 , user_channel_id, required) ,
158180 ( 3 , reason, upgradable_option) ,
181+ } ,
182+ ( 6 , PaymentClaimable ) => {
183+ ( 0 , payment_hash, required) ,
184+ ( 2 , payment_id, required) ,
185+ ( 4 , claimable_amount_msat, required) ,
186+ ( 6 , claim_deadline, option) ,
159187 } ;
160188) ;
161189
@@ -434,12 +462,31 @@ where
434462 receiver_node_id : _,
435463 via_channel_id : _,
436464 via_user_channel_id : _,
437- claim_deadline : _ ,
465+ claim_deadline,
438466 onion_fields : _,
439467 counterparty_skimmed_fee_msat,
440468 } => {
441469 let payment_id = PaymentId ( payment_hash. 0 ) ;
442470 if let Some ( info) = self . payment_store . get ( & payment_id) {
471+ if info. direction == PaymentDirection :: Outbound {
472+ log_info ! (
473+ self . logger,
474+ "Refused inbound payment with ID {}: circular payments are unsupported." ,
475+ payment_id
476+ ) ;
477+ self . channel_manager . fail_htlc_backwards ( & payment_hash) ;
478+
479+ let update = PaymentDetailsUpdate {
480+ status : Some ( PaymentStatus :: Failed ) ,
481+ ..PaymentDetailsUpdate :: new ( payment_id)
482+ } ;
483+ self . payment_store . update ( & update) . unwrap_or_else ( |e| {
484+ log_error ! ( self . logger, "Failed to access payment store: {}" , e) ;
485+ panic ! ( "Failed to access payment store" ) ;
486+ } ) ;
487+ return ;
488+ }
489+
443490 if info. status == PaymentStatus :: Succeeded
444491 || matches ! ( info. kind, PaymentKind :: Spontaneous { .. } )
445492 {
@@ -500,6 +547,38 @@ where
500547 } ) ;
501548 return ;
502549 }
550+
551+ // If this is known by the store but ChannelManager doesn't know the preimage,
552+ // the payment has been registered via `_for_hash` variants and needs to be manually claimed via
553+ // user interaction.
554+ match info. kind {
555+ PaymentKind :: Bolt11 { preimage, .. } => {
556+ if purpose. preimage ( ) . is_none ( ) {
557+ debug_assert ! (
558+ preimage. is_none( ) ,
559+ "We would have registered the preimage if we knew"
560+ ) ;
561+
562+ self . event_queue
563+ . add_event ( Event :: PaymentClaimable {
564+ payment_id,
565+ payment_hash,
566+ claimable_amount_msat : amount_msat,
567+ claim_deadline,
568+ } )
569+ . unwrap_or_else ( |e| {
570+ log_error ! (
571+ self . logger,
572+ "Failed to push to event queue: {}" ,
573+ e
574+ ) ;
575+ panic ! ( "Failed to push to event queue" ) ;
576+ } ) ;
577+ return ;
578+ }
579+ } ,
580+ _ => { } ,
581+ }
503582 }
504583
505584 log_info ! (
@@ -519,19 +598,21 @@ where
519598 ..
520599 } => {
521600 let offer_id = payment_context. offer_id ;
522- let payment = PaymentDetails {
523- id : payment_id,
524- kind : PaymentKind :: Bolt12Offer {
525- hash : Some ( payment_hash) ,
526- preimage : payment_preimage,
527- secret : Some ( payment_secret) ,
528- offer_id,
529- } ,
530- amount_msat : Some ( amount_msat) ,
531- direction : PaymentDirection :: Inbound ,
532- status : PaymentStatus :: Pending ,
601+ let kind = PaymentKind :: Bolt12Offer {
602+ hash : Some ( payment_hash) ,
603+ preimage : payment_preimage,
604+ secret : Some ( payment_secret) ,
605+ offer_id,
533606 } ;
534607
608+ let payment = PaymentDetails :: new (
609+ payment_id,
610+ kind,
611+ Some ( amount_msat) ,
612+ PaymentDirection :: Inbound ,
613+ PaymentStatus :: Pending ,
614+ ) ;
615+
535616 match self . payment_store . insert ( payment) {
536617 Ok ( false ) => ( ) ,
537618 Ok ( true ) => {
@@ -559,17 +640,19 @@ where
559640 } ,
560641 PaymentPurpose :: SpontaneousPayment ( preimage) => {
561642 // Since it's spontaneous, we insert it now into our store.
562- let payment = PaymentDetails {
563- id : payment_id,
564- kind : PaymentKind :: Spontaneous {
565- hash : payment_hash,
566- preimage : Some ( preimage) ,
567- } ,
568- amount_msat : Some ( amount_msat) ,
569- direction : PaymentDirection :: Inbound ,
570- status : PaymentStatus :: Pending ,
643+ let kind = PaymentKind :: Spontaneous {
644+ hash : payment_hash,
645+ preimage : Some ( preimage) ,
571646 } ;
572647
648+ let payment = PaymentDetails :: new (
649+ payment_id,
650+ kind,
651+ Some ( amount_msat) ,
652+ PaymentDirection :: Inbound ,
653+ PaymentStatus :: Pending ,
654+ ) ;
655+
573656 match self . payment_store . insert ( payment) {
574657 Ok ( false ) => ( ) ,
575658 Ok ( true ) => {
0 commit comments