From b4beab6537ea154513fbd3cab9e3f3acaa6c7f6f Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 24 Apr 2017 14:31:26 +0200 Subject: [PATCH] gossip: Make the broadcast interval configurable Adds a new command line flag `--dev-broadcast-interval=` that allows us to specify how often the staggered broadcast should trigger. The value is passed down to `gossipd` via an init message. This is mainly useful for integration tests, since we do not want to wait forever for gossip to propagate. --- lightningd/gossip/gossip.c | 22 +++++++++++++++++++++- lightningd/gossip/gossip_wire.csv | 4 ++++ lightningd/gossip_control.c | 9 +++++++++ lightningd/lightningd.c | 8 ++++++++ lightningd/lightningd.h | 2 ++ 5 files changed, 44 insertions(+), 1 deletion(-) diff --git a/lightningd/gossip/gossip.c b/lightningd/gossip/gossip.c index 3fcb66293..6c5bf9531 100644 --- a/lightningd/gossip/gossip.c +++ b/lightningd/gossip/gossip.c @@ -44,6 +44,8 @@ struct daemon { struct routing_state *rstate; struct timers timers; + + u32 broadcast_interval; }; struct peer { @@ -285,7 +287,8 @@ static struct io_plan *peer_msgin(struct io_conn *conn, static void wake_pkt_out(struct peer *peer) { peer->gossip_sync = true; - new_reltimer(&peer->daemon->timers, peer, time_from_sec(30), + new_reltimer(&peer->daemon->timers, peer, + time_from_msec(peer->daemon->broadcast_interval), wake_pkt_out, peer); /* Notify the peer-write loop */ msg_wake(&peer->peer_out); @@ -617,6 +620,19 @@ static struct io_plan *ping_req(struct io_conn *conn, struct daemon *daemon, return daemon_conn_read_next(conn, &daemon->master); } +/* Parse an incoming gossip init message and assign config variables + * to the daemon. + */ +static struct io_plan *gossip_init(struct daemon_conn *master, + struct daemon *daemon, u8 *msg) +{ + if (!fromwire_gossipctl_init(msg, NULL, &daemon->broadcast_interval)) { + status_failed(WIRE_GOSSIPSTATUS_INIT_FAILED, + "Unable to parse init message"); + } + return daemon_conn_read_next(master->conn, master); +} + static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master) { struct daemon *daemon = container_of(master, struct daemon, master); @@ -626,6 +642,9 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master gossip_wire_type_name(t), tal_count(master->msg_in)); switch (t) { + case WIRE_GOSSIPCTL_INIT: + return gossip_init(master, daemon, master->msg_in); + case WIRE_GOSSIPCTL_NEW_PEER: return new_peer(conn, daemon, master->msg_in); case WIRE_GOSSIPCTL_RELEASE_PEER: @@ -690,6 +709,7 @@ int main(int argc, char *argv[]) daemon->rstate = new_routing_state(daemon, base_log); list_head_init(&daemon->peers); timers_init(&daemon->timers, time_mono()); + daemon->broadcast_interval = 30000; /* stdin == control */ daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req); diff --git a/lightningd/gossip/gossip_wire.csv b/lightningd/gossip/gossip_wire.csv index 7379611d6..3e5c3ae8d 100644 --- a/lightningd/gossip/gossip_wire.csv +++ b/lightningd/gossip/gossip_wire.csv @@ -19,6 +19,10 @@ gossipstatus_peer_failed,10,err,len*u8 #include +# Initialize the gossip daemon +gossipctl_init,0 +gossipctl_init,0,broadcast_interval,4 + # These take an fd, but have no response # (if it is to move onto a channel, we get a status msg). gossipctl_new_peer,1 diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 67c44ebbf..8af5f4829 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -140,6 +140,7 @@ static int gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPSTATUS_FDPASS_FAILED: case WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST: /* These are messages we send, not them. */ + case WIRE_GOSSIPCTL_INIT: case WIRE_GOSSIPCTL_NEW_PEER: case WIRE_GOSSIPCTL_RELEASE_PEER: case WIRE_GOSSIP_GETNODES_REQUEST: @@ -171,13 +172,21 @@ static int gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) return 0; } +/* Create the `gossipd` subdaemon and send the initialization + * message */ void gossip_init(struct lightningd *ld) { + tal_t *tmpctx = tal_tmpctx(ld); + u8 *init; ld->gossip = new_subd(ld, ld, "lightningd_gossip", NULL, gossip_wire_type_name, gossip_msg, gossip_finished, -1); if (!ld->gossip) err(1, "Could not subdaemon gossip"); + + init = towire_gossipctl_init(tmpctx, ld->broadcast_interval); + subd_send_msg(ld->gossip, init); + tal_free(tmpctx); } static bool json_getnodes_reply(struct subd *gossip, const u8 *reply, diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 1e9be5abc..65140dbaf 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -228,6 +228,14 @@ int main(int argc, char *argv[]) opt_register_arg("--dev-debugger=", opt_subd_debug, NULL, ld, "Wait for gdb attach at start of "); + opt_register_arg("--dev-broadcast-interval=", opt_set_uintval, + opt_show_uintval, &ld->broadcast_interval, + "Time between gossip broadcasts in milliseconds (default: 30000)"); + + /* FIXME: move to option initialization once we drop the + * legacy daemon */ + ld->broadcast_interval = 30000; + /* Handle options and config; move to .lightningd */ newdir = handle_opts(&ld->dstate, argc, argv); diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index a482fe7c3..d52af114f 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -55,6 +55,8 @@ struct lightningd { /* HTLCs in flight. */ struct htlc_end_map htlc_ends; + + u32 broadcast_interval; }; void derive_peer_seed(struct lightningd *ld, struct privkey *peer_seed,