Browse Source

channel: Create gossip announcement upon channel establishment

ppa-0.6.1
Christian Decker 8 years ago
committed by Rusty Russell
parent
commit
8d5591f110
  1. 112
      lightningd/channel/channel.c
  2. 1
      lightningd/channel/channel_wire.csv
  3. 8
      lightningd/peer_control.c

112
lightningd/channel/channel.c

@ -6,6 +6,8 @@
#include <ccan/fdpass/fdpass.h>
#include <ccan/io/io.h>
#include <ccan/structeq/structeq.h>
#include <ccan/take/take.h>
#include <ccan/time/time.h>
#include <errno.h>
#include <inttypes.h>
#include <lightningd/channel.h>
@ -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));
}
if (type == WIRE_CHANNEL_ANNOUNCEMENT || type == WIRE_CHANNEL_UPDATE ||
type == WIRE_NODE_ANNOUNCEMENT) {
}
} 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]);
/* 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));

1
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
Can't render this file because it has a wrong number of fields in line 2.

8
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;
}

Loading…
Cancel
Save