@@ -19,13 +19,15 @@ use core::ops::Deref;
1919use core:: pin:: pin;
2020use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
2121use core:: task;
22+ use core:: time:: Duration ;
2223
2324use crate :: events:: EventQueue ;
2425use crate :: lsps0:: ser:: {
25- LSPSMessage , LSPSProtocolMessageHandler , LSPSRequestId , LSPSResponseError ,
26+ LSPSDateTime , LSPSMessage , LSPSProtocolMessageHandler , LSPSRequestId , LSPSResponseError ,
2627 JSONRPC_INTERNAL_ERROR_ERROR_CODE , JSONRPC_INTERNAL_ERROR_ERROR_MESSAGE ,
2728 LSPS0_CLIENT_REJECTED_ERROR_CODE ,
2829} ;
30+ use crate :: utils:: time:: TimeProvider ;
2931use crate :: lsps2:: event:: LSPS2ServiceEvent ;
3032use crate :: lsps2:: payment_queue:: { InterceptedHTLC , PaymentQueue } ;
3133use crate :: lsps2:: utils:: {
@@ -497,6 +499,8 @@ struct OutboundJITChannel {
497499 opening_fee_params : LSPS2OpeningFeeParams ,
498500 payment_size_msat : Option < u64 > ,
499501 trust_model : TrustModel ,
502+ /// The time at which the JIT channel was created (i.e., the buy request was accepted).
503+ created_at : LSPSDateTime ,
500504}
501505
502506impl_writeable_tlv_based ! ( OutboundJITChannel , {
@@ -505,19 +509,21 @@ impl_writeable_tlv_based!(OutboundJITChannel, {
505509 ( 4 , opening_fee_params, required) ,
506510 ( 6 , payment_size_msat, option) ,
507511 ( 8 , trust_model, required) ,
512+ ( 10 , created_at, ( default_value, LSPSDateTime :: new_from_duration_since_epoch( Duration :: ZERO ) ) ) ,
508513} ) ;
509514
510515impl OutboundJITChannel {
511516 fn new (
512517 payment_size_msat : Option < u64 > , opening_fee_params : LSPS2OpeningFeeParams ,
513- user_channel_id : u128 , client_trusts_lsp : bool ,
518+ user_channel_id : u128 , client_trusts_lsp : bool , created_at : LSPSDateTime ,
514519 ) -> Self {
515520 Self {
516521 user_channel_id,
517522 state : OutboundJITChannelState :: new ( ) ,
518523 opening_fee_params,
519524 payment_size_msat,
520525 trust_model : TrustModel :: new ( client_trusts_lsp) ,
526+ created_at,
521527 }
522528 }
523529
@@ -702,9 +708,10 @@ macro_rules! get_or_insert_peer_state_entry {
702708}
703709
704710/// The main object allowing to send and receive bLIP-52 / LSPS2 messages.
705- pub struct LSPS2ServiceHandler < CM : Deref , K : KVStore + Clone , T : BroadcasterInterface >
711+ pub struct LSPS2ServiceHandler < CM : Deref , K : KVStore + Clone , T : BroadcasterInterface , TP : Deref + Clone >
706712where
707713 CM :: Target : AChannelManager ,
714+ TP :: Target : TimeProvider ,
708715{
709716 channel_manager : CM ,
710717 kv_store : K ,
@@ -717,17 +724,20 @@ where
717724 total_pending_requests : AtomicUsize ,
718725 config : LSPS2ServiceConfig ,
719726 persistence_in_flight : AtomicUsize ,
727+ time_provider : TP ,
720728}
721729
722- impl < CM : Deref , K : KVStore + Clone , T : BroadcasterInterface + Clone > LSPS2ServiceHandler < CM , K , T >
730+ impl < CM : Deref , K : KVStore + Clone , T : BroadcasterInterface + Clone , TP : Deref + Clone >
731+ LSPS2ServiceHandler < CM , K , T , TP >
723732where
724733 CM :: Target : AChannelManager ,
734+ TP :: Target : TimeProvider ,
725735{
726736 /// Constructs a `LSPS2ServiceHandler`.
727737 pub ( crate ) fn new (
728738 per_peer_state : HashMap < PublicKey , Mutex < PeerState > > , pending_messages : Arc < MessageQueue > ,
729739 pending_events : Arc < EventQueue < K > > , channel_manager : CM , kv_store : K , tx_broadcaster : T ,
730- config : LSPS2ServiceConfig ,
740+ config : LSPS2ServiceConfig , time_provider : TP ,
731741 ) -> Result < Self , lightning:: io:: Error > {
732742 let mut peer_by_intercept_scid = new_hash_map ( ) ;
733743 let mut peer_by_channel_id = new_hash_map ( ) ;
@@ -768,6 +778,7 @@ where
768778 kv_store,
769779 tx_broadcaster,
770780 config,
781+ time_provider,
771782 } )
772783 }
773784
@@ -921,11 +932,15 @@ where
921932 peer_by_intercept_scid. insert ( intercept_scid, * counterparty_node_id) ;
922933 }
923934
935+ let created_at = LSPSDateTime :: new_from_duration_since_epoch (
936+ self . time_provider . duration_since_epoch ( ) ,
937+ ) ;
924938 let outbound_jit_channel = OutboundJITChannel :: new (
925939 buy_request. payment_size_msat ,
926940 buy_request. opening_fee_params ,
927941 user_channel_id,
928942 client_trusts_lsp,
943+ created_at,
929944 ) ;
930945
931946 peer_state_lock
@@ -2050,10 +2065,11 @@ where
20502065 }
20512066}
20522067
2053- impl < CM : Deref , K : KVStore + Clone , T : BroadcasterInterface + Clone > LSPSProtocolMessageHandler
2054- for LSPS2ServiceHandler < CM , K , T >
2068+ impl < CM : Deref , K : KVStore + Clone , T : BroadcasterInterface + Clone , TP : Deref + Clone >
2069+ LSPSProtocolMessageHandler for LSPS2ServiceHandler < CM , K , T , TP >
20552070where
20562071 CM :: Target : AChannelManager ,
2072+ TP :: Target : TimeProvider ,
20572073{
20582074 type ProtocolMessage = LSPS2Message ;
20592075 const PROTOCOL_NUMBER : Option < u16 > = Some ( 2 ) ;
@@ -2128,18 +2144,21 @@ pub struct LSPS2ServiceHandlerSync<
21282144 CM : Deref ,
21292145 K : KVStore + Clone ,
21302146 T : BroadcasterInterface + Clone ,
2147+ TP : Deref + Clone ,
21312148> where
21322149 CM :: Target : AChannelManager ,
2150+ TP :: Target : TimeProvider ,
21332151{
2134- inner : & ' a LSPS2ServiceHandler < CM , K , T > ,
2152+ inner : & ' a LSPS2ServiceHandler < CM , K , T , TP > ,
21352153}
21362154
2137- impl < ' a , CM : Deref , K : KVStore + Clone , T : BroadcasterInterface + Clone >
2138- LSPS2ServiceHandlerSync < ' a , CM , K , T >
2155+ impl < ' a , CM : Deref , K : KVStore + Clone , T : BroadcasterInterface + Clone , TP : Deref + Clone >
2156+ LSPS2ServiceHandlerSync < ' a , CM , K , T , TP >
21392157where
21402158 CM :: Target : AChannelManager ,
2159+ TP :: Target : TimeProvider ,
21412160{
2142- pub ( crate ) fn from_inner ( inner : & ' a LSPS2ServiceHandler < CM , K , T > ) -> Self {
2161+ pub ( crate ) fn from_inner ( inner : & ' a LSPS2ServiceHandler < CM , K , T , TP > ) -> Self {
21432162 Self { inner }
21442163 }
21452164
@@ -2785,6 +2804,7 @@ mod tests {
27852804 opening_fee_params. clone ( ) ,
27862805 user_channel_id,
27872806 true ,
2807+ LSPSDateTime :: from_str ( "2024-01-01T00:00:00Z" ) . unwrap ( ) ,
27882808 ) ;
27892809
27902810 let opening_payment_hash = PaymentHash ( [ 42 ; 32 ] ) ;
@@ -2864,4 +2884,47 @@ mod tests {
28642884 "Broadcast was not allowed even though all the skimmed fees were collected"
28652885 ) ;
28662886 }
2887+
2888+ #[ test]
2889+ fn test_outbound_jit_channel_created_at_stored ( ) {
2890+ let opening_fee_params = LSPS2OpeningFeeParams {
2891+ min_fee_msat : 1_000 ,
2892+ proportional : 0 ,
2893+ valid_until : LSPSDateTime :: from_str ( "2035-05-20T08:30:45Z" ) . unwrap ( ) ,
2894+ min_lifetime : 144 ,
2895+ max_client_to_self_delay : 128 ,
2896+ min_payment_size_msat : 1 ,
2897+ max_payment_size_msat : 10_000_000_000 ,
2898+ promise : "ignore" . to_string ( ) ,
2899+ } ;
2900+ let created_at = LSPSDateTime :: from_str ( "2024-06-15T12:00:00Z" ) . unwrap ( ) ;
2901+ let channel =
2902+ OutboundJITChannel :: new ( Some ( 1_000_000 ) , opening_fee_params, 1u128 , true , created_at) ;
2903+ assert_eq ! ( channel. created_at, created_at) ;
2904+ }
2905+
2906+ #[ test]
2907+ fn test_outbound_jit_channel_created_at_round_trips ( ) {
2908+ use lightning:: util:: ser:: { Readable , Writeable } ;
2909+
2910+ let opening_fee_params = LSPS2OpeningFeeParams {
2911+ min_fee_msat : 1_000 ,
2912+ proportional : 0 ,
2913+ valid_until : LSPSDateTime :: from_str ( "2035-05-20T08:30:45Z" ) . unwrap ( ) ,
2914+ min_lifetime : 144 ,
2915+ max_client_to_self_delay : 128 ,
2916+ min_payment_size_msat : 1 ,
2917+ max_payment_size_msat : 10_000_000_000 ,
2918+ promise : "ignore" . to_string ( ) ,
2919+ } ;
2920+ let created_at = LSPSDateTime :: from_str ( "2024-06-15T12:00:00Z" ) . unwrap ( ) ;
2921+ let channel =
2922+ OutboundJITChannel :: new ( Some ( 1_000_000 ) , opening_fee_params, 1u128 , true , created_at) ;
2923+
2924+ let mut buf = Vec :: new ( ) ;
2925+ channel. write ( & mut buf) . unwrap ( ) ;
2926+
2927+ let decoded = <OutboundJITChannel as Readable >:: read ( & mut & buf[ ..] ) . unwrap ( ) ;
2928+ assert_eq ! ( decoded. created_at, created_at) ;
2929+ }
28672930}
0 commit comments