diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 09ba87b5a..8156477e0 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -1525,7 +1525,18 @@ static void payment_compute_onion_payloads(struct payment *p) p->step = PAYMENT_STEP_ONION_PAYLOAD; hopcount = tal_count(p->route); - payment_chanhints_apply_route(p, false); + /* Now that we are about to fix the route parameters by + * encoding them in an onion is the right time to update the + * channel hints. */ + if (!payment_chanhints_apply_route(p, false)) { + /* We can still end up with a failed channel_hints + * update, either because a plugin changed the route, + * or because a modifier was not synchronous, allowing + * for multiple concurrent routes being built. If that + * is the case, discard this route and retry. */ + payment_set_step(p, PAYMENT_STEP_RETRY_GETROUTE); + return payment_continue(p); + } /* Now compute the payload we're about to pass to `createonion` */ cr = p->createonion_request = tal(p, struct createonion_request); @@ -1873,6 +1884,7 @@ void payment_continue(struct payment *p) p->current_modifier = -1; switch (p->step) { case PAYMENT_STEP_INITIALIZED: + case PAYMENT_STEP_RETRY_GETROUTE: payment_getroute(p); return; diff --git a/plugins/libplugin-pay.h b/plugins/libplugin-pay.h index 183de12c5..6cc0b35dd 100644 --- a/plugins/libplugin-pay.h +++ b/plugins/libplugin-pay.h @@ -94,6 +94,11 @@ enum payment_step { * to amend the route. */ PAYMENT_STEP_GOT_ROUTE = 2, + /* Something went wrong with the route returned by the + previous step, so retry, but do not rerun the INITIALIZED + modifiers. */ + PAYMENT_STEP_RETRY_GETROUTE = 3, + /* We just computed the onion payload, allow modifiers to amend, * before constructing the onion packet. */ PAYMENT_STEP_ONION_PAYLOAD = 4,