X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Frouting%2Frouter.rs;h=9c5fe8e1f9bd3dab59033644591a4a59b49d173b;hb=b5e959460f1473022321c8b8868fb0f7da6906b5;hp=799b6407981341b0bc4fbfae0f387bdbe23186ad;hpb=266a3aa9152e9d50570ae41b3be1548a715d0754;p=rust-lightning diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 799b6407..9c5fe8e1 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -337,23 +337,34 @@ pub struct Route { /// [`BlindedTail`]s are present, then the pubkey of the last [`RouteHop`] in each path must be /// the same. pub paths: Vec, - /// The `payment_params` parameter passed via [`RouteParameters`] to [`find_route`]. + /// The `route_params` parameter passed to [`find_route`]. /// /// This is used by `ChannelManager` to track information which may be required for retries. - pub payment_params: Option, + /// + /// Will be `None` for objects serialized with LDK versions prior to 0.0.117. + pub route_params: Option, } impl Route { /// Returns the total amount of fees paid on this [`Route`]. /// - /// This doesn't include any extra payment made to the recipient, which can happen in excess of - /// the amount passed to [`find_route`]'s `route_params.final_value_msat`. + /// For objects serialized with LDK 0.0.117 and after, this includes any extra payment made to + /// the recipient, which can happen in excess of the amount passed to [`find_route`] via + /// [`RouteParameters::final_value_msat`], if we had to reach the [`htlc_minimum_msat`] limits. + /// + /// [`htlc_minimum_msat`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_update-message pub fn get_total_fees(&self) -> u64 { - self.paths.iter().map(|path| path.fee_msat()).sum() + let overpaid_value_msat = self.route_params.as_ref() + .map_or(0, |p| self.get_total_amount().saturating_sub(p.final_value_msat)); + overpaid_value_msat + self.paths.iter().map(|path| path.fee_msat()).sum::() } - /// Returns the total amount paid on this [`Route`], excluding the fees. Might be more than - /// requested if we had to reach htlc_minimum_msat. + /// Returns the total amount paid on this [`Route`], excluding the fees. + /// + /// Might be more than requested as part of the given [`RouteParameters::final_value_msat`] if + /// we had to reach the [`htlc_minimum_msat`] limits. + /// + /// [`htlc_minimum_msat`]: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-channel_update-message pub fn get_total_amount(&self) -> u64 { self.paths.iter().map(|path| path.final_value_msat()).sum() } @@ -383,8 +394,11 @@ impl Writeable for Route { } } write_tlv_fields!(writer, { - (1, self.payment_params, option), + // For compatibility with LDK versions prior to 0.0.117, we take the individual + // RouteParameters' fields and reconstruct them on read. + (1, self.route_params.as_ref().map(|p| &p.payment_params), option), (2, blinded_tails, optional_vec), + (3, self.route_params.as_ref().map(|p| p.final_value_msat), option), }); Ok(()) } @@ -411,6 +425,7 @@ impl Readable for Route { _init_and_read_len_prefixed_tlv_fields!(reader, { (1, payment_params, (option: ReadableArgs, min_final_cltv_expiry_delta)), (2, blinded_tails, optional_vec), + (3, final_value_msat, option), }); let blinded_tails = blinded_tails.unwrap_or(Vec::new()); if blinded_tails.len() != 0 { @@ -419,14 +434,23 @@ impl Readable for Route { path.blinded_tail = blinded_tail_opt; } } - Ok(Route { paths, payment_params }) + + // If we previously wrote the corresponding fields, reconstruct RouteParameters. + let route_params = match (payment_params, final_value_msat) { + (Some(payment_params), Some(final_value_msat)) => { + Some(RouteParameters { payment_params, final_value_msat }) + } + _ => None, + }; + + Ok(Route { paths, route_params }) } } /// Parameters needed to find a [`Route`]. /// /// Passed to [`find_route`] and [`build_route_from_hops`]. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct RouteParameters { /// The parameters of the failed payment path. pub payment_params: PaymentParameters, @@ -2489,7 +2513,7 @@ where L::Target: Logger { } } - let route = Route { paths, payment_params: Some(payment_params.clone()) }; + let route = Route { paths, route_params: Some(route_params.clone()) }; log_info!(logger, "Got route: {}", log_route!(route)); Ok(route) } @@ -5953,7 +5977,7 @@ mod tests { short_channel_id: 0, fee_msat: 225, cltv_expiry_delta: 0 }, ], blinded_tail: None }], - payment_params: None, + route_params: None, }; assert_eq!(route.get_total_fees(), 250); @@ -5986,7 +6010,7 @@ mod tests { short_channel_id: 0, fee_msat: 150, cltv_expiry_delta: 0 }, ], blinded_tail: None }], - payment_params: None, + route_params: None, }; assert_eq!(route.get_total_fees(), 200); @@ -5998,7 +6022,7 @@ mod tests { // In an earlier version of `Route::get_total_fees` and `Route::get_total_amount`, they // would both panic if the route was completely empty. We test to ensure they return 0 // here, even though its somewhat nonsensical as a route. - let route = Route { paths: Vec::new(), payment_params: None }; + let route = Route { paths: Vec::new(), route_params: None }; assert_eq!(route.get_total_fees(), 0); assert_eq!(route.get_total_amount(), 0); @@ -6597,7 +6621,7 @@ mod tests { fee_msat: 100, cltv_expiry_delta: 0, }], blinded_tail: None }], - payment_params: None, + route_params: None, }; let encoded_route = route.encode(); let decoded_route: Route = Readable::read(&mut Cursor::new(&encoded_route[..])).unwrap(); @@ -6691,7 +6715,7 @@ mod tests { excess_final_cltv_expiry_delta: 0, final_value_msat: 200, }), - }], payment_params: None}; + }], route_params: None}; let payment_params = PaymentParameters::from_node_id(ln_test_utils::pubkey(47), 18); let (_, network_graph, _, _, _) = build_line_graph();