-
Notifications
You must be signed in to change notification settings - Fork 911
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No next lookup via gossipd #3547
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,6 +128,74 @@ static struct failed_htlc *mk_failed_htlc(const tal_t *ctx, | |
return f; | ||
} | ||
|
||
static void tell_channeld_htlc_failed(const struct htlc_in *hin, | ||
const struct failed_htlc *failed_htlc) | ||
{ | ||
/* Tell peer, if we can. */ | ||
if (!hin->key.channel->owner) | ||
return; | ||
|
||
/* onchaind doesn't care, it can't do anything but wait */ | ||
if (channel_on_chain(hin->key.channel)) | ||
return; | ||
|
||
subd_send_msg(hin->key.channel->owner, | ||
take(towire_channel_fail_htlc(NULL, failed_htlc))); | ||
} | ||
|
||
struct failmsg_update_cbdata { | ||
struct htlc_in *hin; | ||
const u8 *failmsg_needs_update; | ||
}; | ||
|
||
static void failmsg_update_reply(struct subd *gossipd, | ||
const u8 *msg, | ||
const int *unused, | ||
struct failmsg_update_cbdata *cbdata) | ||
{ | ||
u8 *failmsg; | ||
u8 *stripped_update; | ||
struct failed_htlc *failed_htlc; | ||
|
||
/* In theory, we could have no update because channel suddenly closed, | ||
* but it's v. unlikely */ | ||
if (!fromwire_gossip_get_stripped_cupdate_reply(msg, msg, | ||
&stripped_update) | ||
|| !tal_count(stripped_update)) { | ||
log_broken(gossipd->log, | ||
"bad fromwire_gossip_get_stripped_cupdate %s", | ||
tal_hex(msg, msg)); | ||
failmsg = towire_temporary_node_failure(NULL); | ||
} else { | ||
/* End of failmsg is two zero bytes (empty update). */ | ||
assert(tal_count(cbdata->failmsg_needs_update) >= 2); | ||
failmsg = tal_dup_arr(msg, u8, | ||
cbdata->failmsg_needs_update, | ||
tal_count(cbdata->failmsg_needs_update)-2, | ||
0); | ||
towire_u16(&failmsg, tal_count(stripped_update)); | ||
towire_u8_array(&failmsg, | ||
stripped_update, tal_count(stripped_update)); | ||
} | ||
|
||
/* Now we replace dummy failonion with this real one */ | ||
tal_free(cbdata->hin->failonion); | ||
cbdata->hin->failonion | ||
= create_onionreply(cbdata->hin, | ||
cbdata->hin->shared_secret, | ||
failmsg); | ||
|
||
wallet_htlc_update(gossipd->ld->wallet, | ||
cbdata->hin->dbid, cbdata->hin->hstate, | ||
cbdata->hin->preimage, | ||
cbdata->hin->badonion, | ||
cbdata->hin->failonion, NULL); | ||
|
||
failed_htlc = mk_failed_htlc(tmpctx, | ||
cbdata->hin, cbdata->hin->failonion); | ||
tell_channeld_htlc_failed(cbdata->hin, failed_htlc); | ||
} | ||
|
||
static void fail_in_htlc(struct htlc_in *hin, | ||
const struct onionreply *failonion TAKES) | ||
{ | ||
|
@@ -140,17 +208,8 @@ static void fail_in_htlc(struct htlc_in *hin, | |
htlc_in_update_state(hin->key.channel, hin, SENT_REMOVE_HTLC); | ||
htlc_in_check(hin, __func__); | ||
|
||
/* Tell peer, if we can. */ | ||
if (!hin->key.channel->owner) | ||
return; | ||
|
||
/* onchaind doesn't care, it can't do anything but wait */ | ||
if (channel_on_chain(hin->key.channel)) | ||
return; | ||
|
||
failed_htlc = mk_failed_htlc(tmpctx, hin, hin->failonion); | ||
subd_send_msg(hin->key.channel->owner, | ||
take(towire_channel_fail_htlc(NULL, failed_htlc))); | ||
tell_channeld_htlc_failed(hin, failed_htlc); | ||
} | ||
|
||
/* Immediately fail HTLC with a BADONION code */ | ||
|
@@ -167,17 +226,7 @@ static void local_fail_in_htlc_badonion(struct htlc_in *hin, | |
htlc_in_check(hin, __func__); | ||
|
||
failed_htlc = mk_failed_htlc_badonion(tmpctx, hin, badonion); | ||
|
||
/* Tell peer, if we can. */ | ||
if (!hin->key.channel->owner) | ||
return; | ||
|
||
/* onchaind doesn't care, it can't do anything but wait */ | ||
if (channel_on_chain(hin->key.channel)) | ||
return; | ||
|
||
subd_send_msg(hin->key.channel->owner, | ||
take(towire_channel_fail_htlc(NULL, failed_htlc))); | ||
tell_channeld_htlc_failed(hin, failed_htlc); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice simplification 👍 |
||
} | ||
|
||
/* This is used for cases where we can immediately fail the HTLC. */ | ||
|
@@ -193,6 +242,34 @@ void local_fail_in_htlc(struct htlc_in *hin, const u8 *failmsg TAKES) | |
fail_in_htlc(hin, take(failonion)); | ||
} | ||
|
||
/* This is used for cases where we can immediately fail the HTLC, but | ||
* need to append a channel_update. */ | ||
void local_fail_in_htlc_needs_update(struct htlc_in *hin, | ||
const u8 *failmsg_needs_update TAKES, | ||
const struct short_channel_id *failmsg_scid) | ||
{ | ||
struct failmsg_update_cbdata *cbdata; | ||
|
||
/* To avoid the state where we have no failonion, we use a temporary | ||
* one, and update once we get the reply from gossipd. */ | ||
assert(!hin->preimage); | ||
|
||
hin->failonion = create_onionreply(hin, | ||
hin->shared_secret, | ||
towire_temporary_node_failure(tmpctx)); | ||
/* We update state now to signal it's in progress, for persistence. */ | ||
htlc_in_update_state(hin->key.channel, hin, SENT_REMOVE_HTLC); | ||
htlc_in_check(hin, __func__); | ||
|
||
cbdata = tal(hin, struct failmsg_update_cbdata); | ||
cbdata->hin = hin; | ||
cbdata->failmsg_needs_update | ||
= tal_dup_talarr(cbdata, u8, failmsg_needs_update); | ||
subd_req(cbdata, hin->key.channel->peer->ld->gossip, | ||
take(towire_gossip_get_stripped_cupdate(NULL, failmsg_scid)), | ||
-1, 0, failmsg_update_reply, cbdata); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems like your
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I think this is best addressed by freeing HTLCs and peer daemons first, then gossipd. Thanks! |
||
} | ||
|
||
/* Helper to create (common) WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS */ | ||
const u8 *failmsg_incorrect_or_unknown(const tal_t *ctx, | ||
const struct htlc_in *hin) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't we using
tal_bytelen
foru8*
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a line-ball, IMHO. Especially here, where it will actually (due to our explicit fromwire_ generation policy) be NULL instead of empty.