routing: Return boolean from handle_channel_announcement
This will later be used to determine whether or not we should announce ourselves as a node. Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
b5f737e563
commit
ba45ccffd8
|
@ -31,6 +31,7 @@
|
|||
#include <gossipd/handshake.h>
|
||||
#include <gossipd/routing.h>
|
||||
#include <hsmd/client.h>
|
||||
#include <hsmd/gen_hsm_client_wire.h>
|
||||
#include <inttypes.h>
|
||||
#include <lightningd/gossip_msg.h>
|
||||
#include <netdb.h>
|
||||
|
@ -43,6 +44,7 @@
|
|||
#include <unistd.h>
|
||||
#include <wire/gen_peer_wire.h>
|
||||
#include <wire/wire_io.h>
|
||||
#include <wire/wire_sync.h>
|
||||
|
||||
#define HSM_FD 3
|
||||
|
||||
|
@ -371,12 +373,69 @@ static struct io_plan *owner_msg_in(struct io_conn *conn,
|
|||
static struct io_plan *nonlocal_dump_gossip(struct io_conn *conn,
|
||||
struct daemon_conn *dc);
|
||||
|
||||
static void handle_gossip_msg(struct routing_state *rstate, u8 *msg)
|
||||
/* Create a node_announcement with the given signature. It may be NULL
|
||||
* in the case we need to create a provisional announcement for the
|
||||
* HSM to sign. This is typically called twice: once with the dummy
|
||||
* signature to get it signed and a second time to build the full
|
||||
* packet with the signature. The timestamp is handed in since that is
|
||||
* the only thing that may change between the dummy creation and the
|
||||
* call with a signature.*/
|
||||
static u8 *create_node_announcement(const tal_t *ctx, struct daemon *daemon,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
u32 timestamp)
|
||||
{
|
||||
u8 *features = NULL;
|
||||
u8 *addresses = tal_arr(ctx, u8, 0);
|
||||
u8 *announcement;
|
||||
size_t i;
|
||||
if (!sig) {
|
||||
sig = tal(ctx, secp256k1_ecdsa_signature);
|
||||
memset(sig, 0, sizeof(*sig));
|
||||
}
|
||||
for (i = 0; i < tal_count(daemon->wireaddrs); i++)
|
||||
towire_wireaddr(&addresses, daemon->wireaddrs+i);
|
||||
|
||||
announcement =
|
||||
towire_node_announcement(ctx, sig, features, timestamp,
|
||||
&daemon->id, daemon->rgb, daemon->alias,
|
||||
addresses);
|
||||
return announcement;
|
||||
}
|
||||
|
||||
static void send_node_announcement(struct daemon *daemon)
|
||||
{
|
||||
tal_t *tmpctx = tal_tmpctx(daemon);
|
||||
u32 timestamp = time_now().ts.tv_sec;
|
||||
secp256k1_ecdsa_signature sig;
|
||||
u8 *msg, *nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp);
|
||||
|
||||
if (!wire_sync_write(HSM_FD, take(towire_hsm_node_announcement_sig_req(tmpctx, nannounce))))
|
||||
status_failed(STATUS_FAIL_MASTER_IO, "Could not write to HSM: %s", strerror(errno));
|
||||
|
||||
msg = wire_sync_read(tmpctx, HSM_FD);
|
||||
if (!fromwire_hsm_node_announcement_sig_reply(msg, NULL, &sig))
|
||||
status_failed(STATUS_FAIL_MASTER_IO, "HSM returned an invalid node_announcement sig");
|
||||
|
||||
/* We got the signature for out provisional node_announcement back
|
||||
* from the HSM, create the real announcement and forward it to
|
||||
* gossipd so it can take care of forwarding it. */
|
||||
nannounce = create_node_announcement(tmpctx, daemon, &sig, timestamp);
|
||||
handle_node_announcement(daemon->rstate, take(nannounce), tal_len(nannounce));
|
||||
tal_free(tmpctx);
|
||||
}
|
||||
|
||||
static void handle_gossip_msg(struct daemon *daemon, u8 *msg)
|
||||
{
|
||||
struct routing_state *rstate = daemon->rstate;
|
||||
int t = fromwire_peektype(msg);
|
||||
switch(t) {
|
||||
case WIRE_CHANNEL_ANNOUNCEMENT:
|
||||
handle_channel_announcement(rstate, msg, tal_count(msg));
|
||||
/* Add the channel_announcement to the routing state,
|
||||
* it'll tell us whether this is local and signed, so
|
||||
* we can hand in a node_announcement as well. */
|
||||
if(handle_channel_announcement(rstate, msg, tal_count(msg))) {
|
||||
send_node_announcement(daemon);
|
||||
}
|
||||
break;
|
||||
|
||||
case WIRE_NODE_ANNOUNCEMENT:
|
||||
|
@ -489,7 +548,7 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
|
|||
case WIRE_CHANNEL_ANNOUNCEMENT:
|
||||
case WIRE_NODE_ANNOUNCEMENT:
|
||||
case WIRE_CHANNEL_UPDATE:
|
||||
handle_gossip_msg(peer->daemon->rstate, msg);
|
||||
handle_gossip_msg(peer->daemon, msg);
|
||||
return peer_next_in(conn, peer);
|
||||
|
||||
case WIRE_PING:
|
||||
|
@ -661,7 +720,7 @@ static struct io_plan *owner_msg_in(struct io_conn *conn,
|
|||
int type = fromwire_peektype(msg);
|
||||
if (type == WIRE_CHANNEL_ANNOUNCEMENT || type == WIRE_CHANNEL_UPDATE ||
|
||||
type == WIRE_NODE_ANNOUNCEMENT) {
|
||||
handle_gossip_msg(peer->daemon->rstate, dc->msg_in);
|
||||
handle_gossip_msg(peer->daemon, dc->msg_in);
|
||||
} else if (type == WIRE_GOSSIP_GET_UPDATE) {
|
||||
handle_get_update(peer, dc->msg_in);
|
||||
}
|
||||
|
@ -1161,7 +1220,7 @@ static void handle_forwarded_msg(struct io_conn *conn, struct daemon *daemon, co
|
|||
if (!fromwire_gossip_forwarded_msg(msg, msg, NULL, &payload))
|
||||
master_badmsg(WIRE_GOSSIP_FORWARDED_MSG, msg);
|
||||
|
||||
handle_gossip_msg(daemon->rstate, payload);
|
||||
handle_gossip_msg(daemon, payload);
|
||||
}
|
||||
|
||||
static struct io_plan *handshake_out_success(struct io_conn *conn,
|
||||
|
|
|
@ -463,12 +463,12 @@ static bool check_channel_announcement(
|
|||
check_signed_hash(&hash, bitcoin2_sig, bitcoin2_key);
|
||||
}
|
||||
|
||||
void handle_channel_announcement(
|
||||
bool handle_channel_announcement(
|
||||
struct routing_state *rstate,
|
||||
const u8 *announce, size_t len)
|
||||
{
|
||||
u8 *serialized;
|
||||
bool forward = false;
|
||||
bool forward = false, local, sigfail;
|
||||
secp256k1_ecdsa_signature node_signature_1;
|
||||
secp256k1_ecdsa_signature node_signature_2;
|
||||
struct short_channel_id short_channel_id;
|
||||
|
@ -493,7 +493,7 @@ void handle_channel_announcement(
|
|||
&node_id_1, &node_id_2,
|
||||
&bitcoin_key_1, &bitcoin_key_2)) {
|
||||
tal_free(tmpctx);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* BOLT #7:
|
||||
|
@ -507,7 +507,7 @@ void handle_channel_announcement(
|
|||
type_to_string(tmpctx, struct sha256_double,
|
||||
&chain_hash));
|
||||
tal_free(tmpctx);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Check features!
|
||||
|
@ -517,24 +517,31 @@ void handle_channel_announcement(
|
|||
type_to_string(trc, struct short_channel_id,
|
||||
&short_channel_id));
|
||||
|
||||
if (!check_channel_announcement(&node_id_1, &node_id_2, &bitcoin_key_1,
|
||||
&bitcoin_key_2, &node_signature_1,
|
||||
&node_signature_2, &bitcoin_signature_1,
|
||||
&bitcoin_signature_2, serialized)) {
|
||||
local = pubkey_eq(&node_id_1, &rstate->local_id) ||
|
||||
pubkey_eq(&node_id_2, &rstate->local_id);
|
||||
sigfail = !check_channel_announcement(
|
||||
&node_id_1, &node_id_2, &bitcoin_key_1, &bitcoin_key_2,
|
||||
&node_signature_1, &node_signature_2, &bitcoin_signature_1,
|
||||
&bitcoin_signature_2, serialized);
|
||||
|
||||
if (sigfail && !local) {
|
||||
status_trace(
|
||||
"Signature verification of channel announcement failed");
|
||||
tal_free(tmpctx);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
forward |= add_channel_direction(rstate, &node_id_1, &node_id_2,
|
||||
&short_channel_id, serialized);
|
||||
forward |= add_channel_direction(rstate, &node_id_2, &node_id_1,
|
||||
&short_channel_id, serialized);
|
||||
|
||||
if (!forward) {
|
||||
status_trace("Not forwarding channel_announcement");
|
||||
tal_free(tmpctx);
|
||||
return;
|
||||
/* This will not be forwarded so we do not want to
|
||||
* announce the node either, others might drop it. */
|
||||
return false;
|
||||
}
|
||||
|
||||
u8 *tag = tal_arr(tmpctx, u8, 0);
|
||||
|
@ -543,6 +550,7 @@ void handle_channel_announcement(
|
|||
tag, serialized);
|
||||
|
||||
tal_free(tmpctx);
|
||||
return local;
|
||||
}
|
||||
|
||||
void handle_channel_update(struct routing_state *rstate, const u8 *update, size_t len)
|
||||
|
|
|
@ -83,6 +83,9 @@ struct routing_state {
|
|||
struct broadcast_state *broadcasts;
|
||||
|
||||
struct sha256_double chain_hash;
|
||||
|
||||
/* Our own ID so we can identify local channels */
|
||||
struct pubkey local_id;
|
||||
};
|
||||
|
||||
struct route_hop {
|
||||
|
@ -117,7 +120,15 @@ struct node_connection *get_connection_by_scid(const struct routing_state *rstat
|
|||
const u8 direction);
|
||||
|
||||
/* Handlers for incoming messages */
|
||||
void handle_channel_announcement(struct routing_state *rstate, const u8 *announce, size_t len);
|
||||
|
||||
/**
|
||||
* handle_channel_announcement -- Add channel announcement to state
|
||||
*
|
||||
* Returns true if the channel was fully signed and is local. This
|
||||
* means that if we haven't sent a node_announcement just yet, now
|
||||
* would be a good time.
|
||||
*/
|
||||
bool handle_channel_announcement(struct routing_state *rstate, const u8 *announce, size_t len);
|
||||
void handle_channel_update(struct routing_state *rstate, const u8 *update, size_t len);
|
||||
void handle_node_announcement(struct routing_state *rstate, const u8 *node, size_t len);
|
||||
|
||||
|
|
Loading…
Reference in New Issue