@@ -201,16 +201,21 @@ where
201201 & self , counterparty_node_id : PublicKey ,
202202 ) -> Result < ( ) , lightning:: io:: Error > {
203203 let fut = {
204- let outer_state_lock = self . per_peer_state . read ( ) . unwrap ( ) ;
205- let encoded = match outer_state_lock. get ( & counterparty_node_id) {
204+ let mut outer_state_lock = self . per_peer_state . write ( ) . unwrap ( ) ;
205+ let encoded = match outer_state_lock. get_mut ( & counterparty_node_id) {
206206 None => {
207- let err = lightning:: io:: Error :: new (
208- lightning:: io:: ErrorKind :: Other ,
209- "Failed to get peer entry" ,
210- ) ;
211- return Err ( err) ;
207+ // We dropped the peer state by now.
208+ return Ok ( ( ) ) ;
209+ } ,
210+ Some ( entry) => {
211+ if !entry. needs_persist {
212+ // We already have persisted otherwise by now.
213+ return Ok ( ( ) ) ;
214+ } else {
215+ entry. needs_persist = false ;
216+ entry. encode ( )
217+ }
212218 } ,
213- Some ( entry) => entry. encode ( ) ,
214219 } ;
215220
216221 let key = counterparty_node_id. to_string ( ) ;
@@ -223,7 +228,14 @@ where
223228 )
224229 } ;
225230
226- fut. await
231+ fut. await . map_err ( |e| {
232+ self . per_peer_state
233+ . write ( )
234+ . unwrap ( )
235+ . get_mut ( & counterparty_node_id)
236+ . map ( |p| p. needs_persist = true ) ;
237+ e
238+ } )
227239 }
228240
229241 pub ( crate ) async fn persist ( & self ) -> Result < ( ) , lightning:: io:: Error > {
@@ -232,7 +244,10 @@ where
232244 // time.
233245 let need_persist: Vec < PublicKey > = {
234246 let outer_state_lock = self . per_peer_state . read ( ) . unwrap ( ) ;
235- outer_state_lock. iter ( ) . filter_map ( |( k, v) | Some ( * k) ) . collect ( )
247+ outer_state_lock
248+ . iter ( )
249+ . filter_map ( |( k, v) | if v. needs_persist { Some ( * k) } else { None } )
250+ . collect ( )
236251 } ;
237252
238253 for counterparty_node_id in need_persist. into_iter ( ) {
@@ -259,6 +274,7 @@ where
259274 // Don't prune clients with open channels
260275 return true ;
261276 }
277+ // TODO: Remove peer state entry from the KVStore
262278 !peer_state. prune_stale_webhooks ( now)
263279 } ) ;
264280 * last_pruning = Some ( now) ;
@@ -289,6 +305,7 @@ where
289305 webhook. url = params. webhook . clone ( ) ;
290306 webhook. last_used = now;
291307 webhook. last_notification_sent = None ;
308+ peer_state. needs_persist |= true ;
292309 }
293310 } else {
294311 if num_webhooks >= self . config . max_webhooks_per_client as usize {
@@ -649,22 +666,28 @@ where
649666 }
650667}
651668
652- #[ derive( Debug , Default ) ]
669+ #[ derive( Debug ) ]
653670pub ( crate ) struct PeerState {
654671 webhooks : Vec < ( LSPS5AppName , Webhook ) > ,
672+ needs_persist : bool ,
655673}
656674
657675impl PeerState {
658676 fn webhook_mut ( & mut self , name : & LSPS5AppName ) -> Option < & mut Webhook > {
659- self . webhooks . iter_mut ( ) . find_map ( |( n, h) | if n == name { Some ( h) } else { None } )
677+ let res =
678+ self . webhooks . iter_mut ( ) . find_map ( |( n, h) | if n == name { Some ( h) } else { None } ) ;
679+ self . needs_persist |= true ;
680+ res
660681 }
661682
662683 fn webhooks ( & self ) -> & Vec < ( LSPS5AppName , Webhook ) > {
663684 & self . webhooks
664685 }
665686
666687 fn webhooks_mut ( & mut self ) -> & mut Vec < ( LSPS5AppName , Webhook ) > {
667- & mut self . webhooks
688+ let res = & mut self . webhooks ;
689+ self . needs_persist |= true ;
690+ res
668691 }
669692
670693 fn webhooks_len ( & self ) -> usize {
@@ -684,6 +707,7 @@ impl PeerState {
684707 }
685708
686709 self . webhooks . push ( ( name, hook) ) ;
710+ self . needs_persist |= true ;
687711 }
688712
689713 fn remove_webhook ( & mut self , name : & LSPS5AppName ) -> bool {
@@ -696,13 +720,15 @@ impl PeerState {
696720 false
697721 }
698722 } ) ;
723+ self . needs_persist |= true ;
699724 removed
700725 }
701726
702727 fn reset_notification_cooldown ( & mut self ) {
703728 for ( _, h) in self . webhooks . iter_mut ( ) {
704729 h. last_notification_sent = None ;
705730 }
731+ self . needs_persist |= true ;
706732 }
707733
708734 // Returns whether the entire state is empty and can be pruned.
@@ -715,6 +741,15 @@ impl PeerState {
715741 }
716742}
717743
744+ impl Default for PeerState {
745+ fn default ( ) -> Self {
746+ let webhooks = Vec :: new ( ) ;
747+ let needs_persist = true ;
748+ Self { webhooks, needs_persist }
749+ }
750+ }
751+
718752impl_writeable_tlv_based ! ( PeerState , {
719753 ( 0 , webhooks, required_vec) ,
754+ ( _unused, needs_persist, ( static_value, false ) ) ,
720755} ) ;
0 commit comments