mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 10:46:58 +01:00
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:
parent
30f08cc2b0
commit
8939a5001b
14 changed files with 116 additions and 190 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 : "");
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue