Skip to content

Commit 5a7f0cc

Browse files
committed
Make helper function for creating inflight htlc map
1 parent ce81fdf commit 5a7f0cc

File tree

1 file changed

+52
-76
lines changed

1 file changed

+52
-76
lines changed

lightning-invoice/src/payment.rs

Lines changed: 52 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -495,43 +495,7 @@ where
495495

496496
let payer = self.payer.node_id();
497497
let first_hops = self.payer.first_hops();
498-
let inflight_htlcs = {
499-
// Make an attempt at finding existing payment information from `payment_cache`. If it
500-
// does not exist, it probably is a fresh payment and we can just return an empty
501-
// HashMap.
502-
if let Some(payment_info) = self.payment_cache.lock().unwrap().get(&payment_hash) {
503-
let mut total_inflight_map: HashMap<(u64, bool), u64> = HashMap::new();
504-
505-
for path in &payment_info.paths {
506-
if path.is_empty() { break };
507-
// total_inflight_map needs to be direction-sensitive when keeping track of the HTLC value
508-
// that is held up. However, the `hops` array, which is a path returned by `find_route` in
509-
// the router excludes the payer node. In the following lines, the payer's information is
510-
// hardcoded with an inflight value of 0 so that we can correctly represent the first hop
511-
// in our sliding window of two.
512-
let our_node_id: PublicKey = self.payer.node_id();
513-
let reversed_hops_with_payer = core::iter::once((0u64, our_node_id)).chain(
514-
path.split_last().unwrap().1.iter().map(|hop| (hop.fee_msat, hop.pubkey))).rev();
515-
let mut cumulative_msat = path.last().unwrap().fee_msat;
516-
517-
// Taking the reversed vector from above, we zip it with just the reversed hops list to
518-
// work "backwards" of the given path, since the last hop's `fee_msat` actually represents
519-
// the total amount sent.
520-
for (next_hop, prev_hop) in path.iter().rev().zip(reversed_hops_with_payer) {
521-
cumulative_msat += prev_hop.0;
522-
total_inflight_map
523-
.entry((next_hop.short_channel_id, next_hop.pubkey < prev_hop.1))
524-
.and_modify(|used_liquidity_msat| *used_liquidity_msat += cumulative_msat)
525-
.or_insert(cumulative_msat);
526-
}
527-
}
528-
529-
total_inflight_map
530-
} else {
531-
HashMap::new()
532-
}
533-
};
534-
498+
let inflight_htlcs = self.create_inflight_map(&payment_hash);
535499
let route = self.router.find_route(
536500
&payer, &params, &payment_hash, Some(&first_hops.iter().collect::<Vec<_>>()),
537501
&AccountForInFlightHtlcs { scorer: &mut self.scorer.lock(), inflight_htlcs }
@@ -631,7 +595,13 @@ where
631595
) -> Result<(), ()> {
632596
let attempts = self.payment_cache.lock().unwrap().entry(payment_hash)
633597
.and_modify(|info| info.attempts.count += 1 )
634-
.or_insert({ PaymentInfo::new() }).attempts;
598+
.or_insert(PaymentInfo {
599+
attempts: PaymentAttempts {
600+
count: 1,
601+
first_attempted_at: T::now(),
602+
},
603+
paths: vec![],
604+
}).attempts;
635605

636606
if !self.retry.is_retryable_now(&attempts) {
637607
log_trace!(self.logger, "Payment {} exceeded maximum attempts; not retrying ({})", log_bytes!(payment_hash.0), attempts);
@@ -647,42 +617,7 @@ where
647617

648618
let payer = self.payer.node_id();
649619
let first_hops = self.payer.first_hops();
650-
let inflight_htlcs = {
651-
// Make an attempt at finding existing payment information from `payment_cache`. If it
652-
// does not exist, it probably is a fresh payment and we can just return an empty
653-
// HashMap.
654-
if let Some(payment_info) = self.payment_cache.lock().unwrap().get(&payment_hash) {
655-
let mut total_inflight_map: HashMap<(u64, bool), u64> = HashMap::new();
656-
657-
for hops in &payment_info.paths {
658-
if hops.len() < 1 { break };
659-
// total_inflight_map needs to be direction-sensitive when keeping track of the HTLC value
660-
// that is held up. However, the `hops` array, which is a path returned by `find_route` in
661-
// the router excludes the payer node. In the following lines, the payer's information is
662-
// hardcoded with an inflight value of 0 so that we can correctly represent the first hop
663-
// in our sliding window of two.
664-
let our_node_id: PublicKey = self.payer.node_id();
665-
let reversed_hops_with_payer = core::iter::once((0u64, our_node_id)).chain(
666-
hops.split_last().unwrap().1.iter().map(|hop| (hop.fee_msat, hop.pubkey))).rev();
667-
let mut cumulative_msat = hops.last().unwrap().fee_msat;
668-
669-
// Taking the reversed vector from above, we zip it with just the reversed hops list to
670-
// work "backwards" of the given path, since the last hop's `fee_msat` actually represents
671-
// the total amount sent.
672-
for (next_hop, prev_hop) in hops.iter().rev().zip(reversed_hops_with_payer) {
673-
cumulative_msat += prev_hop.0;
674-
total_inflight_map
675-
.entry((next_hop.short_channel_id, next_hop.pubkey < prev_hop.1))
676-
.and_modify(|used_liquidity_msat| *used_liquidity_msat += cumulative_msat)
677-
.or_insert(cumulative_msat);
678-
}
679-
}
680-
681-
total_inflight_map
682-
} else {
683-
HashMap::new()
684-
}
685-
};
620+
let inflight_htlcs = self.create_inflight_map(&payment_hash);
686621

687622
let route = {
688623
let scorer = AccountForInFlightHtlcs { scorer: &mut self.scorer.lock(), inflight_htlcs };
@@ -693,13 +628,11 @@ where
693628
)
694629
};
695630

696-
697631
if route.is_err() {
698632
log_trace!(self.logger, "Failed to find a route for payment {}; not retrying ({:})", log_bytes!(payment_hash.0), attempts);
699633
return Err(());
700634
}
701635

702-
703636
match self.payer.retry_payment(&route.unwrap(), payment_id) {
704637
Ok(()) => Ok(()),
705638
Err(PaymentSendFailure::ParameterError(_)) |
@@ -727,6 +660,49 @@ where
727660
pub fn remove_cached_payment(&self, payment_hash: &PaymentHash) {
728661
self.payment_cache.lock().unwrap().remove(payment_hash);
729662
}
663+
664+
/// Given a [`PaymentHash`], this function looks up inflight path attempts in the payment_cache.
665+
/// Then, it uses the path information inside the cache to construct a HashMap mapping a channel's
666+
/// short channel id and direction to the amount being sent through it.
667+
///
668+
/// This function should be called whenever we need information about currently used up liquidity
669+
/// across payments.
670+
pub fn create_inflight_map(&self, payment_hash: &PaymentHash) -> HashMap<(u64, bool), u64> {
671+
// Make an attempt at finding existing payment information from `payment_cache`. If it
672+
// does not exist, it probably is a fresh payment and we can just return an empty
673+
// HashMap.
674+
if let Some(payment_info) = self.payment_cache.lock().unwrap().get(&payment_hash) {
675+
let mut total_inflight_map: HashMap<(u64, bool), u64> = HashMap::new();
676+
677+
for path in &payment_info.paths {
678+
if path.is_empty() { break };
679+
// total_inflight_map needs to be direction-sensitive when keeping track of the HTLC value
680+
// that is held up. However, the `hops` array, which is a path returned by `find_route` in
681+
// the router excludes the payer node. In the following lines, the payer's information is
682+
// hardcoded with an inflight value of 0 so that we can correctly represent the first hop
683+
// in our sliding window of two.
684+
let our_node_id: PublicKey = self.payer.node_id();
685+
let reversed_hops_with_payer = core::iter::once((0u64, our_node_id)).chain(
686+
path.split_last().unwrap().1.iter().map(|hop| (hop.fee_msat, hop.pubkey))).rev();
687+
let mut cumulative_msat = path.last().unwrap().fee_msat;
688+
689+
// Taking the reversed vector from above, we zip it with just the reversed hops list to
690+
// work "backwards" of the given path, since the last hop's `fee_msat` actually represents
691+
// the total amount sent.
692+
for (next_hop, prev_hop) in path.iter().rev().zip(reversed_hops_with_payer) {
693+
cumulative_msat += prev_hop.0;
694+
total_inflight_map
695+
.entry((next_hop.short_channel_id, next_hop.pubkey < prev_hop.1))
696+
.and_modify(|used_liquidity_msat| *used_liquidity_msat += cumulative_msat)
697+
.or_insert(cumulative_msat);
698+
}
699+
}
700+
701+
return total_inflight_map
702+
} else {
703+
return HashMap::new()
704+
}
705+
}
730706
}
731707

732708
fn expiry_time_from_unix_epoch(invoice: &Invoice) -> Duration {

0 commit comments

Comments
 (0)