@@ -821,7 +821,184 @@ where
821821 amount_msat,
822822 ) ;
823823 let payment_preimage = match purpose {
824- PaymentPurpose :: Bolt11InvoicePayment { payment_preimage, .. } => {
824+ PaymentPurpose :: Bolt11InvoicePayment {
825+ payment_preimage,
826+ payment_secret,
827+ ..
828+ } => {
829+ if payment_preimage. is_none ( ) {
830+ // This is a manual-claim (`_for_hash`) payment that was not
831+ // pre-registered in the payment store. Check metadata store for
832+ // LSP fee limits and create the store entry.
833+ let lsp_fee_limits = self
834+ . payment_metadata_store
835+ . get_lsp_fee_limits_for_payment_id ( & payment_id) ;
836+
837+ if let Some ( ref limits) = lsp_fee_limits {
838+ let max_total_opening_fee_msat = limits
839+ . max_total_opening_fee_msat
840+ . or_else ( || {
841+ limits. max_proportional_opening_fee_ppm_msat . and_then (
842+ |max_prop_fee| {
843+ compute_opening_fee ( amount_msat, 0 , max_prop_fee)
844+ } ,
845+ )
846+ } )
847+ . unwrap_or ( 0 ) ;
848+
849+ if counterparty_skimmed_fee_msat > max_total_opening_fee_msat {
850+ log_info ! (
851+ self . logger,
852+ "Refusing inbound payment with hash {} as the counterparty-withheld fee of {}msat exceeds our limit of {}msat" ,
853+ hex_utils:: to_string( & payment_hash. 0 ) ,
854+ counterparty_skimmed_fee_msat,
855+ max_total_opening_fee_msat,
856+ ) ;
857+ self . channel_manager . fail_htlc_backwards ( & payment_hash) ;
858+ return Ok ( ( ) ) ;
859+ }
860+ }
861+
862+ let kind = if lsp_fee_limits. is_some ( ) {
863+ PaymentKind :: Bolt11Jit {
864+ hash : payment_hash,
865+ preimage : None ,
866+ secret : Some ( payment_secret) ,
867+ counterparty_skimmed_fee_msat : if counterparty_skimmed_fee_msat
868+ > 0
869+ {
870+ Some ( counterparty_skimmed_fee_msat)
871+ } else {
872+ None
873+ } ,
874+ lsp_fee_limits : lsp_fee_limits. unwrap ( ) ,
875+ }
876+ } else {
877+ PaymentKind :: Bolt11 {
878+ hash : payment_hash,
879+ preimage : None ,
880+ secret : Some ( payment_secret) ,
881+ }
882+ } ;
883+
884+ let payment = PaymentDetails :: new (
885+ payment_id,
886+ kind,
887+ Some ( amount_msat) ,
888+ None ,
889+ PaymentDirection :: Inbound ,
890+ PaymentStatus :: Pending ,
891+ ) ;
892+
893+ match self . payment_store . insert ( payment) {
894+ Ok ( _) => { } ,
895+ Err ( e) => {
896+ log_error ! (
897+ self . logger,
898+ "Failed to insert payment with ID {}: {}" ,
899+ payment_id,
900+ e
901+ ) ;
902+ return Err ( ReplayEvent ( ) ) ;
903+ } ,
904+ }
905+
906+ let custom_records = onion_fields
907+ . map ( |cf| {
908+ cf. custom_tlvs ( ) . into_iter ( ) . map ( |tlv| tlv. into ( ) ) . collect ( )
909+ } )
910+ . unwrap_or_default ( ) ;
911+ let event = Event :: PaymentClaimable {
912+ payment_id,
913+ payment_hash,
914+ claimable_amount_msat : amount_msat,
915+ claim_deadline,
916+ custom_records,
917+ } ;
918+ match self . event_queue . add_event ( event) . await {
919+ Ok ( _) => return Ok ( ( ) ) ,
920+ Err ( e) => {
921+ log_error ! ( self . logger, "Failed to push to event queue: {}" , e) ;
922+ return Err ( ReplayEvent ( ) ) ;
923+ } ,
924+ } ;
925+ } else {
926+ // Auto-claim path: payment has a preimage but was not
927+ // pre-registered in the store. Check metadata store for
928+ // LSP fee limits and create the store entry before claiming.
929+ let lsp_fee_limits = self
930+ . payment_metadata_store
931+ . get_lsp_fee_limits_for_payment_id ( & payment_id) ;
932+
933+ if let Some ( ref limits) = lsp_fee_limits {
934+ let max_total_opening_fee_msat = limits
935+ . max_total_opening_fee_msat
936+ . or_else ( || {
937+ limits. max_proportional_opening_fee_ppm_msat . and_then (
938+ |max_prop_fee| {
939+ compute_opening_fee ( amount_msat, 0 , max_prop_fee)
940+ } ,
941+ )
942+ } )
943+ . unwrap_or ( 0 ) ;
944+
945+ if counterparty_skimmed_fee_msat > max_total_opening_fee_msat {
946+ log_info ! (
947+ self . logger,
948+ "Refusing inbound payment with hash {} as the counterparty-withheld fee of {}msat exceeds our limit of {}msat" ,
949+ hex_utils:: to_string( & payment_hash. 0 ) ,
950+ counterparty_skimmed_fee_msat,
951+ max_total_opening_fee_msat,
952+ ) ;
953+ self . channel_manager . fail_htlc_backwards ( & payment_hash) ;
954+ return Ok ( ( ) ) ;
955+ }
956+ }
957+
958+ let kind = if lsp_fee_limits. is_some ( ) {
959+ PaymentKind :: Bolt11Jit {
960+ hash : payment_hash,
961+ preimage : payment_preimage,
962+ secret : Some ( payment_secret) ,
963+ counterparty_skimmed_fee_msat : if counterparty_skimmed_fee_msat
964+ > 0
965+ {
966+ Some ( counterparty_skimmed_fee_msat)
967+ } else {
968+ None
969+ } ,
970+ lsp_fee_limits : lsp_fee_limits. unwrap ( ) ,
971+ }
972+ } else {
973+ PaymentKind :: Bolt11 {
974+ hash : payment_hash,
975+ preimage : payment_preimage,
976+ secret : Some ( payment_secret) ,
977+ }
978+ } ;
979+
980+ let payment = PaymentDetails :: new (
981+ payment_id,
982+ kind,
983+ Some ( amount_msat) ,
984+ None ,
985+ PaymentDirection :: Inbound ,
986+ PaymentStatus :: Pending ,
987+ ) ;
988+
989+ match self . payment_store . insert ( payment) {
990+ Ok ( _) => { } ,
991+ Err ( e) => {
992+ log_error ! (
993+ self . logger,
994+ "Failed to insert payment with ID {}: {}" ,
995+ payment_id,
996+ e
997+ ) ;
998+ return Err ( ReplayEvent ( ) ) ;
999+ } ,
1000+ }
1001+ }
8251002 payment_preimage
8261003 } ,
8271004 PaymentPurpose :: Bolt12OfferPayment {
@@ -960,43 +1137,85 @@ where
9601137 amount_msat,
9611138 ) ;
9621139
963- let update = match purpose {
1140+ let ( update, kind_for_insert ) = match purpose {
9641141 PaymentPurpose :: Bolt11InvoicePayment {
9651142 payment_preimage,
9661143 payment_secret,
9671144 ..
968- } => PaymentDetailsUpdate {
969- preimage : Some ( payment_preimage) ,
970- secret : Some ( Some ( payment_secret) ) ,
971- amount_msat : Some ( Some ( amount_msat) ) ,
972- status : Some ( PaymentStatus :: Succeeded ) ,
973- ..PaymentDetailsUpdate :: new ( payment_id)
1145+ } => {
1146+ let kind = PaymentKind :: Bolt11 {
1147+ hash : payment_hash,
1148+ preimage : payment_preimage,
1149+ secret : Some ( payment_secret. clone ( ) ) ,
1150+ } ;
1151+ let update = PaymentDetailsUpdate {
1152+ preimage : Some ( payment_preimage) ,
1153+ secret : Some ( Some ( payment_secret) ) ,
1154+ amount_msat : Some ( Some ( amount_msat) ) ,
1155+ status : Some ( PaymentStatus :: Succeeded ) ,
1156+ ..PaymentDetailsUpdate :: new ( payment_id)
1157+ } ;
1158+ ( update, kind)
9741159 } ,
9751160 PaymentPurpose :: Bolt12OfferPayment {
976- payment_preimage, payment_secret, ..
977- } => PaymentDetailsUpdate {
978- preimage : Some ( payment_preimage) ,
979- secret : Some ( Some ( payment_secret) ) ,
980- amount_msat : Some ( Some ( amount_msat) ) ,
981- status : Some ( PaymentStatus :: Succeeded ) ,
982- ..PaymentDetailsUpdate :: new ( payment_id)
1161+ payment_preimage,
1162+ payment_secret,
1163+ payment_context,
1164+ ..
1165+ } => {
1166+ let payer_note = payment_context. invoice_request . payer_note_truncated ;
1167+ let offer_id = payment_context. offer_id ;
1168+ let quantity = payment_context. invoice_request . quantity ;
1169+ let kind = PaymentKind :: Bolt12Offer {
1170+ hash : Some ( payment_hash) ,
1171+ preimage : payment_preimage,
1172+ secret : Some ( payment_secret. clone ( ) ) ,
1173+ offer_id,
1174+ payer_note,
1175+ quantity,
1176+ } ;
1177+ let update = PaymentDetailsUpdate {
1178+ preimage : Some ( payment_preimage) ,
1179+ secret : Some ( Some ( payment_secret) ) ,
1180+ amount_msat : Some ( Some ( amount_msat) ) ,
1181+ status : Some ( PaymentStatus :: Succeeded ) ,
1182+ ..PaymentDetailsUpdate :: new ( payment_id)
1183+ } ;
1184+ ( update, kind)
9831185 } ,
9841186 PaymentPurpose :: Bolt12RefundPayment {
9851187 payment_preimage,
9861188 payment_secret,
9871189 ..
988- } => PaymentDetailsUpdate {
989- preimage : Some ( payment_preimage) ,
990- secret : Some ( Some ( payment_secret) ) ,
991- amount_msat : Some ( Some ( amount_msat) ) ,
992- status : Some ( PaymentStatus :: Succeeded ) ,
993- ..PaymentDetailsUpdate :: new ( payment_id)
1190+ } => {
1191+ let kind = PaymentKind :: Bolt12Refund {
1192+ hash : Some ( payment_hash) ,
1193+ preimage : payment_preimage,
1194+ secret : Some ( payment_secret. clone ( ) ) ,
1195+ payer_note : None ,
1196+ quantity : None ,
1197+ } ;
1198+ let update = PaymentDetailsUpdate {
1199+ preimage : Some ( payment_preimage) ,
1200+ secret : Some ( Some ( payment_secret) ) ,
1201+ amount_msat : Some ( Some ( amount_msat) ) ,
1202+ status : Some ( PaymentStatus :: Succeeded ) ,
1203+ ..PaymentDetailsUpdate :: new ( payment_id)
1204+ } ;
1205+ ( update, kind)
9941206 } ,
995- PaymentPurpose :: SpontaneousPayment ( preimage) => PaymentDetailsUpdate {
996- preimage : Some ( Some ( preimage) ) ,
997- amount_msat : Some ( Some ( amount_msat) ) ,
998- status : Some ( PaymentStatus :: Succeeded ) ,
999- ..PaymentDetailsUpdate :: new ( payment_id)
1207+ PaymentPurpose :: SpontaneousPayment ( preimage) => {
1208+ let kind = PaymentKind :: Spontaneous {
1209+ hash : payment_hash,
1210+ preimage : Some ( preimage) ,
1211+ } ;
1212+ let update = PaymentDetailsUpdate {
1213+ preimage : Some ( Some ( preimage) ) ,
1214+ amount_msat : Some ( Some ( amount_msat) ) ,
1215+ status : Some ( PaymentStatus :: Succeeded ) ,
1216+ ..PaymentDetailsUpdate :: new ( payment_id)
1217+ } ;
1218+ ( update, kind)
10001219 } ,
10011220 } ;
10021221
@@ -1006,11 +1225,27 @@ where
10061225 // be the result of a replayed event.
10071226 ) ,
10081227 Ok ( DataStoreUpdateResult :: NotFound ) => {
1009- log_error ! (
1010- self . logger,
1011- "Claimed payment with ID {} couldn't be found in store" ,
1228+ // Payment was auto-claimed without a prior store entry.
1229+ let payment = PaymentDetails :: new (
10121230 payment_id,
1231+ kind_for_insert,
1232+ Some ( amount_msat) ,
1233+ None ,
1234+ PaymentDirection :: Inbound ,
1235+ PaymentStatus :: Succeeded ,
10131236 ) ;
1237+ match self . payment_store . insert ( payment) {
1238+ Ok ( _) => ( ) ,
1239+ Err ( e) => {
1240+ log_error ! (
1241+ self . logger,
1242+ "Failed to insert payment with ID {}: {}" ,
1243+ payment_id,
1244+ e
1245+ ) ;
1246+ return Err ( ReplayEvent ( ) ) ;
1247+ } ,
1248+ }
10141249 } ,
10151250 Err ( e) => {
10161251 log_error ! (
0 commit comments