common: hoist scidd->pubkey conversion function into gossmap.

We will want to use it in the pay plugin too.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-07-17 18:35:11 +09:30
parent 272d313e05
commit b29b96aae8
20 changed files with 102 additions and 42 deletions

View file

@ -9,6 +9,7 @@
#include <common/gossip_store.h>
#include <common/gossmap.h>
#include <common/pseudorand.h>
#include <common/sciddir_or_pubkey.h>
#include <errno.h>
#include <fcntl.h>
#include <gossipd/gossip_store_wiregen.h>
@ -1457,6 +1458,26 @@ u8 *gossmap_node_get_features(const tal_t *ctx,
return ret;
}
bool gossmap_scidd_pubkey(struct gossmap *gossmap,
struct sciddir_or_pubkey *sciddpk)
{
struct gossmap_chan *chan;
struct gossmap_node *node;
struct node_id id;
if (sciddpk->is_pubkey)
return true;
chan = gossmap_find_chan(gossmap, &sciddpk->scidd.scid);
if (!chan)
return false;
node = gossmap_nth_node(gossmap, chan, sciddpk->scidd.dir);
gossmap_node_get_id(gossmap, node, &id);
/* Shouldn't fail! */
return sciddir_or_pubkey_from_node_id(sciddpk, &id);
}
size_t gossmap_lengths(const struct gossmap *map, size_t *total)
{
*total = map->map_size;

View file

@ -8,6 +8,7 @@
#include <common/fp16.h>
struct node_id;
struct sciddir_or_pubkey;
struct gossmap_node {
/* Offset in memory map for node_announce, or 0. */
@ -207,6 +208,10 @@ u8 *gossmap_chan_get_update(const tal_t *ctx,
const struct gossmap_chan *chan,
int dir);
/* Return true if we can map this sciddir_or_pubkey to a pubkey. */
bool gossmap_scidd_pubkey(struct gossmap *gossmap,
struct sciddir_or_pubkey *sciddpk);
/* Returns details from channel_update (must be gossmap_chan_set, and
* does not work for local_updatechan)! */
void gossmap_chan_get_update_details(const struct gossmap *map,

View file

@ -19,6 +19,10 @@ bigsize_t fromwire_bigsize(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
struct channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "fromwire_channel_id called!\n"); abort(); }
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* Generated stub for towire_bigsize */
void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED)
{ fprintf(stderr, "towire_bigsize called!\n"); abort(); }

View file

@ -19,6 +19,10 @@ bigsize_t fromwire_bigsize(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
struct channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "fromwire_channel_id called!\n"); abort(); }
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* Generated stub for towire_bigsize */
void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED)
{ fprintf(stderr, "towire_bigsize called!\n"); abort(); }

View file

@ -8,6 +8,7 @@
#include <common/gossmap.h>
#include <common/gossip_store.h>
#include <common/route.h>
#include <common/sciddir_or_pubkey.h>
#include <common/setup.h>
#include <common/utils.h>
#include <math.h>
@ -30,6 +31,10 @@ bool fromwire_tlv(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
void *record UNNEEDED, struct tlv_field **fields UNNEEDED,
const u64 *extra_types UNNEEDED, size_t *err_off UNNEEDED, u64 *err_type UNNEEDED)
{ fprintf(stderr, "fromwire_tlv called!\n"); abort(); }
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* Generated stub for towire_bigsize */
void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED)
{ fprintf(stderr, "towire_bigsize called!\n"); abort(); }

View file

@ -12,6 +12,7 @@
#include <common/gossmap.h>
#include <common/gossip_store.h>
#include <common/route.h>
#include <common/sciddir_or_pubkey.h>
#include <common/setup.h>
#include <common/utils.h>
#include <bitcoin/chainparams.h>
@ -33,6 +34,10 @@ bool fromwire_tlv(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
void *record UNNEEDED, struct tlv_field **fields UNNEEDED,
const u64 *extra_types UNNEEDED, size_t *err_off UNNEEDED, u64 *err_type UNNEEDED)
{ fprintf(stderr, "fromwire_tlv called!\n"); abort(); }
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* Generated stub for towire_bigsize */
void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED)
{ fprintf(stderr, "towire_bigsize called!\n"); abort(); }

View file

@ -5,6 +5,7 @@
#include <common/gossmap.h>
#include <common/gossip_store.h>
#include <common/route.h>
#include <common/sciddir_or_pubkey.h>
#include <common/setup.h>
#include <common/utils.h>
#include <bitcoin/chainparams.h>
@ -26,6 +27,10 @@ bool fromwire_tlv(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
void *record UNNEEDED, struct tlv_field **fields UNNEEDED,
const u64 *extra_types UNNEEDED, size_t *err_off UNNEEDED, u64 *err_type UNNEEDED)
{ fprintf(stderr, "fromwire_tlv called!\n"); abort(); }
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* Generated stub for towire_bigsize */
void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED)
{ fprintf(stderr, "towire_bigsize called!\n"); abort(); }

View file

@ -197,7 +197,7 @@ plugins/commando: $(PLUGIN_COMMANDO_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJ
# Topology wants to decode node_announcement, and peer_wiregen which
# pulls in some of bitcoin/.
plugins/topology: common/route.o common/dijkstra.o common/gossmap.o common/fp16.o wire/peer_wiregen.o wire/channel_type_wiregen.o bitcoin/block.o bitcoin/preimage.o common/gossmods_listpeerchannels.o $(PLUGIN_TOPOLOGY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
plugins/topology: common/route.o common/dijkstra.o common/gossmap.o common/sciddir_or_pubkey.o common/fp16.o wire/peer_wiregen.o wire/channel_type_wiregen.o bitcoin/block.o bitcoin/preimage.o common/gossmods_listpeerchannels.o $(PLUGIN_TOPOLOGY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
plugins/txprepare: $(PLUGIN_TXPREPARE_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
@ -212,7 +212,7 @@ plugins/offers: $(PLUGIN_OFFERS_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) c
plugins/funder: bitcoin/psbt.o common/psbt_open.o $(PLUGIN_FUNDER_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
plugins/recover: common/gossmap.o common/fp16.o $(PLUGIN_RECOVER_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
plugins/recover: common/gossmap.o common/sciddir_or_pubkey.o common/fp16.o $(PLUGIN_RECOVER_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS)
# This covers all the low-level list RPCs which return simple arrays
SQL_LISTRPCS := listchannels listforwards listhtlcs listinvoices listnodes listoffers listpeers listpeerchannels listclosedchannels listtransactions listsendpays bkpr-listaccountevents bkpr-listincome

View file

@ -545,7 +545,7 @@ static struct command_result *try_establish(struct command *cmd,
target = *epaths->sent->direct_dest;
} else {
struct sciddir_or_pubkey first = bpath->first_node_id;
if (!first.is_pubkey && !convert_to_scidd(cmd, &first))
if (!gossmap_scidd_pubkey(get_gossmap(cmd->plugin), &first))
return establish_path_fail(cmd, "Cannot resolve scidd", epaths);
target = first.pubkey;
}

View file

@ -86,32 +86,6 @@ static struct command_result *injectonionmessage_error(struct command *cmd,
return command_hook_success(cmd);
}
/* So, you gave us a reply scid? Let's do the lookup then! And no,
* we won't accept private channels, just public ones.
*/
bool convert_to_scidd(struct command *cmd,
struct sciddir_or_pubkey *sciddpk)
{
struct gossmap *gossmap = get_gossmap(cmd->plugin);
struct gossmap_chan *chan;
struct gossmap_node *node;
struct node_id id;
chan = gossmap_find_chan(gossmap, &sciddpk->scidd.scid);
if (!chan)
return false;
node = gossmap_nth_node(gossmap, chan, sciddpk->scidd.dir);
gossmap_node_get_id(gossmap, node, &id);
if (!sciddir_or_pubkey_from_node_id(sciddpk, &id)) {
plugin_log(cmd->plugin, LOG_BROKEN,
"Could not convert node %s to pubkey?",
fmt_node_id(tmpctx, &id));
return false;
}
return true;
}
struct command_result *
inject_onionmessage_(struct command *cmd,
const struct onion_message *omsg,
@ -194,14 +168,13 @@ send_onion_reply(struct command *cmd,
onion_reply->reply_path = blinded_path_dup(onion_reply, reply_path);
onion_reply->payload = tal_steal(onion_reply, payload);
if (!onion_reply->reply_path->first_node_id.is_pubkey) {
if (!convert_to_scidd(cmd, &onion_reply->reply_path->first_node_id)) {
plugin_log(cmd->plugin, LOG_DBG,
"Cannot resolve initial reply scidd %s",
fmt_short_channel_id_dir(tmpctx,
&onion_reply->reply_path->first_node_id.scidd));
return command_hook_success(cmd);
}
if (!gossmap_scidd_pubkey(get_gossmap(cmd->plugin),
&onion_reply->reply_path->first_node_id)) {
plugin_log(cmd->plugin, LOG_DBG,
"Cannot resolve initial reply scidd %s",
fmt_short_channel_id_dir(tmpctx,
&onion_reply->reply_path->first_node_id.scidd));
return command_hook_success(cmd);
}
return establish_onion_path(cmd, get_gossmap(cmd->plugin),

View file

@ -25,10 +25,6 @@ extern struct secret offerblinding_base;
/* This is me. */
extern struct pubkey id;
/* If they give us an scid, do a lookup */
bool convert_to_scidd(struct command *cmd,
struct sciddir_or_pubkey *sciddpk);
/* Helper to send a reply (connecting if required), and discard result */
struct command_result *WARN_UNUSED_RESULT
send_onion_reply(struct command *cmd,

View file

@ -429,9 +429,10 @@ static struct command_result *param_paths(struct command *cmd, const char *name,
(*paths)[i]->first_scidd = tal_dup((*paths)[i],
struct short_channel_id_dir,
&init.scidd);
if (!convert_to_scidd(cmd, &init))
if (!gossmap_scidd_pubkey(get_gossmap(cmd->plugin), &init)) {
return command_fail_badparam(cmd, name, buffer, p,
"unknown sciddir");
}
} else {
(*paths)[i]->first_scidd = NULL;
}

View file

@ -14,6 +14,10 @@
#include "../mcf.c"
/* AUTOGENERATED MOCKS START */
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
int main(int argc, char *argv[])

View file

@ -18,6 +18,13 @@
#include <common/utils.h>
#include <sodium/randombytes.h>
/* AUTOGENERATED MOCKS START */
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
static u8 empty_map[] = {10};
static const char *print_flows(const tal_t *ctx, const char *desc,

View file

@ -11,6 +11,10 @@
#include <plugins/renepay/dijkstra.h>
/* AUTOGENERATED MOCKS START */
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
static void insertion_in_increasing_distance(const tal_t *ctx)

View file

@ -50,6 +50,10 @@ struct pay_plugin *pay_plugin;
/* Generated stub for routetracker_cleanup */
void routetracker_cleanup(struct routetracker *routetracker UNNEEDED)
{ fprintf(stderr, "routetracker_cleanup called!\n"); abort(); }
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
static u8 empty_map[] = {

View file

@ -52,6 +52,10 @@ struct pay_plugin *pay_plugin;
/* Generated stub for routetracker_cleanup */
void routetracker_cleanup(struct routetracker *routetracker UNNEEDED)
{ fprintf(stderr, "routetracker_cleanup called!\n"); abort(); }
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
static void swap(int *a, int *b)

View file

@ -20,6 +20,13 @@
#include <common/utils.h>
#include <sodium/randombytes.h>
/* AUTOGENERATED MOCKS START */
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
static u8 empty_map[] = {10};
#define NUM_NODES 4

View file

@ -20,6 +20,13 @@
#include "../flow.c"
#include "../route.c"
/* AUTOGENERATED MOCKS START */
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
static void destroy_route(
struct route *route,
struct route_map * map)

View file

@ -52,6 +52,10 @@ struct pay_plugin *pay_plugin;
/* Generated stub for routetracker_cleanup */
void routetracker_cleanup(struct routetracker *routetracker UNNEEDED)
{ fprintf(stderr, "routetracker_cleanup called!\n"); abort(); }
/* Generated stub for sciddir_or_pubkey_from_node_id */
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "sciddir_or_pubkey_from_node_id called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
static const u8 canned_map[] = {