69
69
//! # &self, route: &Route, payment_id: PaymentId
70
70
//! # ) -> Result<(), PaymentSendFailure> { unimplemented!() }
71
71
//! # fn abandon_payment(&self, payment_id: PaymentId) { unimplemented!() }
72
+ //! # fn inflight_htlcs(&self) -> InFlightHtlcs { unimplemented!() }
72
73
//! # }
73
74
//! #
74
75
//! # struct FakeRouter {}
@@ -289,6 +290,10 @@ pub trait Payer {
289
290
290
291
/// Signals that no further retries for the given payment will occur.
291
292
fn abandon_payment ( & self , payment_id : PaymentId ) ;
293
+
294
+ /// Construct an [`InFlightHtlcs`] containing information about currently used up liquidity
295
+ /// across payments.
296
+ fn inflight_htlcs ( & self ) -> InFlightHtlcs ;
292
297
}
293
298
294
299
/// A trait defining behavior for a [`Router`] implementation that also supports scoring channels
@@ -546,7 +551,7 @@ where
546
551
547
552
let payer = self . payer . node_id ( ) ;
548
553
let first_hops = self . payer . first_hops ( ) ;
549
- let inflight_htlcs = self . create_inflight_map ( ) ;
554
+ let inflight_htlcs = self . payer . inflight_htlcs ( ) ;
550
555
let route = self . router . find_route (
551
556
& payer, & params, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) , inflight_htlcs
552
557
) . map_err ( |e| PaymentError :: Routing ( e) ) ?;
@@ -649,7 +654,7 @@ where
649
654
650
655
let payer = self . payer . node_id ( ) ;
651
656
let first_hops = self . payer . first_hops ( ) ;
652
- let inflight_htlcs = self . create_inflight_map ( ) ;
657
+ let inflight_htlcs = self . payer . inflight_htlcs ( ) ;
653
658
654
659
let route = self . router . find_route (
655
660
& payer, & params, Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) , inflight_htlcs
@@ -704,23 +709,6 @@ where
704
709
pub fn remove_cached_payment ( & self , payment_hash : & PaymentHash ) {
705
710
self . payment_cache . lock ( ) . unwrap ( ) . remove ( payment_hash) ;
706
711
}
707
-
708
- /// Use path information in the payment_cache to construct a HashMap mapping a channel's short
709
- /// channel id and direction to the amount being sent through it.
710
- ///
711
- /// This function should be called whenever we need information about currently used up liquidity
712
- /// across payments.
713
- fn create_inflight_map ( & self ) -> InFlightHtlcs {
714
- let mut total_inflight_map = InFlightHtlcs :: new ( ) ;
715
- // Make an attempt at finding existing payment information from `payment_cache`.
716
- for payment_info in self . payment_cache . lock ( ) . unwrap ( ) . values ( ) {
717
- for path in & payment_info. paths {
718
- total_inflight_map. process_path ( path, self . payer . node_id ( ) ) ;
719
- }
720
- }
721
-
722
- total_inflight_map
723
- }
724
712
}
725
713
726
714
fn expiry_time_from_unix_epoch ( invoice : & Invoice ) -> Duration {
@@ -865,7 +853,6 @@ mod tests {
865
853
use std:: time:: { SystemTime , Duration } ;
866
854
use crate :: time_utils:: tests:: SinceEpoch ;
867
855
use crate :: DEFAULT_EXPIRY_TIME ;
868
- use lightning:: util:: errors:: APIError :: { ChannelUnavailable , MonitorUpdateInProgress } ;
869
856
870
857
fn invoice ( payment_preimage : PaymentPreimage ) -> Invoice {
871
858
let payment_hash = Sha256 :: hash ( & payment_preimage. 0 ) ;
@@ -1591,20 +1578,17 @@ mod tests {
1591
1578
1592
1579
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
1593
1580
let invoice = invoice ( payment_preimage) ;
1594
- let payment_hash = Some ( PaymentHash ( invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ) ;
1595
1581
let final_value_msat = invoice. amount_milli_satoshis ( ) . unwrap ( ) ;
1596
1582
1597
1583
let payer = TestPayer :: new ( ) . expect_send ( Amount :: ForInvoice ( final_value_msat) ) ;
1598
- let final_value_msat = invoice. amount_milli_satoshis ( ) . unwrap ( ) ;
1599
- let route = TestRouter :: route_for_value ( final_value_msat) ;
1600
1584
let router = TestRouter :: new ( TestScorer :: new ( ) ) ;
1601
1585
let logger = TestLogger :: new ( ) ;
1602
1586
let invoice_payer =
1603
1587
InvoicePayer :: new ( & payer, router, & logger, event_handler, Retry :: Attempts ( 0 ) ) ;
1604
1588
1605
- let payment_id = invoice_payer. pay_invoice ( & invoice) . unwrap ( ) ;
1589
+ invoice_payer. pay_invoice ( & invoice) . unwrap ( ) ;
1606
1590
1607
- let inflight_map = invoice_payer. create_inflight_map ( ) ;
1591
+ let inflight_map = invoice_payer. payer . inflight_htlcs ( ) ;
1608
1592
// First path check
1609
1593
assert_eq ! ( inflight_map. 0 . get( & ( 0 , false ) ) . unwrap( ) . clone( ) , 94 ) ;
1610
1594
assert_eq ! ( inflight_map. 0 . get( & ( 1 , true ) ) . unwrap( ) . clone( ) , 84 ) ;
@@ -1613,20 +1597,6 @@ mod tests {
1613
1597
// Second path check
1614
1598
assert_eq ! ( inflight_map. 0 . get( & ( 3 , false ) ) . unwrap( ) . clone( ) , 74 ) ;
1615
1599
assert_eq ! ( inflight_map. 0 . get( & ( 4 , false ) ) . unwrap( ) . clone( ) , 64 ) ;
1616
-
1617
- invoice_payer. handle_event ( Event :: PaymentPathSuccessful {
1618
- payment_id, payment_hash, path : route. paths [ 0 ] . clone ( )
1619
- } ) ;
1620
-
1621
- let inflight_map = invoice_payer. create_inflight_map ( ) ;
1622
-
1623
- assert_eq ! ( inflight_map. 0 . get( & ( 0 , false ) ) , None ) ;
1624
- assert_eq ! ( inflight_map. 0 . get( & ( 1 , true ) ) , None ) ;
1625
- assert_eq ! ( inflight_map. 0 . get( & ( 2 , false ) ) , None ) ;
1626
-
1627
- // Second path should still be inflight
1628
- assert_eq ! ( inflight_map. 0 . get( & ( 3 , false ) ) . unwrap( ) . clone( ) , 74 ) ;
1629
- assert_eq ! ( inflight_map. 0 . get( & ( 4 , false ) ) . unwrap( ) . clone( ) , 64 )
1630
1600
}
1631
1601
1632
1602
#[ test]
@@ -1637,14 +1607,11 @@ mod tests {
1637
1607
1638
1608
let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
1639
1609
let payment_invoice = invoice ( payment_preimage) ;
1640
- let payment_hash = Some ( PaymentHash ( payment_invoice. payment_hash ( ) . clone ( ) . into_inner ( ) ) ) ;
1641
1610
let final_value_msat = payment_invoice. amount_milli_satoshis ( ) . unwrap ( ) ;
1642
1611
1643
1612
let payer = TestPayer :: new ( )
1644
1613
. expect_send ( Amount :: ForInvoice ( final_value_msat) )
1645
1614
. expect_send ( Amount :: ForInvoice ( final_value_msat) ) ;
1646
- let final_value_msat = payment_invoice. amount_milli_satoshis ( ) . unwrap ( ) ;
1647
- let route = TestRouter :: route_for_value ( final_value_msat) ;
1648
1615
let scorer = TestScorer :: new ( )
1649
1616
// 1st invoice, 1st path
1650
1617
. expect_usage ( ChannelUsage { amount_msat : 64 , inflight_htlc_msat : 0 , effective_capacity : EffectiveCapacity :: Unknown } )
@@ -1654,9 +1621,9 @@ mod tests {
1654
1621
. expect_usage ( ChannelUsage { amount_msat : 64 , inflight_htlc_msat : 0 , effective_capacity : EffectiveCapacity :: Unknown } )
1655
1622
. expect_usage ( ChannelUsage { amount_msat : 74 , inflight_htlc_msat : 0 , effective_capacity : EffectiveCapacity :: Unknown } )
1656
1623
// 2nd invoice, 1st path
1657
- . expect_usage ( ChannelUsage { amount_msat : 64 , inflight_htlc_msat : 0 , effective_capacity : EffectiveCapacity :: Unknown } )
1658
- . expect_usage ( ChannelUsage { amount_msat : 84 , inflight_htlc_msat : 0 , effective_capacity : EffectiveCapacity :: Unknown } )
1659
- . expect_usage ( ChannelUsage { amount_msat : 94 , inflight_htlc_msat : 0 , effective_capacity : EffectiveCapacity :: Unknown } )
1624
+ . expect_usage ( ChannelUsage { amount_msat : 64 , inflight_htlc_msat : 64 , effective_capacity : EffectiveCapacity :: Unknown } )
1625
+ . expect_usage ( ChannelUsage { amount_msat : 84 , inflight_htlc_msat : 84 , effective_capacity : EffectiveCapacity :: Unknown } )
1626
+ . expect_usage ( ChannelUsage { amount_msat : 94 , inflight_htlc_msat : 94 , effective_capacity : EffectiveCapacity :: Unknown } )
1660
1627
// 2nd invoice, 2nd path
1661
1628
. expect_usage ( ChannelUsage { amount_msat : 64 , inflight_htlc_msat : 64 , effective_capacity : EffectiveCapacity :: Unknown } )
1662
1629
. expect_usage ( ChannelUsage { amount_msat : 74 , inflight_htlc_msat : 74 , effective_capacity : EffectiveCapacity :: Unknown } ) ;
@@ -1665,16 +1632,12 @@ mod tests {
1665
1632
let invoice_payer =
1666
1633
InvoicePayer :: new ( & payer, router, & logger, event_handler, Retry :: Attempts ( 0 ) ) ;
1667
1634
1668
- // Succeed 1st path, leave 2nd path inflight
1669
- let payment_id = invoice_payer. pay_invoice ( & payment_invoice) . unwrap ( ) ;
1670
- invoice_payer. handle_event ( Event :: PaymentPathSuccessful {
1671
- payment_id, payment_hash, path : route. paths [ 0 ] . clone ( )
1672
- } ) ;
1635
+ // Make first invoice payment.
1636
+ invoice_payer. pay_invoice ( & payment_invoice) . unwrap ( ) ;
1673
1637
1674
1638
// Let's pay a second invoice that will be using the same path. This should trigger the
1675
- // assertions that expect the last 4 ChannelUsage values above where TestScorer is initialized.
1676
- // Particularly, the 2nd path of the 1st payment, since it is not yet complete, should still
1677
- // have 64 msats inflight for paths considering the channel with scid of 1.
1639
+ // assertions that expect `ChannelUsage` values of the first invoice payment that is still
1640
+ // in-flight.
1678
1641
let payment_preimage_2 = PaymentPreimage ( [ 2 ; 32 ] ) ;
1679
1642
let payment_invoice_2 = invoice ( payment_preimage_2) ;
1680
1643
invoice_payer. pay_invoice ( & payment_invoice_2) . unwrap ( ) ;
@@ -1725,6 +1688,7 @@ mod tests {
1725
1688
1726
1689
// Fail 1st path, leave 2nd path inflight
1727
1690
let payment_id = Some ( invoice_payer. pay_invoice ( & payment_invoice) . unwrap ( ) ) ;
1691
+ invoice_payer. payer . fail_path ( & TestRouter :: path_for_value ( final_value_msat) ) ;
1728
1692
invoice_payer. handle_event ( Event :: PaymentPathFailed {
1729
1693
payment_id,
1730
1694
payment_hash,
@@ -1737,6 +1701,7 @@ mod tests {
1737
1701
} ) ;
1738
1702
1739
1703
// Fails again the 1st path of our retry
1704
+ invoice_payer. payer . fail_path ( & TestRouter :: path_for_value ( final_value_msat / 2 ) ) ;
1740
1705
invoice_payer. handle_event ( Event :: PaymentPathFailed {
1741
1706
payment_id,
1742
1707
payment_hash,
@@ -1752,67 +1717,6 @@ mod tests {
1752
1717
} ) ;
1753
1718
}
1754
1719
1755
- #[ test]
1756
- fn accounts_for_some_inflight_htlcs_sent_during_partial_failure ( ) {
1757
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
1758
- let event_handler = |_: Event | { * event_handled. borrow_mut ( ) = true ; } ;
1759
-
1760
- let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
1761
- let invoice_to_pay = invoice ( payment_preimage) ;
1762
- let final_value_msat = invoice_to_pay. amount_milli_satoshis ( ) . unwrap ( ) ;
1763
-
1764
- let retry = TestRouter :: retry_for_invoice ( & invoice_to_pay) ;
1765
- let payer = TestPayer :: new ( )
1766
- . fails_with_partial_failure (
1767
- retry. clone ( ) , OnAttempt ( 1 ) ,
1768
- Some ( vec ! [
1769
- Err ( ChannelUnavailable { err: "abc" . to_string( ) } ) , Err ( MonitorUpdateInProgress )
1770
- ] ) )
1771
- . expect_send ( Amount :: ForInvoice ( final_value_msat) ) ;
1772
-
1773
- let router = TestRouter :: new ( TestScorer :: new ( ) ) ;
1774
- let logger = TestLogger :: new ( ) ;
1775
- let invoice_payer =
1776
- InvoicePayer :: new ( & payer, router, & logger, event_handler, Retry :: Attempts ( 0 ) ) ;
1777
-
1778
- invoice_payer. pay_invoice ( & invoice_to_pay) . unwrap ( ) ;
1779
- let inflight_map = invoice_payer. create_inflight_map ( ) ;
1780
-
1781
- // Only the second path, which failed with `MonitorUpdateInProgress` should be added to our
1782
- // inflight map because retries are disabled.
1783
- assert_eq ! ( inflight_map. 0 . len( ) , 2 ) ;
1784
- }
1785
-
1786
- #[ test]
1787
- fn accounts_for_all_inflight_htlcs_sent_during_partial_failure ( ) {
1788
- let event_handled = core:: cell:: RefCell :: new ( false ) ;
1789
- let event_handler = |_: Event | { * event_handled. borrow_mut ( ) = true ; } ;
1790
-
1791
- let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
1792
- let invoice_to_pay = invoice ( payment_preimage) ;
1793
- let final_value_msat = invoice_to_pay. amount_milli_satoshis ( ) . unwrap ( ) ;
1794
-
1795
- let retry = TestRouter :: retry_for_invoice ( & invoice_to_pay) ;
1796
- let payer = TestPayer :: new ( )
1797
- . fails_with_partial_failure (
1798
- retry. clone ( ) , OnAttempt ( 1 ) ,
1799
- Some ( vec ! [
1800
- Ok ( ( ) ) , Err ( MonitorUpdateInProgress )
1801
- ] ) )
1802
- . expect_send ( Amount :: ForInvoice ( final_value_msat) ) ;
1803
-
1804
- let router = TestRouter :: new ( TestScorer :: new ( ) ) ;
1805
- let logger = TestLogger :: new ( ) ;
1806
- let invoice_payer =
1807
- InvoicePayer :: new ( & payer, router, & logger, event_handler, Retry :: Attempts ( 0 ) ) ;
1808
-
1809
- invoice_payer. pay_invoice ( & invoice_to_pay) . unwrap ( ) ;
1810
- let inflight_map = invoice_payer. create_inflight_map ( ) ;
1811
-
1812
- // All paths successful, hence we check of the existence of all 5 hops.
1813
- assert_eq ! ( inflight_map. 0 . len( ) , 5 ) ;
1814
- }
1815
-
1816
1720
struct TestRouter {
1817
1721
scorer : RefCell < TestScorer > ,
1818
1722
}
@@ -2100,6 +2004,7 @@ mod tests {
2100
2004
expectations : core:: cell:: RefCell < VecDeque < Amount > > ,
2101
2005
attempts : core:: cell:: RefCell < usize > ,
2102
2006
failing_on_attempt : core:: cell:: RefCell < HashMap < usize , PaymentSendFailure > > ,
2007
+ inflight_htlcs_paths : core:: cell:: RefCell < Vec < Vec < RouteHop > > > ,
2103
2008
}
2104
2009
2105
2010
#[ derive( Clone , Debug , PartialEq , Eq ) ]
@@ -2117,6 +2022,7 @@ mod tests {
2117
2022
expectations : core:: cell:: RefCell :: new ( VecDeque :: new ( ) ) ,
2118
2023
attempts : core:: cell:: RefCell :: new ( 0 ) ,
2119
2024
failing_on_attempt : core:: cell:: RefCell :: new ( HashMap :: new ( ) ) ,
2025
+ inflight_htlcs_paths : core:: cell:: RefCell :: new ( Vec :: new ( ) ) ,
2120
2026
}
2121
2027
}
2122
2028
@@ -2161,6 +2067,18 @@ mod tests {
2161
2067
panic ! ( "Unexpected amount: {:?}" , actual_value_msats) ;
2162
2068
}
2163
2069
}
2070
+
2071
+ fn process_route ( & self , route : & Route ) {
2072
+ for path in & route. paths {
2073
+ self . inflight_htlcs_paths . borrow_mut ( ) . push ( path. clone ( ) ) ;
2074
+ }
2075
+ }
2076
+
2077
+ fn fail_path ( & self , path : & Vec < RouteHop > ) {
2078
+ if let Some ( idx) = self . inflight_htlcs_paths . clone ( ) . into_inner ( ) . iter ( ) . position ( |p| p == path) {
2079
+ self . inflight_htlcs_paths . borrow_mut ( ) . swap_remove ( idx) ;
2080
+ }
2081
+ }
2164
2082
}
2165
2083
2166
2084
impl Drop for TestPayer {
@@ -2190,6 +2108,7 @@ mod tests {
2190
2108
_payment_secret : & Option < PaymentSecret > , _payment_id : PaymentId ,
2191
2109
) -> Result < ( ) , PaymentSendFailure > {
2192
2110
self . check_value_msats ( Amount :: ForInvoice ( route. get_total_amount ( ) ) ) ;
2111
+ self . process_route ( route) ;
2193
2112
self . check_attempts ( )
2194
2113
}
2195
2114
@@ -2204,10 +2123,19 @@ mod tests {
2204
2123
& self , route : & Route , _payment_id : PaymentId
2205
2124
) -> Result < ( ) , PaymentSendFailure > {
2206
2125
self . check_value_msats ( Amount :: OnRetry ( route. get_total_amount ( ) ) ) ;
2126
+ self . process_route ( route) ;
2207
2127
self . check_attempts ( )
2208
2128
}
2209
2129
2210
2130
fn abandon_payment ( & self , _payment_id : PaymentId ) { }
2131
+
2132
+ fn inflight_htlcs ( & self ) -> InFlightHtlcs {
2133
+ let mut inflight_htlcs = InFlightHtlcs :: new ( ) ;
2134
+ for path in self . inflight_htlcs_paths . clone ( ) . into_inner ( ) {
2135
+ inflight_htlcs. process_path ( & path, self . node_id ( ) ) ;
2136
+ }
2137
+ inflight_htlcs
2138
+ }
2211
2139
}
2212
2140
2213
2141
// *** Full Featured Functional Tests with a Real ChannelManager ***
0 commit comments