Browse Source

gossip: Extract network changes into their own functions

Moves any modifications based on an incoming gossip message into its own
function separate from the message verification. This allows us to skip
verification when reading messages from a trusted source, e.g., the
gossip_store, speeding up the gossip replay.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
ppa-0.6.1
Christian Decker 7 years ago
committed by Rusty Russell
parent
commit
96ad0e7044
  1. 145
      gossipd/routing.c
  2. 31
      gossipd/routing.h

145
gossipd/routing.c

@ -595,6 +595,41 @@ static void destroy_pending_cannouncement(struct pending_cannouncement *pending,
list_del_from(&rstate->pending_cannouncement, &pending->list);
}
void routing_add_channel_announcement(struct routing_state *rstate,
const u8 *msg TAKES, u64 satoshis)
{
struct chan *chan;
secp256k1_ecdsa_signature node_signature_1, node_signature_2;
secp256k1_ecdsa_signature bitcoin_signature_1, bitcoin_signature_2;
u8 *features;
struct bitcoin_blkid chain_hash;
struct short_channel_id scid;
struct pubkey node_id_1;
struct pubkey node_id_2;
struct pubkey bitcoin_key_1;
struct pubkey bitcoin_key_2;
fromwire_channel_announcement(
tmpctx, msg, &node_signature_1, &node_signature_2,
&bitcoin_signature_1, &bitcoin_signature_2, &features, &chain_hash,
&scid, &node_id_1, &node_id_2, &bitcoin_key_1, &bitcoin_key_2);
/* The channel may already exist if it was non-public from
* local_add_channel(); normally we don't accept new
* channel_announcements. See handle_channel_announcement. */
chan = get_channel(rstate, &scid);
if (!chan)
chan = new_chan(rstate, &scid, &node_id_1, &node_id_2);
/* Channel is now public. */
chan->public = true;
chan->satoshis = satoshis;
if (replace_broadcast(chan, rstate->broadcasts,
&chan->channel_announce_msgidx, take(msg)))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Announcement %s was replaced?",
tal_hex(tmpctx, msg));
}
u8 *handle_channel_announcement(struct routing_state *rstate,
const u8 *announce TAKES,
const struct short_channel_id **scid,
@ -758,7 +793,6 @@ bool handle_pending_cannouncement(struct routing_state *rstate,
bool local;
const u8 *s;
struct pending_cannouncement *pending;
struct chan *chan;
pending = find_pending_cannouncement(rstate, scid);
if (!pending)
@ -798,28 +832,9 @@ bool handle_pending_cannouncement(struct routing_state *rstate,
return false;
}
/* The channel may already exist if it was non-public from
* local_add_channel(); normally we don't accept new
* channel_announcements. See handle_channel_announcement. */
chan = get_channel(rstate, scid);
if (!chan)
chan = new_chan(rstate, scid,
&pending->node_id_1,
&pending->node_id_2);
/* Channel is now public. */
chan->public = true;
chan->satoshis = satoshis;
if (replace_broadcast(chan, rstate->broadcasts,
&chan->channel_announce_msgidx,
pending->announce))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Announcement %s was replaced?",
tal_hex(tmpctx, pending->announce));
if (pending->store)
gossip_store_append(rstate->store, pending->announce);
routing_add_channel_announcement(rstate, pending->announce, satoshis);
local = pubkey_eq(&pending->node_id_1, &rstate->local_id) ||
pubkey_eq(&pending->node_id_2, &rstate->local_id);
@ -890,6 +905,37 @@ void set_connection_values(struct chan *chan,
}
}
void routing_add_channel_update(struct routing_state *rstate,
const u8 *update TAKES)
{
secp256k1_ecdsa_signature signature;
struct short_channel_id short_channel_id;
u32 timestamp;
u16 flags;
u16 expiry;
u64 htlc_minimum_msat;
u32 fee_base_msat;
u32 fee_proportional_millionths;
struct bitcoin_blkid chain_hash;
struct chan *chan;
u8 direction;
fromwire_channel_update(update, &signature, &chain_hash,
&short_channel_id, &timestamp, &flags, &expiry,
&htlc_minimum_msat, &fee_base_msat,
&fee_proportional_millionths);
chan = get_channel(rstate, &short_channel_id);
direction = flags & 0x1;
set_connection_values(chan, direction, fee_base_msat,
fee_proportional_millionths, expiry,
(flags & ROUTING_FLAGS_DISABLED) == 0, timestamp,
htlc_minimum_msat);
replace_broadcast(chan, rstate->broadcasts,
&chan->half[direction].channel_update_msgidx,
take(update));
}
u8 *handle_channel_update(struct routing_state *rstate, const u8 *update,
bool store)
{
@ -983,20 +1029,9 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update,
flags & 0x01,
flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE");
set_connection_values(chan, direction,
fee_base_msat,
fee_proportional_millionths,
expiry,
(flags & ROUTING_FLAGS_DISABLED) == 0,
timestamp,
htlc_minimum_msat);
if (store)
gossip_store_append(rstate->store, serialized);
replace_broadcast(chan, rstate->broadcasts,
&chan->half[direction].channel_update_msgidx,
take(serialized));
routing_add_channel_update(rstate, serialized);
return NULL;
}
@ -1034,6 +1069,36 @@ static struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser)
return wireaddrs;
}
void routing_add_node_announcement(struct routing_state *rstate, const u8 *msg TAKES)
{
struct node *node;
secp256k1_ecdsa_signature signature;
u32 timestamp;
struct pubkey node_id;
u8 rgb_color[3];
u8 alias[32];
u8 *features, *addresses;
struct wireaddr *wireaddrs;
fromwire_node_announcement(tmpctx, msg,
&signature, &features, &timestamp,
&node_id, rgb_color, alias,
&addresses);
node = get_node(rstate, &node_id);
wireaddrs = read_addresses(tmpctx, addresses);
tal_free(node->addresses);
node->addresses = tal_steal(node, wireaddrs);
node->last_timestamp = timestamp;
memcpy(node->rgb_color, rgb_color, 3);
tal_free(node->alias);
node->alias = tal_dup_arr(node, u8, alias, 32, 0);
replace_broadcast(node, rstate->broadcasts,
&node->node_announce_msgidx,
take(msg));
}
u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann,
bool store)
{
@ -1159,20 +1224,10 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann,
status_trace("Received node_announcement for node %s",
type_to_string(tmpctx, struct pubkey, &node_id));
tal_free(node->addresses);
node->addresses = tal_steal(node, wireaddrs);
node->last_timestamp = timestamp;
memcpy(node->rgb_color, rgb_color, 3);
tal_free(node->alias);
node->alias = tal_dup_arr(node, u8, alias, 32, 0);
/* FIXME: remove store guard */
if (store)
gossip_store_append(rstate->store, serialized);
replace_broadcast(node, rstate->broadcasts,
&node->node_announce_msgidx,
take(serialized));
routing_add_node_announcement(rstate, serialized);
return NULL;
}

31
gossipd/routing.h

@ -261,4 +261,35 @@ void route_prune(struct routing_state *rstate);
* the direction bit the matching channel should get */
#define get_channel_direction(from, to) (pubkey_cmp(from, to) > 0)
/**
* Add a channel_announcement to the network view without checking it
*
* Directly add the channel to the local network, without checking it first. Use
* this only for messages from trusted sources. Untrusted sources should use the
* @see{handle_channel_announcement} entrypoint to check before adding.
*/
void routing_add_channel_announcement(struct routing_state *rstate,
const u8 *msg TAKES, u64 satoshis);
/**
* Add a channel_update without checking for errors
*
* Used to actually insert the information in the channel update into the local
* network view. Only use this for messages that are known to be good. For
* untrusted source, requiring verification please use
* @see{handle_channel_update}
*/
void routing_add_channel_update(struct routing_state *rstate,
const u8 *update TAKES);
/**
* Add a node_announcement to the network view without checking it
*
* Directly add the node being announced to the network view, without verifying
* it. This must be from a trusted source, e.g., gossip_store. For untrusted
* sources (peers) please use @see{handle_node_announcement}.
*/
void routing_add_node_announcement(struct routing_state *rstate,
const u8 *msg TAKES);
#endif /* LIGHTNING_GOSSIPD_ROUTING_H */

Loading…
Cancel
Save