From 13717c6ebbb5bdd5c6d30e47e99cfbbf9373ccdf Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 4 May 2019 15:23:13 +0930 Subject: [PATCH] gossipd: hand a gossip_store_fd to all subdaemons. This will let them read from the gossip store directly. Signed-off-by: Rusty Russell --- channeld/channeld.c | 12 +++++++----- closingd/closingd.c | 9 ++++++--- common/peer_failed.c | 10 +++++----- common/peer_failed.h | 11 ++++++----- common/read_peer_msg.c | 3 ++- common/read_peer_msg.h | 4 ++-- common/status.c | 5 +++-- common/status.h | 2 +- connectd/connect_gossip_wire.csv | 2 +- connectd/connect_wire.csv | 2 +- connectd/connectd.c | 30 ++++++++++++++++++------------ gossipd/gossip_store.c | 5 +++++ gossipd/gossip_store.h | 8 +++++++- gossipd/gossipd.c | 12 ++++++++++++ lightningd/channel_control.c | 10 ++++++---- lightningd/closing_control.c | 1 + lightningd/connect_control.c | 6 +++--- lightningd/opening_control.c | 16 ++++++++++------ lightningd/peer_comms.c | 2 ++ lightningd/peer_comms.h | 2 +- lightningd/peer_control.c | 3 ++- lightningd/peer_control.h | 2 +- lightningd/subd.c | 7 ++++--- openingd/openingd.c | 11 ++++++++--- 24 files changed, 114 insertions(+), 61 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 2f7a22c0e..ad46dc72d 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -59,11 +59,12 @@ #include #include -/* stdin == requests, 3 == peer, 4 = gossip, 5 = HSM */ +/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = HSM */ #define MASTER_FD STDIN_FILENO #define PEER_FD 3 #define GOSSIP_FD 4 -#define HSM_FD 5 +#define GOSSIP_STORE_FD 5 +#define HSM_FD 6 struct peer { struct crypto_state cs; @@ -1771,7 +1772,7 @@ static void peer_in(struct peer *peer, const u8 *msg) return; } - if (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, + if (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, &peer->cs, &peer->channel_id, msg)) return; @@ -2232,8 +2233,8 @@ static void peer_reconnect(struct peer *peer, do { clean_tmpctx(); msg = sync_crypto_read(tmpctx, &peer->cs, PEER_FD); - } while (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, &peer->cs, - &peer->channel_id, msg) + } while (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, + &peer->cs, &peer->channel_id, msg) || capture_premature_msg(&premature_msgs, msg)); if (dataloss_protect) { @@ -2971,6 +2972,7 @@ static void send_shutdown_complete(struct peer *peer) take(towire_channel_shutdown_complete(NULL, &peer->cs))); fdpass_send(MASTER_FD, PEER_FD); fdpass_send(MASTER_FD, GOSSIP_FD); + fdpass_send(MASTER_FD, GOSSIP_STORE_FD); close(MASTER_FD); } diff --git a/closingd/closingd.c b/closingd/closingd.c index 8f1b13d3a..f0c13be69 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -23,11 +23,12 @@ #include #include -/* stdin == requests, 3 == peer, 4 = gossip */ +/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */ #define REQ_FD STDIN_FILENO #define PEER_FD 3 #define GOSSIP_FD 4 -#define HSM_FD 5 +#define GOSSIP_STORE_FD 5 +#define HSM_FD 6 static struct bitcoin_tx *close_tx(const tal_t *ctx, struct crypto_state *cs, @@ -101,7 +102,9 @@ static u8 *closing_read_peer_msg(const tal_t *ctx, handle_gossip_msg(PEER_FD, cs, take(msg)); continue; } - if (!handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, cs, + if (!handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, + GOSSIP_STORE_FD, + cs, channel_id, msg)) return msg; } diff --git a/common/peer_failed.c b/common/peer_failed.c index e74c9ee5e..41318dc74 100644 --- a/common/peer_failed.c +++ b/common/peer_failed.c @@ -9,7 +9,7 @@ #include /* We only support one channel per peer anyway */ -void peer_failed_(int peer_fd, int gossip_fd, +void peer_failed_(int peer_fd, int gossip_fd, int gossip_store_fd, struct crypto_state *cs, const struct channel_id *channel_id, const char *fmt, ...) @@ -32,11 +32,11 @@ void peer_failed_(int peer_fd, int gossip_fd, err); peer_billboard(true, desc); tal_free(desc); - status_send_fatal(take(msg), peer_fd, gossip_fd); + status_send_fatal(take(msg), peer_fd, gossip_fd, gossip_store_fd); } /* We're failing because peer sent us an error message */ -void peer_failed_received_errmsg(int peer_fd, int gossip_fd, +void peer_failed_received_errmsg(int peer_fd, int gossip_fd, int gossip_store_fd, struct crypto_state *cs, const char *desc, const struct channel_id *channel_id) @@ -48,11 +48,11 @@ void peer_failed_received_errmsg(int peer_fd, int gossip_fd, channel_id = &all_channels; msg = towire_status_peer_error(NULL, channel_id, desc, cs, NULL); peer_billboard(true, "Received error from peer: %s", desc); - status_send_fatal(take(msg), peer_fd, gossip_fd); + status_send_fatal(take(msg), peer_fd, gossip_fd, gossip_store_fd); } void peer_failed_connection_lost(void) { status_send_fatal(take(towire_status_peer_connection_lost(NULL)), - -1, -1); + -1, -1, -1); } diff --git a/common/peer_failed.h b/common/peer_failed.h index b2ab21618..51cf274ca 100644 --- a/common/peer_failed.h +++ b/common/peer_failed.h @@ -12,18 +12,19 @@ struct channel_id; * @channel_id: channel with error, or NULL for all. * @fmt...: format as per status_failed(STATUS_FAIL_PEER_BAD) */ -#define peer_failed(cs, channel_id, ...) \ - peer_failed_(PEER_FD, GOSSIP_FD, (cs), (channel_id), __VA_ARGS__) +#define peer_failed(cs, channel_id, ...) \ + peer_failed_(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD, \ + (cs), (channel_id), __VA_ARGS__) -void peer_failed_(int peer_fd, int gossip_fd, +void peer_failed_(int peer_fd, int gossip_fd, int gossip_store_fd, struct crypto_state *cs, const struct channel_id *channel_id, const char *fmt, ...) - PRINTF_FMT(5,6) NORETURN; + PRINTF_FMT(6,7) NORETURN; /* We're failing because peer sent us an error message: NULL * channel_id means all channels. */ -void peer_failed_received_errmsg(int peer_fd, int gossip_fd, +void peer_failed_received_errmsg(int peer_fd, int gossip_fd, int gossip_store_fd, struct crypto_state *cs, const char *desc, const struct channel_id *channel_id) NORETURN; diff --git a/common/read_peer_msg.c b/common/read_peer_msg.c index 3aac49909..ca15059a2 100644 --- a/common/read_peer_msg.c +++ b/common/read_peer_msg.c @@ -106,7 +106,7 @@ void handle_gossip_msg(int peer_fd, struct crypto_state *cs, const u8 *msg TAKES tal_free(msg); } -bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, +bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, int gossip_store_fd, struct crypto_state *cs, const struct channel_id *channel_id, const u8 *msg TAKES) @@ -124,6 +124,7 @@ bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, if (is_peer_error(tmpctx, msg, channel_id, &err, &all_channels)) { if (err) peer_failed_received_errmsg(peer_fd, gossip_fd, + gossip_store_fd, cs, err, all_channels ? NULL : channel_id); diff --git a/common/read_peer_msg.h b/common/read_peer_msg.h index af56c86e6..9a0ae2e09 100644 --- a/common/read_peer_msg.h +++ b/common/read_peer_msg.h @@ -57,7 +57,7 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected, /** * handle_peer_gossip_or_error - simple handler for all the above cases. - * @peer_fd, @gossip_fd: peer and gossip fd. + * @peer_fd, @gossip_fd, @gossip_store_fd: peer, gossip and gossip_store fds. * @cs: the cryptostate (updated) * @msg: the peer message (only taken if returns true). * @@ -65,7 +65,7 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected, * to gossipd), an error packet (causes peer_failed_received_errmsg or * ignored), or a message about the wrong channel (sends sync error reply). */ -bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, +bool handle_peer_gossip_or_error(int peer_fd, int gossip_fd, int gossip_store_fd, struct crypto_state *cs, const struct channel_id *channel_id, const u8 *msg TAKES); diff --git a/common/status.c b/common/status.c index a6682839b..3086e7dcc 100644 --- a/common/status.c +++ b/common/status.c @@ -162,7 +162,7 @@ static NORETURN void flush_and_exit(int reason) exit(0x80 | (reason & 0xFF)); } -void status_send_fatal(const u8 *msg TAKES, int fd1, int fd2) +void status_send_fatal(const u8 *msg TAKES, int fd1, int fd2, int fd3) { int reason = fromwire_peektype(msg); breakpoint(); @@ -173,6 +173,7 @@ void status_send_fatal(const u8 *msg TAKES, int fd1, int fd2) assert(!status_conn); fdpass_send(status_fd, fd1); fdpass_send(status_fd, fd2); + fdpass_send(status_fd, fd3); } flush_and_exit(reason); @@ -193,7 +194,7 @@ void status_failed(enum status_failreason reason, const char *fmt, ...) send_backtrace(str); status_send_fatal(take(towire_status_fail(NULL, reason, str)), - -1, -1); + -1, -1, -1); } void master_badmsg(u32 type_expected, const u8 *msg) diff --git a/common/status.h b/common/status.h index 855e1d3d8..16827ed3a 100644 --- a/common/status.h +++ b/common/status.h @@ -51,5 +51,5 @@ void status_failed(enum status_failreason code, void master_badmsg(u32 type_expected, const u8 *msg) NORETURN; void status_send(const u8 *msg TAKES); -void status_send_fatal(const u8 *msg TAKES, int fd1, int fd2) NORETURN; +void status_send_fatal(const u8 *msg TAKES, int fd1, int fd2, int fd3) NORETURN; #endif /* LIGHTNING_COMMON_STATUS_H */ diff --git a/connectd/connect_gossip_wire.csv b/connectd/connect_gossip_wire.csv index c657bbc34..1fadba1fe 100644 --- a/connectd/connect_gossip_wire.csv +++ b/connectd/connect_gossip_wire.csv @@ -8,7 +8,7 @@ gossip_new_peer,,gossip_queries_feature,bool # Did they offer LOCAL_INITIAL_ROUTING_SYNC? gossip_new_peer,,initial_routing_sync,bool -# if success: + fd. +# if success: + gossip fd and gossip_store fd gossip_new_peer_reply,4100 gossip_new_peer_reply,,success,bool diff --git a/connectd/connect_wire.csv b/connectd/connect_wire.csv index 977c3adca..e54ba1746 100644 --- a/connectd/connect_wire.csv +++ b/connectd/connect_wire.csv @@ -45,7 +45,7 @@ connectctl_connect_failed,,failreason,wirestring connectctl_connect_failed,,seconds_to_delay,u32 connectctl_connect_failed,,addrhint,?struct wireaddr_internal -# Connectd -> master: we got a peer. Two fds: peer and gossip +# Connectd -> master: we got a peer. Three fds: peer, gossip and gossip_store connect_peer_connected,2002 connect_peer_connected,,id,struct node_id connect_peer_connected,,addr,struct wireaddr_internal diff --git a/connectd/connectd.c b/connectd/connectd.c index 056f1c649..94fe50b56 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -277,12 +277,17 @@ static void connected_to_peer(struct daemon *daemon, * it to forward gossip to/from the peer. The gossip daemon needs to know a * few of the features of the peer and its id (for reporting). * + * Every peer also has read-only access to the gossip_store, which is handed + * out by gossipd too. + * * The 'localfeatures' is a field in the `init` message, indicating properties * when you're connected to it like we are: there are also 'globalfeatures' * which specify requirements to route a payment through a node. */ -static int get_gossipfd(struct daemon *daemon, - const struct node_id *id, - const u8 *localfeatures) +static bool get_gossipfds(struct daemon *daemon, + const struct node_id *id, + const u8 *localfeatures, + int *gossip_fd, + int *gossip_store_fd) { bool gossip_queries_feature, initial_routing_sync, success; u8 *msg; @@ -318,12 +323,14 @@ static int get_gossipfd(struct daemon *daemon, if (!success) { status_broken("Gossipd did not give us an fd: losing peer %s", type_to_string(tmpctx, struct node_id, id)); - return -1; + return false; } - /* Otherwise, the next thing in the socket will be the file descriptor + /* Otherwise, the next thing in the socket will be the file descriptors * for the per-peer daemon. */ - return fdpass_recv(GOSSIPCTL_FD); + *gossip_fd = fdpass_recv(GOSSIPCTL_FD); + *gossip_store_fd = fdpass_recv(GOSSIPCTL_FD); + return true; } /*~ This is an ad-hoc marshalling structure where we store arguments so we @@ -407,7 +414,7 @@ struct io_plan *peer_connected(struct io_conn *conn, const u8 *peer_connected_msg TAKES, const u8 *localfeatures TAKES) { - int gossip_fd; + int gossip_fd, gossip_store_fd; if (node_set_get(&daemon->peers, id)) return peer_reconnected(conn, daemon, id, peer_connected_msg, @@ -416,14 +423,12 @@ struct io_plan *peer_connected(struct io_conn *conn, /* We've successfully connected. */ connected_to_peer(daemon, conn, id); - gossip_fd = get_gossipfd(daemon, id, localfeatures); - - /* We promised we'd take it by marking it TAKEN above; simply free it. */ + /* We promised we'd take it by marking it TAKEN above; prepare to free it. */ if (taken(localfeatures)) - tal_free(localfeatures); + tal_steal(tmpctx, localfeatures); /* If gossipd can't give us a file descriptor, we give up connecting. */ - if (gossip_fd < 0) + if (!get_gossipfds(daemon, id, localfeatures, &gossip_fd, &gossip_store_fd)) return io_close(conn); /*~ daemon_conn is a message queue for inter-daemon communication: we @@ -433,6 +438,7 @@ struct io_plan *peer_connected(struct io_conn *conn, /* io_conn_fd() extracts the fd from ccan/io's io_conn */ daemon_conn_send_fd(daemon->master, io_conn_fd(conn)); daemon_conn_send_fd(daemon->master, gossip_fd); + daemon_conn_send_fd(daemon->master, gossip_store_fd); /*~ Finally, we add it to the set of pubkeys: tal_dup will handle * take() args for us, by simply tal_steal()ing it. */ diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index 57f94f4a8..7a9c59388 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -565,6 +565,11 @@ const u8 *gossip_store_get(const tal_t *ctx, return msg; } +int gossip_store_readonly_fd(struct gossip_store *gs) +{ + return open(GOSSIP_STORE_FILENAME, O_RDONLY); +} + void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs) { beint32_t hdr[2]; diff --git a/gossipd/gossip_store.h b/gossipd/gossip_store.h index e4fcc4d6c..8584d4b7f 100644 --- a/gossipd/gossip_store.h +++ b/gossipd/gossip_store.h @@ -66,6 +66,12 @@ bool gossip_store_compact(struct gossip_store *gs, struct broadcast_state **bs, u32 *offset); -/* Callback for when gossip_store indexes move */ +/** + * Get a readonly fd for the gossip_store. + * @gs: the gossip store. + * + * Returns -1 on failure, and sets errno. + */ +int gossip_store_readonly_fd(struct gossip_store *gs); #endif /* LIGHTNING_GOSSIPD_GOSSIP_STORE_H */ diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 856e2d030..915ce4f5b 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -1703,6 +1703,7 @@ static struct io_plan *connectd_new_peer(struct io_conn *conn, { struct peer *peer = tal(conn, struct peer); int fds[2]; + int gossip_store_fd; if (!fromwire_gossip_new_peer(msg, &peer->id, &peer->gossip_queries_feature, @@ -1712,10 +1713,20 @@ static struct io_plan *connectd_new_peer(struct io_conn *conn, return io_close(conn); } + gossip_store_fd = gossip_store_readonly_fd(daemon->rstate->broadcasts->gs);; + if (gossip_store_fd < 0) { + status_broken("Failed to get readonly store fd: %s", + strerror(errno)); + daemon_conn_send(daemon->connectd, + take(towire_gossip_new_peer_reply(NULL, false))); + goto done; + } + /* This can happen: we handle it gracefully, returning a `failed` msg. */ if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) { status_broken("Failed to create socketpair: %s", strerror(errno)); + close(gossip_store_fd); daemon_conn_send(daemon->connectd, take(towire_gossip_new_peer_reply(NULL, false))); goto done; @@ -1787,6 +1798,7 @@ static struct io_plan *connectd_new_peer(struct io_conn *conn, daemon_conn_send(daemon->connectd, take(towire_gossip_new_peer_reply(NULL, true))); daemon_conn_send_fd(daemon->connectd, fds[1]); + daemon_conn_send_fd(daemon->connectd, gossip_store_fd); done: return daemon_conn_read_next(conn, daemon->connectd); diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index a8e1bbed3..894337862 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -185,8 +185,8 @@ static void peer_start_closingd_after_shutdown(struct channel *channel, { struct peer_comms *pcomms = new_peer_comms(msg); - /* We expect 2 fds. */ - assert(tal_count(fds) == 2); + /* We expect 3 fds. */ + assert(tal_count(fds) == 3); if (!fromwire_channel_shutdown_complete(msg, &pcomms->cs)) { channel_internal_error(channel, "bad shutdown_complete: %s", @@ -195,6 +195,7 @@ static void peer_start_closingd_after_shutdown(struct channel *channel, } pcomms->peer_fd = fds[0]; pcomms->gossip_fd = fds[1]; + pcomms->gossip_store_fd = fds[2]; /* This sets channel->owner, closes down channeld. */ peer_start_closingd(channel, pcomms, false, NULL); @@ -222,9 +223,9 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) peer_got_shutdown(sd->channel, msg); break; case WIRE_CHANNEL_SHUTDOWN_COMPLETE: - /* We expect 2 fds. */ + /* We expect 3 fds. */ if (!fds) - return 2; + return 3; peer_start_closingd_after_shutdown(sd->channel, msg, fds); break; case WIRE_CHANNEL_FAIL_FALLEN_BEHIND: @@ -292,6 +293,7 @@ void peer_start_channeld(struct channel *channel, channel_set_billboard, take(&pcomms->peer_fd), take(&pcomms->gossip_fd), + take(&pcomms->gossip_store_fd), take(&hsmfd), NULL), false); diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index b816056da..88721eee7 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -185,6 +185,7 @@ void peer_start_closingd(struct channel *channel, channel_set_billboard, take(&pcomms->peer_fd), take(&pcomms->gossip_fd), + take(&pcomms->gossip_store_fd), take(&hsmfd), NULL), false); diff --git a/lightningd/connect_control.c b/lightningd/connect_control.c index cc329268e..beb8a3457 100644 --- a/lightningd/connect_control.c +++ b/lightningd/connect_control.c @@ -304,9 +304,9 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd break; case WIRE_CONNECT_PEER_CONNECTED: - if (tal_count(fds) != 2) - return 2; - peer_connected(connectd->ld, msg, fds[0], fds[1]); + if (tal_count(fds) != 3) + return 3; + peer_connected(connectd->ld, msg, fds[0], fds[1], fds[2]); break; case WIRE_CONNECTCTL_CONNECT_FAILED: diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 325033b08..b4df5171b 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -301,9 +301,10 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp, u8 *remote_upfront_shutdown_script; struct peer_comms *pcomms = new_peer_comms(resp); - assert(tal_count(fds) == 2); + assert(tal_count(fds) == 3); pcomms->peer_fd = fds[0]; pcomms->gossip_fd = fds[1]; + pcomms->gossip_store_fd = fds[2]; /* This is a new channel_info.their_config so set its ID to 0 */ channel_info.their_config.id = 0; @@ -493,9 +494,10 @@ static void opening_fundee_finished(struct subd *openingd, struct peer_comms *pcomms = new_peer_comms(reply); log_debug(uc->log, "Got opening_fundee_finish_response"); - assert(tal_count(fds) == 2); + assert(tal_count(fds) == 3); pcomms->peer_fd = fds[0]; pcomms->gossip_fd = fds[1]; + pcomms->gossip_store_fd = fds[2]; /* This is a new channel_info.their_config, set its ID to 0 */ channel_info.their_config.id = 0; @@ -567,6 +569,7 @@ static void opening_fundee_finished(struct subd *openingd, failed: close(fds[0]); close(fds[1]); + close(fds[3]); tal_free(uc); } @@ -736,8 +739,8 @@ static unsigned int openingd_msg(struct subd *openingd, tal_free(openingd); return 0; } - if (tal_count(fds) != 2) - return 2; + if (tal_count(fds) != 3) + return 3; opening_funder_finished(openingd, msg, fds, uc->fc); return 0; @@ -752,8 +755,8 @@ static unsigned int openingd_msg(struct subd *openingd, return 0; case WIRE_OPENING_FUNDEE: - if (tal_count(fds) != 2) - return 2; + if (tal_count(fds) != 3) + return 3; opening_fundee_finished(openingd, msg, fds, uc); return 0; @@ -799,6 +802,7 @@ void peer_start_openingd(struct peer *peer, opening_channel_set_billboard, take(&pcomms->peer_fd), take(&pcomms->gossip_fd), + take(&pcomms->gossip_store_fd), take(&hsmfd), NULL); if (!uc->openingd) { uncommitted_channel_disconnect(uc, diff --git a/lightningd/peer_comms.c b/lightningd/peer_comms.c index d8b30ce3b..c518d2de6 100644 --- a/lightningd/peer_comms.c +++ b/lightningd/peer_comms.c @@ -7,6 +7,8 @@ static void destroy_peer_comms(struct peer_comms *pcomms) close(pcomms->peer_fd); if (pcomms->gossip_fd != -1) close(pcomms->gossip_fd); + if (pcomms->gossip_store_fd != -1) + close(pcomms->gossip_store_fd); } struct peer_comms *new_peer_comms(const tal_t *ctx) diff --git a/lightningd/peer_comms.h b/lightningd/peer_comms.h index e5c194a1b..15e6b530c 100644 --- a/lightningd/peer_comms.h +++ b/lightningd/peer_comms.h @@ -9,7 +9,7 @@ struct peer_comms { struct crypto_state cs; /* If not -1, closed on freeing */ - int peer_fd, gossip_fd; + int peer_fd, gossip_fd, gossip_store_fd; }; struct peer_comms *new_peer_comms(const tal_t *ctx); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index eec6405d5..b953c49c7 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -795,7 +795,7 @@ REGISTER_PLUGIN_HOOK(peer_connected, peer_connected_hook_cb, /* Connectd tells us a peer has connected: it never hands us duplicates, since * it holds them until we say peer_died. */ void peer_connected(struct lightningd *ld, const u8 *msg, - int peer_fd, int gossip_fd) + int peer_fd, int gossip_fd, int gossip_store_fd) { struct node_id id; u8 *globalfeatures, *localfeatures; @@ -807,6 +807,7 @@ void peer_connected(struct lightningd *ld, const u8 *msg, hook_payload->pcomms = new_peer_comms(hook_payload); hook_payload->pcomms->peer_fd = peer_fd; hook_payload->pcomms->gossip_fd = gossip_fd; + hook_payload->pcomms->gossip_store_fd = gossip_store_fd; if (!fromwire_connect_peer_connected(msg, msg, &id, &hook_payload->addr, diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index f4b1d4f23..797424e7d 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -69,7 +69,7 @@ struct peer *peer_from_json(struct lightningd *ld, const jsmntok_t *peeridtok); void peer_connected(struct lightningd *ld, const u8 *msg, - int peer_fd, int gossip_fd); + int peer_fd, int gossip_fd, int gossip_store_fd); /* Could be configurable. */ #define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL diff --git a/lightningd/subd.c b/lightningd/subd.c index 483ac3f6e..b96291c95 100644 --- a/lightningd/subd.c +++ b/lightningd/subd.c @@ -363,7 +363,7 @@ static bool log_status_fail(struct subd *sd, const u8 *msg) return true; } -static bool handle_peer_error(struct subd *sd, const u8 *msg, int fds[2]) +static bool handle_peer_error(struct subd *sd, const u8 *msg, int fds[3]) { void *channel = sd->channel; struct channel_id channel_id; @@ -378,6 +378,7 @@ static bool handle_peer_error(struct subd *sd, const u8 *msg, int fds[2]) pcomms->peer_fd = fds[0]; pcomms->gossip_fd = fds[1]; + pcomms->gossip_store_fd = fds[2]; /* Don't free sd; we may be about to free channel. */ sd->channel = NULL; @@ -455,11 +456,11 @@ static struct io_plan *sd_msg_read(struct io_conn *conn, struct subd *sd) if (sd->channel) { switch ((enum peer_status)type) { case WIRE_STATUS_PEER_ERROR: - /* We expect 2 fds after this */ + /* We expect 3 fds after this */ if (!sd->fds_in) { /* Don't free msg_in: we go around again. */ tal_steal(sd, sd->msg_in); - plan = sd_collect_fds(conn, sd, 2); + plan = sd_collect_fds(conn, sd, 3); goto out; } if (!handle_peer_error(sd, sd->msg_in, sd->fds_in)) diff --git a/openingd/openingd.c b/openingd/openingd.c index 1bac87d1e..886b3a9f6 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -47,11 +47,12 @@ #include #include -/* stdin == lightningd, 3 == peer, 4 == gossipd, 5 = hsmd */ +/* stdin == lightningd, 3 == peer, 4 == gossipd, 5 = gossip_store, 6 = hsmd */ #define REQ_FD STDIN_FILENO #define PEER_FD 3 #define GOSSIP_FD 4 -#define HSM_FD 5 +#define GOSSIP_STORE_FD 5 +#define HSM_FD 6 /* Global state structure. This is only for the one specific peer and channel */ struct state { @@ -408,6 +409,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state, wire_sync_write(REQ_FD, take(msg)); } peer_failed_received_errmsg(PEER_FD, GOSSIP_FD, + GOSSIP_STORE_FD, &state->cs, err, NULL); } @@ -1306,7 +1308,9 @@ static u8 *handle_peer_in(struct state *state) case WIRE_UPDATE_FEE: case WIRE_ANNOUNCEMENT_SIGNATURES: /* Standard cases */ - if (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, &state->cs, + if (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, + GOSSIP_STORE_FD, + &state->cs, &state->channel_id, msg)) return NULL; break; @@ -1542,6 +1546,7 @@ int main(int argc, char *argv[]) wire_sync_write(REQ_FD, msg); fdpass_send(REQ_FD, PEER_FD); fdpass_send(REQ_FD, GOSSIP_FD); + fdpass_send(REQ_FD, GOSSIP_STORE_FD); status_trace("Sent %s with fd", opening_wire_type_name(fromwire_peektype(msg)));