Skip to content

Commit c93a0a5

Browse files
ZmnSCPxjcdecker
authored andcommitted
plugins/libplugin-pay.c: Make sure blockheight disagreement does not prevent all future progress.
Blockheight disagreement is signalled with a permanent failure at the end node, but is actually a transient failure.
1 parent 6ae412e commit c93a0a5

File tree

1 file changed

+43
-22
lines changed

1 file changed

+43
-22
lines changed

plugins/libplugin-pay.c

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -723,12 +723,50 @@ static void report_tampering(struct payment *p,
723723
}
724724
}
725725

726+
static bool
727+
failure_is_blockheight_disagreement(const struct payment *p,
728+
u32 *blockheight)
729+
{
730+
struct amount_msat unused;
731+
732+
assert(p && p->result);
733+
734+
if (p->result->failcode == 17 /* Former final_expiry_too_soon */)
735+
*blockheight = p->start_block + 1;
736+
else if (!fromwire_incorrect_or_unknown_payment_details(
737+
p->result->raw_message,
738+
&unused, blockheight))
739+
/* If it's incorrect_or_unknown_payment_details, that tells us
740+
* what height they're at */
741+
return false;
742+
743+
/* If we are already at the desired blockheight there is no point in
744+
* waiting, and it is likely just some other error. Notice that
745+
* start_block gets set by the initial getinfo call for each
746+
* attempt.*/
747+
if (*blockheight <= p->start_block)
748+
return false;
749+
750+
return true;
751+
}
752+
726753
static struct command_result *
727754
handle_final_failure(struct command *cmd,
728755
struct payment *p,
729756
const struct node_id *final_id,
730757
enum onion_type failcode)
731758
{
759+
u32 unused;
760+
761+
/* Need to check for blockheight disagreement case here,
762+
* otherwise we would set the abort flag too eagerly.
763+
*/
764+
if (failure_is_blockheight_disagreement(p, &unused)) {
765+
plugin_log(p->plugin, LOG_DBG,
766+
"Blockheight disagreement, not aborting.");
767+
goto nonerror;
768+
}
769+
732770
/* We use an exhaustive switch statement here so you get a compile
733771
* warning when new ones are added, and can think about where they go */
734772
switch (failcode) {
@@ -807,8 +845,10 @@ handle_final_failure(struct command *cmd,
807845
p->result->code = PAY_DESTINATION_PERM_FAIL;
808846
payment_root(p)->abort = true;
809847

848+
nonerror:
810849
payment_fail(p, "%s", p->result->message);
811850
return command_still_pending(cmd);
851+
812852
}
813853

814854

@@ -2471,9 +2511,7 @@ static void waitblockheight_cb(void *d, struct payment *p)
24712511
struct out_req *req;
24722512
struct timeabs now = time_now();
24732513
struct timerel remaining;
2474-
u32 blockheight = p->start_block;
2475-
int failcode;
2476-
const u8 *raw_message;
2514+
u32 blockheight;
24772515
if (p->step != PAYMENT_STEP_FAILED)
24782516
return payment_continue(p);
24792517

@@ -2484,27 +2522,10 @@ static void waitblockheight_cb(void *d, struct payment *p)
24842522
if (time_after(now, p->deadline))
24852523
return payment_continue(p);
24862524

2487-
failcode = p->result->failcode;
2488-
raw_message = p->result->raw_message;
24892525
remaining = time_between(p->deadline, now);
24902526

2491-
if (failcode == 17 /* Former final_expiry_too_soon */) {
2492-
blockheight = p->start_block + 1;
2493-
} else {
2494-
/* If it's incorrect_or_unknown_payment_details, that tells us
2495-
* what height they're at */
2496-
struct amount_msat unused;
2497-
const void *ptr = raw_message;
2498-
if (!fromwire_incorrect_or_unknown_payment_details(
2499-
ptr, &unused, &blockheight))
2500-
return payment_continue(p);
2501-
}
2502-
2503-
/* If we are already at the desired blockheight there is no point in
2504-
* waiting, and it is likely just some other error. Notice that
2505-
* start_block gets set by the initial getinfo call for each
2506-
* attempt.*/
2507-
if (blockheight <= p->start_block)
2527+
/* *Was* it a blockheight disagreement that caused the failure? */
2528+
if (!failure_is_blockheight_disagreement(p, &blockheight))
25082529
return payment_continue(p);
25092530

25102531
plugin_log(p->plugin, LOG_INFORM,

0 commit comments

Comments
 (0)