diff --git a/lightningd/channel/channel.c b/lightningd/channel/channel.c index 1fd934292..1025547b4 100644 --- a/lightningd/channel/channel.c +++ b/lightningd/channel/channel.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include #include @@ -59,7 +61,12 @@ struct peer { int gossip_client_fd; struct daemon_conn gossip_client; + + /* Announcement related information */ struct pubkey node_ids[NUM_SIDES]; + struct short_channel_id short_channel_ids[NUM_SIDES]; + secp256k1_ecdsa_signature announcement_node_sigs[NUM_SIDES]; + secp256k1_ecdsa_signature announcement_bitcoin_sigs[NUM_SIDES]; }; static void queue_pkt(struct peer *peer, const u8 *msg) @@ -82,6 +89,69 @@ static struct io_plan *gossip_client_recv(struct io_conn *conn, return daemon_conn_read_next(conn, dc); } +static void send_announcement_signatures(struct peer *peer) +{ + tal_t *tmpctx = tal_tmpctx(peer); + u8 *msg; + // TODO(cdecker) Use the HSM to generate this signature + secp256k1_ecdsa_signature *sig = + talz(tmpctx, secp256k1_ecdsa_signature); + + msg = towire_announcement_signatures(tmpctx, &peer->channel_id, + &peer->short_channel_ids[LOCAL], + sig, sig); + queue_pkt(peer, take(msg)); + tal_free(tmpctx); +} + +static void announce_channel(struct peer *peer) +{ + tal_t *tmpctx = tal_tmpctx(peer); + u8 local_der[33], remote_der[33]; + int first, second; + u32 timestamp = time_now().ts.tv_sec; + u8 *cannounce, *cupdate, *features = tal_arr(peer, u8, 0); + u16 flags; + + /* Find out in which order we have to list the endpoints */ + pubkey_to_der(local_der, &peer->node_ids[LOCAL]); + pubkey_to_der(remote_der, &peer->node_ids[REMOTE]); + if (memcmp(local_der, remote_der, sizeof(local_der)) < 0) { + first = LOCAL; + second = REMOTE; + } else { + first = REMOTE; + second = LOCAL; + } + + /* Now that we have a working channel, tell the world. */ + cannounce = towire_channel_announcement( + tmpctx, &peer->announcement_node_sigs[first], + &peer->announcement_node_sigs[second], + &peer->announcement_bitcoin_sigs[first], + &peer->announcement_bitcoin_sigs[second], + &peer->short_channel_ids[LOCAL], &peer->node_ids[first], + &peer->node_ids[second], &peer->funding_pubkey[first], + &peer->funding_pubkey[second], features); + + // TODO(cdecker) Create a real signature for this update + secp256k1_ecdsa_signature *sig = + talz(tmpctx, secp256k1_ecdsa_signature); + + flags = first == LOCAL; + cupdate = towire_channel_update( + tmpctx, sig, &peer->short_channel_ids[LOCAL], timestamp, flags, 36, + 1, 10, peer->channel->view[LOCAL].feerate_per_kw); + + queue_pkt(peer, cannounce); + queue_pkt(peer, cupdate); + + daemon_conn_send(&peer->gossip_client, take(cannounce)); + daemon_conn_send(&peer->gossip_client, take(cupdate)); + + tal_free(tmpctx); +} + static struct io_plan *peer_out(struct io_conn *conn, struct peer *peer) { const u8 *out = msg_dequeue(&peer->peer_out); @@ -96,9 +166,6 @@ static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg) struct channel_id chanid; int type = fromwire_peektype(msg); - status_trace("Received %s from peer", wire_type_name(type)); - - if (fromwire_funding_locked(msg, NULL, &chanid, &peer->next_per_commit[REMOTE])) { if (!structeq(&chanid, &peer->channel_id)) @@ -111,12 +178,30 @@ static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg) peer->funding_locked[REMOTE] = true; status_send(towire_channel_received_funding_locked(peer)); - if (peer->funding_locked[LOCAL]) + if (peer->funding_locked[LOCAL]) { status_send(towire_channel_normal_operation(peer)); - } + } + } else if (type == WIRE_ANNOUNCEMENT_SIGNATURES) { + fromwire_announcement_signatures( + msg, NULL, &chanid, &peer->short_channel_ids[REMOTE], + &peer->announcement_node_sigs[REMOTE], + &peer->announcement_bitcoin_sigs[REMOTE]); - if (type == WIRE_CHANNEL_ANNOUNCEMENT || type == WIRE_CHANNEL_UPDATE || - type == WIRE_NODE_ANNOUNCEMENT) { + /* Make sure we agree on the channel ids */ + if (!structeq(&chanid, &peer->channel_id)) { + status_failed( + WIRE_CHANNEL_PEER_BAD_MESSAGE, + "Wrong channel_id or short_channel_id in %s or %s", + tal_hexstr(trc, &chanid, sizeof(struct channel_id)), + tal_hexstr(trc, &peer->short_channel_ids[REMOTE], + sizeof(struct short_channel_id))); + } + if (peer->funding_locked[LOCAL]) { + announce_channel(peer); + } + } else if (type == WIRE_CHANNEL_ANNOUNCEMENT || + type == WIRE_CHANNEL_UPDATE || + type == WIRE_NODE_ANNOUNCEMENT) { daemon_conn_send(&peer->gossip_client, msg); } @@ -125,15 +210,18 @@ static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg) static struct io_plan *req_in(struct io_conn *conn, struct peer *peer) { - if (fromwire_channel_funding_locked(peer->req_in, NULL)) { - u8 *msg = towire_funding_locked(peer, - &peer->channel_id, + if (fromwire_channel_funding_locked(peer->req_in, NULL, + &peer->short_channel_ids[LOCAL])) { + u8 *msg = towire_funding_locked(peer, &peer->channel_id, &peer->next_per_commit[LOCAL]); queue_pkt(peer, msg); peer->funding_locked[LOCAL] = true; + send_announcement_signatures(peer); - if (peer->funding_locked[REMOTE]) + if (peer->funding_locked[REMOTE]) { + announce_channel(peer); status_send(towire_channel_normal_operation(peer)); + } } else status_failed(WIRE_CHANNEL_BAD_COMMAND, "%s", strerror(errno)); diff --git a/lightningd/channel/channel_wire.csv b/lightningd/channel/channel_wire.csv index 6a3260b38..bb07a0b2f 100644 --- a/lightningd/channel/channel_wire.csv +++ b/lightningd/channel/channel_wire.csv @@ -40,3 +40,4 @@ channel_init,562,remote_node_id,33,struct pubkey # Tx is deep enough, go! channel_funding_locked,2 +channel_funding_locked,0,short_channel_id,8,struct short_channel_id \ No newline at end of file diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 7e897290e..17843eaf1 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -530,6 +530,12 @@ static enum watch_result funding_depth_cb(struct peer *peer, void *unused) { const char *txidstr = type_to_string(peer, struct sha256_double, txid); + struct txlocator *loc = locate_tx(peer, peer->ld->topology, txid); + struct short_channel_id scid; + scid.blocknum = loc->blkheight; + scid.txnum = loc->index; + scid.outnum = peer->funding_outnum; + loc = tal_free(loc); log_debug(peer->log, "Funding tx %s depth %u of %u", txidstr, depth, peer->our_config.minimum_depth); @@ -546,7 +552,7 @@ static enum watch_result funding_depth_cb(struct peer *peer, } peer_set_condition(peer, "Funding tx reached depth %u", depth); - subd_send_msg(peer->owner, take(towire_channel_funding_locked(peer))); + subd_send_msg(peer->owner, take(towire_channel_funding_locked(peer, &scid))); return DELETE_WATCH; }