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)