diff --git a/channeld/channel.c b/channeld/channel.c index e40bc5420..924754835 100644 --- a/channeld/channel.c +++ b/channeld/channel.c @@ -1220,6 +1220,8 @@ static u8 *got_commitsig_msg(const tal_t *ctx, (*f)->id = htlc->id; (*f)->failcode = htlc->failcode; (*f)->failreason = cast_const(u8 *, htlc->fail); + (*f)->scid = cast_const(struct short_channel_id *, + htlc->failed_scid); } } else { struct changed_htlc *c = tal_arr_append(&changed); @@ -1508,7 +1510,7 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg) &channel_id, &id, &reason)) { peer_failed(&peer->cs, &peer->channel_id, - "Bad update_fulfill_htlc %s", tal_hex(msg, msg)); + "Bad update_fail_htlc %s", tal_hex(msg, msg)); } e = channel_fail_htlc(peer->channel, LOCAL, id, &htlc); @@ -2243,6 +2245,11 @@ static void handle_fail(struct peer *peer, const u8 *inmsg) case CHANNEL_ERR_REMOVE_OK: h->failcode = failcode; h->fail = tal_steal(h, errpkt); + if (failcode & UPDATE) + h->failed_scid + = tal_dup(h, struct short_channel_id, &scid); + else + h->failed_scid = NULL; send_fail_or_fulfill(peer, h); start_commit_timer(peer); return; diff --git a/channeld/channeld_htlc.h b/channeld/channeld_htlc.h index b4a3f2a73..18a50b600 100644 --- a/channeld/channeld_htlc.h +++ b/channeld/channeld_htlc.h @@ -33,6 +33,8 @@ struct htlc { /* For a local failure, we might have to generate fail ourselves * (or, if BADONION we send a update_fail_malformed_htlc). */ enum onion_type failcode; + /* If failcode & UPDATE, this is channel which failed. Otherwise NULL. */ + const struct short_channel_id *failed_scid; }; static inline bool htlc_has(const struct htlc *h, int flag) diff --git a/channeld/full_channel.c b/channeld/full_channel.c index fde10fe58..b64f7548b 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -322,6 +322,7 @@ static enum channel_add_err add_htlc(struct channel *channel, htlc->rhash = *payment_hash; htlc->fail = NULL; htlc->failcode = 0; + htlc->failed_scid = NULL; htlc->r = NULL; htlc->routing = tal_dup_arr(htlc, u8, routing, TOTAL_PACKET_SIZE, 0); @@ -1052,6 +1053,12 @@ bool channel_force_htlcs(struct channel *channel, 0); else htlc->fail = NULL; + if (failed[i]->scid) + htlc->failed_scid = tal_dup(htlc, + struct short_channel_id, + failed[i]->scid); + else + htlc->failed_scid = NULL; } for (i = 0; i < tal_count(htlcs); i++) { diff --git a/common/htlc_wire.c b/common/htlc_wire.c index 796465f1b..bedd1e1eb 100644 --- a/common/htlc_wire.c +++ b/common/htlc_wire.c @@ -30,6 +30,10 @@ void towire_failed_htlc(u8 **pptr, const struct failed_htlc *failed) assert(!failed->failcode || !tal_len(failed->failreason)); towire_u64(pptr, failed->id); towire_u16(pptr, failed->failcode); + if (failed->failcode & UPDATE) + towire_short_channel_id(pptr, failed->scid); + else + assert(!failed->scid); towire_u16(pptr, tal_count(failed->failreason)); towire_u8_array(pptr, failed->failreason, tal_count(failed->failreason)); } @@ -88,6 +92,11 @@ struct failed_htlc *fromwire_failed_htlc(const tal_t *ctx, const u8 **cursor, si failed->id = fromwire_u64(cursor, max); failed->failcode = fromwire_u16(cursor, max); + if (failed->failcode & UPDATE) { + failed->scid = tal(failed, struct short_channel_id); + fromwire_short_channel_id(cursor, max, failed->scid); + } else + failed->scid = NULL; failreason_len = fromwire_u16(cursor, max); if (failreason_len) failed->failreason = tal_arr(failed, u8, failreason_len); diff --git a/common/htlc_wire.h b/common/htlc_wire.h index 3d0d76a62..f0c5a0cce 100644 --- a/common/htlc_wire.h +++ b/common/htlc_wire.h @@ -29,6 +29,8 @@ struct failed_htlc { /* Either this is 0 and failreason non-NULL, or vice versa. */ enum onion_type failcode; u8 *failreason; + /* Non-NULL if failcode & UPDATE */ + struct short_channel_id *scid; }; struct changed_htlc { diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 94d76033e..df16f8518 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -1387,6 +1387,7 @@ static void add_fulfill(u64 id, enum side side, static void add_fail(u64 id, enum side side, enum onion_type failcode, + const struct short_channel_id *failing_channel, const u8 *failuremsg, const struct failed_htlc ***failed_htlcs, enum side **failed_sides) @@ -1400,6 +1401,13 @@ static void add_fail(u64 id, enum side side, *f = tal(*failed_htlcs, struct failed_htlc); (*f)->id = id; (*f)->failcode = failcode; + if (failcode & UPDATE) { + assert(failing_channel); + (*f)->scid = tal_dup(*f, struct short_channel_id, + failing_channel); + } else + (*f)->scid = NULL; + if (failuremsg) (*f)->failreason = tal_dup_arr(*f, u8, failuremsg, tal_len(failuremsg), 0); @@ -1444,6 +1452,7 @@ void peer_htlcs(const tal_t *ctx, if (hin->failuremsg || hin->failcode) add_fail(hin->key.id, REMOTE, hin->failcode, + &hin->failoutchannel, hin->failuremsg, failed_htlcs, failed_sides); if (hin->preimage) add_fulfill(hin->key.id, REMOTE, hin->preimage, @@ -1463,6 +1472,7 @@ void peer_htlcs(const tal_t *ctx, if (hout->failuremsg || hout->failcode) add_fail(hout->key.id, LOCAL, hout->failcode, + hout->key.channel->scid, hout->failuremsg, failed_htlcs, failed_sides); if (hout->preimage) add_fulfill(hout->key.id, LOCAL, hout->preimage,