connectd: rely on the master to tell us to reconnect.

connectd tells master about every disconnection, and master knows
whether it's important to reconnect.  Just get the master to invoke a new
connect command if it considers the peer important!

The only twist is timeouts: we don't want to immediately reconnect if
we've failed to connect.  To solve this, connectd passes a 'delaytime'
to the master when a connection fails, and the master passes it back
when it asks for a connection.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-08-09 09:55:29 +09:30 committed by Christian Decker
parent 30f08cc2b0
commit 8939a5001b
14 changed files with 116 additions and 190 deletions

View File

@ -67,43 +67,6 @@
#define INITIAL_WAIT_SECONDS 1
#define MAX_WAIT_SECONDS 300
/* We put everything in this struct (redundantly) to pass it to timer cb */
struct important_peerid {
struct daemon *daemon;
struct pubkey id;
/* How long to wait after failed connect */
unsigned int wait_seconds;
/* The timer we're using to reconnect */
struct oneshot *reconnect_timer;
};
/* We keep a set of peer ids we're always trying to reach. */
static const struct pubkey *
important_peerid_keyof(const struct important_peerid *imp)
{
return &imp->id;
}
static bool important_peerid_eq(const struct important_peerid *imp,
const struct pubkey *key)
{
return pubkey_eq(&imp->id, key);
}
static size_t important_peerid_hash(const struct pubkey *id)
{
return siphash24(siphash_seed(), id, sizeof(*id));
}
HTABLE_DEFINE_TYPE(struct important_peerid,
important_peerid_keyof,
important_peerid_hash,
important_peerid_eq,
important_peerid_map);
struct listen_fd {
int fd;
/* If we bind() IPv6 then IPv4 to same port, we *may* fail to listen()
@ -151,15 +114,9 @@ struct daemon {
struct timers timers;
/* Important peers */
struct important_peerid_map important_peerids;
/* Local and global features to offer to peers. */
u8 *localfeatures, *globalfeatures;
/* Automatically reconnect. */
bool reconnect;
/* Allow localhost to be considered "public" */
bool dev_allow_localhost;
@ -192,6 +149,9 @@ struct reaching {
/* How far did we get? */
const char *connstate;
/* How many seconds did we wait this time? */
u32 seconds_waited;
};
struct peer {
@ -225,9 +185,6 @@ struct addrhint {
struct wireaddr_internal addr;
};
/* FIXME: Reorder */
static void retry_important(struct important_peerid *imp);
static struct peer *find_reconnecting_peer(struct daemon *daemon,
const struct pubkey *id)
{
@ -865,7 +822,7 @@ static struct io_plan *connect_init(struct daemon_conn *master,
daemon, msg,
&daemon->id, &daemon->globalfeatures,
&daemon->localfeatures, &proposed_wireaddr,
&proposed_listen_announce, &daemon->reconnect,
&proposed_listen_announce,
&proxyaddr, &daemon->use_proxy_always,
&daemon->dev_allow_localhost, &daemon->use_dns,
&tor_password)) {
@ -955,48 +912,40 @@ struct io_plan *connection_out(struct io_conn *conn, struct reaching *reach)
handshake_out_success, reach);
}
static void PRINTF_FMT(3,4)
static void PRINTF_FMT(4,5)
connect_failed(struct daemon *daemon,
const struct pubkey *id,
u32 seconds_waited,
const char *errfmt, ...)
{
u8 *msg;
struct important_peerid *imp;
va_list ap;
char *err;
u32 wait_seconds;
va_start(ap, errfmt);
err = tal_vfmt(tmpctx, errfmt, ap);
va_end(ap);
/* Wait twice as long to reconnect, between min and max. */
wait_seconds = seconds_waited * 2;
if (wait_seconds > MAX_WAIT_SECONDS)
wait_seconds = MAX_WAIT_SECONDS;
if (wait_seconds < INITIAL_WAIT_SECONDS)
wait_seconds = INITIAL_WAIT_SECONDS;
/* Tell any connect command what happened. */
msg = towire_connectctl_connect_failed(NULL, id, err);
msg = towire_connectctl_connect_failed(NULL, id, err, wait_seconds);
daemon_conn_send(&daemon->master, take(msg));
status_trace("Failed connected out for %s: %s",
type_to_string(tmpctx, struct pubkey, id),
err);
/* If we want to keep trying, do so. */
imp = important_peerid_map_get(&daemon->important_peerids, id);
if (imp) {
imp->wait_seconds *= 2;
if (imp->wait_seconds > MAX_WAIT_SECONDS)
imp->wait_seconds = MAX_WAIT_SECONDS;
status_trace("...will try again in %u seconds",
imp->wait_seconds);
/* If important_id freed, this will be removed too */
imp->reconnect_timer
= new_reltimer(&daemon->timers, imp,
time_from_sec(imp->wait_seconds),
retry_important, imp);
}
}
static void destroy_io_conn(struct io_conn *conn, struct reaching *reach)
{
connect_failed(reach->daemon, &reach->id,
connect_failed(reach->daemon, &reach->id, reach->seconds_waited,
"%s: %s", reach->connstate, strerror(errno));
tal_free(reach);
}
@ -1128,7 +1077,9 @@ gossip_resolve_addr(const tal_t *ctx, const struct pubkey *id)
return addr;
}
static void try_reach_peer(struct daemon *daemon, const struct pubkey *id)
static void try_reach_peer(struct daemon *daemon,
const struct pubkey *id,
u32 seconds_waited)
{
struct wireaddr_internal *a;
struct addrhint *hint;
@ -1166,7 +1117,7 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id)
}
if (!a) {
connect_failed(daemon, id, "No address known");
connect_failed(daemon, id, seconds_waited, "No address known");
return;
}
@ -1221,7 +1172,7 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id)
fd = socket(af, SOCK_STREAM, 0);
if (fd < 0) {
connect_failed(daemon, id,
connect_failed(daemon, id, seconds_waited,
"Can't open %i socket for %s (%s)",
af,
type_to_string(tmpctx, struct pubkey, id),
@ -1235,6 +1186,7 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id)
reach->id = *id;
reach->addr = *a;
reach->connstate = "Connection establishment";
reach->seconds_waited = seconds_waited;
list_add_tail(&daemon->reaching, &reach->list);
tal_add_destructor(reach, destroy_reaching);
@ -1244,34 +1196,16 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id)
io_new_conn(reach, fd, conn_init, reach);
}
/* Called from timer, so needs single-arg declaration */
static void retry_important(struct important_peerid *imp)
{
/* In case we've come off a timer, don't leave dangling pointer */
imp->reconnect_timer = NULL;
/* With --dev-no-reconnect or --offline, we only want explicit
* connects */
if (!imp->daemon->reconnect)
return;
try_reach_peer(imp->daemon, &imp->id);
}
static struct io_plan *connect_to_peer(struct io_conn *conn,
struct daemon *daemon, const u8 *msg)
{
struct pubkey id;
struct important_peerid *imp;
u32 seconds_waited;
if (!fromwire_connectctl_connect_to_peer(msg, &id))
if (!fromwire_connectctl_connect_to_peer(msg, &id, &seconds_waited))
master_badmsg(WIRE_CONNECTCTL_CONNECT_TO_PEER, msg);
/* If this is an important peer, free any outstanding timer */
imp = important_peerid_map_get(&daemon->important_peerids, &id);
if (imp)
imp->reconnect_timer = tal_free(imp->reconnect_timer);
try_reach_peer(daemon, &id);
try_reach_peer(daemon, &id, seconds_waited);
return daemon_conn_read_next(conn, &daemon->master);
}
@ -1292,46 +1226,11 @@ static struct io_plan *addr_hint(struct io_conn *conn,
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *peer_important(struct io_conn *conn,
struct daemon *daemon, const u8 *msg)
{
struct pubkey id;
bool important;
struct important_peerid *imp;
if (!fromwire_connectctl_peer_important(msg, &id, &important))
master_badmsg(WIRE_CONNECTCTL_PEER_IMPORTANT, msg);
imp = important_peerid_map_get(&daemon->important_peerids, &id);
if (important) {
if (!imp) {
imp = tal(daemon, struct important_peerid);
imp->id = id;
imp->daemon = daemon;
imp->wait_seconds = INITIAL_WAIT_SECONDS;
important_peerid_map_add(&daemon->important_peerids,
imp);
/* Start trying to reaching it now. */
retry_important(imp);
}
} else {
if (imp) {
important_peerid_map_del(&daemon->important_peerids,
imp);
/* Stop trying to reach it (if we are) */
tal_free(find_reaching(daemon, &imp->id));
}
}
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *peer_disconnected(struct io_conn *conn,
struct daemon *daemon, const u8 *msg)
{
struct pubkey id, *key;
struct peer *peer;
struct important_peerid *imp;
if (!fromwire_connectctl_peer_disconnected(msg, &id))
master_badmsg(WIRE_CONNECTCTL_PEER_DISCONNECTED, msg);
@ -1352,11 +1251,6 @@ static struct io_plan *peer_disconnected(struct io_conn *conn,
if (peer)
io_wake(peer);
imp = important_peerid_map_get(&daemon->important_peerids, &id);
if (imp) {
imp->wait_seconds = INITIAL_WAIT_SECONDS;
retry_important(imp);
}
return daemon_conn_read_next(conn, &daemon->master);
}
@ -1378,9 +1272,6 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_CONNECTCTL_PEER_ADDRHINT:
return addr_hint(conn, daemon, master->msg_in);
case WIRE_CONNECTCTL_PEER_IMPORTANT:
return peer_important(conn, daemon, master->msg_in);
case WIRE_CONNECTCTL_PEER_DISCONNECTED:
return peer_disconnected(conn, daemon, master->msg_in);
@ -1418,7 +1309,6 @@ int main(int argc, char *argv[])
list_head_init(&daemon->reconnecting);
list_head_init(&daemon->reaching);
list_head_init(&daemon->addrhints);
important_peerid_map_init(&daemon->important_peerids);
timers_init(&daemon->timers, time_mono());
daemon->broken_resolver_response = NULL;
daemon->listen_fds = tal_arr(daemon, struct listen_fd, 0);

View File

@ -11,7 +11,6 @@ connectctl_init,,lfeatures,lflen*u8
connectctl_init,,num_wireaddrs,u16
connectctl_init,,wireaddrs,num_wireaddrs*struct wireaddr_internal
connectctl_init,,listen_announce,num_wireaddrs*enum addr_listen_announce
connectctl_init,,reconnect,bool
connectctl_init,,tor_proxyaddr,?struct wireaddr
connectctl_init,,use_tor_proxy_always,bool
connectctl_init,,dev_allow_localhost,bool
@ -45,16 +44,13 @@ connectctl_peer_addrhint,,addr,struct wireaddr_internal
# Master -> connectd: connect to a peer.
connectctl_connect_to_peer,2001
connectctl_connect_to_peer,,id,struct pubkey
connectctl_connect_to_peer,,seconds_waited,u32
# Connectd->master: connect failed.
connectctl_connect_failed,2020
connectctl_connect_failed,,id,struct pubkey
connectctl_connect_failed,,failreason,wirestring
# Master -> connectd: try to always maintain connection to this peer (or not)
connectctl_peer_important,2010
connectctl_peer_important,,id,struct pubkey
connectctl_peer_important,,important,bool
connectctl_connect_failed,,seconds_to_delay,u32
# Connectd -> master: we got a peer. Two fds: peer and gossip
connect_peer_connected,2002

1 #include <common/cryptomsg.h>
11 connectctl_init,,wireaddrs,num_wireaddrs*struct wireaddr_internal
12 connectctl_init,,listen_announce,num_wireaddrs*enum addr_listen_announce
13 connectctl_init,,reconnect,bool connectctl_init,,tor_proxyaddr,?struct wireaddr
connectctl_init,,tor_proxyaddr,?struct wireaddr
14 connectctl_init,,use_tor_proxy_always,bool
15 connectctl_init,,dev_allow_localhost,bool
16 connectctl_init,,use_dns,bool
44 # Master -> connectd: try to always maintain connection to this peer (or not) connectctl_connect_failed,,failreason,wirestring
45 connectctl_peer_important,2010 connectctl_connect_failed,,seconds_to_delay,u32
46 connectctl_peer_important,,id,struct pubkey # Connectd -> master: we got a peer. Two fds: peer and gossip
47 connect_peer_connected,2002
48 connectctl_peer_important,,important,bool connect_peer_connected,,id,struct pubkey
49 # Connectd -> master: we got a peer. Two fds: peer and gossip connect_peer_connected,,addr,struct wireaddr_internal
50 connect_peer_connected,2002 connect_peer_connected,,crypto_state,struct crypto_state
51 connect_peer_connected,,id,struct pubkey connect_peer_connected,,gflen,u16
52 connect_peer_connected,,addr,struct wireaddr_internal connect_peer_connected,,gfeatures,gflen*u8
53 connect_peer_connected,,crypto_state,struct crypto_state connect_peer_connected,,lflen,u16
connect_peer_connected,,gflen,u16
connect_peer_connected,,gfeatures,gflen*u8
connect_peer_connected,,lflen,u16
connect_peer_connected,,lfeatures,lflen*u8
54 # master -> connectd: peer has disconnected. connect_peer_connected,,lfeatures,lflen*u8
55 connectctl_peer_disconnected,2015 # master -> connectd: peer has disconnected.
56 connectctl_peer_disconnected,,id,struct pubkey connectctl_peer_disconnected,2015

View File

@ -7,6 +7,7 @@
#include <hsmd/gen_hsm_client_wire.h>
#include <inttypes.h>
#include <lightningd/channel.h>
#include <lightningd/connect_control.h>
#include <lightningd/gen_channel_state_names.h>
#include <lightningd/hsm_control.h>
#include <lightningd/jsonrpc.h>
@ -22,7 +23,8 @@ static bool connects_to_peer(struct subd *owner)
return owner && owner->talks_to_peer;
}
void channel_set_owner(struct channel *channel, struct subd *owner)
void channel_set_owner(struct channel *channel, struct subd *owner,
bool reconnect)
{
struct subd *old_owner = channel->owner;
channel->owner = owner;
@ -33,7 +35,12 @@ void channel_set_owner(struct channel *channel, struct subd *owner)
u8 *msg = towire_connectctl_peer_disconnected(NULL,
&channel->peer->id);
subd_send_msg(channel->peer->ld->connectd, take(msg));
channel->connected = false;
}
if (reconnect) {
/* Reconnect after 1 second: prevents some spurious
* reconnects during tests. */
delay_then_reconnect(channel, 1);
}
}
channel->connected = connects_to_peer(owner);
@ -88,7 +95,7 @@ static void destroy_channel(struct channel *channel)
htlc_state_name(hin->hstate));
/* Free any old owner still hanging around. */
channel_set_owner(channel, NULL);
channel_set_owner(channel, NULL, false);
list_del_from(&channel->peer->channels, &channel->list);
}
@ -342,7 +349,7 @@ void channel_fail_permanent(struct channel *channel, const char *fmt, ...)
channel->error = towire_errorfmt(channel, &cid, "%s", why);
}
channel_set_owner(channel, NULL);
channel_set_owner(channel, NULL, false);
/* Drop non-cooperatively (unilateral) to chain. */
drop_to_chain(ld, channel, false);
tal_free(why);
@ -405,5 +412,5 @@ void channel_fail_transient(struct channel *channel, const char *fmt, ...)
}
#endif
channel_set_owner(channel, NULL);
channel_set_owner(channel, NULL, true);
}

View File

@ -152,7 +152,8 @@ void delete_channel(struct channel *channel);
const char *channel_state_name(const struct channel *channel);
const char *channel_state_str(enum channel_state state);
void channel_set_owner(struct channel *channel, struct subd *owner);
void channel_set_owner(struct channel *channel, struct subd *owner,
bool reconnect);
/* Channel has failed, but can try again. */
PRINTF_FMT(2,3) void channel_fail_transient(struct channel *channel,

View File

@ -206,7 +206,8 @@ bool peer_start_channeld(struct channel *channel,
channel_set_billboard,
take(&peer_fd),
take(&gossip_fd),
take(&hsmfd), NULL));
take(&hsmfd), NULL),
false);
if (!channel->owner) {
log_unusual(channel->log, "Could not subdaemon channel: %s",

View File

@ -89,7 +89,7 @@ static void peer_closing_complete(struct channel *channel, const u8 *msg)
}
/* Don't report spurious failure when closingd exits. */
channel_set_owner(channel, NULL);
channel_set_owner(channel, NULL, false);
/* Clear any transient negotiation messages */
channel_set_billboard(channel, false, NULL);
@ -155,7 +155,9 @@ void peer_start_closingd(struct channel *channel,
channel_set_billboard,
take(&peer_fd), take(&gossip_fd),
take(&hsmfd),
NULL));
NULL),
false);
if (!channel->owner) {
log_unusual(channel->log, "Could not subdaemon closing: %s",
strerror(errno));

View File

@ -4,6 +4,8 @@
#include <ccan/list/list.h>
#include <ccan/tal/str/str.h>
#include <common/features.h>
#include <common/memleak.h>
#include <common/timeout.h>
#include <common/wireaddr.h>
#include <connectd/gen_connect_wire.h>
#include <errno.h>
@ -174,7 +176,7 @@ static void json_connect(struct command *cmd,
subd_send_msg(cmd->ld->connectd, take(msg));
}
msg = towire_connectctl_connect_to_peer(NULL, &id);
msg = towire_connectctl_connect_to_peer(NULL, &id, 0);
subd_send_msg(cmd->ld->connectd, take(msg));
/* Leave this here for peer_connected or connect_failed. */
@ -190,13 +192,52 @@ static const struct json_command connect_command = {
};
AUTODATA(json_command, &connect_command);
struct delayed_reconnect {
struct channel *channel;
u32 seconds_delayed;
};
static void maybe_reconnect(struct delayed_reconnect *d)
{
struct peer *peer = d->channel->peer;
/* Might have gone onchain since we started timer. */
if (channel_active(d->channel)) {
u8 *msg = towire_connectctl_connect_to_peer(NULL, &peer->id,
d->seconds_delayed);
subd_send_msg(peer->ld->connectd, take(msg));
}
tal_free(d);
}
void delay_then_reconnect(struct channel *channel, u32 seconds_delay)
{
struct delayed_reconnect *d;
struct lightningd *ld = channel->peer->ld;
if (!ld->reconnect)
return;
d = tal(channel, struct delayed_reconnect);
d->channel = channel;
d->seconds_delayed = seconds_delay;
log_debug(channel->log, "Will try reconnect in %u seconds",
seconds_delay);
notleak(new_reltimer(&ld->timers, d, time_from_sec(seconds_delay),
maybe_reconnect, d));
}
static void connect_failed(struct lightningd *ld, const u8 *msg)
{
struct pubkey id;
char *err;
struct connect *c;
u32 seconds_to_delay;
struct channel *channel;
if (!fromwire_connectctl_connect_failed(tmpctx, msg, &id, &err))
if (!fromwire_connectctl_connect_failed(tmpctx, msg, &id, &err,
&seconds_to_delay))
fatal("Connect gave bad CONNECTCTL_CONNECT_FAILED message %s",
tal_hex(msg, msg));
@ -205,6 +246,11 @@ static void connect_failed(struct lightningd *ld, const u8 *msg)
/* They delete themselves from list */
command_fail(c->cmd, LIGHTNINGD, "%s", err);
}
/* If we have an active channel, then reconnect. */
channel = active_channel_by_id(ld, &id, NULL);
if (channel)
delay_then_reconnect(channel, seconds_to_delay);
}
void connect_succeeded(struct lightningd *ld, const struct pubkey *id)
@ -244,7 +290,6 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd
case WIRE_CONNECTCTL_ACTIVATE:
case WIRE_CONNECTCTL_PEER_ADDRHINT:
case WIRE_CONNECTCTL_CONNECT_TO_PEER:
case WIRE_CONNECTCTL_PEER_IMPORTANT:
case WIRE_CONNECTCTL_PEER_DISCONNECTED:
/* This is a reply, so never gets through to here. */
case WIRE_CONNECTCTL_INIT_REPLY:
@ -333,7 +378,7 @@ int connectd_init(struct lightningd *ld)
tmpctx, &ld->id,
get_offered_global_features(tmpctx),
get_offered_local_features(tmpctx), wireaddrs,
listen_announce, ld->reconnect,
listen_announce,
ld->proxyaddr, ld->use_proxy_always || ld->pure_tor_setup,
allow_localhost, ld->config.use_dns,
ld->tor_service_password ? ld->tor_service_password : "");

View File

@ -9,6 +9,7 @@ struct pubkey;
int connectd_init(struct lightningd *ld);
void connectd_activate(struct lightningd *ld);
void delay_then_reconnect(struct channel *channel, u32 seconds_delay);
void connect_succeeded(struct lightningd *ld, const struct pubkey *id);
void gossip_connect_result(struct lightningd *ld, const u8 *msg);

View File

@ -82,7 +82,7 @@ static enum watch_result onchain_tx_watched(struct channel *channel,
u32 blockheight = channel->peer->ld->topology->tip->height;
if (depth == 0) {
log_unusual(channel->log, "Chain reorganization!");
channel_set_owner(channel, NULL);
channel_set_owner(channel, NULL, false);
/* FIXME!
topology_rescan(peer->ld->topology, peer->funding_txid);
@ -377,7 +377,7 @@ static void onchain_error(struct channel *channel,
/* FIXME: re-launch? */
log_broken(channel->log, "%s", desc);
channel_set_billboard(channel, true, desc);
channel_set_owner(channel, NULL);
channel_set_owner(channel, NULL, false);
}
/* With a reorg, this can get called multiple times; each time we'll kill
@ -412,7 +412,8 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
onchain_error,
channel_set_billboard,
take(&hsmfd),
NULL));
NULL),
false);
if (!channel->owner) {
log_broken(channel->log, "Could not subdaemon onchain: %s",

View File

@ -218,16 +218,6 @@ static void funding_broadcast_failed(struct channel *channel,
exitstatus, err);
}
void tell_connectd_peer_is_important(struct lightningd *ld,
const struct channel *channel)
{
u8 *msg;
/* Tell connectd we need to keep connection to this peer */
msg = towire_connectctl_peer_important(NULL, &channel->peer->id, true);
subd_send_msg(ld->connectd, take(msg));
}
static void opening_funder_finished(struct subd *openingd, const u8 *resp,
const int *fds,
struct funding_channel *fc)
@ -380,8 +370,6 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
channel_watch_funding(ld, channel);
tell_connectd_peer_is_important(ld, channel);
/* Start normal channel daemon. */
peer_start_channeld(channel, &cs, fds[0], fds[1], NULL, false);
@ -492,8 +480,6 @@ static void opening_fundee_finished(struct subd *openingd,
channel_watch_funding(ld, channel);
tell_connectd_peer_is_important(ld, channel);
/* On to normal operation! */
peer_start_channeld(channel, &cs,
fds[0], fds[1], funding_signed, false);

View File

@ -22,6 +22,4 @@ void opening_peer_no_active_channels(struct peer *peer);
void kill_uncommitted_channel(struct uncommitted_channel *uc,
const char *why);
void tell_connectd_peer_is_important(struct lightningd *ld,
const struct channel *channel);
#endif /* LIGHTNING_LIGHTNINGD_OPENING_CONTROL_H */

View File

@ -360,12 +360,6 @@ register_close_command(struct lightningd *ld,
void drop_to_chain(struct lightningd *ld, struct channel *channel,
bool cooperative)
{
u8 *msg;
/* Tell connectd we no longer need to keep connection to this peer */
msg = towire_connectctl_peer_important(NULL, &channel->peer->id, false);
subd_send_msg(ld->connectd, take(msg));
sign_last_tx(channel);
/* Keep broadcasting until we say stop (can fail due to dup,
@ -929,10 +923,12 @@ static void activate_peer(struct peer *peer)
subd_send_msg(peer->ld->connectd, take(msg));
/* We can only have one active channel: make sure connectd
* knows to reconnect. */
* knows to try reconnecting. */
channel = peer_active_channel(peer);
if (channel)
tell_connectd_peer_is_important(ld, channel);
if (channel && ld->reconnect) {
msg = towire_connectctl_connect_to_peer(NULL, &peer->id, 0);
subd_send_msg(ld->connectd, take(msg));
}
list_for_each(&peer->channels, channel, list) {
/* Watching lockin may be unnecessary, but it's harmless. */
@ -1161,6 +1157,9 @@ static void process_dev_forget_channel(struct bitcoind *bitcoind UNUSED,
json_add_txid(response, "funding_txid", &forget->channel->funding_txid);
json_object_end(response);
/* Set error so we don't try to reconnect. */
forget->channel->error = towire_errorfmt(forget->channel, NULL,
"dev_forget_channel");
delete_channel(forget->channel);
command_success(forget->cmd, response);

View File

@ -82,7 +82,7 @@ def test_reconnect_channel_peers(node_factory, executor):
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
# Wait for exponential backoff to give us a 2 second window.
l1.daemon.wait_for_log('...will try again in 2 seconds')
l1.daemon.wait_for_log('Will try reconnect in 2 seconds')
# It should now succeed when it restarts.
l2.start()

View File

@ -62,6 +62,9 @@ void command_success(struct command *cmd UNNEEDED, struct json_result *response
/* Generated stub for connect_succeeded */
void connect_succeeded(struct lightningd *ld UNNEEDED, const struct pubkey *id UNNEEDED)
{ fprintf(stderr, "connect_succeeded called!\n"); abort(); }
/* Generated stub for delay_then_reconnect */
void delay_then_reconnect(struct channel *channel UNNEEDED, u32 seconds_delay UNNEEDED)
{ fprintf(stderr, "delay_then_reconnect called!\n"); abort(); }
/* Generated stub for fromwire_connect_peer_connected */
bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED)
{ fprintf(stderr, "fromwire_connect_peer_connected called!\n"); abort(); }
@ -315,25 +318,21 @@ void subd_req_(const tal_t *ctx UNNEEDED,
/* Generated stub for subd_send_msg */
void subd_send_msg(struct subd *sd UNNEEDED, const u8 *msg_out UNNEEDED)
{ fprintf(stderr, "subd_send_msg called!\n"); abort(); }
/* Generated stub for tell_connectd_peer_is_important */
void tell_connectd_peer_is_important(struct lightningd *ld UNNEEDED,
const struct channel *channel UNNEEDED)
{ fprintf(stderr, "tell_connectd_peer_is_important called!\n"); abort(); }
/* Generated stub for towire_channel_dev_reenable_commit */
u8 *towire_channel_dev_reenable_commit(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_dev_reenable_commit called!\n"); abort(); }
/* Generated stub for towire_channel_send_shutdown */
u8 *towire_channel_send_shutdown(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_send_shutdown called!\n"); abort(); }
/* Generated stub for towire_connectctl_connect_to_peer */
u8 *towire_connectctl_connect_to_peer(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED, u32 seconds_waited UNNEEDED)
{ fprintf(stderr, "towire_connectctl_connect_to_peer called!\n"); abort(); }
/* Generated stub for towire_connectctl_peer_addrhint */
u8 *towire_connectctl_peer_addrhint(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED, const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "towire_connectctl_peer_addrhint called!\n"); abort(); }
/* Generated stub for towire_connectctl_peer_disconnected */
u8 *towire_connectctl_peer_disconnected(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED)
{ fprintf(stderr, "towire_connectctl_peer_disconnected called!\n"); abort(); }
/* Generated stub for towire_connectctl_peer_important */
u8 *towire_connectctl_peer_important(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED, bool important UNNEEDED)
{ fprintf(stderr, "towire_connectctl_peer_important called!\n"); abort(); }
/* Generated stub for towire_errorfmt */
u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
const struct channel_id *channel UNNEEDED,