This addresses Val's feedback on the new Route fee- and
amount-calculation methods, including fixing the panic she
identified and cleaning up various docs and comments.
* Added `get_total_fees` method to route,
to calculate all the fees paid accross each path.
* Added `get_total_amount` method to route,
to calculate the total of actual amounts paid in each path.
PaymentFailed events contain an optional NetworkUpdate describing
changes to the NetworkGraph as conveyed by a node along a failed payment
path according to BOLT 4. An EventHandler should apply the update to the
graph so that future routing decisions can account for it.
Implement EventHandler for NetGraphMsgHandler to update NetworkGraph.
Previously, NetGraphMsgHandler::handle_htlc_fail_channel_update
implemented this behavior.
Now that NetworkGraph uses interior mutability, the RwLock used around
it in NetGraphMsgHandler is no longer needed. This allows for shared
ownership without a lock.
In preparation for giving NetworkGraph shared ownership, wrap individual
fields in RwLock. This allows removing the outer RwLock used in
NetGraphMsgHandler.
Bolt 12 details the process of picking up route hints from payee
using the lightning invoice. This PR brings the changes to use
multiple route hints from payee picked from the invoice.
The route hints are processed in the following manner:-
- `get_route()` receives the hints in `last_hops`.
- Every `RouteHintHop` in `RouteHint` is processed based on
feasiblity of channel capacity and fees.
- If a `RouteHintHop` then preceeding `RouteHintHop`s are not
processed.
- A direct route is checked from `first_hops_targets` to the
first `RouteHintHop` if the respective `RouteHint` is
processed from the payee's end till the first `RouteHintHop`.
`partial_route_hint_test`, `ignores_empty_last_hops_test`,
`multi_hint_last_hops_test` and `last_hops_with_public_channel_test`
test usage of partial route hints for building optimal route,
processing empty route hint hops, complete usage of private route
hints and presence of public channels in route hints respectively.
Resolves: #945
After the merge of #984, Jeff pointed out that `ChannelDetails` has
become a bit of a "bag of variables", and that a few of the variable
names in #984 were more confusing than necessary in context.
This addresses several issues by:
* Splitting counterparty parameters into a separate
`ChannelCounterpartyParameters` struct,
* using the name `unspendable_punishment_reserve` for both outbound
and inbound channel reserves, differentiating them based on their
position in the counterparty parameters struct or not,
* Using the name `force_close_spend_delay` instead of
`spend_csv_on_our_commitment_funds` to better communicate what
is occurring.
This adds four new fields in `ChannelDetails`:
1. holder_selected_ and counterparty_selected_channel_reserve_delay
are useful to determine what amount of the channel is
unavailable for payments.
2. confirmations_required is useful when awaiting funding
confirmation to determine how long you will need to wait.
3. to_self_delay is useful to determine how long it will take to
receive funds after a force-close.
Fixes#983.
Previous to this PR, TLV serialization involved iterating from 0 to the highest
given TLV type. This worked until we decided to implement keysend, which has a
TLV type of ~5.48 billion.
So instead, we now specify the type of whatever is being (de)serialized (which
can be an Option, a Vec type, or a non-Option (specified in the serialization macros as "required").
Lightning invoices allow for zero or more multi-hop route hints. Update
get_route's interface to accept such hints, although only the last hop
from each is used for the time being.
Moves RouteHint from lightning-invoice crate to lightning crate. Adds a
PrivateRoute wrapper around RouteHint for use in lightning-invoice.
NetworkGraph is one of the largest structures we generally
deserialize, so it makes for a good benchmark, even if it isn't the
most complicated one.
As of this commit, on an Intel 2687W v3, these benchmarks take:
test routing::network_graph::benches::read_network_graph ... bench: 2,101,420,078 ns/iter (+/- 6,649,020)
test routing::network_graph::benches::write_network_graph ... bench: 344,696,835 ns/iter (+/- 229,061)
We currently copy the features objects in each channel as we walk
the graph during route calculation. This implies a significant
amount of malloc traffic as the features flags object are stored
on the heap.
Instead, because they features being referenced are in the network
graph which we hold a reference to, we can simply store references
to them.
This nontrivially improves our get_route benchmark by around 5%.
While walking the graph doing Dijkstra's, we may decrease the
amount being sent along one path, and not others, based on the
htlc_minimum_msat value. This may result in a lower relative fees
on that path in comparison to others. In the extreme, this may
result in finding a second path to a node with a lower fee than the
first path found (normally impossible in a Dijkstra's
implementation, as we walk next hops in fee-order).
In such a case, we end up with parts of our state invalid as
further hops beyond that node have been filled in using the
original total fee information.
Instead, we simply track which nodes have been processed and ignore
and further updates to them (as it implies we've reduced the amount
we're sending to find a lower absolute fee, but a higher relative
fee, which isn't a better route).
We check that we are in exactly this case in test builds with new
in-line assertions. Note that these assertions successfully detect
the bug in the previous commit.
Sadly this requires an extra HashMap lookup every time we pop an
element off of our heap, though we can skip a number of heap pushes
during the channel walking.