2021-02-01 03:58:50 +01:00
|
|
|
#include "config.h"
|
2020-05-16 03:29:05 +02:00
|
|
|
#include <assert.h>
|
2024-01-31 04:16:18 +01:00
|
|
|
#include <bitcoin/signature.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
|
|
|
#include <ccan/array_size/array_size.h>
|
|
|
|
#include <ccan/mem/mem.h>
|
|
|
|
#include <ccan/str/hex/hex.h>
|
|
|
|
#include <common/node_id.h>
|
2024-03-20 01:47:55 +01:00
|
|
|
#include <common/utils.h>
|
2020-05-16 03:29:05 +02:00
|
|
|
#include <wire/wire.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
|
|
|
|
|
|
|
/* Convert from pubkey to compressed pubkey. */
|
|
|
|
void node_id_from_pubkey(struct node_id *id, const struct pubkey *key)
|
|
|
|
{
|
|
|
|
size_t outlen = ARRAY_SIZE(id->k);
|
|
|
|
if (!secp256k1_ec_pubkey_serialize(secp256k1_ctx, id->k, &outlen,
|
|
|
|
&key->pubkey,
|
|
|
|
SECP256K1_EC_COMPRESSED))
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
WARN_UNUSED_RESULT
|
|
|
|
bool pubkey_from_node_id(struct pubkey *key, const struct node_id *id)
|
|
|
|
{
|
|
|
|
return secp256k1_ec_pubkey_parse(secp256k1_ctx, &key->pubkey,
|
|
|
|
memcheck(id->k, sizeof(id->k)),
|
|
|
|
sizeof(id->k));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* It's valid if we can convert to a real pubkey. */
|
|
|
|
bool node_id_valid(const struct node_id *id)
|
|
|
|
{
|
|
|
|
struct pubkey key;
|
|
|
|
return pubkey_from_node_id(&key, id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert to hex string of SEC1 encoding */
|
2024-03-20 01:40:16 +01:00
|
|
|
char *fmt_node_id(const tal_t *ctx, const struct node_id *id)
|
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
|
|
|
{
|
|
|
|
return tal_hexstr(ctx, id->k, sizeof(id->k));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert from hex string of SEC1 encoding */
|
|
|
|
bool node_id_from_hexstr(const char *str, size_t slen, struct node_id *id)
|
|
|
|
{
|
|
|
|
return hex_decode(str, slen, id->k, sizeof(id->k))
|
|
|
|
&& node_id_valid(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
int node_id_cmp(const struct node_id *a, const struct node_id *b)
|
|
|
|
{
|
|
|
|
return memcmp(a->k, b->k, sizeof(a->k));
|
|
|
|
}
|
2020-05-16 03:29:05 +02:00
|
|
|
|
|
|
|
void fromwire_node_id(const u8 **cursor, size_t *max, struct node_id *id)
|
|
|
|
{
|
|
|
|
fromwire(cursor, max, &id->k, sizeof(id->k));
|
|
|
|
}
|
|
|
|
|
|
|
|
void towire_node_id(u8 **pptr, const struct node_id *id)
|
|
|
|
{
|
2023-08-21 22:28:16 +02:00
|
|
|
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
|
|
|
/* Cheap sanity check. For wire fuzzing, we only care about correct
|
|
|
|
* encoding of node IDs and not whether the IDs are valid, so we disable
|
|
|
|
* this check while fuzzing. */
|
2020-05-16 03:29:05 +02:00
|
|
|
assert(id->k[0] == 0x2 || id->k[0] == 0x3);
|
2023-08-21 22:28:16 +02:00
|
|
|
#endif
|
2020-05-16 03:29:05 +02:00
|
|
|
towire(pptr, id->k, sizeof(id->k));
|
|
|
|
}
|
2024-01-31 04:16:18 +01:00
|
|
|
|
|
|
|
bool check_signed_hash_nodeid(const struct sha256_double *hash,
|
|
|
|
const secp256k1_ecdsa_signature *signature,
|
|
|
|
const struct node_id *id)
|
|
|
|
{
|
|
|
|
struct pubkey key;
|
|
|
|
|
|
|
|
return pubkey_from_node_id(&key, id)
|
|
|
|
&& check_signed_hash(hash, signature, &key);
|
|
|
|
}
|