diff --git a/channeld/channel.c b/channeld/channel.c index c763605a998e..d9ed24a5b56c 100644 --- a/channeld/channel.c +++ b/channeld/channel.c @@ -199,6 +199,34 @@ static void gossip_in(struct peer *peer, const u8 *msg) wire_type_name(type), tal_hex(msg, msg)); } +/* Send a temporary `channel_announcement` and `channel_update`. These + * are unsigned and mainly used to tell gossip about the channel + * before we have reached the `announcement_depth`, not being signed + * means they will not be relayed, but we can already rely on them for + * our own outgoing payments */ +static void send_temporary_announcement(struct peer *peer) +{ + tal_t *tmpctx; + u8 *msg; + + /* If we are supposed to send a real announcement, don't do a + * dummy one here, hence the check for announce_depth. */ + if (peer->announce_depth_reached || !peer->funding_locked[LOCAL] || + !peer->funding_locked[REMOTE]) + return; + + tmpctx = tal_tmpctx(peer); + + msg = towire_gossip_local_add_channel( + tmpctx, &peer->short_channel_ids[LOCAL], &peer->chain_hash, + &peer->node_ids[REMOTE], 0 /* flags */, peer->cltv_delta, + peer->conf[REMOTE].htlc_minimum_msat, peer->fee_base, + peer->fee_per_satoshi); + wire_sync_write(GOSSIP_FD, take(msg)); + + tal_free(tmpctx); +} + static void send_announcement_signatures(struct peer *peer) { /* First 2 + 256 byte are the signatures and msg type, skip them */ @@ -363,6 +391,8 @@ static void handle_peer_funding_locked(struct peer *peer, const u8 *msg) take(towire_channel_normal_operation(peer))); } + /* Send temporary or final announcements */ + send_temporary_announcement(peer); send_announcement_signatures(peer); } @@ -1808,12 +1838,14 @@ static void handle_funding_locked(struct peer *peer, const u8 *msg) msg_enqueue(&peer->peer_out, take(msg)); peer->funding_locked[LOCAL] = true; - send_announcement_signatures(peer); - if (peer->funding_locked[REMOTE]) { wire_sync_write(MASTER_FD, take(towire_channel_normal_operation(peer))); } + + /* Send temporary or final announcements */ + send_temporary_announcement(peer); + send_announcement_signatures(peer); } static void handle_funding_announce_depth(struct peer *peer, const u8 *msg) diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 172a0f9cc11c..1131595497f7 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -737,6 +738,48 @@ static void handle_get_update(struct peer *peer, const u8 *msg) daemon_conn_send(peer->remote, take(msg)); } +static void handle_local_add_channel(struct peer *peer, u8 *msg) +{ + struct routing_state *rstate = peer->daemon->rstate; + struct short_channel_id scid; + struct sha256_double chain_hash; + struct pubkey remote_node_id; + u16 flags, cltv_expiry_delta, direction; + u32 fee_base_msat, fee_proportional_millionths; + u64 htlc_minimum_msat; + struct node_connection *c; + + if (!fromwire_gossip_local_add_channel( + msg, NULL, &scid, &chain_hash, &remote_node_id, &flags, + &cltv_expiry_delta, &htlc_minimum_msat, &fee_base_msat, + &fee_proportional_millionths)) { + status_trace("Unable to parse local_add_channel message: %s", tal_hex(msg, msg)); + return; + } + + if (!structeq(&chain_hash, &rstate->chain_hash)) { + status_trace("Received channel_announcement for unknown chain %s", + type_to_string(msg, struct sha256_double,&chain_hash)); + return; + } + + if (get_connection_by_scid(rstate, &scid, 0) || get_connection_by_scid(rstate, &scid, 0)) { + status_trace("Attempted to local_add_channel a know channel"); + return; + } + + direction = get_channel_direction(&rstate->local_id, &remote_node_id); + c = half_add_connection(rstate, &rstate->local_id, &remote_node_id, &scid, direction); + + c->active = true; + c->last_timestamp = 0; + c->delay = cltv_expiry_delta; + c->htlc_minimum_msat = htlc_minimum_msat; + c->base_fee = fee_base_msat; + c->proportional_fee = fee_proportional_millionths; + status_trace("Added and updated local channel %s/%d", type_to_string(msg, struct short_channel_id, &scid), direction); +} + /** * owner_msg_in - Called by the `peer->owner_conn` upon receiving a * message @@ -753,7 +796,15 @@ static struct io_plan *owner_msg_in(struct io_conn *conn, handle_gossip_msg(peer->daemon, dc->msg_in); } else if (type == WIRE_GOSSIP_GET_UPDATE) { handle_get_update(peer, dc->msg_in); + } else if (type == WIRE_GOSSIP_LOCAL_ADD_CHANNEL) { + handle_local_add_channel(peer, dc->msg_in); + } else { + status_failed( + STATUS_FAIL_INTERNAL_ERROR, + "Gossip received unknown message of type %s from owner", + gossip_wire_type_name(type)); } + return daemon_conn_read_next(conn, dc); } @@ -1539,6 +1590,7 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master case WIRE_GOSSIP_GETPEERS_REQUEST: return get_peers(conn, daemon, master->msg_in); + /* We send these, we don't receive them */ case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY: case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL: case WIRE_GOSSIP_GETNODES_REPLY: @@ -1552,7 +1604,8 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master case WIRE_GOSSIP_GET_UPDATE: case WIRE_GOSSIP_GET_UPDATE_REPLY: case WIRE_GOSSIP_SEND_GOSSIP: - break; + case WIRE_GOSSIP_LOCAL_ADD_CHANNEL: + break; } /* Master shouldn't give bad requests. */ diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index e5149503bcef..9b4272130016 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -144,3 +144,16 @@ gossip_send_gossip,3016 gossip_send_gossip,,gossip_index,u64 gossip_send_gossip,,len,u16 gossip_send_gossip,,gossip,len*u8 + +# Both sides have seen the funding tx being locked, but we have not +# yet reached the announcement depth. So we add the channel locally so +# we can use it already. +gossip_local_add_channel,3017 +gossip_local_add_channel,,short_channel_id,struct short_channel_id +gossip_local_add_channel,,chain_hash,struct sha256_double +gossip_local_add_channel,,remote_node_id,struct pubkey +gossip_local_add_channel,,flags,u16 +gossip_local_add_channel,,cltv_expiry_delta,u16 +gossip_local_add_channel,,htlc_minimum_msat,u64 +gossip_local_add_channel,,fee_base_msat,u32 +gossip_local_add_channel,,fee_proportional_millionths,u32 \ No newline at end of file diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 9b4eeee03da5..792d4a47c323 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -83,6 +83,10 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY: case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL: break; + /* These are inter-daemon messages, not received by us */ + case WIRE_GOSSIP_LOCAL_ADD_CHANNEL: + break; + case WIRE_GOSSIP_PEER_CONNECTED: if (tal_count(fds) != 2) return 2; diff --git a/tests/test_lightningd.py b/tests/test_lightningd.py index 6a76e1740ae9..69601165ef4e 100644 --- a/tests/test_lightningd.py +++ b/tests/test_lightningd.py @@ -1266,13 +1266,18 @@ def test_permfail_htlc_out(self): l2.daemon.wait_for_log('onchaind complete, forgetting peer') def test_gossip_jsonrpc(self): - l1,l2 = self.connect() - - self.fund_channel(l1,l2,10**5) + l1, l2 = self.line_graph(n=2) # Shouldn't send announce signatures until 6 deep. assert not l1.daemon.is_in_log('peer_out WIRE_ANNOUNCEMENT_SIGNATURES') + # Channels should be activated locally + wait_for(lambda: [c['active'] for c in l1.rpc.getchannels()['channels']] == [True]) + + # Make sure we can route through the channel, will raise on failure + l1.rpc.getroute(l2.info['id'], 100, 1) + + # Now proceed to funding-depth and do a full gossip round l1.bitcoin.generate_block(5) # Could happen in either order. l1.daemon.wait_for_logs(['peer_out WIRE_ANNOUNCEMENT_SIGNATURES',