@@ -75,10 +75,13 @@ const PING_TIMER: u64 = 1;
75
75
/// Prune the network graph of stale entries hourly.
76
76
const NETWORK_PRUNE_TIMER : u64 = 60 * 60 ;
77
77
78
- /// Trait which handles persisting a [`ChannelManager`] to disk.
79
- ///
80
- /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
81
- pub trait ChannelManagerPersister < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref >
78
+ #[ cfg( not( test) ) ]
79
+ const FIRST_NETWORK_PRUNE_TIMER : u64 = 60 ;
80
+ #[ cfg( test) ]
81
+ const FIRST_NETWORK_PRUNE_TIMER : u64 = 1 ;
82
+
83
+ /// Trait that handles persisting a [`ChannelManager`] and [`NetworkGraph`] to disk.
84
+ pub trait Persister < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref >
82
85
where
83
86
M :: Target : ' static + chain:: Watch < Signer > ,
84
87
T :: Target : ' static + BroadcasterInterface ,
@@ -87,24 +90,11 @@ where
87
90
L :: Target : ' static + Logger ,
88
91
{
89
92
/// Persist the given [`ChannelManager`] to disk, returning an error if persistence failed
90
- /// (which will cause the [`BackgroundProcessor`] which called this method to exit.
91
- ///
92
- /// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
93
+ /// (which will cause the [`BackgroundProcessor`] which called this method to exit).
93
94
fn persist_manager ( & self , channel_manager : & ChannelManager < Signer , M , T , K , F , L > ) -> Result < ( ) , std:: io:: Error > ;
94
- }
95
95
96
- impl < Fun , Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref >
97
- ChannelManagerPersister < Signer , M , T , K , F , L > for Fun where
98
- M :: Target : ' static + chain:: Watch < Signer > ,
99
- T :: Target : ' static + BroadcasterInterface ,
100
- K :: Target : ' static + KeysInterface < Signer = Signer > ,
101
- F :: Target : ' static + FeeEstimator ,
102
- L :: Target : ' static + Logger ,
103
- Fun : Fn ( & ChannelManager < Signer , M , T , K , F , L > ) -> Result < ( ) , std:: io:: Error > ,
104
- {
105
- fn persist_manager ( & self , channel_manager : & ChannelManager < Signer , M , T , K , F , L > ) -> Result < ( ) , std:: io:: Error > {
106
- self ( channel_manager)
107
- }
96
+ /// Persist the given [`NetworkGraph`] to disk, returning an error if persistence failed.
97
+ fn persist_graph ( & self , network_graph : & NetworkGraph ) -> Result < ( ) , std:: io:: Error > ;
108
98
}
109
99
110
100
/// Decorates an [`EventHandler`] with common functionality provided by standard [`EventHandler`]s.
@@ -141,17 +131,21 @@ impl BackgroundProcessor {
141
131
/// documentation].
142
132
///
143
133
/// The thread runs indefinitely unless the object is dropped, [`stop`] is called, or
144
- /// ` persist_manager` returns an error. In case of an error, the error is retrieved by calling
134
+ /// [`Persister:: persist_manager`] returns an error. In case of an error, the error is retrieved by calling
145
135
/// either [`join`] or [`stop`].
146
136
///
147
137
/// # Data Persistence
148
138
///
149
- /// ` persist_manager` is responsible for writing out the [`ChannelManager`] to disk, and/or
139
+ /// [`Persister:: persist_manager`] is responsible for writing out the [`ChannelManager`] to disk, and/or
150
140
/// uploading to one or more backup services. See [`ChannelManager::write`] for writing out a
151
141
/// [`ChannelManager`]. See [`FilesystemPersister::persist_manager`] for Rust-Lightning's
152
142
/// provided implementation.
153
143
///
154
- /// Typically, users should either implement [`ChannelManagerPersister`] to never return an
144
+ /// [`Persister::persist_graph`] is responsible for writing out the [`NetworkGraph`] to disk. See
145
+ /// [`NetworkGraph::write`] for writing out a [`NetworkGraph`]. See [`FilesystemPersister::persist_network_graph`]
146
+ /// for Rust-Lightning's provided implementation.
147
+ ///
148
+ /// Typically, users should either implement [`Persister::persist_manager`] to never return an
155
149
/// error or call [`join`] and handle any error that may arise. For the latter case,
156
150
/// `BackgroundProcessor` must be restarted by calling `start` again after handling the error.
157
151
///
@@ -168,7 +162,9 @@ impl BackgroundProcessor {
168
162
/// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
169
163
/// [`ChannelManager::write`]: lightning::ln::channelmanager::ChannelManager#impl-Writeable
170
164
/// [`FilesystemPersister::persist_manager`]: lightning_persister::FilesystemPersister::persist_manager
165
+ /// [`FilesystemPersister::persist_network_graph`]: lightning_persister::FilesystemPersister::persist_network_graph
171
166
/// [`NetworkGraph`]: lightning::routing::network_graph::NetworkGraph
167
+ /// [`NetworkGraph::write`]: lightning::routing::network_graph::NetworkGraph#impl-Writeable
172
168
pub fn start <
173
169
Signer : ' static + Sign ,
174
170
CA : ' static + Deref + Send + Sync ,
@@ -184,14 +180,14 @@ impl BackgroundProcessor {
184
180
CMH : ' static + Deref + Send + Sync ,
185
181
RMH : ' static + Deref + Send + Sync ,
186
182
EH : ' static + EventHandler + Send ,
187
- CMP : ' static + Send + ChannelManagerPersister < Signer , CW , T , K , F , L > ,
183
+ PS : ' static + Send + Persister < Signer , CW , T , K , F , L > ,
188
184
M : ' static + Deref < Target = ChainMonitor < Signer , CF , T , F , L , P > > + Send + Sync ,
189
185
CM : ' static + Deref < Target = ChannelManager < Signer , CW , T , K , F , L > > + Send + Sync ,
190
186
NG : ' static + Deref < Target = NetGraphMsgHandler < G , CA , L > > + Send + Sync ,
191
187
UMH : ' static + Deref + Send + Sync ,
192
188
PM : ' static + Deref < Target = PeerManager < Descriptor , CMH , RMH , L , UMH > > + Send + Sync ,
193
189
> (
194
- persister : CMP , event_handler : EH , chain_monitor : M , channel_manager : CM ,
190
+ persister : PS , event_handler : EH , chain_monitor : M , channel_manager : CM ,
195
191
net_graph_msg_handler : Option < NG > , peer_manager : PM , logger : L
196
192
) -> Self
197
193
where
@@ -273,19 +269,29 @@ impl BackgroundProcessor {
273
269
// falling back to our usual hourly prunes. This avoids short-lived clients never
274
270
// pruning their network graph. We run once 60 seconds after startup before
275
271
// continuing our normal cadence.
276
- if last_prune_call. elapsed ( ) . as_secs ( ) > if have_pruned { NETWORK_PRUNE_TIMER } else { 60 } {
272
+ if last_prune_call. elapsed ( ) . as_secs ( ) > if have_pruned { NETWORK_PRUNE_TIMER } else { FIRST_NETWORK_PRUNE_TIMER } {
277
273
if let Some ( ref handler) = net_graph_msg_handler {
278
274
log_trace ! ( logger, "Pruning network graph of stale entries" ) ;
279
275
handler. network_graph ( ) . remove_stale_channels ( ) ;
276
+ if let Err ( e) = persister. persist_graph ( handler. network_graph ( ) ) {
277
+ log_error ! ( logger, "Error: Failed to persist network graph, check your disk and permissions {}" , e)
278
+ }
280
279
last_prune_call = Instant :: now ( ) ;
281
280
have_pruned = true ;
282
281
}
283
282
}
284
283
}
284
+
285
285
// After we exit, ensure we persist the ChannelManager one final time - this avoids
286
286
// some races where users quit while channel updates were in-flight, with
287
287
// ChannelMonitor update(s) persisted without a corresponding ChannelManager update.
288
- persister. persist_manager ( & * channel_manager)
288
+ persister. persist_manager ( & * channel_manager) ?;
289
+
290
+ // Persist NetworkGraph on exit
291
+ if let Some ( ref handler) = net_graph_msg_handler {
292
+ persister. persist_graph ( handler. network_graph ( ) ) ?;
293
+ }
294
+ Ok ( ( ) )
289
295
} ) ;
290
296
Self { stop_thread : stop_thread_clone, thread_handle : Some ( handle) }
291
297
}
@@ -343,9 +349,10 @@ mod tests {
343
349
use bitcoin:: blockdata:: constants:: genesis_block;
344
350
use bitcoin:: blockdata:: transaction:: { Transaction , TxOut } ;
345
351
use bitcoin:: network:: constants:: Network ;
346
- use lightning:: chain:: { BestBlock , Confirm , chainmonitor} ;
352
+ use lightning:: chain:: chaininterface:: { BroadcasterInterface , FeeEstimator } ;
353
+ use lightning:: chain:: { BestBlock , Confirm , chainmonitor, self } ;
347
354
use lightning:: chain:: channelmonitor:: ANTI_REORG_DELAY ;
348
- use lightning:: chain:: keysinterface:: { InMemorySigner , Recipient , KeysInterface , KeysManager } ;
355
+ use lightning:: chain:: keysinterface:: { InMemorySigner , Recipient , KeysInterface , KeysManager , Sign } ;
349
356
use lightning:: chain:: transaction:: OutPoint ;
350
357
use lightning:: get_event_msg;
351
358
use lightning:: ln:: channelmanager:: { BREAKDOWN_TIMEOUT , ChainParameters , ChannelManager , SimpleArcChannelManager } ;
@@ -355,12 +362,14 @@ mod tests {
355
362
use lightning:: routing:: network_graph:: { NetworkGraph , NetGraphMsgHandler } ;
356
363
use lightning:: util:: config:: UserConfig ;
357
364
use lightning:: util:: events:: { Event , MessageSendEventsProvider , MessageSendEvent } ;
365
+ use lightning:: util:: logger:: Logger ;
358
366
use lightning:: util:: ser:: Writeable ;
359
367
use lightning:: util:: test_utils;
360
368
use lightning_invoice:: payment:: { InvoicePayer , RetryAttempts } ;
361
369
use lightning_invoice:: utils:: DefaultRouter ;
362
370
use lightning_persister:: FilesystemPersister ;
363
371
use std:: fs;
372
+ use std:: ops:: Deref ;
364
373
use std:: path:: PathBuf ;
365
374
use std:: sync:: { Arc , Mutex } ;
366
375
use std:: time:: Duration ;
@@ -402,6 +411,48 @@ mod tests {
402
411
}
403
412
}
404
413
414
+ struct Persister {
415
+ data_dir : String ,
416
+ graph_error : Option < ( std:: io:: ErrorKind , & ' static str ) > ,
417
+ manager_error : Option < ( std:: io:: ErrorKind , & ' static str ) >
418
+ }
419
+
420
+ impl Persister {
421
+ fn new ( data_dir : String ) -> Self {
422
+ Self { data_dir, graph_error : None , manager_error : None }
423
+ }
424
+
425
+ fn with_graph_error ( self , error : std:: io:: ErrorKind , message : & ' static str ) -> Self {
426
+ Self { graph_error : Some ( ( error, message) ) , ..self }
427
+ }
428
+
429
+ fn with_manager_error ( self , error : std:: io:: ErrorKind , message : & ' static str ) -> Self {
430
+ Self { manager_error : Some ( ( error, message) ) , ..self }
431
+ }
432
+ }
433
+
434
+ impl < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > super :: Persister < Signer , M , T , K , F , L > for Persister where
435
+ M :: Target : ' static + chain:: Watch < Signer > ,
436
+ T :: Target : ' static + BroadcasterInterface ,
437
+ K :: Target : ' static + KeysInterface < Signer = Signer > ,
438
+ F :: Target : ' static + FeeEstimator ,
439
+ L :: Target : ' static + Logger ,
440
+ {
441
+ fn persist_manager ( & self , channel_manager : & ChannelManager < Signer , M , T , K , F , L > ) -> Result < ( ) , std:: io:: Error > {
442
+ match self . manager_error {
443
+ None => FilesystemPersister :: persist_manager ( self . data_dir . clone ( ) , channel_manager) ,
444
+ Some ( ( error, message) ) => Err ( std:: io:: Error :: new ( error, message) ) ,
445
+ }
446
+ }
447
+
448
+ fn persist_graph ( & self , network_graph : & NetworkGraph ) -> Result < ( ) , std:: io:: Error > {
449
+ match self . graph_error {
450
+ None => FilesystemPersister :: persist_network_graph ( self . data_dir . clone ( ) , network_graph) ,
451
+ Some ( ( error, message) ) => Err ( std:: io:: Error :: new ( error, message) ) ,
452
+ }
453
+ }
454
+ }
455
+
405
456
fn get_full_filepath ( filepath : String , filename : String ) -> String {
406
457
let mut path = PathBuf :: from ( filepath) ;
407
458
path. push ( filename) ;
@@ -525,19 +576,20 @@ mod tests {
525
576
526
577
// Initiate the background processors to watch each node.
527
578
let data_dir = nodes[ 0 ] . persister . get_data_dir ( ) ;
528
- let persister = move | node : & ChannelManager < InMemorySigner , Arc < ChainMonitor > , Arc < test_utils :: TestBroadcaster > , Arc < KeysManager > , Arc < test_utils :: TestFeeEstimator > , Arc < test_utils :: TestLogger > > | FilesystemPersister :: persist_manager ( data_dir. clone ( ) , node ) ;
579
+ let persister = Persister :: new ( data_dir) ;
529
580
let event_handler = |_: & _ | { } ;
530
581
let bg_processor = BackgroundProcessor :: start ( persister, event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . net_graph_msg_handler . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
531
582
532
583
macro_rules! check_persisted_data {
533
- ( $node: expr, $filepath: expr, $expected_bytes: expr) => {
584
+ ( $node: expr, $filepath: expr) => {
585
+ let mut expected_bytes = Vec :: new( ) ;
534
586
loop {
535
- $ expected_bytes. clear( ) ;
536
- match $node. write( & mut $ expected_bytes) {
587
+ expected_bytes. clear( ) ;
588
+ match $node. write( & mut expected_bytes) {
537
589
Ok ( ( ) ) => {
538
590
match std:: fs:: read( $filepath) {
539
591
Ok ( bytes) => {
540
- if bytes == $ expected_bytes {
592
+ if bytes == expected_bytes {
541
593
break
542
594
} else {
543
595
continue
@@ -554,8 +606,8 @@ mod tests {
554
606
555
607
// Check that the initial channel manager data is persisted as expected.
556
608
let filepath = get_full_filepath ( "test_background_processor_persister_0" . to_string ( ) , "manager" . to_string ( ) ) ;
557
- let mut expected_bytes = Vec :: new ( ) ;
558
- check_persisted_data ! ( nodes [ 0 ] . node , filepath . clone ( ) , expected_bytes ) ;
609
+ check_persisted_data ! ( nodes [ 0 ] . node , filepath . clone ( ) ) ;
610
+
559
611
loop {
560
612
if !nodes[ 0 ] . node . get_persistence_condvar_value ( ) { break }
561
613
}
@@ -564,12 +616,18 @@ mod tests {
564
616
nodes[ 0 ] . node . force_close_channel ( & OutPoint { txid : tx. txid ( ) , index : 0 } . to_channel_id ( ) ) . unwrap ( ) ;
565
617
566
618
// Check that the force-close updates are persisted.
567
- let mut expected_bytes = Vec :: new ( ) ;
568
- check_persisted_data ! ( nodes[ 0 ] . node, filepath. clone( ) , expected_bytes) ;
619
+ check_persisted_data ! ( nodes[ 0 ] . node, filepath. clone( ) ) ;
569
620
loop {
570
621
if !nodes[ 0 ] . node . get_persistence_condvar_value ( ) { break }
571
622
}
572
623
624
+ // Check network graph is persisted
625
+ let filepath = get_full_filepath ( "test_background_processor_persister_0" . to_string ( ) , "network_graph" . to_string ( ) ) ;
626
+ if let Some ( ref handler) = nodes[ 0 ] . net_graph_msg_handler {
627
+ let network_graph = handler. network_graph ( ) ;
628
+ check_persisted_data ! ( network_graph, filepath. clone( ) ) ;
629
+ }
630
+
573
631
assert ! ( bg_processor. stop( ) . is_ok( ) ) ;
574
632
}
575
633
@@ -579,7 +637,7 @@ mod tests {
579
637
// `FRESHNESS_TIMER`.
580
638
let nodes = create_nodes ( 1 , "test_timer_tick_called" . to_string ( ) ) ;
581
639
let data_dir = nodes[ 0 ] . persister . get_data_dir ( ) ;
582
- let persister = move | node : & ChannelManager < InMemorySigner , Arc < ChainMonitor > , Arc < test_utils :: TestBroadcaster > , Arc < KeysManager > , Arc < test_utils :: TestFeeEstimator > , Arc < test_utils :: TestLogger > > | FilesystemPersister :: persist_manager ( data_dir. clone ( ) , node ) ;
640
+ let persister = Persister :: new ( data_dir) ;
583
641
let event_handler = |_: & _ | { } ;
584
642
let bg_processor = BackgroundProcessor :: start ( persister, event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . net_graph_msg_handler . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
585
643
loop {
@@ -596,12 +654,13 @@ mod tests {
596
654
}
597
655
598
656
#[ test]
599
- fn test_persist_error ( ) {
657
+ fn test_channel_manager_persist_error ( ) {
600
658
// Test that if we encounter an error during manager persistence, the thread panics.
601
659
let nodes = create_nodes ( 2 , "test_persist_error" . to_string ( ) ) ;
602
660
open_channel ! ( nodes[ 0 ] , nodes[ 1 ] , 100000 ) ;
603
661
604
- let persister = |_: & _ | Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "test" ) ) ;
662
+ let data_dir = nodes[ 0 ] . persister . get_data_dir ( ) ;
663
+ let persister = Persister :: new ( data_dir) . with_manager_error ( std:: io:: ErrorKind :: Other , "test" ) ;
605
664
let event_handler = |_: & _ | { } ;
606
665
let bg_processor = BackgroundProcessor :: start ( persister, event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . net_graph_msg_handler . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
607
666
match bg_processor. join ( ) {
@@ -613,19 +672,37 @@ mod tests {
613
672
}
614
673
}
615
674
675
+ #[ test]
676
+ fn test_network_graph_persist_error ( ) {
677
+ // Test that if we encounter an error during network graph persistence, an error gets returned.
678
+ let nodes = create_nodes ( 2 , "test_persist_network_graph_error" . to_string ( ) ) ;
679
+ let data_dir = nodes[ 0 ] . persister . get_data_dir ( ) ;
680
+ let persister = Persister :: new ( data_dir) . with_graph_error ( std:: io:: ErrorKind :: Other , "test" ) ;
681
+ let event_handler = |_: & _ | { } ;
682
+ let bg_processor = BackgroundProcessor :: start ( persister, event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . net_graph_msg_handler . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
683
+
684
+ match bg_processor. stop ( ) {
685
+ Ok ( _) => panic ! ( "Expected error persisting network graph" ) ,
686
+ Err ( e) => {
687
+ assert_eq ! ( e. kind( ) , std:: io:: ErrorKind :: Other ) ;
688
+ assert_eq ! ( e. get_ref( ) . unwrap( ) . to_string( ) , "test" ) ;
689
+ } ,
690
+ }
691
+ }
692
+
616
693
#[ test]
617
694
fn test_background_event_handling ( ) {
618
695
let mut nodes = create_nodes ( 2 , "test_background_event_handling" . to_string ( ) ) ;
619
696
let channel_value = 100000 ;
620
697
let data_dir = nodes[ 0 ] . persister . get_data_dir ( ) ;
621
- let persister = move | node : & _ | FilesystemPersister :: persist_manager ( data_dir. clone ( ) , node ) ;
698
+ let persister = Persister :: new ( data_dir. clone ( ) ) ;
622
699
623
700
// Set up a background event handler for FundingGenerationReady events.
624
701
let ( sender, receiver) = std:: sync:: mpsc:: sync_channel ( 1 ) ;
625
702
let event_handler = move |event : & Event | {
626
703
sender. send ( handle_funding_generation_ready ! ( event, channel_value) ) . unwrap ( ) ;
627
704
} ;
628
- let bg_processor = BackgroundProcessor :: start ( persister. clone ( ) , event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . net_graph_msg_handler . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
705
+ let bg_processor = BackgroundProcessor :: start ( persister, event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . net_graph_msg_handler . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
629
706
630
707
// Open a channel and check that the FundingGenerationReady event was handled.
631
708
begin_open_channel ! ( nodes[ 0 ] , nodes[ 1 ] , channel_value) ;
@@ -649,7 +726,7 @@ mod tests {
649
726
// Set up a background event handler for SpendableOutputs events.
650
727
let ( sender, receiver) = std:: sync:: mpsc:: sync_channel ( 1 ) ;
651
728
let event_handler = move |event : & Event | sender. send ( event. clone ( ) ) . unwrap ( ) ;
652
- let bg_processor = BackgroundProcessor :: start ( persister , event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . net_graph_msg_handler . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
729
+ let bg_processor = BackgroundProcessor :: start ( Persister :: new ( data_dir ) , event_handler, nodes[ 0 ] . chain_monitor . clone ( ) , nodes[ 0 ] . node . clone ( ) , nodes[ 0 ] . net_graph_msg_handler . clone ( ) , nodes[ 0 ] . peer_manager . clone ( ) , nodes[ 0 ] . logger . clone ( ) ) ;
653
730
654
731
// Force close the channel and check that the SpendableOutputs event was handled.
655
732
nodes[ 0 ] . node . force_close_channel ( & nodes[ 0 ] . node . list_channels ( ) [ 0 ] . channel_id ) . unwrap ( ) ;
@@ -675,7 +752,7 @@ mod tests {
675
752
676
753
// Initiate the background processors to watch each node.
677
754
let data_dir = nodes[ 0 ] . persister . get_data_dir ( ) ;
678
- let persister = move | node : & ChannelManager < InMemorySigner , Arc < ChainMonitor > , Arc < test_utils :: TestBroadcaster > , Arc < KeysManager > , Arc < test_utils :: TestFeeEstimator > , Arc < test_utils :: TestLogger > > | FilesystemPersister :: persist_manager ( data_dir. clone ( ) , node ) ;
755
+ let persister = Persister :: new ( data_dir) ;
679
756
let scorer = Arc :: new ( Mutex :: new ( test_utils:: TestScorer :: with_penalty ( 0 ) ) ) ;
680
757
let router = DefaultRouter :: new ( Arc :: clone ( & nodes[ 0 ] . network_graph ) , Arc :: clone ( & nodes[ 0 ] . logger ) , random_seed_bytes) ;
681
758
let invoice_payer = Arc :: new ( InvoicePayer :: new ( Arc :: clone ( & nodes[ 0 ] . node ) , router, scorer, Arc :: clone ( & nodes[ 0 ] . logger ) , |_: & _ | { } , RetryAttempts ( 2 ) ) ) ;
0 commit comments