mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
pay: Fix a crash when waitblockheight times out
Fixes #4309 Changelog-Fixed: pay: Fixed an issue where waiting for the blockchain height to sync could time out.
This commit is contained in:
@@ -3003,27 +3003,44 @@ static struct command_result *waitblockheight_rpc_cb(struct command *cmd,
|
|||||||
const jsmntok_t *toks,
|
const jsmntok_t *toks,
|
||||||
struct payment *p)
|
struct payment *p)
|
||||||
{
|
{
|
||||||
const jsmntok_t *blockheighttok =
|
const jsmntok_t *blockheighttok, *codetok;
|
||||||
json_get_member(buffer, toks, "blockheight");
|
|
||||||
u32 blockheight;
|
u32 blockheight;
|
||||||
|
int code;
|
||||||
struct payment *subpayment;
|
struct payment *subpayment;
|
||||||
|
|
||||||
if (!blockheighttok
|
blockheighttok = json_get_member(buffer, toks, "blockheight");
|
||||||
|| !json_to_number(buffer, blockheighttok, &blockheight))
|
|
||||||
plugin_err(p->plugin,
|
|
||||||
"Unexpected result from waitblockheight: %.*s",
|
|
||||||
json_tok_full_len(toks),
|
|
||||||
json_tok_full(buffer, toks));
|
|
||||||
|
|
||||||
subpayment = payment_new(p, NULL, p, p->modifiers);
|
if (!blockheighttok ||
|
||||||
payment_start_at_blockheight(subpayment, blockheight);
|
!json_to_number(buffer, blockheighttok, &blockheight)) {
|
||||||
payment_set_step(p, PAYMENT_STEP_RETRY);
|
codetok = json_get_member(buffer, toks, "code");
|
||||||
subpayment->why =
|
json_to_int(buffer, codetok, &code);
|
||||||
tal_fmt(subpayment, "Retrying after waiting for blockchain sync.");
|
if (code == WAIT_TIMEOUT) {
|
||||||
paymod_log(p, LOG_DBG,
|
payment_fail(
|
||||||
"Retrying after waitblockheight, new partid %"PRIu32,
|
p,
|
||||||
subpayment->partid);
|
"Timed out while attempting to sync to blockheight "
|
||||||
payment_continue(p);
|
"returned by destination. Please finish syncing "
|
||||||
|
"with the blockchain and try again.");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
plugin_err(
|
||||||
|
p->plugin,
|
||||||
|
"Unexpected result from waitblockheight: %.*s",
|
||||||
|
json_tok_full_len(toks),
|
||||||
|
json_tok_full(buffer, toks));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
subpayment = payment_new(p, NULL, p, p->modifiers);
|
||||||
|
payment_start_at_blockheight(subpayment, blockheight);
|
||||||
|
payment_set_step(p, PAYMENT_STEP_RETRY);
|
||||||
|
subpayment->why = tal_fmt(
|
||||||
|
subpayment, "Retrying after waiting for blockchain sync.");
|
||||||
|
paymod_log(
|
||||||
|
p, LOG_DBG,
|
||||||
|
"Retrying after waitblockheight, new partid %" PRIu32,
|
||||||
|
subpayment->partid);
|
||||||
|
payment_continue(p);
|
||||||
|
}
|
||||||
return command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3040,10 +3057,12 @@ static void waitblockheight_cb(void *d, struct payment *p)
|
|||||||
if (p->result == NULL)
|
if (p->result == NULL)
|
||||||
return payment_continue(p);
|
return payment_continue(p);
|
||||||
|
|
||||||
if (time_after(now, p->deadline))
|
/* Check if we'd be waiting more than 0 seconds. If we have
|
||||||
return payment_continue(p);
|
* less than a second then waitblockheight would return
|
||||||
|
* immediately resulting in a loop. */
|
||||||
remaining = time_between(p->deadline, now);
|
remaining = time_between(p->deadline, now);
|
||||||
|
if (time_to_sec(remaining) < 1)
|
||||||
|
return payment_continue(p);
|
||||||
|
|
||||||
/* *Was* it a blockheight disagreement that caused the failure? */
|
/* *Was* it a blockheight disagreement that caused the failure? */
|
||||||
if (!failure_is_blockheight_disagreement(p, &blockheight))
|
if (!failure_is_blockheight_disagreement(p, &blockheight))
|
||||||
|
|||||||
@@ -3935,7 +3935,6 @@ def test_fetchinvoice(node_factory, bitcoind):
|
|||||||
'recurrence_label': 'test recurrence'})
|
'recurrence_label': 'test recurrence'})
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(strict=True)
|
|
||||||
def test_pay_waitblockheight_timeout(node_factory, bitcoind):
|
def test_pay_waitblockheight_timeout(node_factory, bitcoind):
|
||||||
plugin = os.path.join(os.path.dirname(__file__), 'plugins', 'endlesswaitblockheight.py')
|
plugin = os.path.join(os.path.dirname(__file__), 'plugins', 'endlesswaitblockheight.py')
|
||||||
l1, l2 = node_factory.line_graph(2, opts=[{}, {'plugin': plugin}])
|
l1, l2 = node_factory.line_graph(2, opts=[{}, {'plugin': plugin}])
|
||||||
|
|||||||
Reference in New Issue
Block a user