@@ -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+
726753static struct command_result *
727754handle_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