@@ -632,7 +632,7 @@ const CHECK_CLTV_EXPIRY_SANITY: u32 = MIN_CLTV_EXPIRY_DELTA as u32 - LATENCY_GRA
632632const CHECK_CLTV_EXPIRY_SANITY_2 : u32 = MIN_CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2 * CLTV_CLAIM_BUFFER ;
633633
634634/// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels
635- #[ derive( Clone ) ]
635+ #[ derive( Clone , Debug , PartialEq ) ]
636636pub struct ChannelDetails {
637637 /// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
638638 /// thereafter this is the txid of the funding transaction xor the funding transaction output).
@@ -3346,14 +3346,15 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
33463346 Ok ( ( ) )
33473347 }
33483348
3349- fn internal_channel_update ( & self , counterparty_node_id : & PublicKey , msg : & msgs:: ChannelUpdate ) -> Result < ( ) , MsgHandleErrInternal > {
3349+ /// Returns ShouldPersist if anything changed, otherwise either SkipPersist or an Err.
3350+ fn internal_channel_update ( & self , counterparty_node_id : & PublicKey , msg : & msgs:: ChannelUpdate ) -> Result < NotifyOption , MsgHandleErrInternal > {
33503351 let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
33513352 let channel_state = & mut * channel_state_lock;
33523353 let chan_id = match channel_state. short_to_id . get ( & msg. contents . short_channel_id ) {
33533354 Some ( chan_id) => chan_id. clone ( ) ,
33543355 None => {
33553356 // It's not a local channel
3356- return Ok ( ( ) )
3357+ return Ok ( NotifyOption :: SkipPersist )
33573358 }
33583359 } ;
33593360 match channel_state. by_id . entry ( chan_id) {
@@ -3363,15 +3364,15 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
33633364 // If the announcement is about a channel of ours which is public, some
33643365 // other peer may simply be forwarding all its gossip to us. Don't provide
33653366 // a scary-looking error message and return Ok instead.
3366- return Ok ( ( ) ) ;
3367+ return Ok ( NotifyOption :: SkipPersist ) ;
33673368 }
33683369 return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Got a channel_update for a channel from the wrong node - it shouldn't know about our private channels!" . to_owned ( ) , chan_id) ) ;
33693370 }
33703371 try_chan_entry ! ( self , chan. get_mut( ) . channel_update( & msg) , channel_state, chan) ;
33713372 } ,
33723373 hash_map:: Entry :: Vacant ( _) => unreachable ! ( )
33733374 }
3374- Ok ( ( ) )
3375+ Ok ( NotifyOption :: DoPersist )
33753376 }
33763377
33773378 fn internal_channel_reestablish ( & self , counterparty_node_id : & PublicKey , msg : & msgs:: ChannelReestablish ) -> Result < ( ) , MsgHandleErrInternal > {
@@ -4116,8 +4117,13 @@ impl<Signer: Sign, M: Deref , T: Deref , K: Deref , F: Deref , L: Deref >
41164117 }
41174118
41184119 fn handle_channel_update ( & self , counterparty_node_id : & PublicKey , msg : & msgs:: ChannelUpdate ) {
4119- let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
4120- let _ = handle_error ! ( self , self . internal_channel_update( counterparty_node_id, msg) , * counterparty_node_id) ;
4120+ PersistenceNotifierGuard :: optionally_notify ( & self . total_consistency_lock , & self . persistence_notifier , || {
4121+ if let Ok ( persist) = handle_error ! ( self , self . internal_channel_update( counterparty_node_id, msg) , * counterparty_node_id) {
4122+ persist
4123+ } else {
4124+ NotifyOption :: SkipPersist
4125+ }
4126+ } ) ;
41214127 }
41224128
41234129 fn handle_channel_reestablish ( & self , counterparty_node_id : & PublicKey , msg : & msgs:: ChannelReestablish ) {
@@ -4823,6 +4829,9 @@ mod tests {
48234829 use core:: sync:: atomic:: { AtomicBool , Ordering } ;
48244830 use std:: thread;
48254831 use core:: time:: Duration ;
4832+ use ln:: functional_test_utils:: * ;
4833+ use ln:: features:: InitFeatures ;
4834+ use ln:: msgs:: ChannelMessageHandler ;
48264835
48274836 #[ test]
48284837 fn test_wait_timeout ( ) {
@@ -4865,6 +4874,53 @@ mod tests {
48654874 }
48664875 }
48674876 }
4877+
4878+ #[ test]
4879+ fn test_notify_limits ( ) {
4880+ // Check that a few cases which don't require the persistence of a new ChannelManager,
4881+ // indeed, do not cause the persistence of a new ChannelManager.
4882+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
4883+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
4884+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , None , None ] ) ;
4885+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
4886+
4887+ let mut chan = create_announced_chan_between_nodes ( & nodes, 0 , 1 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
4888+
4889+ // We check that the channel info nodes have doesn't change too early, even though we try
4890+ // to connect messages with new values
4891+ chan. 0 . contents . fee_base_msat *= 2 ;
4892+ chan. 1 . contents . fee_base_msat *= 2 ;
4893+ let node_a_chan_info = nodes[ 0 ] . node . list_channels ( ) [ 0 ] . clone ( ) ;
4894+ let node_b_chan_info = nodes[ 1 ] . node . list_channels ( ) [ 0 ] . clone ( ) ;
4895+
4896+ // The first two nodes (which opened a channel) should now require fresh persistence
4897+ assert ! ( nodes[ 0 ] . node. await_persistable_update_timeout( Duration :: from_millis( 1 ) ) ) ;
4898+ assert ! ( nodes[ 1 ] . node. await_persistable_update_timeout( Duration :: from_millis( 1 ) ) ) ;
4899+ // ... but the last node should not.
4900+ assert ! ( !nodes[ 2 ] . node. await_persistable_update_timeout( Duration :: from_millis( 1 ) ) ) ;
4901+ // After persisting the first two nodes they should no longer need fresh persistence.
4902+ assert ! ( !nodes[ 0 ] . node. await_persistable_update_timeout( Duration :: from_millis( 1 ) ) ) ;
4903+ assert ! ( !nodes[ 1 ] . node. await_persistable_update_timeout( Duration :: from_millis( 1 ) ) ) ;
4904+
4905+ // Node 3, unrelated to the only channel, shouldn't care if it receives a channel_update
4906+ // about the channel.
4907+ nodes[ 2 ] . node . handle_channel_update ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan. 0 ) ;
4908+ nodes[ 2 ] . node . handle_channel_update ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan. 1 ) ;
4909+ assert ! ( !nodes[ 2 ] . node. await_persistable_update_timeout( Duration :: from_millis( 1 ) ) ) ;
4910+
4911+ // The nodes which are a party to the channel should also ignore messages from unrelated
4912+ // parties.
4913+ nodes[ 0 ] . node . handle_channel_update ( & nodes[ 2 ] . node . get_our_node_id ( ) , & chan. 0 ) ;
4914+ nodes[ 0 ] . node . handle_channel_update ( & nodes[ 2 ] . node . get_our_node_id ( ) , & chan. 1 ) ;
4915+ nodes[ 1 ] . node . handle_channel_update ( & nodes[ 2 ] . node . get_our_node_id ( ) , & chan. 0 ) ;
4916+ nodes[ 1 ] . node . handle_channel_update ( & nodes[ 2 ] . node . get_our_node_id ( ) , & chan. 1 ) ;
4917+ assert ! ( !nodes[ 0 ] . node. await_persistable_update_timeout( Duration :: from_millis( 1 ) ) ) ;
4918+ assert ! ( !nodes[ 1 ] . node. await_persistable_update_timeout( Duration :: from_millis( 1 ) ) ) ;
4919+
4920+ // At this point the channel info given by peers should still be the same.
4921+ assert_eq ! ( nodes[ 0 ] . node. list_channels( ) [ 0 ] , node_a_chan_info) ;
4922+ assert_eq ! ( nodes[ 1 ] . node. list_channels( ) [ 0 ] , node_b_chan_info) ;
4923+ }
48684924}
48694925
48704926#[ cfg( all( any( test, feature = "_test_utils" ) , feature = "unstable" ) ) ]
0 commit comments