@@ -61,6 +61,8 @@ struct payment {
6161 struct plugin * plugin ;
6262 /* Stop sending new payments after this */
6363 struct timemono deadline ;
64+ /* Blockheight when we started (if in future, wait for this!) */
65+ u32 start_blockheight ;
6466 /* This is the command which is expecting the success/fail. When
6567 * it's NULL, that means we're just cleaning up */
6668 struct command * cmd ;
@@ -631,6 +633,19 @@ static void outgoing_notify_failure(const struct attempt *attempt,
631633 plugin_notification_end (attempt -> payment -> plugin , js );
632634}
633635
636+ /* Extract blockheight from the error */
637+ static u32 error_blockheight (const u8 * errmsg )
638+ {
639+ struct amount_msat htlc_msat ;
640+ u32 height ;
641+
642+ if (!fromwire_incorrect_or_unknown_payment_details (errmsg ,
643+ & htlc_msat ,
644+ & height ))
645+ return 0 ;
646+ return height ;
647+ }
648+
634649static void update_knowledge_from_error (struct command * aux_cmd ,
635650 const char * buf ,
636651 const jsmntok_t * error ,
@@ -765,14 +780,24 @@ static void update_knowledge_from_error(struct command *aux_cmd,
765780 index -- ;
766781 goto strange_error ;
767782
768- case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS :
769- /* FIXME: Maybe this was actually a height
770- * disagreement, so check height */
783+ case WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS : {
784+ struct xpay * xpay = xpay_of (attempt -> payment -> plugin );
785+ u32 blockheight = error_blockheight (replymsg );
786+ if (blockheight > attempt -> payment -> start_blockheight ) {
787+ attempt_log (attempt , LOG_INFORM ,
788+ "Destination failed and said their blockheight was %u (we're at %u): waiting" ,
789+ blockheight , xpay -> blockheight );
790+ /* This will make the next attempt wait. */
791+ attempt -> payment -> start_blockheight = blockheight ;
792+ return ;
793+ }
794+
771795 payment_give_up (aux_cmd , attempt -> payment ,
772796 PAY_DESTINATION_PERM_FAIL ,
773797 "Destination said it doesn't know invoice: %s" ,
774798 errmsg );
775799 return ;
800+ }
776801
777802 case WIRE_MPP_TIMEOUT :
778803 /* Not actually an error at all, nothing to do. */
@@ -1315,6 +1340,35 @@ static struct command_result *getroutes_done_err(struct command *aux_cmd,
13151340 return command_still_pending (aux_cmd );
13161341}
13171342
1343+ static struct command_result * waitblockheight_done (struct command * aux_cmd ,
1344+ const char * method ,
1345+ const char * buf ,
1346+ const jsmntok_t * result ,
1347+ struct payment * payment )
1348+ {
1349+ /* Kick off however much is outstanding */
1350+ struct amount_msat needs_routing ;
1351+
1352+ if (!amount_msat_sub (& needs_routing ,
1353+ payment -> amount ,
1354+ total_being_sent (payment )))
1355+ abort ();
1356+ return getroutes_for (aux_cmd , payment , needs_routing );
1357+ }
1358+
1359+ static struct command_result * waitblockheight_failed (struct command * aux_cmd ,
1360+ const char * method ,
1361+ const char * buf ,
1362+ const jsmntok_t * result ,
1363+ struct payment * payment )
1364+ {
1365+ payment_give_up (aux_cmd , payment , PAY_UNSPECIFIED_ERROR ,
1366+ "Timed out waiting for blockheight %u. %s" ,
1367+ payment -> start_blockheight ,
1368+ payment -> prior_results );
1369+ return command_still_pending (aux_cmd );
1370+ }
1371+
13181372static struct command_result * getroutes_for (struct command * aux_cmd ,
13191373 struct payment * payment ,
13201374 struct amount_msat deliver )
@@ -1345,6 +1399,28 @@ static struct command_result *getroutes_for(struct command *aux_cmd,
13451399 return do_inject (aux_cmd , attempt );
13461400 }
13471401
1402+ /* Failure message indicated a blockheight difference. */
1403+ if (payment -> start_blockheight > xpay -> blockheight ) {
1404+ struct timemono now = time_mono ();
1405+ u64 seconds ;
1406+
1407+ if (time_greater_ (now .ts , payment -> deadline .ts ))
1408+ seconds = 0 ;
1409+ else
1410+ seconds = time_to_sec (timemono_between (payment -> deadline , now ));
1411+
1412+ payment_log (payment , LOG_UNUSUAL ,
1413+ "Our blockheight may be too low: waiting %" PRIu64 " seconds for height %u (we are at %u)" ,
1414+ seconds , payment -> start_blockheight , xpay -> blockheight );
1415+ req = jsonrpc_request_start (aux_cmd , "waitblockheight" ,
1416+ waitblockheight_done ,
1417+ waitblockheight_failed ,
1418+ payment );
1419+ json_add_u32 (req -> js , "blockheight" , payment -> start_blockheight );
1420+ json_add_u64 (req -> js , "timeout" , seconds );
1421+ return send_payment_req (aux_cmd , payment , req );
1422+ }
1423+
13481424 if (!amount_msat_sub (& maxfee , payment -> maxfee , total_fees_being_sent (payment ))) {
13491425 payment_log (payment , LOG_BROKEN , "more fees (%s) in flight than allowed (%s)!" ,
13501426 fmt_amount_msat (tmpctx , total_fees_being_sent (payment )),
@@ -1872,6 +1948,7 @@ static struct command_result *xpay_core(struct command *cmd,
18721948 payment -> prior_results = tal_strdup (payment , "" );
18731949 payment -> deadline = timemono_add (time_mono (), time_from_sec (retryfor ));
18741950 payment -> start_time = time_now ();
1951+ payment -> start_blockheight = xpay -> blockheight ;
18751952 payment -> pay_compat = as_pay ;
18761953 payment -> invstring = tal_strdup (payment , invstring );
18771954 if (layers )
0 commit comments