Browse Source

gossipd: hand a gossip_store_fd to all subdaemons.

This will let them read from the gossip store directly.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
htlc_accepted_hook
Rusty Russell 6 years ago
parent
commit
13717c6ebb
  1. 12
      channeld/channeld.c
  2. 9
      closingd/closingd.c
  3. 10
      common/peer_failed.c
  4. 11
      common/peer_failed.h
  5. 3
      common/read_peer_msg.c
  6. 4
      common/read_peer_msg.h
  7. 5
      common/status.c
  8. 2
      common/status.h
  9. 2
      connectd/connect_gossip_wire.csv
  10. 2
      connectd/connect_wire.csv
  11. 30
      connectd/connectd.c
  12. 5
      gossipd/gossip_store.c
  13. 8
      gossipd/gossip_store.h
  14. 12
      gossipd/gossipd.c
  15. 10
      lightningd/channel_control.c
  16. 1
      lightningd/closing_control.c
  17. 6
      lightningd/connect_control.c
  18. 16
      lightningd/opening_control.c
  19. 2
      lightningd/peer_comms.c
  20. 2
      lightningd/peer_comms.h
  21. 3
      lightningd/peer_control.c
  22. 2
      lightningd/peer_control.h
  23. 7
      lightningd/subd.c
  24. 11
      openingd/openingd.c

12
channeld/channeld.c

@ -59,11 +59,12 @@
#include <wire/wire_io.h> #include <wire/wire_io.h>
#include <wire/wire_sync.h> #include <wire/wire_sync.h>
/* 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 MASTER_FD STDIN_FILENO
#define PEER_FD 3 #define PEER_FD 3
#define GOSSIP_FD 4 #define GOSSIP_FD 4
#define HSM_FD 5 #define GOSSIP_STORE_FD 5
#define HSM_FD 6
struct peer { struct peer {
struct crypto_state cs; struct crypto_state cs;
@ -1771,7 +1772,7 @@ static void peer_in(struct peer *peer, const u8 *msg)
return; 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->cs,
&peer->channel_id, msg)) &peer->channel_id, msg))
return; return;
@ -2232,8 +2233,8 @@ static void peer_reconnect(struct peer *peer,
do { do {
clean_tmpctx(); clean_tmpctx();
msg = sync_crypto_read(tmpctx, &peer->cs, PEER_FD); msg = sync_crypto_read(tmpctx, &peer->cs, PEER_FD);
} while (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, &peer->cs, } while (handle_peer_gossip_or_error(PEER_FD, GOSSIP_FD, GOSSIP_STORE_FD,
&peer->channel_id, msg) &peer->cs, &peer->channel_id, msg)
|| capture_premature_msg(&premature_msgs, msg)); || capture_premature_msg(&premature_msgs, msg));
if (dataloss_protect) { if (dataloss_protect) {
@ -2971,6 +2972,7 @@ static void send_shutdown_complete(struct peer *peer)
take(towire_channel_shutdown_complete(NULL, &peer->cs))); take(towire_channel_shutdown_complete(NULL, &peer->cs)));
fdpass_send(MASTER_FD, PEER_FD); fdpass_send(MASTER_FD, PEER_FD);
fdpass_send(MASTER_FD, GOSSIP_FD); fdpass_send(MASTER_FD, GOSSIP_FD);
fdpass_send(MASTER_FD, GOSSIP_STORE_FD);
close(MASTER_FD); close(MASTER_FD);
} }

9
closingd/closingd.c

@ -23,11 +23,12 @@
#include <wire/peer_wire.h> #include <wire/peer_wire.h>
#include <wire/wire_sync.h> #include <wire/wire_sync.h>
/* stdin == requests, 3 == peer, 4 = gossip */ /* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = hsmd */
#define REQ_FD STDIN_FILENO #define REQ_FD STDIN_FILENO
#define PEER_FD 3 #define PEER_FD 3
#define GOSSIP_FD 4 #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, static struct bitcoin_tx *close_tx(const tal_t *ctx,
struct crypto_state *cs, 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)); handle_gossip_msg(PEER_FD, cs, take(msg));
continue; 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)) channel_id, msg))
return msg; return msg;
} }

10
common/peer_failed.c

@ -9,7 +9,7 @@
#include <stdarg.h> #include <stdarg.h>
/* We only support one channel per peer anyway */ /* 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, struct crypto_state *cs,
const struct channel_id *channel_id, const struct channel_id *channel_id,
const char *fmt, ...) const char *fmt, ...)
@ -32,11 +32,11 @@ void peer_failed_(int peer_fd, int gossip_fd,
err); err);
peer_billboard(true, desc); peer_billboard(true, desc);
tal_free(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 */ /* 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, struct crypto_state *cs,
const char *desc, const char *desc,
const struct channel_id *channel_id) 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; channel_id = &all_channels;
msg = towire_status_peer_error(NULL, channel_id, desc, cs, NULL); msg = towire_status_peer_error(NULL, channel_id, desc, cs, NULL);
peer_billboard(true, "Received error from peer: %s", desc); 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) void peer_failed_connection_lost(void)
{ {
status_send_fatal(take(towire_status_peer_connection_lost(NULL)), status_send_fatal(take(towire_status_peer_connection_lost(NULL)),
-1, -1); -1, -1, -1);
} }

11
common/peer_failed.h

@ -12,18 +12,19 @@ struct channel_id;
* @channel_id: channel with error, or NULL for all. * @channel_id: channel with error, or NULL for all.
* @fmt...: format as per status_failed(STATUS_FAIL_PEER_BAD) * @fmt...: format as per status_failed(STATUS_FAIL_PEER_BAD)
*/ */
#define peer_failed(cs, channel_id, ...) \ #define peer_failed(cs, channel_id, ...) \
peer_failed_(PEER_FD, GOSSIP_FD, (cs), (channel_id), __VA_ARGS__) 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, struct crypto_state *cs,
const struct channel_id *channel_id, const struct channel_id *channel_id,
const char *fmt, ...) const char *fmt, ...)
PRINTF_FMT(5,6) NORETURN; PRINTF_FMT(6,7) NORETURN;
/* We're failing because peer sent us an error message: NULL /* We're failing because peer sent us an error message: NULL
* channel_id means all channels. */ * 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, struct crypto_state *cs,
const char *desc, const char *desc,
const struct channel_id *channel_id) NORETURN; const struct channel_id *channel_id) NORETURN;

3
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); 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, struct crypto_state *cs,
const struct channel_id *channel_id, const struct channel_id *channel_id,
const u8 *msg TAKES) 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 (is_peer_error(tmpctx, msg, channel_id, &err, &all_channels)) {
if (err) if (err)
peer_failed_received_errmsg(peer_fd, gossip_fd, peer_failed_received_errmsg(peer_fd, gossip_fd,
gossip_store_fd,
cs, err, cs, err,
all_channels all_channels
? NULL : channel_id); ? NULL : channel_id);

4
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. * 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) * @cs: the cryptostate (updated)
* @msg: the peer message (only taken if returns true). * @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 * to gossipd), an error packet (causes peer_failed_received_errmsg or
* ignored), or a message about the wrong channel (sends sync error reply). * 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, struct crypto_state *cs,
const struct channel_id *channel_id, const struct channel_id *channel_id,
const u8 *msg TAKES); const u8 *msg TAKES);

5
common/status.c

@ -162,7 +162,7 @@ static NORETURN void flush_and_exit(int reason)
exit(0x80 | (reason & 0xFF)); 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); int reason = fromwire_peektype(msg);
breakpoint(); breakpoint();
@ -173,6 +173,7 @@ void status_send_fatal(const u8 *msg TAKES, int fd1, int fd2)
assert(!status_conn); assert(!status_conn);
fdpass_send(status_fd, fd1); fdpass_send(status_fd, fd1);
fdpass_send(status_fd, fd2); fdpass_send(status_fd, fd2);
fdpass_send(status_fd, fd3);
} }
flush_and_exit(reason); flush_and_exit(reason);
@ -193,7 +194,7 @@ void status_failed(enum status_failreason reason, const char *fmt, ...)
send_backtrace(str); send_backtrace(str);
status_send_fatal(take(towire_status_fail(NULL, reason, 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) void master_badmsg(u32 type_expected, const u8 *msg)

2
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 master_badmsg(u32 type_expected, const u8 *msg) NORETURN;
void status_send(const u8 *msg TAKES); 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 */ #endif /* LIGHTNING_COMMON_STATUS_H */

2
connectd/connect_gossip_wire.csv

@ -8,7 +8,7 @@ gossip_new_peer,,gossip_queries_feature,bool
# Did they offer LOCAL_INITIAL_ROUTING_SYNC? # Did they offer LOCAL_INITIAL_ROUTING_SYNC?
gossip_new_peer,,initial_routing_sync,bool 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,4100
gossip_new_peer_reply,,success,bool gossip_new_peer_reply,,success,bool

Can't render this file because it has a wrong number of fields in line 4.

2
connectd/connect_wire.csv

@ -45,7 +45,7 @@ connectctl_connect_failed,,failreason,wirestring
connectctl_connect_failed,,seconds_to_delay,u32 connectctl_connect_failed,,seconds_to_delay,u32
connectctl_connect_failed,,addrhint,?struct wireaddr_internal 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,2002
connect_peer_connected,,id,struct node_id connect_peer_connected,,id,struct node_id
connect_peer_connected,,addr,struct wireaddr_internal connect_peer_connected,,addr,struct wireaddr_internal

Can't render this file because it has a wrong number of fields in line 5.

30
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 * 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). * 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 * The 'localfeatures' is a field in the `init` message, indicating properties
* when you're connected to it like we are: there are also 'globalfeatures' * when you're connected to it like we are: there are also 'globalfeatures'
* which specify requirements to route a payment through a node. */ * which specify requirements to route a payment through a node. */
static int get_gossipfd(struct daemon *daemon, static bool get_gossipfds(struct daemon *daemon,
const struct node_id *id, const struct node_id *id,
const u8 *localfeatures) const u8 *localfeatures,
int *gossip_fd,
int *gossip_store_fd)
{ {
bool gossip_queries_feature, initial_routing_sync, success; bool gossip_queries_feature, initial_routing_sync, success;
u8 *msg; u8 *msg;
@ -318,12 +323,14 @@ static int get_gossipfd(struct daemon *daemon,
if (!success) { if (!success) {
status_broken("Gossipd did not give us an fd: losing peer %s", status_broken("Gossipd did not give us an fd: losing peer %s",
type_to_string(tmpctx, struct node_id, id)); 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. */ * 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 /*~ 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 *peer_connected_msg TAKES,
const u8 *localfeatures TAKES) const u8 *localfeatures TAKES)
{ {
int gossip_fd; int gossip_fd, gossip_store_fd;
if (node_set_get(&daemon->peers, id)) if (node_set_get(&daemon->peers, id))
return peer_reconnected(conn, daemon, id, peer_connected_msg, 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. */ /* We've successfully connected. */
connected_to_peer(daemon, conn, id); connected_to_peer(daemon, conn, id);
gossip_fd = get_gossipfd(daemon, id, localfeatures); /* We promised we'd take it by marking it TAKEN above; prepare to free it. */
/* We promised we'd take it by marking it TAKEN above; simply free it. */
if (taken(localfeatures)) if (taken(localfeatures))
tal_free(localfeatures); tal_steal(tmpctx, localfeatures);
/* If gossipd can't give us a file descriptor, we give up connecting. */ /* 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); return io_close(conn);
/*~ daemon_conn is a message queue for inter-daemon communication: we /*~ 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 */ /* 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, io_conn_fd(conn));
daemon_conn_send_fd(daemon->master, gossip_fd); 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 /*~ Finally, we add it to the set of pubkeys: tal_dup will handle
* take() args for us, by simply tal_steal()ing it. */ * take() args for us, by simply tal_steal()ing it. */

5
gossipd/gossip_store.c

@ -565,6 +565,11 @@ const u8 *gossip_store_get(const tal_t *ctx,
return msg; 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) void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
{ {
beint32_t hdr[2]; beint32_t hdr[2];

8
gossipd/gossip_store.h

@ -66,6 +66,12 @@ bool gossip_store_compact(struct gossip_store *gs,
struct broadcast_state **bs, struct broadcast_state **bs,
u32 *offset); 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 */ #endif /* LIGHTNING_GOSSIPD_GOSSIP_STORE_H */

12
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); struct peer *peer = tal(conn, struct peer);
int fds[2]; int fds[2];
int gossip_store_fd;
if (!fromwire_gossip_new_peer(msg, &peer->id, if (!fromwire_gossip_new_peer(msg, &peer->id,
&peer->gossip_queries_feature, &peer->gossip_queries_feature,
@ -1712,10 +1713,20 @@ static struct io_plan *connectd_new_peer(struct io_conn *conn,
return io_close(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. */ /* This can happen: we handle it gracefully, returning a `failed` msg. */
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));
close(gossip_store_fd);
daemon_conn_send(daemon->connectd, daemon_conn_send(daemon->connectd,
take(towire_gossip_new_peer_reply(NULL, false))); take(towire_gossip_new_peer_reply(NULL, false)));
goto done; goto done;
@ -1787,6 +1798,7 @@ static struct io_plan *connectd_new_peer(struct io_conn *conn,
daemon_conn_send(daemon->connectd, daemon_conn_send(daemon->connectd,
take(towire_gossip_new_peer_reply(NULL, true))); take(towire_gossip_new_peer_reply(NULL, true)));
daemon_conn_send_fd(daemon->connectd, fds[1]); daemon_conn_send_fd(daemon->connectd, fds[1]);
daemon_conn_send_fd(daemon->connectd, gossip_store_fd);
done: done:
return daemon_conn_read_next(conn, daemon->connectd); return daemon_conn_read_next(conn, daemon->connectd);

10
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); struct peer_comms *pcomms = new_peer_comms(msg);
/* We expect 2 fds. */ /* We expect 3 fds. */
assert(tal_count(fds) == 2); assert(tal_count(fds) == 3);
if (!fromwire_channel_shutdown_complete(msg, &pcomms->cs)) { if (!fromwire_channel_shutdown_complete(msg, &pcomms->cs)) {
channel_internal_error(channel, "bad shutdown_complete: %s", 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->peer_fd = fds[0];
pcomms->gossip_fd = fds[1]; pcomms->gossip_fd = fds[1];
pcomms->gossip_store_fd = fds[2];
/* This sets channel->owner, closes down channeld. */ /* This sets channel->owner, closes down channeld. */
peer_start_closingd(channel, pcomms, false, NULL); 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); peer_got_shutdown(sd->channel, msg);
break; break;
case WIRE_CHANNEL_SHUTDOWN_COMPLETE: case WIRE_CHANNEL_SHUTDOWN_COMPLETE:
/* We expect 2 fds. */ /* We expect 3 fds. */
if (!fds) if (!fds)
return 2; return 3;
peer_start_closingd_after_shutdown(sd->channel, msg, fds); peer_start_closingd_after_shutdown(sd->channel, msg, fds);
break; break;
case WIRE_CHANNEL_FAIL_FALLEN_BEHIND: case WIRE_CHANNEL_FAIL_FALLEN_BEHIND:
@ -292,6 +293,7 @@ void peer_start_channeld(struct channel *channel,
channel_set_billboard, channel_set_billboard,
take(&pcomms->peer_fd), take(&pcomms->peer_fd),
take(&pcomms->gossip_fd), take(&pcomms->gossip_fd),
take(&pcomms->gossip_store_fd),
take(&hsmfd), NULL), take(&hsmfd), NULL),
false); false);

1
lightningd/closing_control.c

@ -185,6 +185,7 @@ void peer_start_closingd(struct channel *channel,
channel_set_billboard, channel_set_billboard,
take(&pcomms->peer_fd), take(&pcomms->peer_fd),
take(&pcomms->gossip_fd), take(&pcomms->gossip_fd),
take(&pcomms->gossip_store_fd),
take(&hsmfd), take(&hsmfd),
NULL), NULL),
false); false);

6
lightningd/connect_control.c

@ -304,9 +304,9 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd
break; break;
case WIRE_CONNECT_PEER_CONNECTED: case WIRE_CONNECT_PEER_CONNECTED:
if (tal_count(fds) != 2) if (tal_count(fds) != 3)
return 2; return 3;
peer_connected(connectd->ld, msg, fds[0], fds[1]); peer_connected(connectd->ld, msg, fds[0], fds[1], fds[2]);
break; break;
case WIRE_CONNECTCTL_CONNECT_FAILED: case WIRE_CONNECTCTL_CONNECT_FAILED:

16
lightningd/opening_control.c

@ -301,9 +301,10 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
u8 *remote_upfront_shutdown_script; u8 *remote_upfront_shutdown_script;
struct peer_comms *pcomms = new_peer_comms(resp); struct peer_comms *pcomms = new_peer_comms(resp);
assert(tal_count(fds) == 2); assert(tal_count(fds) == 3);
pcomms->peer_fd = fds[0]; pcomms->peer_fd = fds[0];
pcomms->gossip_fd = fds[1]; 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 */ /* This is a new channel_info.their_config so set its ID to 0 */
channel_info.their_config.id = 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); struct peer_comms *pcomms = new_peer_comms(reply);
log_debug(uc->log, "Got opening_fundee_finish_response"); 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->peer_fd = fds[0];
pcomms->gossip_fd = fds[1]; pcomms->gossip_fd = fds[1];
pcomms->gossip_store_fd = fds[2];
/* This is a new channel_info.their_config, set its ID to 0 */ /* This is a new channel_info.their_config, set its ID to 0 */
channel_info.their_config.id = 0; channel_info.their_config.id = 0;
@ -567,6 +569,7 @@ static void opening_fundee_finished(struct subd *openingd,
failed: failed:
close(fds[0]); close(fds[0]);
close(fds[1]); close(fds[1]);
close(fds[3]);
tal_free(uc); tal_free(uc);
} }
@ -736,8 +739,8 @@ static unsigned int openingd_msg(struct subd *openingd,
tal_free(openingd); tal_free(openingd);
return 0; return 0;
} }
if (tal_count(fds) != 2) if (tal_count(fds) != 3)
return 2; return 3;
opening_funder_finished(openingd, msg, fds, uc->fc); opening_funder_finished(openingd, msg, fds, uc->fc);
return 0; return 0;
@ -752,8 +755,8 @@ static unsigned int openingd_msg(struct subd *openingd,
return 0; return 0;
case WIRE_OPENING_FUNDEE: case WIRE_OPENING_FUNDEE:
if (tal_count(fds) != 2) if (tal_count(fds) != 3)
return 2; return 3;
opening_fundee_finished(openingd, msg, fds, uc); opening_fundee_finished(openingd, msg, fds, uc);
return 0; return 0;
@ -799,6 +802,7 @@ void peer_start_openingd(struct peer *peer,
opening_channel_set_billboard, opening_channel_set_billboard,
take(&pcomms->peer_fd), take(&pcomms->peer_fd),
take(&pcomms->gossip_fd), take(&pcomms->gossip_fd),
take(&pcomms->gossip_store_fd),
take(&hsmfd), NULL); take(&hsmfd), NULL);
if (!uc->openingd) { if (!uc->openingd) {
uncommitted_channel_disconnect(uc, uncommitted_channel_disconnect(uc,

2
lightningd/peer_comms.c

@ -7,6 +7,8 @@ static void destroy_peer_comms(struct peer_comms *pcomms)
close(pcomms->peer_fd); close(pcomms->peer_fd);
if (pcomms->gossip_fd != -1) if (pcomms->gossip_fd != -1)
close(pcomms->gossip_fd); 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) struct peer_comms *new_peer_comms(const tal_t *ctx)

2
lightningd/peer_comms.h

@ -9,7 +9,7 @@
struct peer_comms { struct peer_comms {
struct crypto_state cs; struct crypto_state cs;
/* If not -1, closed on freeing */ /* 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); struct peer_comms *new_peer_comms(const tal_t *ctx);

3
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 /* 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_died. */
void peer_connected(struct lightningd *ld, const u8 *msg, 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; struct node_id id;
u8 *globalfeatures, *localfeatures; 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 = new_peer_comms(hook_payload);
hook_payload->pcomms->peer_fd = peer_fd; hook_payload->pcomms->peer_fd = peer_fd;
hook_payload->pcomms->gossip_fd = gossip_fd; hook_payload->pcomms->gossip_fd = gossip_fd;
hook_payload->pcomms->gossip_store_fd = gossip_store_fd;
if (!fromwire_connect_peer_connected(msg, msg, if (!fromwire_connect_peer_connected(msg, msg,
&id, &hook_payload->addr, &id, &hook_payload->addr,

2
lightningd/peer_control.h

@ -69,7 +69,7 @@ struct peer *peer_from_json(struct lightningd *ld,
const jsmntok_t *peeridtok); const jsmntok_t *peeridtok);
void peer_connected(struct lightningd *ld, const u8 *msg, 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. */ /* Could be configurable. */
#define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL #define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL

7
lightningd/subd.c

@ -363,7 +363,7 @@ static bool log_status_fail(struct subd *sd, const u8 *msg)
return true; 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; void *channel = sd->channel;
struct channel_id channel_id; 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->peer_fd = fds[0];
pcomms->gossip_fd = fds[1]; pcomms->gossip_fd = fds[1];
pcomms->gossip_store_fd = fds[2];
/* Don't free sd; we may be about to free channel. */ /* Don't free sd; we may be about to free channel. */
sd->channel = NULL; sd->channel = NULL;
@ -455,11 +456,11 @@ static struct io_plan *sd_msg_read(struct io_conn *conn, struct subd *sd)
if (sd->channel) { if (sd->channel) {
switch ((enum peer_status)type) { switch ((enum peer_status)type) {
case WIRE_STATUS_PEER_ERROR: case WIRE_STATUS_PEER_ERROR:
/* We expect 2 fds after this */ /* We expect 3 fds after this */
if (!sd->fds_in) { if (!sd->fds_in) {
/* Don't free msg_in: we go around again. */ /* Don't free msg_in: we go around again. */
tal_steal(sd, sd->msg_in); tal_steal(sd, sd->msg_in);
plan = sd_collect_fds(conn, sd, 2); plan = sd_collect_fds(conn, sd, 3);
goto out; goto out;
} }
if (!handle_peer_error(sd, sd->msg_in, sd->fds_in)) if (!handle_peer_error(sd, sd->msg_in, sd->fds_in))

11
openingd/openingd.c

@ -47,11 +47,12 @@
#include <wire/wire.h> #include <wire/wire.h>
#include <wire/wire_sync.h> #include <wire/wire_sync.h>
/* 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 REQ_FD STDIN_FILENO
#define PEER_FD 3 #define PEER_FD 3
#define GOSSIP_FD 4 #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 */ /* Global state structure. This is only for the one specific peer and channel */
struct state { 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)); wire_sync_write(REQ_FD, take(msg));
} }
peer_failed_received_errmsg(PEER_FD, GOSSIP_FD, peer_failed_received_errmsg(PEER_FD, GOSSIP_FD,
GOSSIP_STORE_FD,
&state->cs, err, &state->cs, err,
NULL); NULL);
} }
@ -1306,7 +1308,9 @@ static u8 *handle_peer_in(struct state *state)
case WIRE_UPDATE_FEE: case WIRE_UPDATE_FEE:
case WIRE_ANNOUNCEMENT_SIGNATURES: case WIRE_ANNOUNCEMENT_SIGNATURES:
/* Standard cases */ /* 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)) &state->channel_id, msg))
return NULL; return NULL;
break; break;
@ -1542,6 +1546,7 @@ int main(int argc, char *argv[])
wire_sync_write(REQ_FD, msg); wire_sync_write(REQ_FD, msg);
fdpass_send(REQ_FD, PEER_FD); fdpass_send(REQ_FD, PEER_FD);
fdpass_send(REQ_FD, GOSSIP_FD); fdpass_send(REQ_FD, GOSSIP_FD);
fdpass_send(REQ_FD, GOSSIP_STORE_FD);
status_trace("Sent %s with fd", status_trace("Sent %s with fd",
opening_wire_type_name(fromwire_peektype(msg))); opening_wire_type_name(fromwire_peektype(msg)));

Loading…
Cancel
Save