mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-03-14 07:06:42 +01:00
Add direct hops to intros after all blinded paths in pathfinding
When we do pathfinding with blinded paths, we start each pathfinding iteration by inserting all the blinded paths into our nodes map as last-hops to the destination. As we do that, we check if any of the introduction points happen to be nodes we have direct chanels with, as we want to use the local info for such channels and support finding a path even if that channel is not publicly announced. However, as we iterate the blinded paths, we may find a second blinded path from the same introduction point which we prefer over the first. If this happens, we would already have added info from us over the local channel to that intro point and end up with calculations for the first hop to a blinded path that we no longer prefer. This is ultimately fixed here in two ways: (a) we process the first-hop channels to blinded path introduction points in a separate loop after we've processed all blinded paths, ensuring we only ever consider a channel to the blinded path we will ultimately prefer. (b) In the next commit, we add we add a new tracking bool in `PathBuildingHop` called `best_path_from_hop_selected` which we set when we process a channel backwards from a node, indicating that we've committed to the best path to the node and check when we add a new path to a node. This would have resulted in a much earlier debug-assertion in fuzzing or several tests.
This commit is contained in:
parent
0351a24722
commit
b2c635b8e0
1 changed files with 13 additions and 3 deletions
|
@ -2937,6 +2937,7 @@ where L::Target: Logger {
|
|||
introduction_node_id_cache.len(),
|
||||
"introduction_node_id_cache was built by iterating the blinded_route_hints, so they should be the same len"
|
||||
);
|
||||
let mut blind_intros_added = hash_map_with_capacity(payment_params.payee.blinded_route_hints().len());
|
||||
for (hint_idx, hint) in payment_params.payee.blinded_route_hints().iter().enumerate() {
|
||||
// Only add the hops in this route to our candidate set if either
|
||||
// we have a direct channel to the first hop or the first hop is
|
||||
|
@ -2951,12 +2952,21 @@ where L::Target: Logger {
|
|||
} else {
|
||||
CandidateRouteHop::Blinded(BlindedPathCandidate { source_node_counter, source_node_id, hint, hint_idx })
|
||||
};
|
||||
let mut path_contribution_msat = path_value_msat;
|
||||
if let Some(hop_used_msat) = add_entry!(&candidate,
|
||||
0, path_contribution_msat, 0, 0_u64, 0, 0)
|
||||
0, path_value_msat, 0, 0_u64, 0, 0)
|
||||
{
|
||||
path_contribution_msat = hop_used_msat;
|
||||
blind_intros_added.insert(source_node_id, (hop_used_msat, candidate));
|
||||
} else { continue }
|
||||
}
|
||||
// If we added a blinded path from an introduction node to the destination, where the
|
||||
// introduction node is one of our direct peers, we need to scan our `first_channels`
|
||||
// to detect this. However, doing so immediately after calling `add_entry`, above, could
|
||||
// result in incorrect behavior if we, in a later loop iteration, update the fee from the
|
||||
// same introduction point to the destination (due to a different blinded path with the
|
||||
// same introduction point having a lower score).
|
||||
// Thus, we track the nodes that we added paths from in `blind_intros_added` and scan for
|
||||
// introduction points we have a channel with after processing all blinded paths.
|
||||
for (source_node_id, (path_contribution_msat, candidate)) in blind_intros_added {
|
||||
if let Some((first_channels, peer_node_counter)) = first_hop_targets.get_mut(source_node_id) {
|
||||
sort_first_hop_channels(
|
||||
first_channels, &used_liquidities, recommended_value_msat, our_node_pubkey
|
||||
|
|
Loading…
Add table
Reference in a new issue