Skip to content

Commit fa64750

Browse files
ZmnSCPxjcdecker
authored andcommitted
plugins/libplugin-pay.c: Be less aggressive with advancing through routehints.
Only advance through routehints if no route was found at all, or if the estimated capacity at the routehint is lower than the amount that we have to send through the routehint. Changelog-Fixed: pay: Be less aggressive with forgetting routehints.
1 parent 9b5977f commit fa64750

File tree

1 file changed

+52
-4
lines changed

1 file changed

+52
-4
lines changed

plugins/libplugin-pay.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@ static struct command_result *payment_getroute_result(struct command *cmd,
384384
/* Ensure that our fee and CLTV budgets are respected. */
385385
if (amount_msat_greater(fee, p->constraints.fee_budget)) {
386386
payment_exclude_most_expensive(p);
387+
p->route = tal_free(p->route);
387388
payment_fail(
388389
p, "Fee exceeds our fee budget: %s > %s, discarding route",
389390
type_to_string(tmpctx, struct amount_msat, &fee),
@@ -393,9 +394,11 @@ static struct command_result *payment_getroute_result(struct command *cmd,
393394
}
394395

395396
if (p->route[0].delay > p->constraints.cltv_budget) {
397+
u32 delay = p->route[0].delay;
396398
payment_exclude_longest_delay(p);
399+
p->route = tal_free(p->route);
397400
payment_fail(p, "CLTV delay exceeds our CLTV budget: %d > %d",
398-
p->route[0].delay, p->constraints.cltv_budget);
401+
delay, p->constraints.cltv_budget);
399402
return command_still_pending(cmd);
400403
}
401404

@@ -1764,12 +1767,17 @@ static struct route_info **filter_routehints(struct routehints_data *d,
17641767
return tal_steal(d, hints);
17651768
}
17661769

1770+
static bool route_msatoshi(struct amount_msat *total,
1771+
const struct amount_msat msat,
1772+
const struct route_info *route, size_t num_route);
1773+
17671774
static bool routehint_excluded(struct payment *p,
17681775
const struct route_info *routehint)
17691776
{
17701777
const struct node_id *nodes = payment_get_excluded_nodes(tmpctx, p);
17711778
const struct short_channel_id_dir *chans =
17721779
payment_get_excluded_channels(tmpctx, p);
1780+
const struct channel_hint *hints = payment_root(p)->channel_hints;
17731781

17741782
/* Note that we ignore direction here: in theory, we could have
17751783
* found that one direction of a channel is unavailable, but they
@@ -1783,6 +1791,41 @@ static bool routehint_excluded(struct payment *p,
17831791
for (size_t j = 0; j < tal_count(chans); j++)
17841792
if (short_channel_id_eq(&chans[j].scid, &r->short_channel_id))
17851793
return true;
1794+
1795+
/* Skip the capacity check if this is the last hop
1796+
* in the routehint.
1797+
* The last hop in the routehint delivers the exact
1798+
* final amount to the destination, which
1799+
* payment_get_excluded_channels uses for excluding
1800+
* already.
1801+
* Thus, the capacity check below only really matters
1802+
* for multi-hop routehints.
1803+
*/
1804+
if (i == tal_count(routehint) - 1)
1805+
continue;
1806+
1807+
/* Check our capacity fits. */
1808+
struct amount_msat needed_capacity;
1809+
if (!route_msatoshi(&needed_capacity, p->amount,
1810+
r + 1, tal_count(routehint) - i - 1))
1811+
return true;
1812+
/* Why do we scan the hints again if
1813+
* payment_get_excluded_channels already does?
1814+
* Because payment_get_excluded_channels checks the
1815+
* amount at destination, but we know that we are
1816+
* a specific distance from the destination and we
1817+
* know the exact capacity we need to send via this
1818+
* channel, which is greater than the destination.
1819+
*/
1820+
for (size_t j = 0; j < tal_count(hints); j++) {
1821+
if (!short_channel_id_eq(&hints[j].scid.scid, &r->short_channel_id))
1822+
continue;
1823+
/* We exclude on equality because we set the estimate
1824+
* to the smallest failed attempt. */
1825+
if (amount_msat_greater_eq(needed_capacity,
1826+
hints[j].estimated_capacity))
1827+
return true;
1828+
}
17861829
}
17871830
return false;
17881831
}
@@ -2007,9 +2050,14 @@ static struct routehints_data *routehint_data_init(struct payment *p)
20072050
pd = payment_mod_routehints_get_data(payment_root(p));
20082051
d->destination_reachable = pd->destination_reachable;
20092052
d->routehints = pd->routehints;
2010-
if (p->parent->step == PAYMENT_STEP_RETRY)
2011-
d->offset = pd->offset + 1;
2012-
else
2053+
pd = payment_mod_routehints_get_data(p->parent);
2054+
if (p->parent->step == PAYMENT_STEP_RETRY) {
2055+
d->offset = pd->offset;
2056+
/* If the previous try failed to route, advance
2057+
* to the next routehint. */
2058+
if (!p->parent->route)
2059+
++d->offset;
2060+
} else
20132061
d->offset = 0;
20142062
return d;
20152063
} else {

0 commit comments

Comments
 (0)