diff --git a/lightningd/gossip/gossip.c b/lightningd/gossip/gossip.c index 4f62fc1c4..37a1144c7 100644 --- a/lightningd/gossip/gossip.c +++ b/lightningd/gossip/gossip.c @@ -418,15 +418,27 @@ static struct io_plan *release_peer(struct io_conn *conn, struct daemon *daemon, "%s", tal_hex(trc, msg)); peer = find_peer(daemon, unique_id); - if (!peer) - status_failed(WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST, - "Unknown peer %"PRIu64, unique_id); + if (!peer) { + /* This can happen with a reconnect vs connect race. + * See gossip_peer_released in master daemon. */ + struct crypto_state dummy; - send_peer_with_fds(peer, - take(towire_gossipctl_release_peer_reply(msg, + status_trace("release_peer: Unknown peer %"PRIu64, unique_id); + memset(&dummy, 0, sizeof(dummy)); + daemon_conn_send(&daemon->master, + take(towire_gossipctl_release_peer_reply(msg, + ~unique_id, + &dummy))); + /* Needs two fds, send dummies. */ + daemon_conn_send_fd(&daemon->master, dup(STDOUT_FILENO)); + daemon_conn_send_fd(&daemon->master, dup(STDOUT_FILENO)); + } else { + send_peer_with_fds(peer, + take(towire_gossipctl_release_peer_reply(msg, unique_id, &peer->pcs.cs))); - io_close_taken_fd(peer->conn); + io_close_taken_fd(peer->conn); + } return daemon_conn_read_next(conn, &daemon->master); } diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 512be11a3..5f981fbe0 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -1846,9 +1846,15 @@ static bool gossip_peer_released(struct subd *gossip, fatal("Gossup daemon gave invalid reply %s", tal_hex(gossip, resp)); - if (id != fc->peer->unique_id) - fatal("Gossup daemon release gave %"PRIu64" not %"PRIu64, - id, fc->peer->unique_id); + /* This is how gossipd handles a reconnect (gossipctl_fail_peer) racing + * with us trying to connect. */ + if (id != fc->peer->unique_id) { + tal_del_destructor(fc, fail_fundchannel_command); + command_fail(fc->cmd, "Peer reconnected, try again"); + close(fds[0]); + close(fds[1]); + return true; + } peer_set_condition(fc->peer, GOSSIPD, OPENINGD); opening = new_subd(fc->peer->ld, ld,