channeld: send channel_announce and initial update to master, not gossipd.

There is a race we see sometimes under valgrind on Travis which shows
gossipd receiving the node_announce from master before it reads the
channel_announce from channeld, and thus fails.  The simplest solution
is to send the channel_announce and channel_update to master as well,
so it can ensure it sends them to gossipd in order

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-10-23 14:41:38 +10:30 committed by Christian Decker
parent 66a0c55322
commit ebdecebb1a
3 changed files with 40 additions and 28 deletions

View File

@ -231,9 +231,10 @@ static void send_announcement_signatures(struct peer *peer)
tal_free(tmpctx); tal_free(tmpctx);
} }
static void send_channel_update(struct peer *peer, bool disabled) static u8 *create_channel_update(const tal_t *ctx,
struct peer *peer, bool disabled)
{ {
tal_t *tmpctx = tal_tmpctx(peer); tal_t *tmpctx = tal_tmpctx(ctx);
u32 timestamp = time_now().ts.tv_sec; u32 timestamp = time_now().ts.tv_sec;
u16 flags; u16 flags;
u8 *cupdate, *msg; u8 *cupdate, *msg;
@ -257,14 +258,12 @@ static void send_channel_update(struct peer *peer, bool disabled)
strerror(errno)); strerror(errno));
msg = wire_sync_read(tmpctx, HSM_FD); msg = wire_sync_read(tmpctx, HSM_FD);
if (!msg || !fromwire_hsm_cupdate_sig_reply(tmpctx, msg, NULL, &cupdate)) if (!msg || !fromwire_hsm_cupdate_sig_reply(ctx, msg, NULL, &cupdate))
status_failed(STATUS_FAIL_HSM_IO, status_failed(STATUS_FAIL_HSM_IO,
"Reading cupdate_sig_req: %s", "Reading cupdate_sig_req: %s",
strerror(errno)); strerror(errno));
daemon_conn_send(&peer->gossip_client, cupdate);
msg_enqueue(&peer->peer_out, cupdate);
tal_free(tmpctx); tal_free(tmpctx);
return cupdate;
} }
/* Tentatively create a channel_announcement, possibly with invalid /* Tentatively create a channel_announcement, possibly with invalid
@ -297,15 +296,6 @@ static u8 *create_channel_announcement(const tal_t *ctx, struct peer *peer)
return cannounce; return cannounce;
} }
static void send_channel_announcement(struct peer *peer)
{
u8 *msg = create_channel_announcement(peer, peer);
/* Makes a copy */
msg_enqueue(&peer->peer_out, msg);
/* Takes ownership */
daemon_conn_send(&peer->gossip_client, take(msg));
}
static struct io_plan *peer_out(struct io_conn *conn, struct peer *peer) static struct io_plan *peer_out(struct io_conn *conn, struct peer *peer)
{ {
const u8 *out = msg_dequeue(&peer->peer_out); const u8 *out = msg_dequeue(&peer->peer_out);
@ -362,11 +352,16 @@ static struct io_plan *handle_peer_funding_locked(struct io_conn *conn,
static void announce_channel(struct peer *peer) static void announce_channel(struct peer *peer)
{ {
send_channel_announcement(peer); u8 *cannounce, *cupdate;
send_channel_update(peer, false);
/* Tell the master that we just announced the channel, cannounce = create_channel_announcement(peer, peer);
* so it may announce the node */ cupdate = create_channel_update(cannounce, peer, false);
wire_sync_write(MASTER_FD, take(towire_channel_announced(peer)));
/* Tell the master that we to announce channel (it does node) */
wire_sync_write(MASTER_FD, take(towire_channel_announce(peer,
cannounce,
cupdate)));
tal_free(cannounce);
} }
static struct io_plan *handle_peer_announcement_signatures(struct io_conn *conn, static struct io_plan *handle_peer_announcement_signatures(struct io_conn *conn,
@ -1406,7 +1401,10 @@ static void peer_conn_broken(struct io_conn *conn, struct peer *peer)
{ {
/* If we have signatures, send an update to say we're disabled. */ /* If we have signatures, send an update to say we're disabled. */
if (peer->have_sigs[LOCAL] && peer->have_sigs[REMOTE]) { if (peer->have_sigs[LOCAL] && peer->have_sigs[REMOTE]) {
send_channel_update(peer, true); u8 *cupdate = create_channel_update(conn, peer, true);
daemon_conn_send(&peer->gossip_client, cupdate);
msg_enqueue(&peer->peer_out, take(cupdate));
/* Make sure gossipd actually gets this message before dying */ /* Make sure gossipd actually gets this message before dying */
daemon_conn_sync_flush(&peer->gossip_client); daemon_conn_sync_flush(&peer->gossip_client);
@ -1954,7 +1952,7 @@ static void req_in(struct peer *peer, const u8 *msg)
case WIRE_CHANNEL_INIT: case WIRE_CHANNEL_INIT:
case WIRE_CHANNEL_OFFER_HTLC_REPLY: case WIRE_CHANNEL_OFFER_HTLC_REPLY:
case WIRE_CHANNEL_PING_REPLY: case WIRE_CHANNEL_PING_REPLY:
case WIRE_CHANNEL_ANNOUNCED: case WIRE_CHANNEL_ANNOUNCE:
case WIRE_CHANNEL_SENDING_COMMITSIG: case WIRE_CHANNEL_SENDING_COMMITSIG:
case WIRE_CHANNEL_GOT_COMMITSIG: case WIRE_CHANNEL_GOT_COMMITSIG:
case WIRE_CHANNEL_GOT_REVOKE: case WIRE_CHANNEL_GOT_REVOKE:

View File

@ -102,8 +102,12 @@ channel_ping,,len,u16
channel_ping_reply,1111 channel_ping_reply,1111
channel_ping_reply,,totlen,u16 channel_ping_reply,,totlen,u16
# Channeld tells the master that the channel has been announced # Channeld tells the master to announce the channel (with first update)
channel_announced,1012 channel_announce,1012
channel_announce,,announce_len,u16
channel_announce,,announce,announce_len*u8
channel_announce,,update_len,u16
channel_announce,,update,update_len*u8
# When we receive funding_locked. # When we receive funding_locked.
channel_got_funding_locked,1019 channel_got_funding_locked,1019

1 # Received and sent funding_locked
102 # SENT_ADD_COMMIT, SENT_REMOVE_ACK_COMMIT, SENT_ADD_ACK_COMMIT, SENT_REMOVE_COMMIT channel_got_funding_locked,,next_per_commit_point,struct pubkey
103 channel_sending_commitsig,,num_changed,u16 # When we send a commitment_signed message, tell master.
104 channel_sending_commitsig,,changed,num_changed*struct changed_htlc channel_sending_commitsig,1020
105 channel_sending_commitsig,,commit_sig,secp256k1_ecdsa_signature channel_sending_commitsig,,commitnum,u64
106 channel_sending_commitsig,,num_htlc_sigs,u16 # SENT_ADD_COMMIT, SENT_REMOVE_ACK_COMMIT, SENT_ADD_ACK_COMMIT, SENT_REMOVE_COMMIT
107 channel_sending_commitsig,,num_changed,u16
108 channel_sending_commitsig,,changed,num_changed*struct changed_htlc
109 channel_sending_commitsig,,commit_sig,secp256k1_ecdsa_signature
110 channel_sending_commitsig,,num_htlc_sigs,u16
111 channel_sending_commitsig,,htlc_sigs,num_htlc_sigs*secp256k1_ecdsa_signature
112 # Wait for reply, to make sure it's on disk before we send commit.
113 channel_sending_commitsig_reply,1120

View File

@ -1546,15 +1546,16 @@ static u8 *create_node_announcement(const tal_t *ctx, struct lightningd *ld,
* an update, so we can now start sending a node_announcement. The * an update, so we can now start sending a node_announcement. The
* first step is to build the provisional announcement and ask the HSM * first step is to build the provisional announcement and ask the HSM
* to sign it. */ * to sign it. */
static void peer_channel_announced(struct peer *peer, const u8 *msg) static void peer_channel_announce(struct peer *peer, const u8 *msg)
{ {
struct lightningd *ld = peer->ld; struct lightningd *ld = peer->ld;
tal_t *tmpctx = tal_tmpctx(peer); tal_t *tmpctx = tal_tmpctx(peer);
secp256k1_ecdsa_signature sig; secp256k1_ecdsa_signature sig;
u8 *cannounce, *cupdate;
u8 *announcement, *wrappedmsg; u8 *announcement, *wrappedmsg;
u32 timestamp = time_now().ts.tv_sec; u32 timestamp = time_now().ts.tv_sec;
if (!fromwire_channel_announced(msg, NULL)) { if (!fromwire_channel_announce(msg, msg, NULL, &cannounce, &cupdate)) {
peer_internal_error(peer, "bad fromwire_channel_announced %s", peer_internal_error(peer, "bad fromwire_channel_announced %s",
tal_hex(peer, msg)); tal_hex(peer, msg));
return; return;
@ -1574,6 +1575,15 @@ static void peer_channel_announced(struct peer *peer, const u8 *msg)
* from the HSM, create the real announcement and forward it to * from the HSM, create the real announcement and forward it to
* gossipd so it can take care of forwarding it. */ * gossipd so it can take care of forwarding it. */
announcement = create_node_announcement(tmpctx, ld, &sig, timestamp); announcement = create_node_announcement(tmpctx, ld, &sig, timestamp);
/* We have to send channel_announce before channel_update and
* node_announcement */
wrappedmsg = towire_gossip_forwarded_msg(tmpctx, cannounce);
subd_send_msg(ld->gossip, take(wrappedmsg));
wrappedmsg = towire_gossip_forwarded_msg(tmpctx, cupdate);
subd_send_msg(ld->gossip, take(wrappedmsg));
wrappedmsg = towire_gossip_forwarded_msg(tmpctx, announcement); wrappedmsg = towire_gossip_forwarded_msg(tmpctx, announcement);
subd_send_msg(ld->gossip, take(wrappedmsg)); subd_send_msg(ld->gossip, take(wrappedmsg));
tal_free(tmpctx); tal_free(tmpctx);
@ -1956,8 +1966,8 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
case WIRE_CHANNEL_GOT_REVOKE: case WIRE_CHANNEL_GOT_REVOKE:
peer_got_revoke(sd->peer, msg); peer_got_revoke(sd->peer, msg);
break; break;
case WIRE_CHANNEL_ANNOUNCED: case WIRE_CHANNEL_ANNOUNCE:
peer_channel_announced(sd->peer, msg); peer_channel_announce(sd->peer, msg);
break; break;
case WIRE_CHANNEL_GOT_FUNDING_LOCKED: case WIRE_CHANNEL_GOT_FUNDING_LOCKED:
peer_got_funding_locked(sd->peer, msg); peer_got_funding_locked(sd->peer, msg);