paymod: Routehintmod signals that we can retry if getroute fails

The shortcut in the retry_mod that we can skip retrying if getroute fails or
we have no result is only valid if the parameters don't change. As we iterate
through the routehints the parameters change, and so we must signal to the
retry_mod that it can retry even in those cases.
This commit is contained in:
Christian Decker 2020-07-23 16:07:39 +02:00
parent 52a8b8f9e7
commit 85ec438d34
2 changed files with 17 additions and 2 deletions

View File

@ -27,6 +27,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
p->abort = false; p->abort = false;
p->route = NULL; p->route = NULL;
p->temp_exclusion = NULL; p->temp_exclusion = NULL;
p->failroute_retry = false;
/* Copy over the relevant pieces of information. */ /* Copy over the relevant pieces of information. */
if (parent != NULL) { if (parent != NULL) {
@ -1527,7 +1528,7 @@ static bool payment_can_retry(struct payment *p)
bool is_final; bool is_final;
if (p->result == NULL) if (p->result == NULL)
return false; return p->failroute_retry;
idx = res->erring_index != NULL ? *res->erring_index : 0; idx = res->erring_index != NULL ? *res->erring_index : 0;
is_final = (idx == tal_count(p->route)); is_final = (idx == tal_count(p->route));
@ -1595,7 +1596,7 @@ static inline void retry_step_cb(struct retry_mod_data *rd,
/* If we failed to find a route, it's unlikely we can suddenly find a /* If we failed to find a route, it's unlikely we can suddenly find a
* new one without any other changes, so it's time to give up. */ * new one without any other changes, so it's time to give up. */
if (p->route == NULL) if (p->route == NULL && !p->failroute_retry)
return payment_continue(p); return payment_continue(p);
/* If the root is marked as abort, we do not retry anymore */ /* If the root is marked as abort, we do not retry anymore */
@ -1839,7 +1840,14 @@ static u32 route_cltv(u32 cltv,
* routehint entry point. */ * routehint entry point. */
static void routehint_pre_getroute(struct routehints_data *d, struct payment *p) static void routehint_pre_getroute(struct routehints_data *d, struct payment *p)
{ {
bool have_more;
d->current_routehint = next_routehint(d, p); d->current_routehint = next_routehint(d, p);
/* Signal that we could retry with another routehint even if getroute
* fails. */
have_more = (d->offset < tal_count(d->routehints) - 1);
p->failroute_retry = have_more;
if (d->current_routehint != NULL) { if (d->current_routehint != NULL) {
if (!route_msatoshi(&p->getroute->amount, p->amount, if (!route_msatoshi(&p->getroute->amount, p->amount,
d->current_routehint, d->current_routehint,

View File

@ -255,6 +255,13 @@ struct payment {
/* Human readable explanation of why this payment failed. */ /* Human readable explanation of why this payment failed. */
const char *failreason; const char *failreason;
/* If a failed getroute call can be retried for this payment. Allows
* us for example to signal to any retry modifier that we can retry
* despite getroute not returning a usable route. This can be the case
* if we switch any of the parameters such as destination or
* amount. */
bool failroute_retry;
}; };
struct payment_modifier { struct payment_modifier {