@@ -43,6 +43,11 @@ use sync::Mutex;
43
43
use core:: ops:: Deref ;
44
44
use bitcoin:: hashes:: hex:: ToHex ;
45
45
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
+
46
51
/// The maximum number of extra bytes which we do not understand in a gossip message before we will
47
52
/// refuse to relay the message.
48
53
const MAX_EXCESS_BYTES_FOR_RELAY : usize = 1024 ;
@@ -628,6 +633,10 @@ pub struct ChannelInfo {
628
633
/// Everything else is useful only for sending out for initial routing sync.
629
634
/// Not stored if contains excess data to prevent DoS.
630
635
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 ,
631
640
}
632
641
633
642
impl fmt:: Display for ChannelInfo {
@@ -640,6 +649,7 @@ impl fmt::Display for ChannelInfo {
640
649
641
650
impl_writeable_tlv_based ! ( ChannelInfo , {
642
651
( 0 , features, required) ,
652
+ ( 1 , announcement_received_time, ( default_value, 0 ) ) ,
643
653
( 2 , node_one, required) ,
644
654
( 4 , one_to_two, required) ,
645
655
( 6 , node_two, required) ,
@@ -952,6 +962,13 @@ impl NetworkGraph {
952
962
} ,
953
963
} ;
954
964
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
+
955
972
let chan_info = ChannelInfo {
956
973
features : msg. features . clone ( ) ,
957
974
node_one : NodeId :: from_pubkey ( & msg. node_id_1 ) ,
@@ -961,6 +978,7 @@ impl NetworkGraph {
961
978
capacity_sats : utxo_value,
962
979
announcement_message : if msg. excess_data . len ( ) <= MAX_EXCESS_BYTES_FOR_RELAY
963
980
{ full_msg. cloned ( ) } else { None } ,
981
+ announcement_received_time,
964
982
} ;
965
983
966
984
let mut channels = self . channels . write ( ) . unwrap ( ) ;
@@ -1052,15 +1070,14 @@ impl NetworkGraph {
1052
1070
///
1053
1071
/// While there is no formal requirement that nodes regularly re-broadcast their channel
1054
1072
/// 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.
1056
1074
///
1057
1075
/// This method is automatically called immediately before writing the network graph via
1058
1076
/// [`Writeable::write`].
1059
1077
///
1060
1078
/// This method is only available with the `std` feature. See
1061
1079
/// [`NetworkGraph::remove_stale_channels_with_time`] for `no-std` use.
1062
1080
pub fn remove_stale_channels ( & self ) {
1063
- use std:: time:: { SystemTime , UNIX_EPOCH } ;
1064
1081
let time = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . expect ( "Time must be > 1970" ) . as_secs ( ) ;
1065
1082
self . remove_stale_channels_with_time ( time) ;
1066
1083
}
@@ -1074,11 +1091,11 @@ impl NetworkGraph {
1074
1091
/// pruning occurrs for updates which are at least two weeks old, which we implement here.
1075
1092
///
1076
1093
/// 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 .
1078
1095
pub fn remove_stale_channels_with_time ( & self , current_time_unix : u64 ) {
1079
1096
let mut channels = self . channels . write ( ) . unwrap ( ) ;
1080
1097
// 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 ;
1082
1099
// Sadly BTreeMap::retain was only stabilized in 1.53 so we can't switch to it for some
1083
1100
// time.
1084
1101
let mut scids_to_remove = Vec :: new ( ) ;
@@ -1090,7 +1107,12 @@ impl NetworkGraph {
1090
1107
info. two_to_one = None ;
1091
1108
}
1092
1109
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
+ }
1094
1116
}
1095
1117
}
1096
1118
if !scids_to_remove. is_empty ( ) {
@@ -1919,10 +1941,23 @@ mod tests {
1919
1941
}
1920
1942
1921
1943
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 ) ;
1923
1945
assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) , 1 ) ;
1924
1946
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
+ }
1926
1961
} else {
1927
1962
// Permanent closing deletes a channel
1928
1963
net_graph_msg_handler. handle_event ( & Event :: PaymentPathFailed {
0 commit comments