From c536616bee8e745f8cb160fbb1790119d58367f6 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 10 Jan 2017 15:38:33 +1030 Subject: [PATCH] lightningd/lightningd: wire up lightningd_gossip. Now we hand peers off to the gossip daemon, to do the INIT handshake and re-transmit/receive gossip. They may stay there forever if neither we nor them wants to open a channel. Signed-off-by: Rusty Russell --- lightningd/Makefile | 4 +- lightningd/gossip_control.c | 118 ++++++++++++++++++++++++++++++++++++ lightningd/gossip_control.h | 9 +++ lightningd/lightningd.c | 4 ++ lightningd/lightningd.h | 3 + lightningd/peer_control.c | 16 +++-- 6 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 lightningd/gossip_control.c create mode 100644 lightningd/gossip_control.h diff --git a/lightningd/Makefile b/lightningd/Makefile index 672954b2f..b4a7ce316 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -31,6 +31,7 @@ LIGHTNINGD_LIB_OBJS := $(LIGHTNINGD_LIB_SRC:.c=.o) LIGHTNINGD_LIB_HEADERS := $(LIGHTNINGD_LIB_SRC:.c=.h) LIGHTNINGD_SRC := \ + lightningd/gossip_control.c \ lightningd/hsm_control.c \ lightningd/lightningd.c \ lightningd/peer_control.c \ @@ -42,6 +43,7 @@ LIGHTNINGD_JSMN_OBJS := daemon/jsmn.o LIGHTNINGD_JSMN_HEADERS := daemon/jsmn/jsmn.h LIGHTNINGD_HEADERS := \ + lightningd/gossip_control.h \ lightningd/hsm_control.h \ lightningd/lightningd.h \ lightningd/peer_control.h \ @@ -64,7 +66,7 @@ check-whitespace: $(LIGHTNINGD_SRC:%=check-whitespace/%) $(LIGHTNINGD_HEADERS:%= check-lightningd-makefile: @if [ "`ls lightningd/*.h | grep -v lightningd/gen | tr '\012' ' '`" != "`echo $(LIGHTNINGD_HEADERS) ''`" ]; then echo LIGHTNINGD_HEADERS incorrect; exit 1; fi -lightningd/lightningd: $(LIGHTNINGD_OBJS) $(LIGHTNINGD_OLD_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_JSMN_OBJS) $(CORE_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_HSM_CONTROL_OBJS) $(LIGHTNINGD_HANDSHAKE_CONTROL_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a +lightningd/lightningd: $(LIGHTNINGD_OBJS) $(LIGHTNINGD_OLD_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_JSMN_OBJS) $(CORE_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_HSM_CONTROL_OBJS) $(LIGHTNINGD_HANDSHAKE_CONTROL_OBJS) $(LIGHTNINGD_GOSSIP_CONTROL_OBJS) $(LIBBASE58_OBJS) libsecp256k1.a clean: lightningd-clean diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c new file mode 100644 index 000000000..f3681ab01 --- /dev/null +++ b/lightningd/gossip_control.c @@ -0,0 +1,118 @@ +#include "gossip_control.h" +#include "lightningd.h" +#include "peer_control.h" +#include "subdaemon.h" +#include +#include +#include +#include +#include +#include + +static void gossip_finished(struct subdaemon *gossip, int status) +{ + if (WIFEXITED(status)) + errx(1, "Gossip failed (exit status %i), exiting.", + WEXITSTATUS(status)); + errx(1, "Gossip failed (signal %u), exiting.", WTERMSIG(status)); +} + +static void peer_bad_message(struct subdaemon *gossip, const u8 *msg) +{ + u64 unique_id; + struct peer *peer; + u8 *err; + + if (!fromwire_gossipstatus_peer_bad_msg(msg, msg, NULL, + &unique_id, &err)) + fatal("Gossip gave bad PEER_BAD message %s", tal_hex(msg, msg)); + + peer = peer_by_unique_id(gossip->ld, unique_id); + if (!peer) + fatal("Gossip gave bad peerid %"PRIu64, unique_id); + + log_info(gossip->log, "Peer %s gave bad msg %s", + type_to_string(msg, struct pubkey, peer->id), + tal_hex(msg, msg)); + tal_free(peer); +} + +static void peer_nongossip(struct subdaemon *gossip, const u8 *msg, int fd) +{ + u64 unique_id; + struct peer *peer; + u8 *inner; + struct crypto_state *cs; + + if (!fromwire_gossipstatus_peer_nongossip(msg, msg, NULL, + &unique_id, &cs, &inner)) + fatal("Gossip gave bad PEER_NONGOSSIP message %s", + tal_hex(msg, msg)); + + peer = peer_by_unique_id(gossip->ld, unique_id); + if (!peer) + fatal("Gossip gave bad peerid %"PRIu64, unique_id); + + log_info(gossip->log, "Peer %s said %s", + type_to_string(msg, struct pubkey, peer->id), + gossip_status_wire_type_name(fromwire_peektype(inner))); + + /* FIXME: create new daemon to handle peer. */ +} + +static void peer_ready(struct subdaemon *gossip, const u8 *msg) +{ + u64 unique_id; + struct peer *peer; + + if (!fromwire_gossipstatus_peer_ready(msg, NULL, &unique_id)) + fatal("Gossip gave bad PEER_READY message %s", + tal_hex(msg, msg)); + + peer = peer_by_unique_id(gossip->ld, unique_id); + if (!peer) + fatal("Gossip gave bad peerid %"PRIu64, unique_id); + + log_info_struct(gossip->log, "Peer %s ready for channel open", + struct pubkey, peer->id); + + /* FIXME: finish json connect cmd if any. */ +} + +static enum subdaemon_status gossip_status(struct subdaemon *gossip, + const u8 *msg, int fd) +{ + enum gossip_status_wire_type t = fromwire_peektype(msg); + + switch (t) { + /* We don't get told about fatal errors. */ + case WIRE_GOSSIPSTATUS_INIT_FAILED: + case WIRE_GOSSIPSTATUS_BAD_NEW_PEER_REQUEST: + case WIRE_GOSSIPSTATUS_BAD_REQUEST: + case WIRE_GOSSIPSTATUS_FDPASS_FAILED: + case WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST: + break; + case WIRE_GOSSIPSTATUS_PEER_BAD_MSG: + peer_bad_message(gossip, msg); + break; + case WIRE_GOSSIPSTATUS_PEER_NONGOSSIP: + if (fd == -1) + return STATUS_NEED_FD; + peer_nongossip(gossip, msg, fd); + break; + case WIRE_GOSSIPSTATUS_PEER_READY: + peer_ready(gossip, msg); + break; + } + return STATUS_COMPLETE; +} + +void gossip_init(struct lightningd *ld) +{ + ld->gossip = new_subdaemon(ld, ld, "lightningd_gossip", + gossip_status_wire_type_name, + gossip_control_wire_type_name, + gossip_status, gossip_finished, -1); + if (!ld->gossip) + err(1, "Could not subdaemon gossip"); +} diff --git a/lightningd/gossip_control.h b/lightningd/gossip_control.h new file mode 100644 index 000000000..d16939d66 --- /dev/null +++ b/lightningd/gossip_control.h @@ -0,0 +1,9 @@ +#ifndef LIGHTNING_LIGHTNINGD_GOSSIP_CONTROL_H +#define LIGHTNING_LIGHTNINGD_GOSSIP_CONTROL_H +#include "config.h" +#include + +struct lightningd; + +void gossip_init(struct lightningd *ld); +#endif /* LIGHTNING_LIGHTNINGD_HSM_CONTROL_H */ diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 55184175a..37061fe3b 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -1,3 +1,4 @@ +#include "gossip_control.h" #include "hsm_control.h" #include "lightningd.h" #include "peer_control.h" @@ -172,6 +173,9 @@ int main(int argc, char *argv[]) /* Set up HSM. */ hsm_init(ld, newdir); + /* Set up gossip daemon. */ + gossip_init(ld); + /* Create RPC socket (if any) */ setup_jsonrpc(&ld->dstate, ld->dstate.rpc_filename); diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index 3474e1de4..410d36dab 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -25,6 +25,9 @@ struct lightningd { /* Bearer of all my secrets. */ struct subdaemon *hsm; + /* Daemon looking after peers during init / before channel. */ + struct subdaemon *gossip; + /* All peers we're tracking. */ struct list_head peers; }; diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 1056acb94..9991670b4 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -69,14 +71,20 @@ static void handshake_succeeded(struct subdaemon *hs, const u8 *msg, /* FIXME: Look for peer duplicates! */ - /* Peer is now a full-fledged citizen. */ - /* Tell handshaked to exit. */ subdaemon_req(peer->owner, take(towire_handshake_exit_req(msg)), -1, NULL, NULL, NULL); - /* FIXME: start lightningd_connect */ - peer->owner = NULL; + peer->owner = peer->ld->gossip; + tal_steal(peer->owner, peer); + + /* Tell gossip to handle it now. */ + msg = towire_gossipctl_new_peer(msg, peer->unique_id, cs); + subdaemon_req(peer->ld->gossip, msg, peer->fd, &peer->fd, NULL, NULL); + + /* Peer struct longer owns fd. */ + peer->fd = -1; + return; err: