@@ -26,6 +26,7 @@ use core::fmt;
2626pub ( super ) struct PeerState {
2727 outbound_channels_by_order_id : HashMap < LSPS1OrderId , ChannelOrder > ,
2828 pending_requests : HashMap < LSPSRequestId , LSPS1Request > ,
29+ needs_persist : bool ,
2930}
3031
3132impl PeerState {
@@ -43,6 +44,7 @@ impl PeerState {
4344 channel_details,
4445 } ;
4546 self . outbound_channels_by_order_id . insert ( order_id, channel_order. clone ( ) ) ;
47+ self . needs_persist |= true ;
4648 channel_order
4749 }
4850
@@ -66,6 +68,7 @@ impl PeerState {
6668 . ok_or ( PeerStateError :: UnknownOrderId ) ?;
6769 order. order_state = order_state;
6870 order. channel_details = channel_details;
71+ self . needs_persist |= true ;
6972 Ok ( ( ) )
7073 }
7174
@@ -88,11 +91,39 @@ impl PeerState {
8891 pub ( super ) fn has_active_requests ( & self ) -> bool {
8992 !self . outbound_channels_by_order_id . is_empty ( )
9093 }
94+
95+ pub ( super ) fn needs_persist ( & self ) -> bool {
96+ self . needs_persist
97+ }
98+
99+ pub ( super ) fn set_needs_persist ( & mut self , needs_persist : bool ) {
100+ self . needs_persist = needs_persist;
101+ }
102+
103+ pub ( super ) fn is_prunable ( & self ) -> bool {
104+ // Return whether the entire state is empty.
105+ self . pending_requests . is_empty ( ) && self . outbound_channels_by_order_id . is_empty ( )
106+ }
107+
108+ pub ( super ) fn prune_pending_requests ( & mut self ) {
109+ self . pending_requests . clear ( )
110+ }
111+
112+ pub ( super ) fn prune_expired_request_state ( & mut self ) {
113+ self . outbound_channels_by_order_id . retain ( |_order_id, entry| {
114+ if entry. is_prunable ( ) {
115+ self . needs_persist |= true ;
116+ return false ;
117+ }
118+ true
119+ } ) ;
120+ }
91121}
92122
93123impl_writeable_tlv_based ! ( PeerState , {
94124 ( 0 , outbound_channels_by_order_id, required) ,
95125 ( _unused, pending_requests, ( static_value, new_hash_map( ) ) ) ,
126+ ( _unused, needs_persist, ( static_value, false ) ) ,
96127} ) ;
97128
98129#[ derive( Debug , Copy , Clone ) ]
@@ -121,6 +152,29 @@ pub(super) struct ChannelOrder {
121152 pub ( super ) channel_details : Option < LSPS1ChannelInfo > ,
122153}
123154
155+ impl ChannelOrder {
156+ fn is_prunable ( & self ) -> bool {
157+ let all_payment_details_expired;
158+ #[ cfg( feature = "time" ) ]
159+ {
160+ all_payment_details_expired =
161+ self . payment_details . bolt11 . as_ref ( ) . is_none_or ( |d| d. expires_at . is_past ( ) )
162+ && self . payment_details . bolt12 . as_ref ( ) . is_none_or ( |d| d. expires_at . is_past ( ) )
163+ && self . payment_details . onchain . as_ref ( ) . is_none_or ( |d| d. expires_at . is_past ( ) ) ;
164+ }
165+ #[ cfg( not( feature = "time" ) ) ]
166+ {
167+ // TODO: We need to find a way to check expiry times in no-std builds.
168+ all_payment_details_expired = false ;
169+ }
170+
171+ let created_or_failed =
172+ matches ! ( self . order_state, LSPS1OrderState :: Created | LSPS1OrderState :: Failed ) ;
173+
174+ all_payment_details_expired && created_or_failed
175+ }
176+ }
177+
124178impl_writeable_tlv_based ! ( ChannelOrder , {
125179 ( 0 , order_params, required) ,
126180 ( 2 , order_state, required) ,
0 commit comments