common/node_id: new type.
Node ids are pubkeys, but we only use them as pubkeys for routing and checking
gossip messages. So we're packing and unpacking them constantly, and wasting
some space and time.
This introduces a new type, explicitly the SEC1 compressed encoding
(33 bytes). We ensure its validity when we load from the db, or get it
from JSON. We still use 'struct pubkey' for peer messages, which checks
validity.
Results from 5 runs, min-max(mean +/- stddev):
store_load_msec,vsz_kb,store_rewrite_sec,listnodes_sec,listchannels_sec,routing_sec,peer_write_all_sec
39475-39572(39518+/-36),2880732,41.150000-41.390000(41.298+/-0.085),2.260000-2.550000(2.336+/-0.11),44.390000-65.150000(58.648+/-7.5),32.740000-33.020000(32.89+/-0.093),44.130000-45.090000(44.566+/-0.32)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-04-08 08:34:06 +02:00
|
|
|
/* Encapsulation for pubkeys used as node ids: more compact, more dangerous. */
|
|
|
|
#ifndef LIGHTNING_COMMON_NODE_ID_H
|
|
|
|
#define LIGHTNING_COMMON_NODE_ID_H
|
|
|
|
#include "config.h"
|
|
|
|
#include <bitcoin/pubkey.h>
|
2023-01-16 04:25:48 +01:00
|
|
|
#include <ccan/crypto/siphash24/siphash24.h>
|
|
|
|
#include <ccan/htable/htable_type.h>
|
|
|
|
#include <common/pseudorand.h>
|
common/node_id: new type.
Node ids are pubkeys, but we only use them as pubkeys for routing and checking
gossip messages. So we're packing and unpacking them constantly, and wasting
some space and time.
This introduces a new type, explicitly the SEC1 compressed encoding
(33 bytes). We ensure its validity when we load from the db, or get it
from JSON. We still use 'struct pubkey' for peer messages, which checks
validity.
Results from 5 runs, min-max(mean +/- stddev):
store_load_msec,vsz_kb,store_rewrite_sec,listnodes_sec,listchannels_sec,routing_sec,peer_write_all_sec
39475-39572(39518+/-36),2880732,41.150000-41.390000(41.298+/-0.085),2.260000-2.550000(2.336+/-0.11),44.390000-65.150000(58.648+/-7.5),32.740000-33.020000(32.89+/-0.093),44.130000-45.090000(44.566+/-0.32)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-04-08 08:34:06 +02:00
|
|
|
|
|
|
|
struct node_id {
|
|
|
|
u8 k[PUBKEY_CMPR_LEN];
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline bool node_id_eq(const struct node_id *a,
|
|
|
|
const struct node_id *b)
|
|
|
|
{
|
|
|
|
return memcmp(a->k, b->k, sizeof(a->k)) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Is this actually a valid pubkey? Relatively expensive. */
|
|
|
|
bool node_id_valid(const struct node_id *id);
|
|
|
|
|
|
|
|
/* Convert from pubkey to compressed pubkey. */
|
|
|
|
void node_id_from_pubkey(struct node_id *id, const struct pubkey *key);
|
|
|
|
|
|
|
|
/* Returns false if not a valid pubkey: relatively expensive */
|
|
|
|
WARN_UNUSED_RESULT
|
|
|
|
bool pubkey_from_node_id(struct pubkey *key, const struct node_id *id);
|
|
|
|
|
|
|
|
/* Convert to hex string of SEC1 encoding. */
|
|
|
|
char *node_id_to_hexstr(const tal_t *ctx, const struct node_id *id);
|
|
|
|
|
|
|
|
/* Convert from hex string of SEC1 encoding: checks validity! */
|
|
|
|
bool node_id_from_hexstr(const char *str, size_t slen, struct node_id *id);
|
|
|
|
|
|
|
|
/* Compare the keys `a` and `b`. Return <0 if `a`<`b`, 0 if equal and >0 otherwise */
|
|
|
|
int node_id_cmp(const struct node_id *a, const struct node_id *b);
|
|
|
|
|
|
|
|
/* If the two nodes[] are id1 and id2, which index would id1 be? */
|
|
|
|
static inline int node_id_idx(const struct node_id *id1,
|
|
|
|
const struct node_id *id2)
|
|
|
|
{
|
|
|
|
return node_id_cmp(id1, id2) > 0;
|
|
|
|
}
|
|
|
|
|
2020-05-16 03:29:05 +02:00
|
|
|
/* marshal/unmarshal functions */
|
|
|
|
void towire_node_id(u8 **pptr, const struct node_id *id);
|
|
|
|
void fromwire_node_id(const u8 **cursor, size_t *max, struct node_id *id);
|
2023-01-16 04:25:48 +01:00
|
|
|
|
|
|
|
/* Hash table functions for node ids */
|
|
|
|
static inline const struct node_id *node_id_keyof(const struct node_id *id)
|
|
|
|
{
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We need to define a hashing function. siphash24 is a fast yet
|
|
|
|
* cryptographic hash in ccan/crypto/siphash24; we might be able to get away
|
|
|
|
* with a slightly faster hash with fewer guarantees, but it's good hygiene to
|
|
|
|
* use this unless it's a proven bottleneck. siphash_seed() is a function in
|
|
|
|
* common/pseudorand which sets up a seed for our hashing; it's different
|
|
|
|
* every time the program is run. */
|
|
|
|
static inline size_t node_id_hash(const struct node_id *id)
|
|
|
|
{
|
|
|
|
return siphash24(siphash_seed(), id->k, sizeof(id->k));
|
|
|
|
}
|
common/node_id: new type.
Node ids are pubkeys, but we only use them as pubkeys for routing and checking
gossip messages. So we're packing and unpacking them constantly, and wasting
some space and time.
This introduces a new type, explicitly the SEC1 compressed encoding
(33 bytes). We ensure its validity when we load from the db, or get it
from JSON. We still use 'struct pubkey' for peer messages, which checks
validity.
Results from 5 runs, min-max(mean +/- stddev):
store_load_msec,vsz_kb,store_rewrite_sec,listnodes_sec,listchannels_sec,routing_sec,peer_write_all_sec
39475-39572(39518+/-36),2880732,41.150000-41.390000(41.298+/-0.085),2.260000-2.550000(2.336+/-0.11),44.390000-65.150000(58.648+/-7.5),32.740000-33.020000(32.89+/-0.093),44.130000-45.090000(44.566+/-0.32)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2019-04-08 08:34:06 +02:00
|
|
|
#endif /* LIGHTNING_COMMON_NODE_ID_H */
|