From 7ab5c424b6767195fc688b7cbb6b088169c5503a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 18 Feb 2020 10:27:58 +1030 Subject: [PATCH] gossipd: provide (stripped) channel_update when resolving a channel. I hadn't realized that lightningd asks gossipd every time we forward a payment. But I'm going to abuse it here to get the latest channel_update, otherwise (as lightningd takes over error message generation) lightningd needs to do an async request at various painful points. So have gossipd tell us the lastest update (stripped so compatible with the strange in-onion-error format). Signed-off-by: Rusty Russell --- gossipd/gossip_wire.csv | 2 ++ gossipd/gossipd.c | 20 +++++++++++++++++++- lightningd/channel.c | 1 + lightningd/channel.h | 3 +++ lightningd/peer_htlcs.c | 14 +++++++++++++- wallet/test/run-wallet.c | 2 +- 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index c7190e37c..bf6ed8911 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -80,6 +80,8 @@ msgdata,gossip_get_channel_peer,channel_id,short_channel_id, msgtype,gossip_get_channel_peer_reply,3109 msgdata,gossip_get_channel_peer_reply,peer_id,?node_id, +msgdata,gossip_get_channel_peer_reply,stripped_update_len,u16, +msgdata,gossip_get_channel_peer_reply,stripped_update,u8,stripped_update_len # gossipd->master: we're closing this channel. msgtype,gossip_local_channel_close,3027 diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 1abbecf9a..7fe0ffae4 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -1342,6 +1342,7 @@ static struct io_plan *get_channel_peer(struct io_conn *conn, struct short_channel_id scid; struct local_chan *local_chan; const struct node_id *key; + const u8 *stripped_update; if (!fromwire_gossip_get_channel_peer(msg, &scid)) master_badmsg(WIRE_GOSSIP_GET_CHANNEL_PEER, msg); @@ -1351,11 +1352,28 @@ static struct io_plan *get_channel_peer(struct io_conn *conn, status_debug("Failed to resolve local channel %s", type_to_string(tmpctx, struct short_channel_id, &scid)); key = NULL; + stripped_update = NULL; } else { + const struct half_chan *hc; + key = &local_chan->chan->nodes[!local_chan->direction]->id; + /* Since we're going to use it, make sure it's up-to-date. */ + refresh_local_channel(daemon, local_chan, false); + + hc = &local_chan->chan->half[local_chan->direction]; + if (is_halfchan_defined(hc)) { + const u8 *update; + + update = gossip_store_get(tmpctx, daemon->rstate->gs, + hc->bcast.index); + stripped_update = tal_dup_arr(tmpctx, u8, update + 2, + tal_count(update) - 2, 0); + } else + stripped_update = NULL; } daemon_conn_send(daemon->master, - take(towire_gossip_get_channel_peer_reply(NULL, key))); + take(towire_gossip_get_channel_peer_reply(NULL, key, + stripped_update))); return daemon_conn_read_next(conn, daemon->master); } diff --git a/lightningd/channel.c b/lightningd/channel.c index a34de0f4f..4c4f5de5c 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -265,6 +265,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, = tal_steal(channel, remote_upfront_shutdown_script); channel->option_static_remotekey = option_static_remotekey; channel->forgets = tal_arr(channel, struct command *, 0); + channel->stripped_update = NULL; list_add_tail(&peer->channels, &channel->list); tal_add_destructor(channel, destroy_channel); diff --git a/lightningd/channel.h b/lightningd/channel.h index 3b4f150da..a5bb82441 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -123,6 +123,9 @@ struct channel { /* Any commands trying to forget us. */ struct command **forgets; + + /* Lastest channel_update from gossipd, if any: type stripped! */ + const u8 *stripped_update; }; struct channel *new_channel(struct peer *peer, u64 dbid, diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index f0c24bae4..72ee361da 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -510,6 +510,7 @@ static void forward_htlc(struct htlc_in *hin, struct amount_msat amt_to_forward, u32 outgoing_cltv_value, const struct node_id *next_hop, + const u8 *stripped_update TAKES, const u8 next_onion[TOTAL_PACKET_SIZE]) { enum onion_type failcode; @@ -525,9 +526,17 @@ static void forward_htlc(struct htlc_in *hin, hin, next ? next->scid : NULL, NULL, FORWARD_LOCAL_FAILED, hin->failcode); + if (taken(stripped_update)) + tal_free(stripped_update); return; } + /* OK, apply any channel_update gossipd gave us for this channel. */ + tal_free(next->stripped_update); + next->stripped_update + = tal_dup_arr(next, u8, stripped_update, + tal_count(stripped_update), 0); + /* BOLT #7: * * The origin node: @@ -627,8 +636,10 @@ static void channel_resolve_reply(struct subd *gossip, const u8 *msg, const int *fds UNUSED, struct gossip_resolve *gr) { struct node_id *peer_id; + u8 *stripped_update; - if (!fromwire_gossip_get_channel_peer_reply(msg, msg, &peer_id)) { + if (!fromwire_gossip_get_channel_peer_reply(msg, msg, &peer_id, + &stripped_update)) { log_broken(gossip->log, "bad fromwire_gossip_get_channel_peer_reply %s", tal_hex(msg, msg)); @@ -647,6 +658,7 @@ static void channel_resolve_reply(struct subd *gossip, const u8 *msg, forward_htlc(gr->hin, gr->hin->cltv_expiry, gr->amt_to_forward, gr->outgoing_cltv_value, peer_id, + take(stripped_update), gr->next_onion); tal_free(gr); } diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 364133a48..802b5fdb7 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -116,7 +116,7 @@ bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UN bool fromwire_custommsg_in(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **msg UNNEEDED) { fprintf(stderr, "fromwire_custommsg_in called!\n"); abort(); } /* Generated stub for fromwire_gossip_get_channel_peer_reply */ -bool fromwire_gossip_get_channel_peer_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id **peer_id UNNEEDED) +bool fromwire_gossip_get_channel_peer_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id **peer_id UNNEEDED, u8 **stripped_update UNNEEDED) { fprintf(stderr, "fromwire_gossip_get_channel_peer_reply called!\n"); abort(); } /* Generated stub for fromwire_hsm_sign_commitment_tx_reply */ bool fromwire_hsm_sign_commitment_tx_reply(const void *p UNNEEDED, struct bitcoin_signature *sig UNNEEDED)