mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 07:04:22 +01:00
connectd: hold peer until we're interested.
Either because lightningd tells us it wants to talk, or because the peer says something about a channel. We also introduce a behavior change: we disconnect after a failed open. We might want to modify this later, but we it's a side-effect of openingd not holding onto idle connections. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -312,6 +312,7 @@ static struct peer *new_peer(struct daemon *daemon,
|
|||||||
peer->sent_to_peer = NULL;
|
peer->sent_to_peer = NULL;
|
||||||
peer->urgent = false;
|
peer->urgent = false;
|
||||||
peer->ready_to_die = false;
|
peer->ready_to_die = false;
|
||||||
|
peer->active = false;
|
||||||
peer->peer_outq = msg_queue_new(peer, false);
|
peer->peer_outq = msg_queue_new(peer, false);
|
||||||
|
|
||||||
#if DEVELOPER
|
#if DEVELOPER
|
||||||
@@ -321,11 +322,6 @@ static struct peer *new_peer(struct daemon *daemon,
|
|||||||
|
|
||||||
peer->to_peer = conn;
|
peer->to_peer = conn;
|
||||||
|
|
||||||
/* Aim for connection to shuffle data back and forth: sets up
|
|
||||||
* peer->subds[0] */
|
|
||||||
if (!multiplex_subd_setup(peer, fd_for_subd))
|
|
||||||
return tal_free(peer);
|
|
||||||
|
|
||||||
/* Now we own it */
|
/* Now we own it */
|
||||||
tal_steal(peer, peer->to_peer);
|
tal_steal(peer, peer->to_peer);
|
||||||
peer_htable_add(&daemon->peers, peer);
|
peer_htable_add(&daemon->peers, peer);
|
||||||
@@ -424,9 +420,9 @@ struct io_plan *peer_connected(struct io_conn *conn,
|
|||||||
|
|
||||||
/*~ daemon_conn is a message queue for inter-daemon communication: we
|
/*~ daemon_conn is a message queue for inter-daemon communication: we
|
||||||
* queue up the `connect_peer_connected` message to tell lightningd
|
* queue up the `connect_peer_connected` message to tell lightningd
|
||||||
* we have connected, and give the peer fd. */
|
* we have connected. Once it says something interesting, we tell
|
||||||
|
* it that, too. */
|
||||||
daemon_conn_send(daemon->master, take(msg));
|
daemon_conn_send(daemon->master, take(msg));
|
||||||
daemon_conn_send_fd(daemon->master, subd_fd);
|
|
||||||
|
|
||||||
/*~ Now we set up this connection to read/write from subd */
|
/*~ Now we set up this connection to read/write from subd */
|
||||||
return multiplex_peer_setup(conn, peer);
|
return multiplex_peer_setup(conn, peer);
|
||||||
@@ -1791,7 +1787,7 @@ static void try_connect_peer(struct daemon *daemon,
|
|||||||
existing = peer_htable_get(&daemon->peers, id);
|
existing = peer_htable_get(&daemon->peers, id);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
/* If it's exiting now, we've raced: reconnect after */
|
/* If it's exiting now, we've raced: reconnect after */
|
||||||
if (tal_count(existing->subds) != 0
|
if ((tal_count(existing->subds) != 0 || !existing->active)
|
||||||
&& existing->to_peer
|
&& existing->to_peer
|
||||||
&& !existing->ready_to_die) {
|
&& !existing->ready_to_die) {
|
||||||
/* Tell it it's already connected so it doesn't
|
/* Tell it it's already connected so it doesn't
|
||||||
@@ -1897,9 +1893,11 @@ void peer_conn_closed(struct peer *peer)
|
|||||||
struct connecting *connect = find_connecting(peer->daemon, &peer->id);
|
struct connecting *connect = find_connecting(peer->daemon, &peer->id);
|
||||||
|
|
||||||
/* These should be closed already! */
|
/* These should be closed already! */
|
||||||
assert(!peer->subds);
|
assert(tal_count(peer->subds) == 0);
|
||||||
assert(!peer->to_peer);
|
assert(!peer->to_peer);
|
||||||
assert(peer->ready_to_die);
|
assert(peer->ready_to_die || !peer->active);
|
||||||
|
|
||||||
|
status_peer_debug(&peer->id, "peer_conn_closed");
|
||||||
|
|
||||||
/* Tell gossipd to stop asking this peer gossip queries */
|
/* Tell gossipd to stop asking this peer gossip queries */
|
||||||
daemon_conn_send(peer->daemon->gossipd,
|
daemon_conn_send(peer->daemon->gossipd,
|
||||||
@@ -1923,32 +1921,24 @@ void peer_conn_closed(struct peer *peer)
|
|||||||
try_connect_one_addr(connect);
|
try_connect_one_addr(connect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A peer is gone: clean things up. */
|
|
||||||
static void cleanup_dead_peer(struct daemon *daemon, const struct node_id *id)
|
|
||||||
{
|
|
||||||
struct peer *peer;
|
|
||||||
|
|
||||||
/* We should stay in sync with lightningd at all times. */
|
|
||||||
peer = peer_htable_get(&daemon->peers, id);
|
|
||||||
if (!peer)
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"peer_disconnected unknown peer: %s",
|
|
||||||
type_to_string(tmpctx, struct node_id, id));
|
|
||||||
status_peer_debug(id, "disconnect");
|
|
||||||
|
|
||||||
/* When it's finished, it will call peer_conn_closed() */
|
|
||||||
close_peer_conn(peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lightningd tells us a peer should be disconnected. */
|
/* lightningd tells us a peer should be disconnected. */
|
||||||
static void peer_discard(struct daemon *daemon, const u8 *msg)
|
static void peer_discard(struct daemon *daemon, const u8 *msg)
|
||||||
{
|
{
|
||||||
struct node_id id;
|
struct node_id id;
|
||||||
|
struct peer *peer;
|
||||||
|
|
||||||
if (!fromwire_connectd_discard_peer(msg, &id))
|
if (!fromwire_connectd_discard_peer(msg, &id))
|
||||||
master_badmsg(WIRE_CONNECTD_DISCARD_PEER, msg);
|
master_badmsg(WIRE_CONNECTD_DISCARD_PEER, msg);
|
||||||
|
|
||||||
cleanup_dead_peer(daemon, &id);
|
/* We should stay in sync with lightningd, but this can happen
|
||||||
|
* under stress. */
|
||||||
|
peer = peer_htable_get(&daemon->peers, &id);
|
||||||
|
if (!peer)
|
||||||
|
return;
|
||||||
|
status_peer_debug(&id, "disconnect");
|
||||||
|
|
||||||
|
/* When it's finished, it will call peer_conn_closed() */
|
||||||
|
close_peer_conn(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lightningd tells us to send a msg and disconnect. */
|
/* lightningd tells us to send a msg and disconnect. */
|
||||||
@@ -2031,6 +2021,10 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
|||||||
send_custommsg(daemon, msg);
|
send_custommsg(daemon, msg);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
case WIRE_CONNECTD_PEER_MAKE_ACTIVE:
|
||||||
|
peer_make_active(daemon, msg);
|
||||||
|
goto out;
|
||||||
|
|
||||||
case WIRE_CONNECTD_DEV_MEMLEAK:
|
case WIRE_CONNECTD_DEV_MEMLEAK:
|
||||||
#if DEVELOPER
|
#if DEVELOPER
|
||||||
dev_connect_memleak(daemon, msg);
|
dev_connect_memleak(daemon, msg);
|
||||||
@@ -2041,6 +2035,7 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
|||||||
case WIRE_CONNECTD_ACTIVATE_REPLY:
|
case WIRE_CONNECTD_ACTIVATE_REPLY:
|
||||||
case WIRE_CONNECTD_PEER_CONNECTED:
|
case WIRE_CONNECTD_PEER_CONNECTED:
|
||||||
case WIRE_CONNECTD_PEER_ALREADY_CONNECTED:
|
case WIRE_CONNECTD_PEER_ALREADY_CONNECTED:
|
||||||
|
case WIRE_CONNECTD_PEER_ACTIVE:
|
||||||
case WIRE_CONNECTD_RECONNECTED:
|
case WIRE_CONNECTD_RECONNECTED:
|
||||||
case WIRE_CONNECTD_CONNECT_FAILED:
|
case WIRE_CONNECTD_CONNECT_FAILED:
|
||||||
case WIRE_CONNECTD_DEV_MEMLEAK_REPLY:
|
case WIRE_CONNECTD_DEV_MEMLEAK_REPLY:
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ struct peer {
|
|||||||
* it's done). */
|
* it's done). */
|
||||||
bool ready_to_die;
|
bool ready_to_die;
|
||||||
|
|
||||||
|
/* Has this ever been active? (i.e. ever had a subd attached?) */
|
||||||
|
bool active;
|
||||||
|
|
||||||
/* When socket has Nagle overridden */
|
/* When socket has Nagle overridden */
|
||||||
bool urgent;
|
bool urgent;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <bitcoin/block.h>
|
#include <bitcoin/block.h>
|
||||||
|
#include <common/channel_id.h>
|
||||||
#include <common/cryptomsg.h>
|
#include <common/cryptomsg.h>
|
||||||
#include <common/features.h>
|
#include <common/features.h>
|
||||||
#include <common/node_id.h>
|
#include <common/node_id.h>
|
||||||
@@ -62,7 +63,7 @@ msgdata,connectd_connect_failed,failreason,wirestring,
|
|||||||
msgdata,connectd_connect_failed,seconds_to_delay,u32,
|
msgdata,connectd_connect_failed,seconds_to_delay,u32,
|
||||||
msgdata,connectd_connect_failed,addrhint,?wireaddr_internal,
|
msgdata,connectd_connect_failed,addrhint,?wireaddr_internal,
|
||||||
|
|
||||||
# Connectd -> master: we got a peer. Plus fd for peer daemon
|
# Connectd -> master: we got a peer.
|
||||||
msgtype,connectd_peer_connected,2002
|
msgtype,connectd_peer_connected,2002
|
||||||
msgdata,connectd_peer_connected,id,node_id,
|
msgdata,connectd_peer_connected,id,node_id,
|
||||||
msgdata,connectd_peer_connected,addr,wireaddr_internal,
|
msgdata,connectd_peer_connected,addr,wireaddr_internal,
|
||||||
@@ -75,6 +76,18 @@ msgdata,connectd_peer_connected,features,u8,flen
|
|||||||
msgtype,connectd_peer_disconnect_done,2006
|
msgtype,connectd_peer_disconnect_done,2006
|
||||||
msgdata,connectd_peer_disconnect_done,id,node_id,
|
msgdata,connectd_peer_disconnect_done,id,node_id,
|
||||||
|
|
||||||
|
# Master -> connectd: make peer active immediately (we want to talk)
|
||||||
|
msgtype,connectd_peer_make_active,2004
|
||||||
|
msgdata,connectd_peer_make_active,id,node_id,
|
||||||
|
msgdata,connectd_peer_make_active,channel_id,?channel_id,
|
||||||
|
|
||||||
|
# Connectd -> master: peer said something interesting (or you said make_active)
|
||||||
|
# Plus fd for peer daemon.
|
||||||
|
msgtype,connectd_peer_active,2005
|
||||||
|
msgdata,connectd_peer_active,id,node_id,
|
||||||
|
msgdata,connectd_peer_active,msgtype,?u16,
|
||||||
|
msgdata,connectd_peer_active,channel_id,?channel_id,
|
||||||
|
|
||||||
# master -> connectd: peer no longer wanted, you can disconnect.
|
# master -> connectd: peer no longer wanted, you can disconnect.
|
||||||
msgtype,connectd_discard_peer,2015
|
msgtype,connectd_discard_peer,2015
|
||||||
msgdata,connectd_discard_peer,id,node_id,
|
msgdata,connectd_discard_peer,id,node_id,
|
||||||
|
|||||||
|
@@ -401,6 +401,67 @@ void send_custommsg(struct daemon *daemon, const u8 *msg)
|
|||||||
inject_peer_msg(peer, take(custommsg));
|
inject_peer_msg(peer, take(custommsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: fwd decl */
|
||||||
|
static struct subd *multiplex_subd_setup(struct peer *peer, int *fd_for_subd);
|
||||||
|
|
||||||
|
static struct subd *activate_peer(struct peer *peer,
|
||||||
|
const enum peer_wire *type,
|
||||||
|
const struct channel_id *channel_id)
|
||||||
|
{
|
||||||
|
int fd_for_subd;
|
||||||
|
u16 t, *tp;
|
||||||
|
struct subd *subd;
|
||||||
|
|
||||||
|
/* If it wasn't active before, it is now! */
|
||||||
|
peer->active = true;
|
||||||
|
|
||||||
|
subd = multiplex_subd_setup(peer, &fd_for_subd);
|
||||||
|
if (!subd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* wire routines want a u16, not an enum */
|
||||||
|
if (type) {
|
||||||
|
t = *type;
|
||||||
|
tp = &t;
|
||||||
|
} else {
|
||||||
|
tp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We tell lightningd to fire up a subdaemon to handle this! */
|
||||||
|
daemon_conn_send(peer->daemon->master,
|
||||||
|
take(towire_connectd_peer_active(NULL, &peer->id,
|
||||||
|
tp,
|
||||||
|
channel_id)));
|
||||||
|
daemon_conn_send_fd(peer->daemon->master, fd_for_subd);
|
||||||
|
return subd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void peer_make_active(struct daemon *daemon, const u8 *msg)
|
||||||
|
{
|
||||||
|
struct node_id id;
|
||||||
|
struct peer *peer;
|
||||||
|
struct channel_id *channel_id;
|
||||||
|
|
||||||
|
if (!fromwire_connectd_peer_make_active(msg, msg, &id, &channel_id))
|
||||||
|
master_badmsg(WIRE_CONNECTD_PEER_MAKE_ACTIVE, msg);
|
||||||
|
|
||||||
|
/* Races can happen: this might be gone by now. */
|
||||||
|
peer = peer_htable_get(&daemon->peers, &id);
|
||||||
|
if (!peer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Could be disconnecting now */
|
||||||
|
if (!peer->to_peer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Could be made active already by receiving a message (esp reestablish!) */
|
||||||
|
if (tal_count(peer->subds) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!activate_peer(peer, NULL, channel_id))
|
||||||
|
tal_free(peer);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_ping_in(struct peer *peer, const u8 *msg)
|
static void handle_ping_in(struct peer *peer, const u8 *msg)
|
||||||
{
|
{
|
||||||
u8 *pong;
|
u8 *pong;
|
||||||
@@ -593,7 +654,7 @@ static struct io_plan *write_to_peer(struct io_conn *peer_conn,
|
|||||||
msg = msg_dequeue(peer->peer_outq);
|
msg = msg_dequeue(peer->peer_outq);
|
||||||
|
|
||||||
/* Is it time to send final? */
|
/* Is it time to send final? */
|
||||||
if (!msg && peer->final_msg && !peer->subds) {
|
if (!msg && peer->final_msg && tal_count(peer->subds) == 0) {
|
||||||
/* OK, send this then close. */
|
/* OK, send this then close. */
|
||||||
msg = peer->final_msg;
|
msg = peer->final_msg;
|
||||||
peer->final_msg = NULL;
|
peer->final_msg = NULL;
|
||||||
@@ -603,8 +664,10 @@ static struct io_plan *write_to_peer(struct io_conn *peer_conn,
|
|||||||
|
|
||||||
/* Still nothing to send? */
|
/* Still nothing to send? */
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
/* We close once subds are all closed. */
|
/* We close once subds are all closed; or if we're not
|
||||||
if (!peer->subds) {
|
active, when told to die. */
|
||||||
|
if ((peer->active || peer->ready_to_die)
|
||||||
|
&& tal_count(peer->subds) == 0) {
|
||||||
set_closing_timer(peer, peer_conn);
|
set_closing_timer(peer, peer_conn);
|
||||||
return io_sock_shutdown(peer_conn);
|
return io_sock_shutdown(peer_conn);
|
||||||
}
|
}
|
||||||
@@ -748,10 +811,19 @@ static struct io_plan *read_body_from_peer_done(struct io_conn *peer_conn,
|
|||||||
return read_hdr_from_peer(peer_conn, peer);
|
return read_hdr_from_peer(peer_conn, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't find a subdaemon for this, discard and keep reading. */
|
/* If we don't find a subdaemon for this, activate a new one. */
|
||||||
subd = find_subd(peer, &channel_id);
|
subd = find_subd(peer, &channel_id);
|
||||||
if (!subd)
|
if (!subd) {
|
||||||
return read_hdr_from_peer(peer_conn, peer);
|
struct channel_id channel_id;
|
||||||
|
enum peer_wire t = fromwire_peektype(decrypted);
|
||||||
|
bool has_channel_id = extract_channel_id(decrypted, &channel_id);
|
||||||
|
status_peer_debug(&peer->id, "Activating for message %s",
|
||||||
|
peer_wire_name(t));
|
||||||
|
subd = activate_peer(peer, &t,
|
||||||
|
has_channel_id ? &channel_id : NULL);
|
||||||
|
if (!subd)
|
||||||
|
return io_close(peer_conn);
|
||||||
|
}
|
||||||
|
|
||||||
/* Tell them to write. */
|
/* Tell them to write. */
|
||||||
msg_enqueue(subd->outq, take(decrypted));
|
msg_enqueue(subd->outq, take(decrypted));
|
||||||
@@ -806,19 +878,18 @@ static void destroy_subd(struct subd *subd)
|
|||||||
struct peer *peer = subd->peer;
|
struct peer *peer = subd->peer;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
|
||||||
|
status_peer_debug(&peer->id,
|
||||||
|
"destroy_subd: %zu subds, to_peer conn %p, read_to_die = %u",
|
||||||
|
tal_count(peer->subds), peer->to_peer,
|
||||||
|
peer->ready_to_die);
|
||||||
for (pos = 0; peer->subds[pos] != subd; pos++)
|
for (pos = 0; peer->subds[pos] != subd; pos++)
|
||||||
assert(pos < tal_count(peer->subds));
|
assert(pos < tal_count(peer->subds));
|
||||||
|
|
||||||
tal_arr_remove(&peer->subds, pos);
|
tal_arr_remove(&peer->subds, pos);
|
||||||
|
|
||||||
/* Last one out frees array, sets to NULL as an indicator */
|
/* In case they were waiting for this to send final_msg */
|
||||||
if (tal_count(peer->subds) == 0) {
|
if (tal_count(peer->subds) == 0 && peer->final_msg)
|
||||||
peer->subds = tal_free(peer->subds);
|
msg_wake(peer->peer_outq);
|
||||||
|
|
||||||
/* In case they were waiting for this to send final_msg */
|
|
||||||
if (peer->final_msg)
|
|
||||||
msg_wake(peer->peer_outq);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure we try to keep reading from peer, so we know if
|
/* Make sure we try to keep reading from peer, so we know if
|
||||||
* it hangs up! */
|
* it hangs up! */
|
||||||
@@ -835,7 +906,7 @@ void close_peer_conn(struct peer *peer)
|
|||||||
peer->ready_to_die = true;
|
peer->ready_to_die = true;
|
||||||
|
|
||||||
/* Already dead? */
|
/* Already dead? */
|
||||||
if (!peer->subds && !peer->to_peer) {
|
if (tal_count(peer->subds) == 0 && !peer->to_peer) {
|
||||||
peer_conn_closed(peer);
|
peer_conn_closed(peer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -844,7 +915,7 @@ void close_peer_conn(struct peer *peer)
|
|||||||
msg_wake(peer->peer_outq);
|
msg_wake(peer->peer_outq);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool multiplex_subd_setup(struct peer *peer, int *fd_for_subd)
|
static struct subd *multiplex_subd_setup(struct peer *peer, int *fd_for_subd)
|
||||||
{
|
{
|
||||||
int fds[2];
|
int fds[2];
|
||||||
struct subd *subd;
|
struct subd *subd;
|
||||||
@@ -852,7 +923,7 @@ bool multiplex_subd_setup(struct peer *peer, int *fd_for_subd)
|
|||||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
|
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
|
||||||
status_broken("Failed to create socketpair: %s",
|
status_broken("Failed to create socketpair: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
subd = tal(peer->subds, struct subd);
|
subd = tal(peer->subds, struct subd);
|
||||||
@@ -868,7 +939,7 @@ bool multiplex_subd_setup(struct peer *peer, int *fd_for_subd)
|
|||||||
tal_add_destructor(subd, destroy_subd);
|
tal_add_destructor(subd, destroy_subd);
|
||||||
|
|
||||||
*fd_for_subd = fds[1];
|
*fd_for_subd = fds[1];
|
||||||
return true;
|
return subd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_peer_conn(struct io_conn *peer_conn, struct peer *peer)
|
static void destroy_peer_conn(struct io_conn *peer_conn, struct peer *peer)
|
||||||
@@ -876,14 +947,15 @@ static void destroy_peer_conn(struct io_conn *peer_conn, struct peer *peer)
|
|||||||
assert(peer->to_peer == peer_conn);
|
assert(peer->to_peer == peer_conn);
|
||||||
peer->to_peer = NULL;
|
peer->to_peer = NULL;
|
||||||
|
|
||||||
/* Flush internal connections if not already. */
|
/* Flush internal connections if any. */
|
||||||
if (peer->subds) {
|
if (tal_count(peer->subds) != 0) {
|
||||||
for (size_t i = 0; i < tal_count(peer->subds); i++)
|
for (size_t i = 0; i < tal_count(peer->subds); i++)
|
||||||
msg_wake(peer->subds[i]->outq);
|
msg_wake(peer->subds[i]->outq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peer->ready_to_die)
|
/* If lightningd says we're ready, or we were never had a subd, finish */
|
||||||
|
if (peer->ready_to_die || !peer->active)
|
||||||
peer_conn_closed(peer);
|
peer_conn_closed(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,6 +970,9 @@ struct io_plan *multiplex_peer_setup(struct io_conn *peer_conn,
|
|||||||
peer->expecting_pong = PONG_UNEXPECTED;
|
peer->expecting_pong = PONG_UNEXPECTED;
|
||||||
set_ping_timer(peer);
|
set_ping_timer(peer);
|
||||||
|
|
||||||
|
/* This used to be in openingd; don't break tests. */
|
||||||
|
status_peer_debug(&peer->id, "Handed peer, entering loop");
|
||||||
|
|
||||||
return io_duplex(peer_conn,
|
return io_duplex(peer_conn,
|
||||||
read_hdr_from_peer(peer_conn, peer),
|
read_hdr_from_peer(peer_conn, peer),
|
||||||
write_to_peer(peer_conn, peer));
|
write_to_peer(peer_conn, peer));
|
||||||
@@ -907,7 +982,7 @@ void multiplex_final_msg(struct peer *peer, const u8 *final_msg TAKES)
|
|||||||
{
|
{
|
||||||
peer->ready_to_die = true;
|
peer->ready_to_die = true;
|
||||||
peer->final_msg = tal_dup_talarr(peer, u8, final_msg);
|
peer->final_msg = tal_dup_talarr(peer, u8, final_msg);
|
||||||
if (!peer->subds)
|
if (tal_count(peer->subds) == 0)
|
||||||
io_wake(peer->peer_outq);
|
io_wake(peer->peer_outq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ struct peer;
|
|||||||
struct io_conn;
|
struct io_conn;
|
||||||
struct feature_set;
|
struct feature_set;
|
||||||
|
|
||||||
/* Set up peer->to_subd; sets fd_for_subd to pass to lightningd. */
|
|
||||||
bool multiplex_subd_setup(struct peer *peer, int *fd_for_subd);
|
|
||||||
|
|
||||||
/* Take over peer_conn as peer->to_peer */
|
/* Take over peer_conn as peer->to_peer */
|
||||||
struct io_plan *multiplex_peer_setup(struct io_conn *peer_conn,
|
struct io_plan *multiplex_peer_setup(struct io_conn *peer_conn,
|
||||||
struct peer *peer);
|
struct peer *peer);
|
||||||
@@ -37,4 +34,7 @@ void send_manual_ping(struct daemon *daemon, const u8 *msg);
|
|||||||
|
|
||||||
/* When lightningd says to send a custom message (from a plugin) */
|
/* When lightningd says to send a custom message (from a plugin) */
|
||||||
void send_custommsg(struct daemon *daemon, const u8 *msg);
|
void send_custommsg(struct daemon *daemon, const u8 *msg);
|
||||||
|
|
||||||
|
/* Lightningd wants to talk to you. */
|
||||||
|
void peer_make_active(struct daemon *daemon, const u8 *msg);
|
||||||
#endif /* LIGHTNING_CONNECTD_MULTIPLEX_H */
|
#endif /* LIGHTNING_CONNECTD_MULTIPLEX_H */
|
||||||
|
|||||||
@@ -1369,7 +1369,7 @@ class NodeFactory(object):
|
|||||||
# getpeers.
|
# getpeers.
|
||||||
if not fundchannel:
|
if not fundchannel:
|
||||||
for src, dst in connections:
|
for src, dst in connections:
|
||||||
dst.daemon.wait_for_log(r'{}-.*-chan#[0-9]*: Handed peer, entering loop'.format(src.info['id']))
|
dst.daemon.wait_for_log(r'{}-connectd: Handed peer, entering loop'.format(src.info['id']))
|
||||||
return
|
return
|
||||||
|
|
||||||
bitcoind = nodes[0].bitcoin
|
bitcoind = nodes[0].bitcoin
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ struct open_attempt *new_channel_open_attempt(struct channel *channel)
|
|||||||
oa->our_upfront_shutdown_script = NULL;
|
oa->our_upfront_shutdown_script = NULL;
|
||||||
oa->cmd = NULL;
|
oa->cmd = NULL;
|
||||||
oa->aborted = false;
|
oa->aborted = false;
|
||||||
|
oa->open_msg = NULL;
|
||||||
|
|
||||||
return oa;
|
return oa;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ struct open_attempt {
|
|||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
struct amount_sat funding;
|
struct amount_sat funding;
|
||||||
const u8 *our_upfront_shutdown_script;
|
const u8 *our_upfront_shutdown_script;
|
||||||
|
|
||||||
|
/* First msg to send to dualopend (to make it create channel) */
|
||||||
|
const u8 *open_msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct channel {
|
struct channel {
|
||||||
|
|||||||
@@ -419,6 +419,7 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd
|
|||||||
case WIRE_CONNECTD_DISCARD_PEER:
|
case WIRE_CONNECTD_DISCARD_PEER:
|
||||||
case WIRE_CONNECTD_DEV_MEMLEAK:
|
case WIRE_CONNECTD_DEV_MEMLEAK:
|
||||||
case WIRE_CONNECTD_PEER_FINAL_MSG:
|
case WIRE_CONNECTD_PEER_FINAL_MSG:
|
||||||
|
case WIRE_CONNECTD_PEER_MAKE_ACTIVE:
|
||||||
case WIRE_CONNECTD_PING:
|
case WIRE_CONNECTD_PING:
|
||||||
case WIRE_CONNECTD_SEND_ONIONMSG:
|
case WIRE_CONNECTD_SEND_ONIONMSG:
|
||||||
case WIRE_CONNECTD_CUSTOMMSG_OUT:
|
case WIRE_CONNECTD_CUSTOMMSG_OUT:
|
||||||
@@ -434,9 +435,13 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WIRE_CONNECTD_PEER_CONNECTED:
|
case WIRE_CONNECTD_PEER_CONNECTED:
|
||||||
|
peer_connected(connectd->ld, msg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WIRE_CONNECTD_PEER_ACTIVE:
|
||||||
if (tal_count(fds) != 1)
|
if (tal_count(fds) != 1)
|
||||||
return 1;
|
return 1;
|
||||||
peer_connected(connectd->ld, msg, fds[0]);
|
peer_active(connectd->ld, msg, fds[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WIRE_CONNECTD_PEER_DISCONNECT_DONE:
|
case WIRE_CONNECTD_PEER_DISCONNECT_DONE:
|
||||||
@@ -629,8 +634,7 @@ static struct command_result *json_sendcustommsg(struct command *cmd,
|
|||||||
type_to_string(cmd, struct node_id, dest));
|
type_to_string(cmd, struct node_id, dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: This won't work once connectd keeps peers */
|
if (!peer->is_connected) {
|
||||||
if (!peer_get_owning_subd(peer)) {
|
|
||||||
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||||
"Peer is not connected: %s",
|
"Peer is not connected: %s",
|
||||||
type_to_string(cmd, struct node_id, dest));
|
type_to_string(cmd, struct node_id, dest));
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <common/psbt_open.h>
|
#include <common/psbt_open.h>
|
||||||
#include <common/shutdown_scriptpubkey.h>
|
#include <common/shutdown_scriptpubkey.h>
|
||||||
#include <common/type_to_string.h>
|
#include <common/type_to_string.h>
|
||||||
|
#include <connectd/connectd_wiregen.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <hsmd/capabilities.h>
|
#include <hsmd/capabilities.h>
|
||||||
#include <lightningd/chaintopology.h>
|
#include <lightningd/chaintopology.h>
|
||||||
@@ -2525,7 +2526,6 @@ static struct command_result *json_openchannel_init(struct command *cmd,
|
|||||||
struct open_attempt *oa;
|
struct open_attempt *oa;
|
||||||
struct lease_rates *rates;
|
struct lease_rates *rates;
|
||||||
struct command_result *res;
|
struct command_result *res;
|
||||||
u8 *msg;
|
|
||||||
|
|
||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("id", param_node_id, &id),
|
p_req("id", param_node_id, &id),
|
||||||
@@ -2591,9 +2591,12 @@ static struct command_result *json_openchannel_init(struct command *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
channel = peer_unsaved_channel(peer);
|
channel = peer_unsaved_channel(peer);
|
||||||
if (!channel || !channel->owner)
|
if (!channel) {
|
||||||
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
channel = new_unsaved_channel(peer,
|
||||||
"Peer not connected");
|
peer->ld->config.fee_base,
|
||||||
|
peer->ld->config.fee_per_satoshi);
|
||||||
|
}
|
||||||
|
|
||||||
if (channel->open_attempt
|
if (channel->open_attempt
|
||||||
|| !list_empty(&channel->inflights))
|
|| !list_empty(&channel->inflights))
|
||||||
return command_fail(cmd, FUNDING_STATE_INVALID,
|
return command_fail(cmd, FUNDING_STATE_INVALID,
|
||||||
@@ -2670,7 +2673,7 @@ static struct command_result *json_openchannel_init(struct command *cmd,
|
|||||||
} else
|
} else
|
||||||
our_upfront_shutdown_script_wallet_index = NULL;
|
our_upfront_shutdown_script_wallet_index = NULL;
|
||||||
|
|
||||||
msg = towire_dualopend_opener_init(NULL,
|
oa->open_msg = towire_dualopend_opener_init(oa,
|
||||||
psbt, *amount,
|
psbt, *amount,
|
||||||
oa->our_upfront_shutdown_script,
|
oa->our_upfront_shutdown_script,
|
||||||
our_upfront_shutdown_script_wallet_index,
|
our_upfront_shutdown_script_wallet_index,
|
||||||
@@ -2682,7 +2685,10 @@ static struct command_result *json_openchannel_init(struct command *cmd,
|
|||||||
false,
|
false,
|
||||||
rates);
|
rates);
|
||||||
|
|
||||||
subd_send_msg(channel->owner, take(msg));
|
/* Tell connectd to hand us this so we can start dualopend */
|
||||||
|
subd_send_msg(peer->ld->connectd,
|
||||||
|
take(towire_connectd_peer_make_active(NULL, &peer->id,
|
||||||
|
NULL)));
|
||||||
return command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3056,7 +3062,6 @@ static struct command_result *json_queryrates(struct command *cmd,
|
|||||||
struct wally_psbt *psbt;
|
struct wally_psbt *psbt;
|
||||||
struct open_attempt *oa;
|
struct open_attempt *oa;
|
||||||
u32 *our_upfront_shutdown_script_wallet_index;
|
u32 *our_upfront_shutdown_script_wallet_index;
|
||||||
u8 *msg;
|
|
||||||
struct command_result *res;
|
struct command_result *res;
|
||||||
|
|
||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
@@ -3077,6 +3082,10 @@ static struct command_result *json_queryrates(struct command *cmd,
|
|||||||
return command_fail(cmd, FUNDING_UNKNOWN_PEER, "Unknown peer");
|
return command_fail(cmd, FUNDING_UNKNOWN_PEER, "Unknown peer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!peer->is_connected)
|
||||||
|
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
||||||
|
"Peer not connected");
|
||||||
|
|
||||||
/* We can't query rates for a peer we have a channel with */
|
/* We can't query rates for a peer we have a channel with */
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (channel)
|
if (channel)
|
||||||
@@ -3086,9 +3095,12 @@ static struct command_result *json_queryrates(struct command *cmd,
|
|||||||
channel_state_name(channel));
|
channel_state_name(channel));
|
||||||
|
|
||||||
channel = peer_unsaved_channel(peer);
|
channel = peer_unsaved_channel(peer);
|
||||||
if (!channel || !channel->owner)
|
if (!channel) {
|
||||||
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
channel = new_unsaved_channel(peer,
|
||||||
"Peer not connected");
|
peer->ld->config.fee_base,
|
||||||
|
peer->ld->config.fee_per_satoshi);
|
||||||
|
}
|
||||||
|
|
||||||
if (channel->open_attempt
|
if (channel->open_attempt
|
||||||
|| !list_empty(&channel->inflights))
|
|| !list_empty(&channel->inflights))
|
||||||
return command_fail(cmd, FUNDING_STATE_INVALID,
|
return command_fail(cmd, FUNDING_STATE_INVALID,
|
||||||
@@ -3140,7 +3152,7 @@ static struct command_result *json_queryrates(struct command *cmd,
|
|||||||
} else
|
} else
|
||||||
our_upfront_shutdown_script_wallet_index = NULL;
|
our_upfront_shutdown_script_wallet_index = NULL;
|
||||||
|
|
||||||
msg = towire_dualopend_opener_init(NULL,
|
oa->open_msg = towire_dualopend_opener_init(oa,
|
||||||
psbt, *amount,
|
psbt, *amount,
|
||||||
oa->our_upfront_shutdown_script,
|
oa->our_upfront_shutdown_script,
|
||||||
our_upfront_shutdown_script_wallet_index,
|
our_upfront_shutdown_script_wallet_index,
|
||||||
@@ -3152,7 +3164,10 @@ static struct command_result *json_queryrates(struct command *cmd,
|
|||||||
true,
|
true,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
subd_send_msg(channel->owner, take(msg));
|
/* Tell connectd to hand us this so we can start dualopend */
|
||||||
|
subd_send_msg(peer->ld->connectd,
|
||||||
|
take(towire_connectd_peer_make_active(NULL, &peer->id,
|
||||||
|
NULL)));
|
||||||
return command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3212,9 +3227,9 @@ AUTODATA(json_command, &openchannel_signed_command);
|
|||||||
AUTODATA(json_command, &openchannel_bump_command);
|
AUTODATA(json_command, &openchannel_bump_command);
|
||||||
AUTODATA(json_command, &openchannel_abort_command);
|
AUTODATA(json_command, &openchannel_abort_command);
|
||||||
|
|
||||||
static void start_fresh_dualopend(struct peer *peer,
|
bool peer_start_dualopend(struct peer *peer,
|
||||||
struct peer_fd *peer_fd,
|
struct peer_fd *peer_fd,
|
||||||
struct channel *channel)
|
struct channel *channel)
|
||||||
{
|
{
|
||||||
int hsmfd;
|
int hsmfd;
|
||||||
u32 max_to_self_delay;
|
u32 max_to_self_delay;
|
||||||
@@ -3242,7 +3257,7 @@ static void start_fresh_dualopend(struct peer *peer,
|
|||||||
channel_internal_error(channel,
|
channel_internal_error(channel,
|
||||||
"Running lightningd_dualopend: %s",
|
"Running lightningd_dualopend: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_config(peer->ld, &channel->our_config,
|
channel_config(peer->ld, &channel->our_config,
|
||||||
@@ -3268,7 +3283,7 @@ static void start_fresh_dualopend(struct peer *peer,
|
|||||||
&channel->local_funding_pubkey,
|
&channel->local_funding_pubkey,
|
||||||
channel->minimum_depth);
|
channel->minimum_depth);
|
||||||
subd_send_msg(channel->owner, take(msg));
|
subd_send_msg(channel->owner, take(msg));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_restart_dualopend(struct peer *peer,
|
void peer_restart_dualopend(struct peer *peer,
|
||||||
@@ -3284,7 +3299,7 @@ void peer_restart_dualopend(struct peer *peer,
|
|||||||
u8 *msg;
|
u8 *msg;
|
||||||
|
|
||||||
if (channel_unsaved(channel)) {
|
if (channel_unsaved(channel)) {
|
||||||
start_fresh_dualopend(peer, peer_fd, channel);
|
peer_start_dualopend(peer, peer_fd, channel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hsmfd = hsm_get_client_fd(peer->ld, &peer->id, channel->dbid,
|
hsmfd = hsm_get_client_fd(peer->ld, &peer->id, channel->dbid,
|
||||||
@@ -3374,16 +3389,3 @@ void peer_restart_dualopend(struct peer *peer,
|
|||||||
|
|
||||||
subd_send_msg(channel->owner, take(msg));
|
subd_send_msg(channel->owner, take(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_start_dualopend(struct peer *peer, struct peer_fd *peer_fd)
|
|
||||||
{
|
|
||||||
struct channel *channel;
|
|
||||||
|
|
||||||
/* And we never touch this. */
|
|
||||||
assert(!peer_unsaved_channel(peer));
|
|
||||||
channel = new_unsaved_channel(peer,
|
|
||||||
peer->ld->config.fee_base,
|
|
||||||
peer->ld->config.fee_per_satoshi);
|
|
||||||
|
|
||||||
start_fresh_dualopend(peer, peer_fd, channel);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
struct peer_fd;
|
struct peer_fd;
|
||||||
|
|
||||||
void peer_start_dualopend(struct peer *peer, struct peer_fd *peer_fd);
|
bool peer_start_dualopend(struct peer *peer, struct peer_fd *peer_fd,
|
||||||
|
struct channel *channel);
|
||||||
|
|
||||||
void peer_restart_dualopend(struct peer *peer,
|
void peer_restart_dualopend(struct peer *peer,
|
||||||
struct peer_fd *peer_fd,
|
struct peer_fd *peer_fd,
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ new_uncommitted_channel(struct peer *peer)
|
|||||||
tal_add_destructor(uc, destroy_uncommitted_channel);
|
tal_add_destructor(uc, destroy_uncommitted_channel);
|
||||||
|
|
||||||
uc->got_offer = false;
|
uc->got_offer = false;
|
||||||
|
uc->open_daemon = NULL;
|
||||||
|
|
||||||
return uc;
|
return uc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ struct funding_channel {
|
|||||||
/* Whether or not this is in the middle of getting funded */
|
/* Whether or not this is in the middle of getting funded */
|
||||||
bool inflight;
|
bool inflight;
|
||||||
|
|
||||||
|
/* Initial openingd_funder_start msg */
|
||||||
|
const u8 *open_msg;
|
||||||
|
|
||||||
/* Any commands trying to cancel us. */
|
/* Any commands trying to cancel us. */
|
||||||
struct command **cancels;
|
struct command **cancels;
|
||||||
|
|
||||||
@@ -95,8 +98,7 @@ struct funding_channel {
|
|||||||
struct peer_fd *peer_fd;
|
struct peer_fd *peer_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uncommitted_channel *
|
struct uncommitted_channel *new_uncommitted_channel(struct peer *peer);
|
||||||
new_uncommitted_channel(struct peer *peer);
|
|
||||||
|
|
||||||
void opend_channel_errmsg(struct uncommitted_channel *uc,
|
void opend_channel_errmsg(struct uncommitted_channel *uc,
|
||||||
struct peer_fd *peer_fd,
|
struct peer_fd *peer_fd,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <common/json_tok.h>
|
#include <common/json_tok.h>
|
||||||
#include <common/param.h>
|
#include <common/param.h>
|
||||||
#include <common/type_to_string.h>
|
#include <common/type_to_string.h>
|
||||||
|
#include <connectd/connectd_wiregen.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <hsmd/capabilities.h>
|
#include <hsmd/capabilities.h>
|
||||||
#include <lightningd/chaintopology.h>
|
#include <lightningd/chaintopology.h>
|
||||||
@@ -894,7 +895,7 @@ static unsigned int openingd_msg(struct subd *openingd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_start_openingd(struct peer *peer, struct peer_fd *peer_fd)
|
bool peer_start_openingd(struct peer *peer, struct peer_fd *peer_fd)
|
||||||
{
|
{
|
||||||
int hsmfd;
|
int hsmfd;
|
||||||
u32 max_to_self_delay;
|
u32 max_to_self_delay;
|
||||||
@@ -902,9 +903,9 @@ void peer_start_openingd(struct peer *peer, struct peer_fd *peer_fd)
|
|||||||
struct uncommitted_channel *uc;
|
struct uncommitted_channel *uc;
|
||||||
const u8 *msg;
|
const u8 *msg;
|
||||||
|
|
||||||
assert(!peer->uncommitted_channel);
|
assert(peer->uncommitted_channel);
|
||||||
|
uc = peer->uncommitted_channel;
|
||||||
uc = peer->uncommitted_channel = new_uncommitted_channel(peer);
|
assert(!uc->open_daemon);
|
||||||
|
|
||||||
hsmfd = hsm_get_client_fd(peer->ld, &uc->peer->id, uc->dbid,
|
hsmfd = hsm_get_client_fd(peer->ld, &uc->peer->id, uc->dbid,
|
||||||
HSM_CAP_COMMITMENT_POINT
|
HSM_CAP_COMMITMENT_POINT
|
||||||
@@ -925,7 +926,7 @@ void peer_start_openingd(struct peer *peer, struct peer_fd *peer_fd)
|
|||||||
"Running lightning_openingd: %s",
|
"Running lightning_openingd: %s",
|
||||||
strerror(errno)));
|
strerror(errno)));
|
||||||
tal_free(uc);
|
tal_free(uc);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel_config(peer->ld, &uc->our_config,
|
channel_config(peer->ld, &uc->our_config,
|
||||||
@@ -954,6 +955,7 @@ void peer_start_openingd(struct peer *peer, struct peer_fd *peer_fd)
|
|||||||
feerate_max(peer->ld, NULL),
|
feerate_max(peer->ld, NULL),
|
||||||
IFDEV(peer->ld->dev_force_tmp_channel_id, NULL));
|
IFDEV(peer->ld->dev_force_tmp_channel_id, NULL));
|
||||||
subd_send_msg(uc->open_daemon, take(msg));
|
subd_send_msg(uc->open_daemon, take(msg));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct command_result *json_fundchannel_complete(struct command *cmd,
|
static struct command_result *json_fundchannel_complete(struct command *cmd,
|
||||||
@@ -986,12 +988,15 @@ static struct command_result *json_fundchannel_complete(struct command *cmd,
|
|||||||
return command_fail(cmd, LIGHTNINGD, "Peer already %s",
|
return command_fail(cmd, LIGHTNINGD, "Peer already %s",
|
||||||
channel_state_name(channel));
|
channel_state_name(channel));
|
||||||
|
|
||||||
if (!peer->uncommitted_channel)
|
if (!peer->is_connected)
|
||||||
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
||||||
"Peer not connected");
|
"Peer not connected");
|
||||||
|
|
||||||
if (!peer->uncommitted_channel->fc || !peer->uncommitted_channel->fc->inflight)
|
if (!peer->uncommitted_channel
|
||||||
|
|| !peer->uncommitted_channel->fc
|
||||||
|
|| !peer->uncommitted_channel->fc->inflight)
|
||||||
return command_fail(cmd, LIGHTNINGD, "No channel funding in progress.");
|
return command_fail(cmd, LIGHTNINGD, "No channel funding in progress.");
|
||||||
|
|
||||||
if (peer->uncommitted_channel->fc->cmd)
|
if (peer->uncommitted_channel->fc->cmd)
|
||||||
return command_fail(cmd, LIGHTNINGD, "Channel funding in progress.");
|
return command_fail(cmd, LIGHTNINGD, "Channel funding in progress.");
|
||||||
|
|
||||||
@@ -1082,6 +1087,8 @@ static struct command_result *json_fundchannel_cancel(struct command *cmd,
|
|||||||
return command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_debug(cmd->ld->log, "fundchannel_cancel no uncommitted_channel!");
|
||||||
|
|
||||||
/* Handle `fundchannel_cancel` after `fundchannel_complete`. */
|
/* Handle `fundchannel_cancel` after `fundchannel_complete`. */
|
||||||
return cancel_channel_before_broadcast(cmd, peer);
|
return cancel_channel_before_broadcast(cmd, peer);
|
||||||
}
|
}
|
||||||
@@ -1101,7 +1108,6 @@ static struct command_result *json_fundchannel_start(struct command *cmd,
|
|||||||
bool *announce_channel;
|
bool *announce_channel;
|
||||||
u32 *feerate_per_kw;
|
u32 *feerate_per_kw;
|
||||||
|
|
||||||
u8 *msg = NULL;
|
|
||||||
struct amount_sat *amount;
|
struct amount_sat *amount;
|
||||||
struct amount_msat *push_msat;
|
struct amount_msat *push_msat;
|
||||||
u32 *upfront_shutdown_script_wallet_index;
|
u32 *upfront_shutdown_script_wallet_index;
|
||||||
@@ -1154,6 +1160,10 @@ static struct command_result *json_fundchannel_start(struct command *cmd,
|
|||||||
return command_fail(cmd, FUNDING_UNKNOWN_PEER, "Unknown peer");
|
return command_fail(cmd, FUNDING_UNKNOWN_PEER, "Unknown peer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!peer->is_connected)
|
||||||
|
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
||||||
|
"Peer not connected");
|
||||||
|
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer already %s",
|
return command_fail(cmd, LIGHTNINGD, "Peer already %s",
|
||||||
@@ -1170,9 +1180,10 @@ static struct command_result *json_fundchannel_start(struct command *cmd,
|
|||||||
" must use `openchannel_init` not"
|
" must use `openchannel_init` not"
|
||||||
" `fundchannel_start`.");
|
" `fundchannel_start`.");
|
||||||
|
|
||||||
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
log_debug(cmd->ld->log, "fundchannel_start: allocating uncommitted_channel");
|
||||||
"Peer not connected");
|
peer->uncommitted_channel = new_uncommitted_channel(peer);
|
||||||
}
|
} else
|
||||||
|
log_debug(cmd->ld->log, "fundchannel_start: reusing uncommitted_channel");
|
||||||
|
|
||||||
if (peer->uncommitted_channel->fc) {
|
if (peer->uncommitted_channel->fc) {
|
||||||
return command_fail(cmd, LIGHTNINGD, "Already funding channel");
|
return command_fail(cmd, LIGHTNINGD, "Already funding channel");
|
||||||
@@ -1228,7 +1239,8 @@ static struct command_result *json_fundchannel_start(struct command *cmd,
|
|||||||
} else
|
} else
|
||||||
upfront_shutdown_script_wallet_index = NULL;
|
upfront_shutdown_script_wallet_index = NULL;
|
||||||
|
|
||||||
msg = towire_openingd_funder_start(NULL,
|
fc->open_msg
|
||||||
|
= towire_openingd_funder_start(fc,
|
||||||
*amount,
|
*amount,
|
||||||
fc->push,
|
fc->push,
|
||||||
fc->our_upfront_shutdown_script,
|
fc->our_upfront_shutdown_script,
|
||||||
@@ -1236,7 +1248,10 @@ static struct command_result *json_fundchannel_start(struct command *cmd,
|
|||||||
*feerate_per_kw,
|
*feerate_per_kw,
|
||||||
fc->channel_flags);
|
fc->channel_flags);
|
||||||
|
|
||||||
subd_send_msg(peer->uncommitted_channel->open_daemon, take(msg));
|
/* Tell connectd to make this active; when it does, we can continue */
|
||||||
|
subd_send_msg(peer->ld->connectd,
|
||||||
|
take(towire_connectd_peer_make_active(NULL, &peer->id,
|
||||||
|
NULL)));
|
||||||
return command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ struct uncommitted_channel;
|
|||||||
void json_add_uncommitted_channel(struct json_stream *response,
|
void json_add_uncommitted_channel(struct json_stream *response,
|
||||||
const struct uncommitted_channel *uc);
|
const struct uncommitted_channel *uc);
|
||||||
|
|
||||||
void peer_start_openingd(struct peer *peer,
|
bool peer_start_openingd(struct peer *peer,
|
||||||
struct peer_fd *peer_fd);
|
struct peer_fd *peer_fd);
|
||||||
|
|
||||||
struct subd *peer_get_owning_subd(struct peer *peer);
|
struct subd *peer_get_owning_subd(struct peer *peer);
|
||||||
|
|||||||
@@ -944,7 +944,6 @@ struct peer_connected_hook_payload {
|
|||||||
struct wireaddr *remote_addr;
|
struct wireaddr *remote_addr;
|
||||||
bool incoming;
|
bool incoming;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
struct peer_fd *peer_fd;
|
|
||||||
u8 *error;
|
u8 *error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1028,11 +1027,6 @@ static void peer_connected_hook_final(struct peer_connected_hook_payload *payloa
|
|||||||
}
|
}
|
||||||
case DUALOPEND_OPEN_INIT:
|
case DUALOPEND_OPEN_INIT:
|
||||||
case DUALOPEND_AWAITING_LOCKIN:
|
case DUALOPEND_AWAITING_LOCKIN:
|
||||||
assert(!channel->owner);
|
|
||||||
channel->peer->addr = addr;
|
|
||||||
channel->peer->connected_incoming = payload->incoming;
|
|
||||||
peer_restart_dualopend(peer, payload->peer_fd, channel);
|
|
||||||
return;
|
|
||||||
case CHANNELD_AWAITING_LOCKIN:
|
case CHANNELD_AWAITING_LOCKIN:
|
||||||
case CHANNELD_NORMAL:
|
case CHANNELD_NORMAL:
|
||||||
case CHANNELD_SHUTTING_DOWN:
|
case CHANNELD_SHUTTING_DOWN:
|
||||||
@@ -1040,31 +1034,31 @@ static void peer_connected_hook_final(struct peer_connected_hook_payload *payloa
|
|||||||
assert(!channel->owner);
|
assert(!channel->owner);
|
||||||
channel->peer->addr = addr;
|
channel->peer->addr = addr;
|
||||||
channel->peer->connected_incoming = payload->incoming;
|
channel->peer->connected_incoming = payload->incoming;
|
||||||
peer_start_channeld(channel, payload->peer_fd, NULL, true,
|
goto make_active;
|
||||||
NULL);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here, it means we have no channel */
|
/* If we get here, it means we have no channel */
|
||||||
assert(!channel);
|
assert(!channel);
|
||||||
if (feature_negotiated(ld->our_features,
|
|
||||||
peer->their_features,
|
|
||||||
OPT_DUAL_FUND)) {
|
|
||||||
peer_start_dualopend(peer, payload->peer_fd);
|
|
||||||
} else
|
|
||||||
peer_start_openingd(peer, payload->peer_fd);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
send_error:
|
send_error:
|
||||||
log_debug(ld->log, "Telling connectd to send error %s",
|
log_peer_debug(ld->log, &peer->id, "Telling connectd to send error %s",
|
||||||
tal_hex(tmpctx, error));
|
tal_hex(tmpctx, error));
|
||||||
/* Get connectd to send error and close. */
|
/* Get connectd to send error and close. */
|
||||||
subd_send_msg(ld->connectd,
|
subd_send_msg(ld->connectd,
|
||||||
take(towire_connectd_peer_final_msg(NULL, &peer->id,
|
take(towire_connectd_peer_final_msg(NULL, &peer->id,
|
||||||
error)));
|
error)));
|
||||||
tal_free(payload->peer_fd);
|
return;
|
||||||
|
|
||||||
|
make_active:
|
||||||
|
log_peer_debug(ld->log, &peer->id,
|
||||||
|
"Telling connectd to make active, state %s",
|
||||||
|
channel_state_name(channel));
|
||||||
|
subd_send_msg(ld->connectd,
|
||||||
|
take(towire_connectd_peer_make_active(NULL, &peer->id,
|
||||||
|
&channel->cid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -1179,8 +1173,8 @@ REGISTER_PLUGIN_HOOK(peer_connected,
|
|||||||
struct peer_connected_hook_payload *);
|
struct peer_connected_hook_payload *);
|
||||||
|
|
||||||
/* Connectd tells us a peer has connected: it never hands us duplicates, since
|
/* Connectd tells us a peer has connected: it never hands us duplicates, since
|
||||||
* it holds them until we say peer_died. */
|
* it holds them until we say peer_disconnected. */
|
||||||
void peer_connected(struct lightningd *ld, const u8 *msg, int peer_fd)
|
void peer_connected(struct lightningd *ld, const u8 *msg)
|
||||||
{
|
{
|
||||||
struct node_id id;
|
struct node_id id;
|
||||||
u8 *their_features;
|
u8 *their_features;
|
||||||
@@ -1198,8 +1192,6 @@ void peer_connected(struct lightningd *ld, const u8 *msg, int peer_fd)
|
|||||||
fatal("Connectd gave bad CONNECT_PEER_CONNECTED message %s",
|
fatal("Connectd gave bad CONNECT_PEER_CONNECTED message %s",
|
||||||
tal_hex(msg, msg));
|
tal_hex(msg, msg));
|
||||||
|
|
||||||
hook_payload->peer_fd = new_peer_fd(hook_payload, peer_fd);
|
|
||||||
|
|
||||||
/* If we're already dealing with this peer, hand off to correct
|
/* If we're already dealing with this peer, hand off to correct
|
||||||
* subdaemon. Otherwise, we'll hand to openingd to wait there. */
|
* subdaemon. Otherwise, we'll hand to openingd to wait there. */
|
||||||
peer = peer_by_id(ld, &id);
|
peer = peer_by_id(ld, &id);
|
||||||
@@ -1237,6 +1229,137 @@ void peer_connected(struct lightningd *ld, const u8 *msg, int peer_fd)
|
|||||||
plugin_hook_call_peer_connected(ld, hook_payload);
|
plugin_hook_call_peer_connected(ld, hook_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* connectd tells us a peer has an interesting message, and hands us an
|
||||||
|
* fd to give to the correct subdaemon. Unlike peer_connected, this is racy:
|
||||||
|
* we might have just told it to disconnect peer. */
|
||||||
|
void peer_active(struct lightningd *ld, const u8 *msg, int fd)
|
||||||
|
{
|
||||||
|
struct node_id id;
|
||||||
|
u16 *msgtype;
|
||||||
|
struct channel *channel;
|
||||||
|
struct channel_id *channel_id;
|
||||||
|
struct peer *peer;
|
||||||
|
bool dual_fund;
|
||||||
|
u8 *error;
|
||||||
|
struct peer_fd *peer_fd = new_peer_fd(tmpctx, fd);
|
||||||
|
|
||||||
|
/* FIXME: Use msgtype to determine what to do! */
|
||||||
|
if (!fromwire_connectd_peer_active(msg, msg, &id, &msgtype, &channel_id))
|
||||||
|
fatal("Connectd gave bad CONNECTD_PEER_ACTIVE message %s",
|
||||||
|
tal_hex(msg, msg));
|
||||||
|
|
||||||
|
peer = peer_by_id(ld, &id);
|
||||||
|
if (!peer) {
|
||||||
|
/* This race is possible, but I want to see it in CI. */
|
||||||
|
log_broken(ld->log, "Unknown active peer %s",
|
||||||
|
type_to_string(tmpctx, struct node_id, &id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel = peer_active_channel(peer);
|
||||||
|
|
||||||
|
/* It might be v2 opening, though, since we hang onto these */
|
||||||
|
if (!channel)
|
||||||
|
channel = peer_unsaved_channel(peer);
|
||||||
|
|
||||||
|
if (channel) {
|
||||||
|
switch (channel->state) {
|
||||||
|
case ONCHAIN:
|
||||||
|
case FUNDING_SPEND_SEEN:
|
||||||
|
case CLOSINGD_COMPLETE:
|
||||||
|
/* Channel is supposed to be active!*/
|
||||||
|
abort();
|
||||||
|
case CLOSED:
|
||||||
|
/* Channel should not have been loaded */
|
||||||
|
abort();
|
||||||
|
|
||||||
|
/* We consider this "active" but we only send an error */
|
||||||
|
case AWAITING_UNILATERAL: {
|
||||||
|
/* channel->error is not saved in db, so this can
|
||||||
|
* happen if we restart. */
|
||||||
|
error = towire_errorfmt(tmpctx, &channel->cid,
|
||||||
|
"Awaiting unilateral close");
|
||||||
|
goto send_error;
|
||||||
|
}
|
||||||
|
case DUALOPEND_OPEN_INIT:
|
||||||
|
/* We asked for this, to open? */
|
||||||
|
if (!msgtype
|
||||||
|
&& channel->open_attempt
|
||||||
|
&& channel->open_attempt->open_msg) {
|
||||||
|
if (peer_start_dualopend(peer, peer_fd, channel))
|
||||||
|
subd_send_msg(channel->owner, channel->open_attempt->open_msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Fall through. */
|
||||||
|
case DUALOPEND_AWAITING_LOCKIN:
|
||||||
|
assert(!channel->owner);
|
||||||
|
peer_restart_dualopend(peer, peer_fd, channel);
|
||||||
|
return;
|
||||||
|
case CHANNELD_AWAITING_LOCKIN:
|
||||||
|
case CHANNELD_NORMAL:
|
||||||
|
case CHANNELD_SHUTTING_DOWN:
|
||||||
|
case CLOSINGD_SIGEXCHANGE:
|
||||||
|
assert(!channel->owner);
|
||||||
|
peer_start_channeld(channel,
|
||||||
|
peer_fd,
|
||||||
|
NULL, true,
|
||||||
|
NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
dual_fund = feature_negotiated(ld->our_features,
|
||||||
|
peer->their_features,
|
||||||
|
OPT_DUAL_FUND);
|
||||||
|
|
||||||
|
/* Did we ask for this? */
|
||||||
|
if (!msgtype) {
|
||||||
|
/* If it was dual_fund, it will have peer_unsaved_channel above */
|
||||||
|
if (dual_fund) {
|
||||||
|
log_broken(ld->log, "Unsolicited active df peer %s?",
|
||||||
|
type_to_string(tmpctx, struct node_id,
|
||||||
|
&peer->id));
|
||||||
|
} else {
|
||||||
|
const struct uncommitted_channel *uc
|
||||||
|
= peer->uncommitted_channel;
|
||||||
|
|
||||||
|
if (!uc->open_daemon
|
||||||
|
&& uc->fc
|
||||||
|
&& uc->fc->open_msg) {
|
||||||
|
if (peer_start_openingd(peer, peer_fd)) {
|
||||||
|
subd_send_msg(uc->open_daemon,
|
||||||
|
uc->fc->open_msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_broken(ld->log, "Unsolicited active peer %s?",
|
||||||
|
type_to_string(tmpctx, struct node_id,
|
||||||
|
&peer->id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* OK, it's unsolicited. What kind of open do they want? */
|
||||||
|
if (dual_fund) {
|
||||||
|
channel = new_unsaved_channel(peer,
|
||||||
|
peer->ld->config.fee_base,
|
||||||
|
peer->ld->config.fee_per_satoshi);
|
||||||
|
peer_start_dualopend(peer, peer_fd, channel);
|
||||||
|
} else {
|
||||||
|
peer->uncommitted_channel = new_uncommitted_channel(peer);
|
||||||
|
peer_start_openingd(peer, peer_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
send_error:
|
||||||
|
log_peer_debug(ld->log, &peer->id, "Telling connectd to send error %s",
|
||||||
|
tal_hex(tmpctx, error));
|
||||||
|
/* Get connectd to send error and close. */
|
||||||
|
subd_send_msg(ld->connectd,
|
||||||
|
take(towire_connectd_peer_final_msg(NULL, &peer->id,
|
||||||
|
error)));
|
||||||
|
}
|
||||||
|
|
||||||
struct disconnect_command {
|
struct disconnect_command {
|
||||||
struct list_node list;
|
struct list_node list;
|
||||||
/* Command structure. This is the parent of the close command. */
|
/* Command structure. This is the parent of the close command. */
|
||||||
@@ -1262,8 +1385,13 @@ void peer_disconnect_done(struct lightningd *ld, const u8 *msg)
|
|||||||
|
|
||||||
/* If we still have peer, it's disconnected now */
|
/* If we still have peer, it's disconnected now */
|
||||||
p = peer_by_id(ld, &id);
|
p = peer_by_id(ld, &id);
|
||||||
if (p)
|
if (p) {
|
||||||
p->is_connected = false;
|
p->is_connected = false;
|
||||||
|
/* If we only cared about peer because of connectd, free it. */
|
||||||
|
if (list_empty(&p->channels) && !p->uncommitted_channel) {
|
||||||
|
tal_free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Fire off plugin notifications */
|
/* Fire off plugin notifications */
|
||||||
notify_disconnect(ld, &id);
|
notify_disconnect(ld, &id);
|
||||||
@@ -1744,6 +1872,9 @@ static struct command_result *json_disconnect(struct command *cmd,
|
|||||||
|
|
||||||
peer = peer_by_id(cmd->ld, id);
|
peer = peer_by_id(cmd->ld, id);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
|
return command_fail(cmd, LIGHTNINGD, "Unknown peer");
|
||||||
|
}
|
||||||
|
if (!peer->is_connected) {
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
}
|
}
|
||||||
channel = peer_active_channel(peer);
|
channel = peer_active_channel(peer);
|
||||||
@@ -1761,11 +1892,15 @@ static struct command_result *json_disconnect(struct command *cmd,
|
|||||||
channel_unsaved_close_conn(channel, "disconnect command");
|
channel_unsaved_close_conn(channel, "disconnect command");
|
||||||
goto wait_for_connectd;
|
goto wait_for_connectd;
|
||||||
}
|
}
|
||||||
if (!peer->uncommitted_channel) {
|
if (peer->uncommitted_channel) {
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
kill_uncommitted_channel(peer->uncommitted_channel,
|
||||||
|
"disconnect command");
|
||||||
|
goto wait_for_connectd;
|
||||||
}
|
}
|
||||||
kill_uncommitted_channel(peer->uncommitted_channel,
|
|
||||||
"disconnect command");
|
/* It's just sitting in connectd. */
|
||||||
|
subd_send_msg(cmd->ld->connectd,
|
||||||
|
take(towire_connectd_discard_peer(NULL, id)));
|
||||||
|
|
||||||
wait_for_connectd:
|
wait_for_connectd:
|
||||||
/* Connectd tells us when it's finally disconnected */
|
/* Connectd tells us when it's finally disconnected */
|
||||||
|
|||||||
@@ -67,8 +67,9 @@ struct peer *peer_from_json(struct lightningd *ld,
|
|||||||
const char *buffer,
|
const char *buffer,
|
||||||
const jsmntok_t *peeridtok);
|
const jsmntok_t *peeridtok);
|
||||||
|
|
||||||
void peer_connected(struct lightningd *ld, const u8 *msg, int peer_fd);
|
void peer_connected(struct lightningd *ld, const u8 *msg);
|
||||||
void peer_disconnect_done(struct lightningd *ld, const u8 *msg);
|
void peer_disconnect_done(struct lightningd *ld, const u8 *msg);
|
||||||
|
void peer_active(struct lightningd *ld, const u8 *msg, int peer_fd);
|
||||||
|
|
||||||
/* Could be configurable. */
|
/* Could be configurable. */
|
||||||
#define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL
|
#define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL
|
||||||
|
|||||||
@@ -204,6 +204,9 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
|||||||
/* Generated stub for fromwire_channeld_dev_memleak_reply */
|
/* Generated stub for fromwire_channeld_dev_memleak_reply */
|
||||||
bool fromwire_channeld_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
|
bool fromwire_channeld_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_channeld_dev_memleak_reply called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_channeld_dev_memleak_reply called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_connectd_peer_active */
|
||||||
|
bool fromwire_connectd_peer_active(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u16 **msgtype UNNEEDED, struct channel_id **channel_id UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_connectd_peer_active called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_connectd_peer_connected */
|
/* Generated stub for fromwire_connectd_peer_connected */
|
||||||
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED)
|
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
|
||||||
@@ -460,6 +463,14 @@ struct oneshot *new_reltimer_(struct timers *timers UNNEEDED,
|
|||||||
struct timerel expire UNNEEDED,
|
struct timerel expire UNNEEDED,
|
||||||
void (*cb)(void *) UNNEEDED, void *arg UNNEEDED)
|
void (*cb)(void *) UNNEEDED, void *arg UNNEEDED)
|
||||||
{ fprintf(stderr, "new_reltimer_ called!\n"); abort(); }
|
{ fprintf(stderr, "new_reltimer_ called!\n"); abort(); }
|
||||||
|
/* Generated stub for new_uncommitted_channel */
|
||||||
|
struct uncommitted_channel *new_uncommitted_channel(struct peer *peer UNNEEDED)
|
||||||
|
{ fprintf(stderr, "new_uncommitted_channel called!\n"); abort(); }
|
||||||
|
/* Generated stub for new_unsaved_channel */
|
||||||
|
struct channel *new_unsaved_channel(struct peer *peer UNNEEDED,
|
||||||
|
u32 feerate_base UNNEEDED,
|
||||||
|
u32 feerate_ppm UNNEEDED)
|
||||||
|
{ fprintf(stderr, "new_unsaved_channel called!\n"); abort(); }
|
||||||
/* Generated stub for node_id_cmp */
|
/* Generated stub for node_id_cmp */
|
||||||
int node_id_cmp(const struct node_id *a UNNEEDED, const struct node_id *b UNNEEDED)
|
int node_id_cmp(const struct node_id *a UNNEEDED, const struct node_id *b UNNEEDED)
|
||||||
{ fprintf(stderr, "node_id_cmp called!\n"); abort(); }
|
{ fprintf(stderr, "node_id_cmp called!\n"); abort(); }
|
||||||
@@ -586,10 +597,11 @@ void peer_start_channeld(struct channel *channel UNNEEDED,
|
|||||||
const u8 *reestablish_only UNNEEDED)
|
const u8 *reestablish_only UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); }
|
{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); }
|
||||||
/* Generated stub for peer_start_dualopend */
|
/* Generated stub for peer_start_dualopend */
|
||||||
void peer_start_dualopend(struct peer *peer UNNEEDED, struct peer_fd *peer_fd UNNEEDED)
|
bool peer_start_dualopend(struct peer *peer UNNEEDED, struct peer_fd *peer_fd UNNEEDED,
|
||||||
|
struct channel *channel UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_start_dualopend called!\n"); abort(); }
|
{ fprintf(stderr, "peer_start_dualopend called!\n"); abort(); }
|
||||||
/* Generated stub for peer_start_openingd */
|
/* Generated stub for peer_start_openingd */
|
||||||
void peer_start_openingd(struct peer *peer UNNEEDED,
|
bool peer_start_openingd(struct peer *peer UNNEEDED,
|
||||||
struct peer_fd *peer_fd UNNEEDED)
|
struct peer_fd *peer_fd UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_start_openingd called!\n"); abort(); }
|
{ fprintf(stderr, "peer_start_openingd called!\n"); abort(); }
|
||||||
/* Generated stub for peer_unsaved_channel */
|
/* Generated stub for peer_unsaved_channel */
|
||||||
@@ -640,9 +652,15 @@ u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)
|
|||||||
/* Generated stub for towire_channeld_dev_reenable_commit */
|
/* Generated stub for towire_channeld_dev_reenable_commit */
|
||||||
u8 *towire_channeld_dev_reenable_commit(const tal_t *ctx UNNEEDED)
|
u8 *towire_channeld_dev_reenable_commit(const tal_t *ctx UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_channeld_dev_reenable_commit called!\n"); abort(); }
|
{ fprintf(stderr, "towire_channeld_dev_reenable_commit called!\n"); abort(); }
|
||||||
|
/* Generated stub for towire_connectd_discard_peer */
|
||||||
|
u8 *towire_connectd_discard_peer(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_connectd_discard_peer called!\n"); abort(); }
|
||||||
/* Generated stub for towire_connectd_peer_final_msg */
|
/* Generated stub for towire_connectd_peer_final_msg */
|
||||||
u8 *towire_connectd_peer_final_msg(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const u8 *msg UNNEEDED)
|
u8 *towire_connectd_peer_final_msg(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const u8 *msg UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_connectd_peer_final_msg called!\n"); abort(); }
|
{ fprintf(stderr, "towire_connectd_peer_final_msg called!\n"); abort(); }
|
||||||
|
/* Generated stub for towire_connectd_peer_make_active */
|
||||||
|
u8 *towire_connectd_peer_make_active(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const struct channel_id *channel_id UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_connectd_peer_make_active called!\n"); abort(); }
|
||||||
/* Generated stub for towire_dualopend_dev_memleak */
|
/* Generated stub for towire_dualopend_dev_memleak */
|
||||||
u8 *towire_dualopend_dev_memleak(const tal_t *ctx UNNEEDED)
|
u8 *towire_dualopend_dev_memleak(const tal_t *ctx UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_dualopend_dev_memleak called!\n"); abort(); }
|
{ fprintf(stderr, "towire_dualopend_dev_memleak called!\n"); abort(); }
|
||||||
|
|||||||
@@ -3932,9 +3932,6 @@ int main(int argc, char *argv[])
|
|||||||
* N'th per-commitment point. But since N=0, it won't give us one. */
|
* N'th per-commitment point. But since N=0, it won't give us one. */
|
||||||
assert(none == NULL);
|
assert(none == NULL);
|
||||||
|
|
||||||
/*~ Turns out this is useful for testing, to make sure we're ready. */
|
|
||||||
status_debug("Handed peer, entering loop");
|
|
||||||
|
|
||||||
/*~ We manually run a little poll() loop here. With only two fds */
|
/*~ We manually run a little poll() loop here. With only two fds */
|
||||||
pollfd[0].fd = REQ_FD;
|
pollfd[0].fd = REQ_FD;
|
||||||
pollfd[0].events = POLLIN;
|
pollfd[0].events = POLLIN;
|
||||||
|
|||||||
@@ -313,6 +313,7 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags)
|
|||||||
struct tlv_accept_channel_tlvs *accept_tlvs;
|
struct tlv_accept_channel_tlvs *accept_tlvs;
|
||||||
char *err_reason;
|
char *err_reason;
|
||||||
|
|
||||||
|
status_debug("funder_channel_start");
|
||||||
if (!setup_channel_funder(state))
|
if (!setup_channel_funder(state))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -1428,9 +1429,6 @@ int main(int argc, char *argv[])
|
|||||||
* N'th per-commitment point. But since N=0, it won't give us one. */
|
* N'th per-commitment point. But since N=0, it won't give us one. */
|
||||||
assert(none == NULL);
|
assert(none == NULL);
|
||||||
|
|
||||||
/*~ Turns out this is useful for testing, to make sure we're ready. */
|
|
||||||
status_debug("Handed peer, entering loop");
|
|
||||||
|
|
||||||
/*~ We manually run a little poll() loop here. With only three fds */
|
/*~ We manually run a little poll() loop here. With only three fds */
|
||||||
pollfd[0].fd = REQ_FD;
|
pollfd[0].fd = REQ_FD;
|
||||||
pollfd[0].events = POLLIN;
|
pollfd[0].events = POLLIN;
|
||||||
|
|||||||
@@ -3448,7 +3448,8 @@ def test_you_forgot_closed_channel(node_factory, executor):
|
|||||||
assert only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['state'] == 'CLOSINGD_SIGEXCHANGE'
|
assert only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])['state'] == 'CLOSINGD_SIGEXCHANGE'
|
||||||
|
|
||||||
# l1 reconnects, it should succeed.
|
# l1 reconnects, it should succeed.
|
||||||
l1.rpc.disconnect(l2.info['id'], force=True)
|
if only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['connected']:
|
||||||
|
l1.rpc.disconnect(l2.info['id'], force=True)
|
||||||
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||||
fut.result(TIMEOUT)
|
fut.result(TIMEOUT)
|
||||||
|
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ def test_remote_disconnect(node_factory):
|
|||||||
l1, l2 = node_factory.get_nodes(2)
|
l1, l2 = node_factory.get_nodes(2)
|
||||||
|
|
||||||
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||||
assert l2.rpc.listpeers()['peers'] != []
|
wait_for(lambda: l2.rpc.listpeers()['peers'] != [])
|
||||||
l2.rpc.disconnect(l1.info['id'])
|
l2.rpc.disconnect(l1.info['id'])
|
||||||
|
|
||||||
# l1 should notice!
|
# l1 should notice!
|
||||||
@@ -2576,9 +2576,9 @@ def test_disconnectpeer(node_factory, bitcoind):
|
|||||||
wait_for(lambda: l2.rpc.getpeer(l1.info['id']) is None)
|
wait_for(lambda: l2.rpc.getpeer(l1.info['id']) is None)
|
||||||
|
|
||||||
# Make sure you cannot disconnect after disconnecting
|
# Make sure you cannot disconnect after disconnecting
|
||||||
with pytest.raises(RpcError, match=r'Peer not connected'):
|
with pytest.raises(RpcError, match=r'Unknown peer'):
|
||||||
l1.rpc.disconnect(l2.info['id'])
|
l1.rpc.disconnect(l2.info['id'])
|
||||||
with pytest.raises(RpcError, match=r'Peer not connected'):
|
with pytest.raises(RpcError, match=r'Unknown peer'):
|
||||||
l2.rpc.disconnect(l1.info['id'])
|
l2.rpc.disconnect(l1.info['id'])
|
||||||
|
|
||||||
# Fund channel l1 -> l3
|
# Fund channel l1 -> l3
|
||||||
|
|||||||
@@ -2337,6 +2337,7 @@ def test_listforwards(node_factory, bitcoind):
|
|||||||
assert len(c24_forwards) == 1
|
assert len(c24_forwards) == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.openchannel('v1')
|
||||||
def test_version_reexec(node_factory, bitcoind):
|
def test_version_reexec(node_factory, bitcoind):
|
||||||
badopeningd = os.path.join(os.path.dirname(__file__), "plugins", "badopeningd.sh")
|
badopeningd = os.path.join(os.path.dirname(__file__), "plugins", "badopeningd.sh")
|
||||||
version = subprocess.check_output(['lightningd/lightningd',
|
version = subprocess.check_output(['lightningd/lightningd',
|
||||||
@@ -2358,7 +2359,12 @@ def test_version_reexec(node_factory, bitcoind):
|
|||||||
'fff6')) # type
|
'fff6')) # type
|
||||||
f.write(bytes('badversion\0', encoding='utf8'))
|
f.write(bytes('badversion\0', encoding='utf8'))
|
||||||
|
|
||||||
|
# Opening a channel will fire subd.
|
||||||
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
|
||||||
|
try:
|
||||||
|
l1.fundchannel(l2)
|
||||||
|
except RpcError:
|
||||||
|
pass
|
||||||
|
|
||||||
l1.daemon.wait_for_log("openingd.*version 'badversion' not '{}': restarting".format(version))
|
l1.daemon.wait_for_log("openingd.*version 'badversion' not '{}': restarting".format(version))
|
||||||
|
|
||||||
|
|||||||
@@ -148,6 +148,9 @@ bool fromwire_channeld_offer_htlc_reply(const tal_t *ctx UNNEEDED, const void *p
|
|||||||
/* Generated stub for fromwire_channeld_sending_commitsig */
|
/* Generated stub for fromwire_channeld_sending_commitsig */
|
||||||
bool fromwire_channeld_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct penalty_base **pbase UNNEEDED, struct fee_states **fee_states UNNEEDED, struct height_states **blockheight_states UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_signature *commit_sig UNNEEDED, struct bitcoin_signature **htlc_sigs UNNEEDED)
|
bool fromwire_channeld_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u64 *commitnum UNNEEDED, struct penalty_base **pbase UNNEEDED, struct fee_states **fee_states UNNEEDED, struct height_states **blockheight_states UNNEEDED, struct changed_htlc **changed UNNEEDED, struct bitcoin_signature *commit_sig UNNEEDED, struct bitcoin_signature **htlc_sigs UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_channeld_sending_commitsig called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_channeld_sending_commitsig called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_connectd_peer_active */
|
||||||
|
bool fromwire_connectd_peer_active(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u16 **msgtype UNNEEDED, struct channel_id **channel_id UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_connectd_peer_active called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_connectd_peer_connected */
|
/* Generated stub for fromwire_connectd_peer_connected */
|
||||||
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED)
|
bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct wireaddr **remote_addr UNNEEDED, bool *incoming UNNEEDED, u8 **features UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_connectd_peer_connected called!\n"); abort(); }
|
||||||
@@ -476,6 +479,9 @@ struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,
|
|||||||
/* Generated stub for new_peer_fd */
|
/* Generated stub for new_peer_fd */
|
||||||
struct peer_fd *new_peer_fd(const tal_t *ctx UNNEEDED, int peer_fd UNNEEDED)
|
struct peer_fd *new_peer_fd(const tal_t *ctx UNNEEDED, int peer_fd UNNEEDED)
|
||||||
{ fprintf(stderr, "new_peer_fd called!\n"); abort(); }
|
{ fprintf(stderr, "new_peer_fd called!\n"); abort(); }
|
||||||
|
/* Generated stub for new_uncommitted_channel */
|
||||||
|
struct uncommitted_channel *new_uncommitted_channel(struct peer *peer UNNEEDED)
|
||||||
|
{ fprintf(stderr, "new_uncommitted_channel called!\n"); abort(); }
|
||||||
/* Generated stub for notify_chain_mvt */
|
/* Generated stub for notify_chain_mvt */
|
||||||
void notify_chain_mvt(struct lightningd *ld UNNEEDED, const struct chain_coin_mvt *mvt UNNEEDED)
|
void notify_chain_mvt(struct lightningd *ld UNNEEDED, const struct chain_coin_mvt *mvt UNNEEDED)
|
||||||
{ fprintf(stderr, "notify_chain_mvt called!\n"); abort(); }
|
{ fprintf(stderr, "notify_chain_mvt called!\n"); abort(); }
|
||||||
@@ -631,10 +637,11 @@ void peer_start_channeld(struct channel *channel UNNEEDED,
|
|||||||
const u8 *reestablish_only UNNEEDED)
|
const u8 *reestablish_only UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); }
|
{ fprintf(stderr, "peer_start_channeld called!\n"); abort(); }
|
||||||
/* Generated stub for peer_start_dualopend */
|
/* Generated stub for peer_start_dualopend */
|
||||||
void peer_start_dualopend(struct peer *peer UNNEEDED, struct peer_fd *peer_fd UNNEEDED)
|
bool peer_start_dualopend(struct peer *peer UNNEEDED, struct peer_fd *peer_fd UNNEEDED,
|
||||||
|
struct channel *channel UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_start_dualopend called!\n"); abort(); }
|
{ fprintf(stderr, "peer_start_dualopend called!\n"); abort(); }
|
||||||
/* Generated stub for peer_start_openingd */
|
/* Generated stub for peer_start_openingd */
|
||||||
void peer_start_openingd(struct peer *peer UNNEEDED,
|
bool peer_start_openingd(struct peer *peer UNNEEDED,
|
||||||
struct peer_fd *peer_fd UNNEEDED)
|
struct peer_fd *peer_fd UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_start_openingd called!\n"); abort(); }
|
{ fprintf(stderr, "peer_start_openingd called!\n"); abort(); }
|
||||||
/* Generated stub for plugin_hook_call_ */
|
/* Generated stub for plugin_hook_call_ */
|
||||||
@@ -729,6 +736,9 @@ u8 *towire_connectd_discard_peer(const tal_t *ctx UNNEEDED, const struct node_id
|
|||||||
/* Generated stub for towire_connectd_peer_final_msg */
|
/* Generated stub for towire_connectd_peer_final_msg */
|
||||||
u8 *towire_connectd_peer_final_msg(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const u8 *msg UNNEEDED)
|
u8 *towire_connectd_peer_final_msg(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const u8 *msg UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_connectd_peer_final_msg called!\n"); abort(); }
|
{ fprintf(stderr, "towire_connectd_peer_final_msg called!\n"); abort(); }
|
||||||
|
/* Generated stub for towire_connectd_peer_make_active */
|
||||||
|
u8 *towire_connectd_peer_make_active(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const struct channel_id *channel_id UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_connectd_peer_make_active called!\n"); abort(); }
|
||||||
/* Generated stub for towire_dualopend_dev_memleak */
|
/* Generated stub for towire_dualopend_dev_memleak */
|
||||||
u8 *towire_dualopend_dev_memleak(const tal_t *ctx UNNEEDED)
|
u8 *towire_dualopend_dev_memleak(const tal_t *ctx UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_dualopend_dev_memleak called!\n"); abort(); }
|
{ fprintf(stderr, "towire_dualopend_dev_memleak called!\n"); abort(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user