@@ -47,8 +47,7 @@ use lightning::events::MessageSendEventsProvider;
47
47
use lightning:: ln:: channel:: FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE ;
48
48
use lightning:: ln:: channel_state:: ChannelDetails ;
49
49
use lightning:: ln:: channelmanager:: {
50
- ChainParameters , ChannelManager , ChannelManagerReadArgs , PaymentId , PaymentSendFailure ,
51
- RecipientOnionFields ,
50
+ ChainParameters , ChannelManager , ChannelManagerReadArgs , PaymentId , RecipientOnionFields , Retry ,
52
51
} ;
53
52
use lightning:: ln:: functional_test_utils:: * ;
54
53
use lightning:: ln:: msgs:: {
@@ -58,7 +57,9 @@ use lightning::ln::script::ShutdownScript;
58
57
use lightning:: ln:: types:: ChannelId ;
59
58
use lightning:: offers:: invoice:: UnsignedBolt12Invoice ;
60
59
use lightning:: onion_message:: messenger:: { Destination , MessageRouter , OnionMessagePath } ;
61
- use lightning:: routing:: router:: { InFlightHtlcs , Path , Route , RouteHop , RouteParameters , Router } ;
60
+ use lightning:: routing:: router:: {
61
+ InFlightHtlcs , Path , PaymentParameters , Route , RouteHop , RouteParameters , Router ,
62
+ } ;
62
63
use lightning:: sign:: {
63
64
EntropySource , InMemorySigner , KeyMaterial , NodeSigner , Recipient , SignerProvider ,
64
65
} ;
@@ -82,6 +83,7 @@ use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey}
82
83
83
84
use lightning:: io:: Cursor ;
84
85
use std:: cmp:: { self , Ordering } ;
86
+ use std:: collections:: VecDeque ;
85
87
use std:: mem;
86
88
use std:: sync:: atomic;
87
89
use std:: sync:: { Arc , Mutex } ;
@@ -112,13 +114,18 @@ impl FeeEstimator for FuzzEstimator {
112
114
}
113
115
}
114
116
115
- struct FuzzRouter { }
117
+ struct FuzzRouter {
118
+ pub next_routes : Mutex < VecDeque < Route > > ,
119
+ }
116
120
117
121
impl Router for FuzzRouter {
118
122
fn find_route (
119
123
& self , _payer : & PublicKey , _params : & RouteParameters ,
120
124
_first_hops : Option < & [ & ChannelDetails ] > , _inflight_htlcs : InFlightHtlcs ,
121
125
) -> Result < Route , msgs:: LightningError > {
126
+ if let Some ( route) = self . next_routes . lock ( ) . unwrap ( ) . pop_front ( ) {
127
+ return Ok ( route) ;
128
+ }
122
129
Err ( msgs:: LightningError {
123
130
err : String :: from ( "Not implemented" ) ,
124
131
action : msgs:: ErrorAction :: IgnoreError ,
@@ -434,6 +441,34 @@ impl KeyProvider {
434
441
}
435
442
}
436
443
444
+ // Returns a bool indicating whether the payment failed.
445
+ #[ inline]
446
+ fn check_payment_send_events (
447
+ source : & ChanMan , amt : u64 , min_sendable : u64 , max_sendable : u64 ,
448
+ ) -> bool {
449
+ let mut payment_failed = false ;
450
+ let events = source. get_and_clear_pending_events ( ) ;
451
+ assert ! ( events. len( ) == 2 || events. len( ) == 0 ) ;
452
+ for ev in events {
453
+ match ev {
454
+ events:: Event :: PaymentPathFailed {
455
+ failure : events:: PathFailure :: InitialSend { err } ,
456
+ ..
457
+ } => {
458
+ check_api_err ( err, amt > max_sendable || amt < min_sendable) ;
459
+ } ,
460
+ events:: Event :: PaymentFailed { .. } => { } ,
461
+ _ => panic ! ( ) ,
462
+ } ;
463
+ payment_failed = true ;
464
+ }
465
+ // Note that while the max is a strict upper-bound, we can occasionally send substantially
466
+ // below the minimum, with some gap which is unusable immediately below the minimum. Thus,
467
+ // we don't check against min_value_sendable here.
468
+ assert ! ( payment_failed || ( amt <= max_sendable) ) ;
469
+ payment_failed
470
+ }
471
+
437
472
#[ inline]
438
473
fn check_api_err ( api_err : APIError , sendable_bounds_violated : bool ) {
439
474
match api_err {
@@ -460,34 +495,6 @@ fn check_api_err(api_err: APIError, sendable_bounds_violated: bool) {
460
495
} ,
461
496
}
462
497
}
463
- #[ inline]
464
- fn check_payment_err ( send_err : PaymentSendFailure , sendable_bounds_violated : bool ) {
465
- match send_err {
466
- PaymentSendFailure :: ParameterError ( api_err) => {
467
- check_api_err ( api_err, sendable_bounds_violated)
468
- } ,
469
- PaymentSendFailure :: PathParameterError ( per_path_results) => {
470
- for res in per_path_results {
471
- if let Err ( api_err) = res {
472
- check_api_err ( api_err, sendable_bounds_violated) ;
473
- }
474
- }
475
- } ,
476
- PaymentSendFailure :: AllFailedResendSafe ( per_path_results) => {
477
- for api_err in per_path_results {
478
- check_api_err ( api_err, sendable_bounds_violated) ;
479
- }
480
- } ,
481
- PaymentSendFailure :: PartialFailure { results, .. } => {
482
- for res in results {
483
- if let Err ( api_err) = res {
484
- check_api_err ( api_err, sendable_bounds_violated) ;
485
- }
486
- }
487
- } ,
488
- PaymentSendFailure :: DuplicatePayment => panic ! ( ) ,
489
- }
490
- }
491
498
492
499
type ChanMan < ' a > = ChannelManager <
493
500
Arc < TestChainMonitor > ,
@@ -546,34 +553,36 @@ fn send_payment(
546
553
. find ( |chan| chan. short_channel_id == Some ( dest_chan_id) )
547
554
. map ( |chan| ( chan. next_outbound_htlc_minimum_msat , chan. next_outbound_htlc_limit_msat ) )
548
555
. unwrap_or ( ( 0 , 0 ) ) ;
549
- if let Err ( err) = source. send_payment_with_route (
550
- Route {
551
- paths : vec ! [ Path {
552
- hops: vec![ RouteHop {
553
- pubkey: dest. get_our_node_id( ) ,
554
- node_features: dest. node_features( ) ,
555
- short_channel_id: dest_chan_id,
556
- channel_features: dest. channel_features( ) ,
557
- fee_msat: amt,
558
- cltv_expiry_delta: 200 ,
559
- maybe_announced_channel: true ,
560
- } ] ,
561
- blinded_tail: None ,
556
+ let mut next_routes = source. router . next_routes . lock ( ) . unwrap ( ) ;
557
+ next_routes. push_back ( Route {
558
+ paths : vec ! [ Path {
559
+ hops: vec![ RouteHop {
560
+ pubkey: dest. get_our_node_id( ) ,
561
+ node_features: dest. node_features( ) ,
562
+ short_channel_id: dest_chan_id,
563
+ channel_features: dest. channel_features( ) ,
564
+ fee_msat: amt,
565
+ cltv_expiry_delta: 200 ,
566
+ maybe_announced_channel: true ,
562
567
} ] ,
563
- route_params : None ,
564
- } ,
568
+ blinded_tail: None ,
569
+ } ] ,
570
+ route_params : None ,
571
+ } ) ;
572
+ let route_params = RouteParameters :: from_payment_params_and_value (
573
+ PaymentParameters :: from_node_id ( source. get_our_node_id ( ) , TEST_FINAL_CLTV ) ,
574
+ amt,
575
+ ) ;
576
+ if let Err ( err) = source. send_payment (
565
577
payment_hash,
566
578
RecipientOnionFields :: secret_only ( payment_secret) ,
567
579
PaymentId ( payment_id) ,
580
+ route_params,
581
+ Retry :: Attempts ( 0 ) ,
568
582
) {
569
- check_payment_err ( err, amt > max_value_sendable || amt < min_value_sendable) ;
570
- false
583
+ panic ! ( "Errored with {:?} on initial payment send" , err) ;
571
584
} else {
572
- // Note that while the max is a strict upper-bound, we can occasionally send substantially
573
- // below the minimum, with some gap which is unusable immediately below the minimum. Thus,
574
- // we don't check against min_value_sendable here.
575
- assert ! ( amt <= max_value_sendable) ;
576
- true
585
+ check_payment_send_events ( source, amt, min_value_sendable, max_value_sendable)
577
586
}
578
587
}
579
588
@@ -615,54 +624,56 @@ fn send_hop_payment(
615
624
. map ( |chan| ( chan. next_outbound_htlc_minimum_msat , chan. next_outbound_htlc_limit_msat ) )
616
625
. unwrap_or ( ( 0 , 0 ) ) ;
617
626
let first_hop_fee = 50_000 ;
618
- if let Err ( err) = source. send_payment_with_route (
619
- Route {
620
- paths : vec ! [ Path {
621
- hops: vec![
622
- RouteHop {
623
- pubkey: middle. get_our_node_id( ) ,
624
- node_features: middle. node_features( ) ,
625
- short_channel_id: middle_chan_id,
626
- channel_features: middle. channel_features( ) ,
627
- fee_msat: first_hop_fee,
628
- cltv_expiry_delta: 100 ,
629
- maybe_announced_channel: true ,
630
- } ,
631
- RouteHop {
632
- pubkey: dest. get_our_node_id( ) ,
633
- node_features: dest. node_features( ) ,
634
- short_channel_id: dest_chan_id,
635
- channel_features: dest. channel_features( ) ,
636
- fee_msat: amt,
637
- cltv_expiry_delta: 200 ,
638
- maybe_announced_channel: true ,
639
- } ,
640
- ] ,
641
- blinded_tail: None ,
642
- } ] ,
643
- route_params : None ,
644
- } ,
627
+ let mut next_routes = source. router . next_routes . lock ( ) . unwrap ( ) ;
628
+ next_routes. push_back ( Route {
629
+ paths : vec ! [ Path {
630
+ hops: vec![
631
+ RouteHop {
632
+ pubkey: middle. get_our_node_id( ) ,
633
+ node_features: middle. node_features( ) ,
634
+ short_channel_id: middle_chan_id,
635
+ channel_features: middle. channel_features( ) ,
636
+ fee_msat: first_hop_fee,
637
+ cltv_expiry_delta: 100 ,
638
+ maybe_announced_channel: true ,
639
+ } ,
640
+ RouteHop {
641
+ pubkey: dest. get_our_node_id( ) ,
642
+ node_features: dest. node_features( ) ,
643
+ short_channel_id: dest_chan_id,
644
+ channel_features: dest. channel_features( ) ,
645
+ fee_msat: amt,
646
+ cltv_expiry_delta: 200 ,
647
+ maybe_announced_channel: true ,
648
+ } ,
649
+ ] ,
650
+ blinded_tail: None ,
651
+ } ] ,
652
+ route_params : None ,
653
+ } ) ;
654
+ let route_params = RouteParameters :: from_payment_params_and_value (
655
+ PaymentParameters :: from_node_id ( source. get_our_node_id ( ) , TEST_FINAL_CLTV ) ,
656
+ amt,
657
+ ) ;
658
+ if let Err ( err) = source. send_payment (
645
659
payment_hash,
646
660
RecipientOnionFields :: secret_only ( payment_secret) ,
647
661
PaymentId ( payment_id) ,
662
+ route_params,
663
+ Retry :: Attempts ( 0 ) ,
648
664
) {
649
- let sent_amt = amt + first_hop_fee;
650
- check_payment_err ( err, sent_amt < min_value_sendable || sent_amt > max_value_sendable) ;
651
- false
665
+ panic ! ( "Errored with {:?} on initial payment send" , err) ;
652
666
} else {
653
- // Note that while the max is a strict upper-bound, we can occasionally send substantially
654
- // below the minimum, with some gap which is unusable immediately below the minimum. Thus,
655
- // we don't check against min_value_sendable here.
656
- assert ! ( amt + first_hop_fee <= max_value_sendable) ;
657
- true
667
+ let sent_amt = amt + first_hop_fee;
668
+ check_payment_send_events ( source, sent_amt, min_value_sendable, max_value_sendable)
658
669
}
659
670
}
660
671
661
672
#[ inline]
662
673
pub fn do_test < Out : Output > ( data : & [ u8 ] , underlying_out : Out , anchors : bool ) {
663
674
let out = SearchingOutput :: new ( underlying_out) ;
664
675
let broadcast = Arc :: new ( TestBroadcaster { } ) ;
665
- let router = FuzzRouter { } ;
676
+ let router = FuzzRouter { next_routes : Mutex :: new ( VecDeque :: new ( ) ) } ;
666
677
667
678
macro_rules! make_node {
668
679
( $node_id: expr, $fee_estimator: expr) => { {
0 commit comments