From 8c2c1fe1c258fedaa6cfd12e986e0c0c98514150 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 25 Apr 2018 22:07:38 +0930 Subject: [PATCH] openingd: tell gossipd that the peer is important once funding tx in place. And on channel_fail_permanent and closing (the two places we drop to chain), we tell gossipd it's no longer important. Fixes: #1316 Signed-off-by: Rusty Russell --- gossipd/gossip.c | 15 ++++++++++++++- gossipd/gossip_wire.csv | 2 ++ lightningd/channel.c | 9 +++++---- lightningd/closing_control.c | 5 +++++ lightningd/gossip_control.c | 7 ++++++- lightningd/opening_control.c | 21 +++++++++++++++++++++ lightningd/peer_control.c | 2 +- lightningd/peer_control.h | 3 --- wallet/test/run-wallet.c | 3 +++ 9 files changed, 57 insertions(+), 10 deletions(-) diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 7e3b886c6..d263636bd 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -84,6 +84,9 @@ struct daemon { /* To make sure our node_announcement timestamps increase */ u32 last_announce_timestamp; + + /* Only matters if DEVELOPER defined */ + bool no_reconnect; }; /* Peers we're trying to reach. */ @@ -185,6 +188,10 @@ static bool try_reach_peer(struct daemon *daemon, const struct pubkey *id, static void destroy_peer(struct peer *peer) { list_del_from(&peer->daemon->peers, &peer->list); +#if DEVELOPER + if (peer->daemon->no_reconnect) + return; +#endif if (peer->keep_connected) try_reach_peer(peer->daemon, &peer->id, true); } @@ -1498,7 +1505,7 @@ static struct io_plan *gossip_init(struct daemon_conn *master, daemon, msg, &daemon->broadcast_interval, &chain_hash, &daemon->id, &port, &daemon->globalfeatures, &daemon->localfeatures, &daemon->wireaddrs, daemon->rgb, - daemon->alias, &update_channel_interval)) { + daemon->alias, &update_channel_interval, &daemon->no_reconnect)) { master_badmsg(WIRE_GOSSIPCTL_INIT, msg); } /* Prune time is twice update time */ @@ -1825,6 +1832,12 @@ static struct io_plan *peer_important(struct io_conn *conn, if (p) p->keep_connected = important; +#if DEVELOPER + /* With --dev-no-reconnect, we only want explicit connects */ + if (daemon->no_reconnect) + important = false; +#endif + /* If it's important and we're not connected/connecting, do so now. */ if (important && !r && !p) try_reach_peer(daemon, &id, true); diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index 3399b7bd7..32600c543 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -18,6 +18,8 @@ gossipctl_init,,wireaddrs,num_wireaddrs*struct wireaddr gossipctl_init,,rgb,3*u8 gossipctl_init,,alias,32*u8 gossipctl_init,,update_channel_interval,u32 +# DEVELOPER only +gossipctl_init,,no_reconnect,bool # Gossipd->master, I am ready. gossipctl_init_reply,3100 diff --git a/lightningd/channel.c b/lightningd/channel.c index 952e046b7..c2ee3d678 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -309,6 +309,7 @@ void channel_fail_permanent(struct channel *channel, const char *fmt, ...) va_list ap; char *why; struct channel_id cid; + u8 *msg; va_start(ap, fmt); why = tal_vfmt(channel, fmt, ap); @@ -333,6 +334,10 @@ void channel_fail_permanent(struct channel *channel, const char *fmt, ...) channel->error = towire_errorfmt(channel, &cid, "%s", why); } + /* Tell gossipd we no longer need to keep connection to this peer */ + msg = towire_gossipctl_peer_important(NULL, &channel->peer->id, false); + subd_send_msg(ld->gossip, take(msg)); + channel_set_owner(channel, NULL); /* Drop non-cooperatively (unilateral) to chain. */ drop_to_chain(ld, channel, false); @@ -397,8 +402,4 @@ void channel_fail_transient(struct channel *channel, const char *fmt, ...) #endif channel_set_owner(channel, NULL); - - /* Reconnect unless we've dropped/are dropping to chain. */ - if (channel_active(channel)) - try_reconnect(channel->peer); } diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index 225c888b4..ed9357373 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -93,6 +94,10 @@ static void peer_closing_complete(struct channel *channel, const u8 *msg) if (channel->state == CLOSINGD_COMPLETE) return; + /* Tell gossipd we no longer need to keep connection to this peer */ + msg = towire_gossipctl_peer_important(NULL, &channel->peer->id, false); + subd_send_msg(channel->peer->ld->gossip, take(msg)); + /* Channel gets dropped to chain cooperatively. */ drop_to_chain(channel->peer->ld, channel, true); channel_set_state(channel, CLOSINGD_SIGEXCHANGE, CLOSINGD_COMPLETE); diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index f81aac36c..6d62659c7 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -194,6 +194,11 @@ void gossip_init(struct lightningd *ld) u8 *msg; int hsmfd; u64 capabilities = HSM_CAP_ECDH | HSM_CAP_SIGN_GOSSIP; +#if DEVELOPER + bool no_reconnect = ld->no_reconnect; +#else + bool no_reconnect = false; +#endif msg = towire_hsm_client_hsmfd(tmpctx, &ld->id, capabilities); if (!wire_sync_write(ld->hsm_fd, msg)) @@ -218,7 +223,7 @@ void gossip_init(struct lightningd *ld) &get_chainparams(ld)->genesis_blockhash, &ld->id, ld->portnum, get_offered_global_features(tmpctx), get_offered_local_features(tmpctx), ld->wireaddrs, ld->rgb, - ld->alias, ld->config.channel_update_interval); + ld->alias, ld->config.channel_update_interval, no_reconnect); subd_req(ld->gossip, ld->gossip, msg, -1, 0, gossip_init_done, NULL); /* Wait for init done */ diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index b5434db78..18953540b 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -255,6 +255,23 @@ static void funding_broadcast_failed(struct channel *channel, exitstatus, err); } +static void tell_gossipd_peer_is_important(struct lightningd *ld, + const struct channel *channel) +{ + u8 *msg; + +#if DEVELOPER + /* Don't schedule an attempt if we disabled reconnections with + * the `--dev-no-reconnect` flag */ + if (ld->no_reconnect) + return; +#endif /* DEVELOPER */ + + /* Tell gossipd we need to keep connection to this peer */ + msg = towire_gossipctl_peer_important(NULL, &channel->peer->id, true); + subd_send_msg(ld->gossip, take(msg)); +} + static void opening_funder_finished(struct subd *openingd, const u8 *resp, const int *fds, struct funding_channel *fc) @@ -410,6 +427,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, channel_watch_funding(ld, channel); + tell_gossipd_peer_is_important(ld, channel); + /* Start normal channel daemon. */ peer_start_channeld(channel, &cs, gossip_index, fds[0], fds[1], NULL, false); @@ -515,6 +534,8 @@ static void opening_fundee_finished(struct subd *openingd, channel_watch_funding(ld, channel); + tell_gossipd_peer_is_important(ld, channel); + /* On to normal operation! */ peer_start_channeld(channel, &cs, gossip_index, fds[0], fds[1], funding_signed, false); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index ae74e54e9..09727c4ee 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -1090,7 +1090,7 @@ static const struct json_command close_command = { }; AUTODATA(json_command, &close_command); -void try_reconnect(struct peer *peer) +static void try_reconnect(struct peer *peer) { struct lightningd *ld = peer->ld; u8 *msg; diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 4cac8e46d..dd8b524f1 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -61,9 +61,6 @@ struct peer *new_peer(struct lightningd *ld, u64 dbid, /* Also removes from db. */ void delete_peer(struct peer *peer); -/* Tell gossipd to try to reconnect (unless --dev-no-reconnect) */ -void try_reconnect(struct peer *peer); - struct peer *peer_by_id(struct lightningd *ld, const struct pubkey *id); struct peer *peer_from_json(struct lightningd *ld, const char *buffer, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index c65f354db..4fda1a5cd 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -387,6 +387,9 @@ u8 *towire_gossipctl_peer_addrhint(const tal_t *ctx UNNEEDED, const struct pubke /* Generated stub for towire_gossipctl_peer_disconnect */ u8 *towire_gossipctl_peer_disconnect(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED) { fprintf(stderr, "towire_gossipctl_peer_disconnect called!\n"); abort(); } +/* Generated stub for towire_gossipctl_peer_important */ +u8 *towire_gossipctl_peer_important(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED, bool important UNNEEDED) +{ fprintf(stderr, "towire_gossipctl_peer_important called!\n"); abort(); } /* Generated stub for towire_gossipctl_reach_peer */ u8 *towire_gossipctl_reach_peer(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED) { fprintf(stderr, "towire_gossipctl_reach_peer called!\n"); abort(); }