77
88use core:: future:: Future ;
99use core:: task:: { Poll , Waker } ;
10- use std:: collections:: VecDeque ;
10+ use std:: collections:: { BTreeMap , VecDeque } ;
1111use std:: ops:: Deref ;
1212use std:: sync:: { Arc , Mutex } ;
1313
@@ -50,7 +50,7 @@ use crate::payment::asynchronous::static_invoice_store::StaticInvoiceStore;
5050use crate :: payment:: store:: {
5151 PaymentDetails , PaymentDetailsUpdate , PaymentDirection , PaymentKind , PaymentStatus ,
5252} ;
53- use crate :: payment:: PaymentMetadata ;
53+ use crate :: payment:: { PaymentMetadata , LDK_NODE_BOLT12_PAYMENT_METADATA_KEY } ;
5454use crate :: runtime:: Runtime ;
5555use crate :: types:: {
5656 CustomTlvRecord , DynStore , KeysManager , OnionMessenger , PaymentStore , Sweeper , Wallet ,
@@ -600,8 +600,9 @@ where
600600 }
601601 }
602602
603- fn lsps2_max_total_opening_fee_msat ( payment_metadata : & [ u8 ] , amount_msat : u64 ) -> Option < u64 > {
604- let metadata = PaymentMetadata :: read ( & mut & payment_metadata[ ..] ) . ok ( ) ?;
603+ fn lsps2_max_total_opening_fee_msat_from_metadata (
604+ metadata : PaymentMetadata , amount_msat : u64 ,
605+ ) -> Option < u64 > {
605606 let lsps2_parameters = metadata. lsps2_parameters ?;
606607 lsps2_parameters. max_total_opening_fee_msat . or_else ( || {
607608 lsps2_parameters. max_proportional_opening_fee_ppm_msat . and_then ( |max_prop_fee| {
@@ -611,6 +612,19 @@ where
611612 } )
612613 }
613614
615+ fn lsps2_max_total_opening_fee_msat ( payment_metadata : & [ u8 ] , amount_msat : u64 ) -> Option < u64 > {
616+ let metadata = PaymentMetadata :: read ( & mut & payment_metadata[ ..] ) . ok ( ) ?;
617+ Self :: lsps2_max_total_opening_fee_msat_from_metadata ( metadata, amount_msat)
618+ }
619+
620+ fn lsps2_max_total_opening_fee_msat_from_bolt12_metadata (
621+ payment_metadata : Option < & BTreeMap < u64 , Vec < u8 > > > , amount_msat : u64 ,
622+ ) -> Option < u64 > {
623+ let encoded_metadata = payment_metadata?. get ( & LDK_NODE_BOLT12_PAYMENT_METADATA_KEY ) ?;
624+ let metadata = PaymentMetadata :: read ( & mut & encoded_metadata[ ..] ) . ok ( ) ?;
625+ Self :: lsps2_max_total_opening_fee_msat_from_metadata ( metadata, amount_msat)
626+ }
627+
614628 pub async fn handle_event ( & self , event : LdkEvent ) -> Result < ( ) , ReplayEvent > {
615629 match event {
616630 LdkEvent :: FundingGenerationReady {
@@ -799,13 +813,19 @@ where
799813 . and_then ( |metadata| {
800814 Self :: lsps2_max_total_opening_fee_msat ( metadata, amount_msat)
801815 } ) ,
816+ PaymentPurpose :: Bolt12OfferPayment { payment_context, .. } => {
817+ Self :: lsps2_max_total_opening_fee_msat_from_bolt12_metadata (
818+ payment_context. payment_metadata . as_ref ( ) ,
819+ amount_msat,
820+ )
821+ } ,
802822 _ => None ,
803823 } ;
804824
805825 let Some ( max_total_opening_fee_msat) = max_total_opening_fee_msat else {
806826 log_info ! (
807827 self . logger,
808- "Refusing inbound payment with hash {} as the counterparty withheld {}msat without valid BOLT11 LSPS2 payment metadata" ,
828+ "Refusing inbound payment with hash {} as the counterparty withheld {}msat without valid LSPS2 payment metadata" ,
809829 hex_utils:: to_string( & payment_hash. 0 ) ,
810830 counterparty_skimmed_fee_msat,
811831 ) ;
@@ -829,18 +849,24 @@ where
829849 match & info. kind {
830850 PaymentKind :: Bolt11 { .. } => {
831851 let update = PaymentDetailsUpdate {
832- counterparty_skimmed_fee_msat : Some ( Some ( counterparty_skimmed_fee_msat) ) ,
852+ counterparty_skimmed_fee_msat : Some ( Some (
853+ counterparty_skimmed_fee_msat,
854+ ) ) ,
833855 ..PaymentDetailsUpdate :: new ( payment_id)
834856 } ;
835857 match self . payment_store . update ( update) . await {
836858 Ok ( _) => ( ) ,
837859 Err ( e) => {
838- log_error ! ( self . logger, "Failed to access payment store: {}" , e) ;
860+ log_error ! (
861+ self . logger,
862+ "Failed to access payment store: {}" ,
863+ e
864+ ) ;
839865 return Err ( ReplayEvent ( ) ) ;
840866 } ,
841867 } ;
842868 } ,
843- _ => debug_assert ! ( false , "We only expect the counterparty to get away with withholding fees for BOLT11 payments." ) ,
869+ _ => { } ,
844870 }
845871 }
846872 }
@@ -1936,6 +1962,7 @@ mod tests {
19361962 max_total_opening_fee_msat : Some ( 42_000 ) ,
19371963 max_proportional_opening_fee_ppm_msat : None ,
19381964 } ) ,
1965+ lsps2_bolt12_invoice_parameters : None ,
19391966 } ;
19401967
19411968 assert_eq ! (
@@ -1947,14 +1974,37 @@ mod tests {
19471974 ) ;
19481975 }
19491976
1977+ #[ test]
1978+ fn lsps2_bolt12_payment_metadata_decodes_total_fee_limit ( ) {
1979+ let metadata = PaymentMetadata {
1980+ lsps2_parameters : Some ( LSPS2Parameters {
1981+ max_total_opening_fee_msat : None ,
1982+ max_proportional_opening_fee_ppm_msat : Some ( 10_000 ) ,
1983+ } ) ,
1984+ lsps2_bolt12_invoice_parameters : None ,
1985+ }
1986+ . encode_as_bolt12_payment_metadata ( ) ;
1987+
1988+ assert_eq ! (
1989+ EventHandler :: <Arc <TestLogger >>:: lsps2_max_total_opening_fee_msat_from_bolt12_metadata(
1990+ Some ( & metadata) ,
1991+ 100_000
1992+ ) ,
1993+ Some ( 1_000 )
1994+ ) ;
1995+ }
1996+
19501997 #[ test]
19511998 fn lsps2_payment_metadata_missing_or_malformed_limit_is_rejected ( ) {
1952- let empty_metadata = PaymentMetadata { lsps2_parameters : None } . encode ( ) ;
1999+ let empty_metadata =
2000+ PaymentMetadata { lsps2_parameters : None , lsps2_bolt12_invoice_parameters : None }
2001+ . encode ( ) ;
19532002 let metadata_without_fee_limit = PaymentMetadata {
19542003 lsps2_parameters : Some ( LSPS2Parameters {
19552004 max_total_opening_fee_msat : None ,
19562005 max_proportional_opening_fee_ppm_msat : None ,
19572006 } ) ,
2007+ lsps2_bolt12_invoice_parameters : None ,
19582008 }
19592009 . encode ( ) ;
19602010
0 commit comments