mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
channel: Create gossip announcement upon channel establishment
This commit is contained in:
parent
5a1fbb7aaf
commit
8d5591f110
@ -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));
|
||||
}
|
||||
}
|
||||
} 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));
|
||||
|
||||
|
@ -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
|
|
@ -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…
Reference in New Issue
Block a user