@@ -129,7 +129,31 @@ impl Readable for Route {
129129 }
130130}
131131
132+ /// Parameters needed to re-compute a [`Route`] for retrying a failed payment path.
133+ ///
134+ /// Provided in [`Event::PaymentPathFailed`] and passed to [`get_retry_route`].
135+ ///
136+ /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
137+ #[ derive( Clone , Debug ) ]
138+ pub struct PaymentPathRetry {
139+ /// The recipient of the failed payment path.
140+ pub payee : Payee ,
141+
142+ /// The amount in msats sent on the failed payment path.
143+ pub final_value_msat : u64 ,
144+
145+ /// The CLTV on the final hop of the failed payment path.
146+ pub final_cltv_expiry_delta : u32 ,
147+ }
148+
149+ impl_writeable_tlv_based ! ( PaymentPathRetry , {
150+ ( 0 , payee, required) ,
151+ ( 2 , final_value_msat, required) ,
152+ ( 4 , final_cltv_expiry_delta, required) ,
153+ } ) ;
154+
132155/// The recipient of a payment.
156+ #[ derive( Clone , Debug ) ]
133157pub struct Payee {
134158 /// The node id of the payee.
135159 pubkey : PublicKey ,
@@ -146,6 +170,12 @@ pub struct Payee {
146170 pub route_hints : Vec < RouteHint > ,
147171}
148172
173+ impl_writeable_tlv_based ! ( Payee , {
174+ ( 0 , pubkey, required) ,
175+ ( 2 , features, option) ,
176+ ( 4 , route_hints, vec_type) ,
177+ } ) ;
178+
149179impl Payee {
150180 /// Creates a payee with the node id of the given `pubkey`.
151181 pub fn new ( pubkey : PublicKey ) -> Self {
@@ -180,6 +210,28 @@ impl Payee {
180210#[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
181211pub struct RouteHint ( pub Vec < RouteHintHop > ) ;
182212
213+
214+ impl Writeable for RouteHint {
215+ fn write < W : :: util:: ser:: Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
216+ ( self . 0 . len ( ) as u64 ) . write ( writer) ?;
217+ for hop in self . 0 . iter ( ) {
218+ hop. write ( writer) ?;
219+ }
220+ Ok ( ( ) )
221+ }
222+ }
223+
224+ impl Readable for RouteHint {
225+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
226+ let hop_count: u64 = Readable :: read ( reader) ?;
227+ let mut hops = Vec :: with_capacity ( cmp:: min ( hop_count, 16 ) as usize ) ;
228+ for _ in 0 ..hop_count {
229+ hops. push ( Readable :: read ( reader) ?) ;
230+ }
231+ Ok ( Self ( hops) )
232+ }
233+ }
234+
183235/// A channel descriptor for a hop along a payment path.
184236#[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
185237pub struct RouteHintHop {
@@ -197,6 +249,15 @@ pub struct RouteHintHop {
197249 pub htlc_maximum_msat : Option < u64 > ,
198250}
199251
252+ impl_writeable_tlv_based ! ( RouteHintHop , {
253+ ( 0 , src_node_id, required) ,
254+ ( 1 , htlc_minimum_msat, option) ,
255+ ( 2 , short_channel_id, required) ,
256+ ( 3 , htlc_maximum_msat, option) ,
257+ ( 4 , fees, required) ,
258+ ( 6 , cltv_expiry_delta, required) ,
259+ } ) ;
260+
200261#[ derive( Eq , PartialEq ) ]
201262struct RouteGraphNode {
202263 node_id : NodeId ,
@@ -413,13 +474,31 @@ fn compute_fees(amount_msat: u64, channel_fees: RoutingFees) -> Option<u64> {
413474pub fn get_keysend_route < L : Deref , S : routing:: Score > (
414475 our_node_pubkey : & PublicKey , network : & NetworkGraph , payee : & PublicKey ,
415476 first_hops : Option < & [ & ChannelDetails ] > , last_hops : & [ & RouteHint ] , final_value_msat : u64 ,
416- final_cltv : u32 , logger : L , scorer : & S
477+ final_cltv_expiry_delta : u32 , logger : L , scorer : & S
417478) -> Result < Route , LightningError >
418479where L :: Target : Logger {
419480 let route_hints = last_hops. iter ( ) . map ( |hint| ( * hint) . clone ( ) ) . collect ( ) ;
420481 let payee = Payee :: for_keysend ( * payee) . with_route_hints ( route_hints) ;
421482 get_route (
422- our_node_pubkey, & payee, network, first_hops, final_value_msat, final_cltv, logger, scorer
483+ our_node_pubkey, & payee, network, first_hops, final_value_msat, final_cltv_expiry_delta,
484+ logger, scorer
485+ )
486+ }
487+
488+ /// Gets a route suitable for retrying a failed payment path.
489+ ///
490+ /// Used to re-compute a [`Route`] when handling a [`Event::PaymentPathFailed`]. Any adjustments to
491+ /// the [`NetworkGraph`] and channel scores should be made prior to calling this function.
492+ ///
493+ /// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
494+ pub fn get_retry_route < L : Deref , S : routing:: Score > (
495+ our_node_pubkey : & PublicKey , retry : & PaymentPathRetry , network : & NetworkGraph ,
496+ first_hops : Option < & [ & ChannelDetails ] > , logger : L , scorer : & S
497+ ) -> Result < Route , LightningError >
498+ where L :: Target : Logger {
499+ get_route (
500+ our_node_pubkey, & retry. payee , network, first_hops, retry. final_value_msat ,
501+ retry. final_cltv_expiry_delta , logger, scorer
423502 )
424503}
425504
@@ -443,8 +522,8 @@ where L::Target: Logger {
443522/// htlc_minimum_msat/htlc_maximum_msat *are* checked as they may change based on the receiving node.
444523pub fn get_route < L : Deref , S : routing:: Score > (
445524 our_node_pubkey : & PublicKey , payee : & Payee , network : & NetworkGraph ,
446- first_hops : Option < & [ & ChannelDetails ] > , final_value_msat : u64 , final_cltv : u32 , logger : L ,
447- scorer : & S
525+ first_hops : Option < & [ & ChannelDetails ] > , final_value_msat : u64 , final_cltv_expiry_delta : u32 ,
526+ logger : L , scorer : & S
448527) -> Result < Route , LightningError >
449528where L :: Target : Logger {
450529 let payee_node_id = NodeId :: from_pubkey ( & payee. pubkey ) ;
@@ -1154,7 +1233,7 @@ where L::Target: Logger {
11541233 }
11551234 ordered_hops. last_mut ( ) . unwrap ( ) . 0 . fee_msat = value_contribution_msat;
11561235 ordered_hops. last_mut ( ) . unwrap ( ) . 0 . hop_use_fee_msat = 0 ;
1157- ordered_hops. last_mut ( ) . unwrap ( ) . 0 . cltv_expiry_delta = final_cltv ;
1236+ ordered_hops. last_mut ( ) . unwrap ( ) . 0 . cltv_expiry_delta = final_cltv_expiry_delta ;
11581237
11591238 log_trace ! ( logger, "Found a path back to us from the target with {} hops contributing up to {} msat: {:?}" ,
11601239 ordered_hops. len( ) , value_contribution_msat, ordered_hops) ;
0 commit comments