@@ -43,6 +43,11 @@ use sync::Mutex;
4343use core:: ops:: Deref ;
4444use bitcoin:: hashes:: hex:: ToHex ;
4545
46+ #[ cfg( feature = "std" ) ]
47+ use std:: time:: { SystemTime , UNIX_EPOCH } ;
48+
49+ const STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS : u64 = 60 * 60 * 24 * 14 ;
50+
4651/// The maximum number of extra bytes which we do not understand in a gossip message before we will
4752/// refuse to relay the message.
4853const MAX_EXCESS_BYTES_FOR_RELAY : usize = 1024 ;
@@ -628,6 +633,10 @@ pub struct ChannelInfo {
628633 /// Everything else is useful only for sending out for initial routing sync.
629634 /// Not stored if contains excess data to prevent DoS.
630635 pub announcement_message : Option < ChannelAnnouncement > ,
636+ /// The timestamp when we received the announcement, if we are running with feature = "std"
637+ /// (which we can probably assume we are - no-std environments probably won't have a full
638+ /// network graph in memory!).
639+ announcement_received_time : u64 ,
631640}
632641
633642impl fmt:: Display for ChannelInfo {
@@ -640,6 +649,7 @@ impl fmt::Display for ChannelInfo {
640649
641650impl_writeable_tlv_based ! ( ChannelInfo , {
642651 ( 0 , features, required) ,
652+ ( 1 , announcement_received_time, ( default_value, 0 ) ) ,
643653 ( 2 , node_one, required) ,
644654 ( 4 , one_to_two, required) ,
645655 ( 6 , node_two, required) ,
@@ -952,6 +962,13 @@ impl NetworkGraph {
952962 } ,
953963 } ;
954964
965+ #[ allow( unused_mut, unused_assignments) ]
966+ let mut announcement_received_time = 0 ;
967+ #[ cfg( feature = "std" ) ]
968+ {
969+ announcement_received_time = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . expect ( "Time must be > 1970" ) . as_secs ( ) ;
970+ }
971+
955972 let chan_info = ChannelInfo {
956973 features : msg. features . clone ( ) ,
957974 node_one : NodeId :: from_pubkey ( & msg. node_id_1 ) ,
@@ -961,6 +978,7 @@ impl NetworkGraph {
961978 capacity_sats : utxo_value,
962979 announcement_message : if msg. excess_data . len ( ) <= MAX_EXCESS_BYTES_FOR_RELAY
963980 { full_msg. cloned ( ) } else { None } ,
981+ announcement_received_time,
964982 } ;
965983
966984 let mut channels = self . channels . write ( ) . unwrap ( ) ;
@@ -1052,15 +1070,14 @@ impl NetworkGraph {
10521070 ///
10531071 /// While there is no formal requirement that nodes regularly re-broadcast their channel
10541072 /// updates every two weeks, the non-normative section of BOLT 7 currently suggests that
1055- /// pruning occurrs for updates which are at least two weeks old, which we implement here.
1073+ /// pruning occurs for updates which are at least two weeks old, which we implement here.
10561074 ///
10571075 /// This method is automatically called immediately before writing the network graph via
10581076 /// [`Writeable::write`].
10591077 ///
10601078 /// This method is only available with the `std` feature. See
10611079 /// [`NetworkGraph::remove_stale_channels_with_time`] for `no-std` use.
10621080 pub fn remove_stale_channels ( & self ) {
1063- use std:: time:: { SystemTime , UNIX_EPOCH } ;
10641081 let time = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . expect ( "Time must be > 1970" ) . as_secs ( ) ;
10651082 self . remove_stale_channels_with_time ( time) ;
10661083 }
@@ -1074,11 +1091,11 @@ impl NetworkGraph {
10741091 /// pruning occurrs for updates which are at least two weeks old, which we implement here.
10751092 ///
10761093 /// This function takes the current unix time as an argument. For users with the `std` feature
1077- /// enabled, [`NetworkGraph::remove_stale_channels`] may be preferrable .
1094+ /// enabled, [`NetworkGraph::remove_stale_channels`] may be preferable .
10781095 pub fn remove_stale_channels_with_time ( & self , current_time_unix : u64 ) {
10791096 let mut channels = self . channels . write ( ) . unwrap ( ) ;
10801097 // Time out if we haven't received an update in at least 14 days.
1081- let min_time_unix: u32 = ( current_time_unix - 60 * 60 * 14 ) as u32 ;
1098+ let min_time_unix: u32 = ( current_time_unix - STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS ) as u32 ;
10821099 // Sadly BTreeMap::retain was only stabilized in 1.53 so we can't switch to it for some
10831100 // time.
10841101 let mut scids_to_remove = Vec :: new ( ) ;
@@ -1090,7 +1107,12 @@ impl NetworkGraph {
10901107 info. two_to_one = None ;
10911108 }
10921109 if info. one_to_two . is_none ( ) && info. two_to_one . is_none ( ) {
1093- scids_to_remove. push ( * scid) ;
1110+ // We check the announcement_received_time here to ensure we don't drop
1111+ // announcements that we just received and are just waiting for our peer to send a
1112+ // channel_update for.
1113+ if info. announcement_received_time < min_time_unix as u64 {
1114+ scids_to_remove. push ( * scid) ;
1115+ }
10941116 }
10951117 }
10961118 if !scids_to_remove. is_empty ( ) {
@@ -1919,10 +1941,23 @@ mod tests {
19191941 }
19201942
19211943 if remove_by_timeout {
1922- network_graph. remove_stale_channels_with_time ( 100 + 60 * 60 * 14 ) ;
1944+ network_graph. remove_stale_channels_with_time ( 100 + 60 * 60 * 24 * 14 ) ;
19231945 assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) , 1 ) ;
19241946 assert_eq ! ( network_graph. read_only( ) . nodes( ) . len( ) , 2 ) ;
1925- network_graph. remove_stale_channels_with_time ( 101 + 60 * 60 * 14 ) ;
1947+
1948+ network_graph. remove_stale_channels_with_time ( 101 + 60 * 60 * 24 * 14 ) ;
1949+ #[ cfg( feature = "std" ) ]
1950+ {
1951+ // In std mode, a further check is performed before fully removing the channel -
1952+ // the channel_announcement must have been received at least two weeks ago. We
1953+ // fudge that here by indicating the time has jumped two weeks.
1954+ assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) , 1 ) ;
1955+ assert_eq ! ( network_graph. read_only( ) . nodes( ) . len( ) , 2 ) ;
1956+
1957+ use std:: time:: { SystemTime , UNIX_EPOCH } ;
1958+ let announcement_time = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . expect ( "Time must be > 1970" ) . as_secs ( ) ;
1959+ network_graph. remove_stale_channels_with_time ( announcement_time + 1 + 60 * 60 * 24 * 14 ) ;
1960+ }
19261961 } else {
19271962 // Permanent closing deletes a channel
19281963 net_graph_msg_handler. handle_event ( & Event :: PaymentPathFailed {
0 commit comments