From f449f9d3ef3fcd919908ef292aa9e5b0a9c5d4ba Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 30 Jul 2018 11:51:28 +0200 Subject: [PATCH] onion: Make sure we understand the channel_update in the onionreply As was pointed out by @robtex we have underspecified the format of the nested `channel_update` in the onionreply: lnd and eclair inserted the raw channel_update without the type prefix, while we went for the full wire format, including the type prefix. While we agreed that with the type it is more flexible, and consistent, we decided to adapt to the majority and at least be compatibly broken. This commit takes care of being able to interpret either format correctly. It's not perfect since signatures can happen to start with 0x0102 (the channel_update type) but that'll happen only once ever 65k failures. --- lightningd/pay.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lightningd/pay.c b/lightningd/pay.c index e9c6d9990..5f30e3286 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -187,6 +187,27 @@ void payment_succeeded(struct lightningd *ld, struct htlc_out *hout, payment_trigger_success(ld, &hout->payment_hash); } +/* Fix up the channel_update to include the type if it doesn't currently have + * one. See ElementsProject/lightning#1730 and lightningnetwork/lnd#1599 for the + * in-depth discussion on why we break message parsing here... */ +static u8 *patch_channel_update(const tal_t *ctx, u8 *channel_update TAKES) +{ + u8 *fixed; + if (channel_update != NULL && + fromwire_peektype(channel_update) != WIRE_CHANNEL_UPDATE) { + /* This should be a channel_update, prefix with the + * WIRE_CHANNEL_UPDATE type, but isn't. Let's prefix it. */ + fixed = tal_arr(ctx, u8, 0); + towire_u16(&fixed, WIRE_CHANNEL_UPDATE); + towire(&fixed, channel_update, tal_bytelen(channel_update)); + if (taken(channel_update)) + tal_free(channel_update); + return fixed; + } else { + return channel_update; + } +} + /* Return NULL if the wrapped onion error message has no * channel_update field, or return the embedded * channel_update message otherwise. */ @@ -217,9 +238,9 @@ static u8 *channel_update_from_onion_error(const tal_t *ctx, onion_message, &channel_update)) /* No channel update. */ - channel_update = NULL; + return NULL; - return channel_update; + return patch_channel_update(ctx, take(channel_update)); } /* Return a struct routing_failure for an immediate failure