mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 07:34:24 +01:00
lightningd: fix crash when failing htlc once channeld dies.
We were reaching through it to get `ld`, but channeld is already dead.
Caught this on test_onchaind_replay (without valgrind) on my test machine:
INFO 0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518-chan#1: Peer transient failure in CHANNELD_NORMAL: channeld: Owning subdaemon channeld died (62208)
**BROKEN** lightningd: FATAL SIGNAL 11 (version f6e1735)
**BROKEN** lightningd: backtrace: common/daemon.c:44 (send_backtrace) 0x5634dc83dc55
**BROKEN** lightningd: backtrace: common/daemon.c:52 (crashdump) 0x5634dc83dca9
**BROKEN** lightningd: backtrace: (null):0 ((null)) 0x7fd4b7c0b46f
**BROKEN** lightningd: backtrace: lightningd/peer_htlcs.c:285 (failmsg_incorrect_or_unknown) 0x5634dc82625a
**BROKEN** lightningd: backtrace: lightningd/htlc_set.c:109 (htlc_set_add) 0x5634dc801e5c
**BROKEN** lightningd: backtrace: lightningd/peer_htlcs.c:496 (handle_localpay) 0x5634dc826997
**BROKEN** lightningd: backtrace: lightningd/peer_htlcs.c:1008 (htlc_accepted_hook_callback) 0x5634dc827e60
**BROKEN** lightningd: backtrace: lightningd/plugin_hook.c:197 (plugin_hook_callback) 0x5634dc831ea1
**BROKEN** lightningd: backtrace: lightningd/plugin.c:261 (plugin_response_handle) 0x5634dc82d2c3
**BROKEN** lightningd: backtrace: lightningd/plugin.c:359 (plugin_read_json_one) 0x5634dc82d46f
**BROKEN** lightningd: backtrace: lightningd/plugin.c:391 (plugin_read_json) 0x5634dc82d5c6
**BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:59 (next_plan) 0x5634dc896319
**BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:407 (do_plan) 0x5634dc896efe
**BROKEN** lightningd: backtrace: ccan/ccan/io/io.c:417 (io_ready) 0x5634dc896f40
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -106,7 +106,7 @@ void htlc_set_add(struct lightningd *ld,
|
|||||||
total_msat, payment_secret);
|
total_msat, payment_secret);
|
||||||
if (!details) {
|
if (!details) {
|
||||||
local_fail_in_htlc(hin,
|
local_fail_in_htlc(hin,
|
||||||
take(failmsg_incorrect_or_unknown(NULL, hin)));
|
take(failmsg_incorrect_or_unknown(NULL, ld, hin)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ void htlc_set_add(struct lightningd *ld,
|
|||||||
/* We check this now, since we want to fail with this as soon
|
/* We check this now, since we want to fail with this as soon
|
||||||
* as possible, to avoid other probing attacks. */
|
* as possible, to avoid other probing attacks. */
|
||||||
if (!payment_secret) {
|
if (!payment_secret) {
|
||||||
local_fail_in_htlc(hin, take(failmsg_incorrect_or_unknown(NULL, hin)));
|
local_fail_in_htlc(hin, take(failmsg_incorrect_or_unknown(NULL, ld, hin)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tal_arr_expand(&set->htlcs, hin);
|
tal_arr_expand(&set->htlcs, hin);
|
||||||
@@ -193,7 +193,7 @@ void htlc_set_add(struct lightningd *ld,
|
|||||||
/* This catches the case of the first payment in a set. */
|
/* This catches the case of the first payment in a set. */
|
||||||
if (!payment_secret) {
|
if (!payment_secret) {
|
||||||
htlc_set_fail(set,
|
htlc_set_fail(set,
|
||||||
take(failmsg_incorrect_or_unknown(NULL, hin)));
|
take(failmsg_incorrect_or_unknown(NULL, ld, hin)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ static void invoice_payload_remove_set(struct htlc_set *set,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const u8 *hook_gives_failmsg(const tal_t *ctx,
|
static const u8 *hook_gives_failmsg(const tal_t *ctx,
|
||||||
struct log *log,
|
struct lightningd *ld,
|
||||||
const struct htlc_in *hin,
|
const struct htlc_in *hin,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *toks)
|
const jsmntok_t *toks)
|
||||||
@@ -181,7 +181,7 @@ static const u8 *hook_gives_failmsg(const tal_t *ctx,
|
|||||||
if (json_tok_streq(buffer, resulttok, "continue")) {
|
if (json_tok_streq(buffer, resulttok, "continue")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (json_tok_streq(buffer, resulttok, "reject")) {
|
} else if (json_tok_streq(buffer, resulttok, "reject")) {
|
||||||
return failmsg_incorrect_or_unknown(ctx, hin);
|
return failmsg_incorrect_or_unknown(ctx, ld, hin);
|
||||||
} else
|
} else
|
||||||
fatal("Invalid invoice_payment hook result: %.*s",
|
fatal("Invalid invoice_payment hook result: %.*s",
|
||||||
toks[0].end - toks[0].start, buffer);
|
toks[0].end - toks[0].start, buffer);
|
||||||
@@ -204,7 +204,7 @@ static const u8 *hook_gives_failmsg(const tal_t *ctx,
|
|||||||
static bool warned = false;
|
static bool warned = false;
|
||||||
if (!warned) {
|
if (!warned) {
|
||||||
warned = true;
|
warned = true;
|
||||||
log_unusual(log,
|
log_unusual(ld->log,
|
||||||
"Plugin did not return object with "
|
"Plugin did not return object with "
|
||||||
"'result' or 'failure_message' fields. "
|
"'result' or 'failure_message' fields. "
|
||||||
"This is now deprecated and you should "
|
"This is now deprecated and you should "
|
||||||
@@ -212,7 +212,7 @@ static const u8 *hook_gives_failmsg(const tal_t *ctx,
|
|||||||
"{'result': 'reject'} or "
|
"{'result': 'reject'} or "
|
||||||
"{'failure_message'... instead.");
|
"{'failure_message'... instead.");
|
||||||
}
|
}
|
||||||
return failmsg_incorrect_or_unknown(ctx, hin);
|
return failmsg_incorrect_or_unknown(ctx, ld, hin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json_to_number(buffer, t, &val))
|
if (!json_to_number(buffer, t, &val))
|
||||||
@@ -227,7 +227,7 @@ static const u8 *hook_gives_failmsg(const tal_t *ctx,
|
|||||||
" changing to incorrect_or_unknown_payment_details",
|
" changing to incorrect_or_unknown_payment_details",
|
||||||
val);
|
val);
|
||||||
|
|
||||||
return failmsg_incorrect_or_unknown(ctx, hin);
|
return failmsg_incorrect_or_unknown(ctx, ld, hin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -258,12 +258,12 @@ invoice_payment_hook_cb(struct invoice_payment_hook_payload *payload,
|
|||||||
* we can also fail */
|
* we can also fail */
|
||||||
if (!wallet_invoice_find_by_label(ld->wallet, &invoice, payload->label)) {
|
if (!wallet_invoice_find_by_label(ld->wallet, &invoice, payload->label)) {
|
||||||
htlc_set_fail(payload->set, take(failmsg_incorrect_or_unknown(
|
htlc_set_fail(payload->set, take(failmsg_incorrect_or_unknown(
|
||||||
NULL, payload->set->htlcs[0])));
|
NULL, ld, payload->set->htlcs[0])));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did we have a hook result? */
|
/* Did we have a hook result? */
|
||||||
failmsg = hook_gives_failmsg(NULL, ld->log,
|
failmsg = hook_gives_failmsg(NULL, ld,
|
||||||
payload->set->htlcs[0], buffer, toks);
|
payload->set->htlcs[0], buffer, toks);
|
||||||
if (failmsg) {
|
if (failmsg) {
|
||||||
htlc_set_fail(payload->set, take(failmsg));
|
htlc_set_fail(payload->set, take(failmsg));
|
||||||
|
|||||||
@@ -278,11 +278,12 @@ void local_fail_in_htlc_needs_update(struct htlc_in *hin,
|
|||||||
|
|
||||||
/* Helper to create (common) WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS */
|
/* Helper to create (common) WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS */
|
||||||
const u8 *failmsg_incorrect_or_unknown(const tal_t *ctx,
|
const u8 *failmsg_incorrect_or_unknown(const tal_t *ctx,
|
||||||
|
struct lightningd *ld,
|
||||||
const struct htlc_in *hin)
|
const struct htlc_in *hin)
|
||||||
{
|
{
|
||||||
return towire_incorrect_or_unknown_payment_details(
|
return towire_incorrect_or_unknown_payment_details(
|
||||||
ctx, hin->msat,
|
ctx, hin->msat,
|
||||||
get_block_height(hin->key.channel->owner->ld->topology));
|
get_block_height(ld->topology));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* localfail are for handing to the local payer if it's local. */
|
/* localfail are for handing to the local payer if it's local. */
|
||||||
@@ -489,7 +490,7 @@ static void handle_localpay(struct htlc_in *hin,
|
|||||||
hin->cltv_expiry,
|
hin->cltv_expiry,
|
||||||
get_block_height(ld->topology),
|
get_block_height(ld->topology),
|
||||||
ld->config.cltv_final);
|
ld->config.cltv_final);
|
||||||
failmsg = failmsg_incorrect_or_unknown(NULL, hin);
|
failmsg = failmsg_incorrect_or_unknown(NULL, ld, hin);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,5 +82,6 @@ void json_format_forwarding_object(struct json_stream *response, const char *fie
|
|||||||
|
|
||||||
/* Helper to create (common) WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS */
|
/* Helper to create (common) WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS */
|
||||||
const u8 *failmsg_incorrect_or_unknown(const tal_t *ctx,
|
const u8 *failmsg_incorrect_or_unknown(const tal_t *ctx,
|
||||||
|
struct lightningd *ld,
|
||||||
const struct htlc_in *hin);
|
const struct htlc_in *hin);
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_PEER_HTLCS_H */
|
#endif /* LIGHTNING_LIGHTNINGD_PEER_HTLCS_H */
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ char *encode_scriptpubkey_to_addr(const tal_t *ctx UNNEEDED,
|
|||||||
{ fprintf(stderr, "encode_scriptpubkey_to_addr called!\n"); abort(); }
|
{ fprintf(stderr, "encode_scriptpubkey_to_addr called!\n"); abort(); }
|
||||||
/* Generated stub for failmsg_incorrect_or_unknown */
|
/* Generated stub for failmsg_incorrect_or_unknown */
|
||||||
const u8 *failmsg_incorrect_or_unknown(const tal_t *ctx UNNEEDED,
|
const u8 *failmsg_incorrect_or_unknown(const tal_t *ctx UNNEEDED,
|
||||||
|
struct lightningd *ld UNNEEDED,
|
||||||
const struct htlc_in *hin UNNEEDED)
|
const struct htlc_in *hin UNNEEDED)
|
||||||
{ fprintf(stderr, "failmsg_incorrect_or_unknown called!\n"); abort(); }
|
{ fprintf(stderr, "failmsg_incorrect_or_unknown called!\n"); abort(); }
|
||||||
/* Generated stub for fatal */
|
/* Generated stub for fatal */
|
||||||
|
|||||||
Reference in New Issue
Block a user