@@ -16,7 +16,7 @@ use lightning::io;
16
16
use crate :: error:: GraphSyncError ;
17
17
use crate :: RapidGossipSync ;
18
18
19
- #[ cfg( all( feature = "std" , not( test) , not ( feature = "_test_utils" ) ) ) ]
19
+ #[ cfg( all( feature = "std" , not( test) ) ) ]
20
20
use std:: time:: { SystemTime , UNIX_EPOCH } ;
21
21
22
22
#[ cfg( not( feature = "std" ) ) ]
@@ -34,13 +34,28 @@ const MAX_INITIAL_NODE_ID_VECTOR_CAPACITY: u32 = 50_000;
34
34
35
35
/// We remove disallow gossip data that's more than two weeks old, per BOLT 7's
36
36
/// suggestion.
37
- #[ cfg( all( feature = "std" , not( test) , not( feature = "_test_utils" ) ) ) ]
38
37
const STALE_RGS_UPDATE_AGE_LIMIT_SECS : u64 = 60 * 60 * 24 * 14 ;
39
38
40
39
impl < NG : Deref < Target =NetworkGraph < L > > , L : Deref > RapidGossipSync < NG , L > where L :: Target : Logger {
41
40
pub ( crate ) fn update_network_graph_from_byte_stream < R : io:: Read > (
41
+ & self ,
42
+ read_cursor : & mut R ,
43
+ ) -> Result < u32 , GraphSyncError > {
44
+ #[ allow( unused_mut) ]
45
+ let mut current_time_unix = None ;
46
+ #[ cfg( all( feature = "std" , not( test) ) ) ]
47
+ {
48
+ // Note that many tests rely on being able to set arbitrarily old timestamps, thus we
49
+ // disable this check during tests!
50
+ current_time_unix = Some ( SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . expect ( "Time must be > 1970" ) . as_secs ( ) ) ;
51
+ }
52
+ self . update_network_graph_from_byte_stream_no_std ( read_cursor, current_time_unix)
53
+ }
54
+
55
+ pub ( crate ) fn update_network_graph_from_byte_stream_no_std < R : io:: Read > (
42
56
& self ,
43
57
mut read_cursor : & mut R ,
58
+ current_time_unix : Option < u64 >
44
59
) -> Result < u32 , GraphSyncError > {
45
60
let mut prefix = [ 0u8 ; 4 ] ;
46
61
read_cursor. read_exact ( & mut prefix) ?;
@@ -51,19 +66,17 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
51
66
52
67
let chain_hash: BlockHash = Readable :: read ( read_cursor) ?;
53
68
let latest_seen_timestamp: u32 = Readable :: read ( read_cursor) ?;
54
- // backdate the applied timestamp by a week
55
- let backdated_timestamp = latest_seen_timestamp. saturating_sub ( 24 * 3600 * 7 ) ;
56
69
57
- #[ cfg( all( feature = "std" , not( test) , not( feature = "_test_utils" ) ) ) ]
58
- {
59
- // Note that many tests rely on being able to set arbitrarily old timestamps, thus we
60
- // disable this check during tests!
61
- let time = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . expect ( "Time must be > 1970" ) . as_secs ( ) ;
62
- if ( latest_seen_timestamp as u64 ) < time - STALE_RGS_UPDATE_AGE_LIMIT_SECS {
70
+ if let Some ( time) = current_time_unix {
71
+ println ! ( "latest seen timestamp: {}" , latest_seen_timestamp) ;
72
+ if ( latest_seen_timestamp as u64 ) < time. saturating_sub ( STALE_RGS_UPDATE_AGE_LIMIT_SECS ) {
63
73
return Err ( LightningError { err : "Rapid Gossip Sync data is more than two weeks old" . to_owned ( ) , action : ErrorAction :: IgnoreError } . into ( ) ) ;
64
74
}
65
75
}
66
76
77
+ // backdate the applied timestamp by a week
78
+ let backdated_timestamp = latest_seen_timestamp. saturating_sub ( 24 * 3600 * 7 ) ;
79
+
67
80
let node_id_count: u32 = Readable :: read ( read_cursor) ?;
68
81
let mut node_ids: Vec < PublicKey > = Vec :: with_capacity ( core:: cmp:: min (
69
82
node_id_count,
@@ -233,6 +246,7 @@ mod tests {
233
246
use lightning:: util:: test_utils:: TestLogger ;
234
247
235
248
use crate :: error:: GraphSyncError ;
249
+ use crate :: processing:: STALE_RGS_UPDATE_AGE_LIMIT_SECS ;
236
250
use crate :: RapidGossipSync ;
237
251
238
252
#[ test]
@@ -544,6 +558,115 @@ mod tests {
544
558
assert ! ( after. contains( "783241506229452801" ) ) ;
545
559
}
546
560
561
+ #[ test]
562
+ fn full_update_succeeds_with_edge_timestamp_age ( ) {
563
+ const LATEST_SEEN_TIMESTAMP : u64 = 1642291930 ;
564
+ let valid_input = vec ! [
565
+ 76 , 68 , 75 , 1 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 , 174 , 99 , 247 ,
566
+ 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 97 , 227 , 98 , 218 ,
567
+ 0 , 0 , 0 , 4 , 2 , 22 , 7 , 207 , 206 , 25 , 164 , 197 , 231 , 230 , 231 , 56 , 102 , 61 , 250 , 251 ,
568
+ 187 , 172 , 38 , 46 , 79 , 247 , 108 , 44 , 155 , 48 , 219 , 238 , 252 , 53 , 192 , 6 , 67 , 2 , 36 , 125 ,
569
+ 157 , 176 , 223 , 175 , 234 , 116 , 94 , 248 , 201 , 225 , 97 , 235 , 50 , 47 , 115 , 172 , 63 , 136 ,
570
+ 88 , 216 , 115 , 11 , 111 , 217 , 114 , 84 , 116 , 124 , 231 , 107 , 2 , 158 , 1 , 242 , 121 , 152 , 106 ,
571
+ 204 , 131 , 186 , 35 , 93 , 70 , 216 , 10 , 237 , 224 , 183 , 89 , 95 , 65 , 3 , 83 , 185 , 58 , 138 ,
572
+ 181 , 64 , 187 , 103 , 127 , 68 , 50 , 2 , 201 , 19 , 17 , 138 , 136 , 149 , 185 , 226 , 156 , 137 , 175 ,
573
+ 110 , 32 , 237 , 0 , 217 , 90 , 31 , 100 , 228 , 149 , 46 , 219 , 175 , 168 , 77 , 4 , 143 , 38 , 128 ,
574
+ 76 , 97 , 0 , 0 , 0 , 2 , 0 , 0 , 255 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 0 , 1 , 0 , 0 , 255 , 2 , 68 ,
575
+ 226 , 0 , 6 , 11 , 0 , 1 , 2 , 3 , 0 , 0 , 0 , 4 , 0 , 40 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 232 , 0 , 0 , 3 , 232 ,
576
+ 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 29 , 129 , 25 , 192 , 255 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 60 , 0 , 0 ,
577
+ 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 100 , 0 , 0 , 2 , 224 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 0 , 29 , 0 ,
578
+ 0 , 0 , 1 , 0 , 0 , 0 , 125 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 255 , 2 , 68 , 226 , 0 , 6 , 11 , 0 , 1 ,
579
+ 0 , 0 , 1 ,
580
+ ] ;
581
+
582
+ let block_hash = genesis_block ( Network :: Bitcoin ) . block_hash ( ) ;
583
+ let logger = TestLogger :: new ( ) ;
584
+ let network_graph = NetworkGraph :: new ( block_hash, & logger) ;
585
+
586
+ assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) , 0 ) ;
587
+
588
+ let earliest_failing_time = LATEST_SEEN_TIMESTAMP + STALE_RGS_UPDATE_AGE_LIMIT_SECS ;
589
+
590
+ let rapid_sync = RapidGossipSync :: new ( & network_graph) ;
591
+ let update_result = rapid_sync. update_network_graph_no_std ( & valid_input[ ..] , Some ( earliest_failing_time) ) ;
592
+ assert ! ( update_result. is_ok( ) ) ;
593
+ assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) , 2 ) ;
594
+ }
595
+
596
+ #[ test]
597
+ fn full_update_succeeds_with_oldest_possible_timestamp ( ) {
598
+ let valid_input = vec ! [
599
+ 76 , 68 , 75 , 1 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 , 174 , 99 , 247 ,
600
+ 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 97 , 227 , 98 , 218 ,
601
+ 0 , 0 , 0 , 4 , 2 , 22 , 7 , 207 , 206 , 25 , 164 , 197 , 231 , 230 , 231 , 56 , 102 , 61 , 250 , 251 ,
602
+ 187 , 172 , 38 , 46 , 79 , 247 , 108 , 44 , 155 , 48 , 219 , 238 , 252 , 53 , 192 , 6 , 67 , 2 , 36 , 125 ,
603
+ 157 , 176 , 223 , 175 , 234 , 116 , 94 , 248 , 201 , 225 , 97 , 235 , 50 , 47 , 115 , 172 , 63 , 136 ,
604
+ 88 , 216 , 115 , 11 , 111 , 217 , 114 , 84 , 116 , 124 , 231 , 107 , 2 , 158 , 1 , 242 , 121 , 152 , 106 ,
605
+ 204 , 131 , 186 , 35 , 93 , 70 , 216 , 10 , 237 , 224 , 183 , 89 , 95 , 65 , 3 , 83 , 185 , 58 , 138 ,
606
+ 181 , 64 , 187 , 103 , 127 , 68 , 50 , 2 , 201 , 19 , 17 , 138 , 136 , 149 , 185 , 226 , 156 , 137 , 175 ,
607
+ 110 , 32 , 237 , 0 , 217 , 90 , 31 , 100 , 228 , 149 , 46 , 219 , 175 , 168 , 77 , 4 , 143 , 38 , 128 ,
608
+ 76 , 97 , 0 , 0 , 0 , 2 , 0 , 0 , 255 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 0 , 1 , 0 , 0 , 255 , 2 , 68 ,
609
+ 226 , 0 , 6 , 11 , 0 , 1 , 2 , 3 , 0 , 0 , 0 , 4 , 0 , 40 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 232 , 0 , 0 , 3 , 232 ,
610
+ 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 29 , 129 , 25 , 192 , 255 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 60 , 0 , 0 ,
611
+ 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 100 , 0 , 0 , 2 , 224 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 0 , 29 , 0 ,
612
+ 0 , 0 , 1 , 0 , 0 , 0 , 125 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 255 , 2 , 68 , 226 , 0 , 6 , 11 , 0 , 1 ,
613
+ 0 , 0 , 1 ,
614
+ ] ;
615
+
616
+ let block_hash = genesis_block ( Network :: Bitcoin ) . block_hash ( ) ;
617
+ let logger = TestLogger :: new ( ) ;
618
+ let network_graph = NetworkGraph :: new ( block_hash, & logger) ;
619
+
620
+ assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) , 0 ) ;
621
+
622
+ let rapid_sync = RapidGossipSync :: new ( & network_graph) ;
623
+ let update_result = rapid_sync. update_network_graph_no_std ( & valid_input[ ..] , Some ( 0 ) ) ;
624
+ assert ! ( update_result. is_ok( ) ) ;
625
+ assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) , 2 ) ;
626
+ }
627
+
628
+ #[ test]
629
+ fn full_update_fails_with_old_timestamp ( ) {
630
+ const LATEST_SEEN_TIMESTAMP : u64 = 1642291930 ;
631
+ let valid_input = vec ! [
632
+ 76 , 68 , 75 , 1 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 , 174 , 99 , 247 ,
633
+ 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 97 , 227 , 98 , 218 ,
634
+ 0 , 0 , 0 , 4 , 2 , 22 , 7 , 207 , 206 , 25 , 164 , 197 , 231 , 230 , 231 , 56 , 102 , 61 , 250 , 251 ,
635
+ 187 , 172 , 38 , 46 , 79 , 247 , 108 , 44 , 155 , 48 , 219 , 238 , 252 , 53 , 192 , 6 , 67 , 2 , 36 , 125 ,
636
+ 157 , 176 , 223 , 175 , 234 , 116 , 94 , 248 , 201 , 225 , 97 , 235 , 50 , 47 , 115 , 172 , 63 , 136 ,
637
+ 88 , 216 , 115 , 11 , 111 , 217 , 114 , 84 , 116 , 124 , 231 , 107 , 2 , 158 , 1 , 242 , 121 , 152 , 106 ,
638
+ 204 , 131 , 186 , 35 , 93 , 70 , 216 , 10 , 237 , 224 , 183 , 89 , 95 , 65 , 3 , 83 , 185 , 58 , 138 ,
639
+ 181 , 64 , 187 , 103 , 127 , 68 , 50 , 2 , 201 , 19 , 17 , 138 , 136 , 149 , 185 , 226 , 156 , 137 , 175 ,
640
+ 110 , 32 , 237 , 0 , 217 , 90 , 31 , 100 , 228 , 149 , 46 , 219 , 175 , 168 , 77 , 4 , 143 , 38 , 128 ,
641
+ 76 , 97 , 0 , 0 , 0 , 2 , 0 , 0 , 255 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 0 , 1 , 0 , 0 , 255 , 2 , 68 ,
642
+ 226 , 0 , 6 , 11 , 0 , 1 , 2 , 3 , 0 , 0 , 0 , 4 , 0 , 40 , 0 , 0 , 0 , 0 , 0 , 0 , 3 , 232 , 0 , 0 , 3 , 232 ,
643
+ 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 29 , 129 , 25 , 192 , 255 , 8 , 153 , 192 , 0 , 2 , 27 , 0 , 0 , 60 , 0 , 0 ,
644
+ 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 100 , 0 , 0 , 2 , 224 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 0 , 29 , 0 ,
645
+ 0 , 0 , 1 , 0 , 0 , 0 , 125 , 0 , 0 , 0 , 0 , 58 , 85 , 116 , 216 , 255 , 2 , 68 , 226 , 0 , 6 , 11 , 0 , 1 ,
646
+ 0 , 0 , 1 ,
647
+ ] ;
648
+
649
+ let block_hash = genesis_block ( Network :: Bitcoin ) . block_hash ( ) ;
650
+ let logger = TestLogger :: new ( ) ;
651
+ let network_graph = NetworkGraph :: new ( block_hash, & logger) ;
652
+
653
+ assert_eq ! ( network_graph. read_only( ) . channels( ) . len( ) , 0 ) ;
654
+
655
+ let earliest_failing_time = LATEST_SEEN_TIMESTAMP + STALE_RGS_UPDATE_AGE_LIMIT_SECS + 1 ;
656
+
657
+ let rapid_sync = RapidGossipSync :: new ( & network_graph) ;
658
+ let update_result = rapid_sync. update_network_graph_no_std ( & valid_input[ ..] , Some ( earliest_failing_time) ) ;
659
+ assert ! ( update_result. is_err( ) ) ;
660
+ if let Err ( GraphSyncError :: LightningError ( lightning_error) ) = update_result {
661
+ assert_eq ! (
662
+ lightning_error. err,
663
+ "Rapid Gossip Sync data is more than two weeks old"
664
+ ) ;
665
+ } else {
666
+ panic ! ( "Unexpected update result: {:?}" , update_result)
667
+ }
668
+ }
669
+
547
670
#[ test]
548
671
pub fn update_fails_with_unknown_version ( ) {
549
672
let unknown_version_input = vec ! [
0 commit comments