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>
This commit is contained in:
Christian Decker 2018-03-22 15:11:24 +01:00 committed by Rusty Russell
parent a571bf9d3a
commit 96ad0e7044
2 changed files with 131 additions and 45 deletions

View file

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

View file

@ -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 */