mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +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/fdpass/fdpass.h>
|
||||||
#include <ccan/io/io.h>
|
#include <ccan/io/io.h>
|
||||||
#include <ccan/structeq/structeq.h>
|
#include <ccan/structeq/structeq.h>
|
||||||
|
#include <ccan/take/take.h>
|
||||||
|
#include <ccan/time/time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <lightningd/channel.h>
|
#include <lightningd/channel.h>
|
||||||
@ -59,7 +61,12 @@ struct peer {
|
|||||||
|
|
||||||
int gossip_client_fd;
|
int gossip_client_fd;
|
||||||
struct daemon_conn gossip_client;
|
struct daemon_conn gossip_client;
|
||||||
|
|
||||||
|
/* Announcement related information */
|
||||||
struct pubkey node_ids[NUM_SIDES];
|
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)
|
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);
|
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)
|
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);
|
||||||
@ -96,9 +166,6 @@ static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg)
|
|||||||
struct channel_id chanid;
|
struct channel_id chanid;
|
||||||
int type = fromwire_peektype(msg);
|
int type = fromwire_peektype(msg);
|
||||||
|
|
||||||
status_trace("Received %s from peer", wire_type_name(type));
|
|
||||||
|
|
||||||
|
|
||||||
if (fromwire_funding_locked(msg, NULL, &chanid,
|
if (fromwire_funding_locked(msg, NULL, &chanid,
|
||||||
&peer->next_per_commit[REMOTE])) {
|
&peer->next_per_commit[REMOTE])) {
|
||||||
if (!structeq(&chanid, &peer->channel_id))
|
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;
|
peer->funding_locked[REMOTE] = true;
|
||||||
status_send(towire_channel_received_funding_locked(peer));
|
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));
|
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 ||
|
/* Make sure we agree on the channel ids */
|
||||||
type == WIRE_NODE_ANNOUNCEMENT) {
|
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);
|
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)
|
static struct io_plan *req_in(struct io_conn *conn, struct peer *peer)
|
||||||
{
|
{
|
||||||
if (fromwire_channel_funding_locked(peer->req_in, NULL)) {
|
if (fromwire_channel_funding_locked(peer->req_in, NULL,
|
||||||
u8 *msg = towire_funding_locked(peer,
|
&peer->short_channel_ids[LOCAL])) {
|
||||||
&peer->channel_id,
|
u8 *msg = towire_funding_locked(peer, &peer->channel_id,
|
||||||
&peer->next_per_commit[LOCAL]);
|
&peer->next_per_commit[LOCAL]);
|
||||||
queue_pkt(peer, msg);
|
queue_pkt(peer, msg);
|
||||||
peer->funding_locked[LOCAL] = true;
|
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));
|
status_send(towire_channel_normal_operation(peer));
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
status_failed(WIRE_CHANNEL_BAD_COMMAND, "%s", strerror(errno));
|
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!
|
# Tx is deep enough, go!
|
||||||
channel_funding_locked,2
|
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)
|
void *unused)
|
||||||
{
|
{
|
||||||
const char *txidstr = type_to_string(peer, struct sha256_double, txid);
|
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",
|
log_debug(peer->log, "Funding tx %s depth %u of %u",
|
||||||
txidstr, depth, peer->our_config.minimum_depth);
|
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);
|
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;
|
return DELETE_WATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user