gossipd: hand all candidates up to lightningd to select routeboost.

This lets us do more flexible filtering in the next patch.  But it also
keeps some weird logic out of gossipd.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2019-12-17 16:41:08 +10:30
committed by ZmnSCPxj, ZmnSCPxj jxPCSmnZ
parent 3f3a48dae9
commit 11dc1b341c
5 changed files with 135 additions and 57 deletions

View File

@@ -379,6 +379,7 @@ static struct route_info **select_inchan(const tal_t *ctx,
struct lightningd *ld,
struct amount_msat amount_needed,
const struct route_info *inchans,
const bool *deadends,
bool *any_offline)
{
/* BOLT11 struct wants an array of arrays (can provide multiple routes) */
@@ -413,6 +414,10 @@ static struct route_info **select_inchan(const tal_t *ctx,
if (!c)
continue;
/* Is it a dead-end? */
if (deadends[i])
continue;
/* Channel balance as seen by our node:
|<----------------- capacity ----------------->|
@@ -494,30 +499,88 @@ static struct route_info **select_inchan(const tal_t *ctx,
}
/* Encapsulating struct while we wait for gossipd to give us incoming channels */
struct chanhints {
bool expose_all_private;
struct short_channel_id *hints;
};
struct invoice_info {
struct command *cmd;
struct preimage payment_preimage;
struct bolt11 *b11;
struct json_escape *label;
struct chanhints *chanhints;
};
static void append_routes(struct route_info **dst, const struct route_info *src)
{
size_t n = tal_count(*dst);
tal_resize(dst, n + tal_count(src));
memcpy(*dst + n, src, tal_count(src) * sizeof(*src));
}
static void append_bools(bool **dst, const bool *src)
{
size_t n = tal_count(*dst);
tal_resize(dst, n + tal_count(src));
memcpy(*dst + n, src, tal_count(src) * sizeof(*src));
}
static bool all_true(const bool *barr, size_t n)
{
for (size_t i = 0; i < n; i++) {
if (!barr[i])
return false;
}
return true;
}
static void gossipd_incoming_channels_reply(struct subd *gossipd,
const u8 *msg,
const int *fs,
struct invoice_info *info)
{
struct json_stream *response;
struct route_info *inchans;
struct route_info *inchans, *private;
bool *inchan_deadends, *private_deadends;
bool any_offline;
struct invoice invoice;
char *b11enc;
const struct invoice_details *details;
struct wallet *wallet = info->cmd->ld->wallet;
const struct chanhints *chanhints = info->chanhints;
if (!fromwire_gossip_get_incoming_channels_reply(tmpctx, msg, &inchans))
if (!fromwire_gossip_get_incoming_channels_reply(tmpctx, msg,
&inchans,
&inchan_deadends,
&private,
&private_deadends))
fatal("Gossip gave bad GOSSIP_GET_INCOMING_CHANNELS_REPLY %s",
tal_hex(msg, msg));
/* fromwire explicitly makes empty arrays into NULL */
if (!inchans) {
inchans = tal_arr(tmpctx, struct route_info, 0);
inchan_deadends = tal_arr(tmpctx, bool, 0);
}
if (chanhints->expose_all_private) {
append_routes(&inchans, private);
append_bools(&inchan_deadends, private_deadends);
} else if (chanhints->hints) {
/* FIXME: Implement hint support! */
assert(!tal_count(chanhints->hints));
} else {
/* By default, only consider private channels if there are
* no public channels *at all* */
if (tal_count(inchans) == 0) {
append_routes(&inchans, private);
append_bools(&inchan_deadends, private_deadends);
}
}
#if DEVELOPER
/* dev-routes overrides this. */
any_offline = false;
@@ -528,6 +591,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
info->cmd->ld,
info->b11->msat ? *info->b11->msat : AMOUNT_MSAT(1),
inchans,
inchan_deadends,
&any_offline);
/* FIXME: add private routes if necessary! */
@@ -578,14 +642,19 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
any_offline
? " (among currently connected peers)" : "");
if (any_offline)
if (tal_count(inchans) == 0)
json_add_string(response, "warning_capacity",
"No channels");
else if (all_true(inchan_deadends, tal_count(inchans)))
json_add_string(response, "warning_deadends",
"No channel with a peer that is not a dead end");
else if (any_offline)
json_add_string(response, "warning_offline",
"No channel with a peer that is currently connected"
" has sufficient incoming capacity");
else
json_add_string(response, "warning_capacity",
"No channel with a peer that is not a dead end,"
" has sufficient incoming capacity");
"No channel with a peer that has sufficient incoming capacity");
}
was_pending(command_success(info->cmd, response));
@@ -739,6 +808,7 @@ static struct command_result *json_invoice(struct command *cmd,
info = tal(cmd, struct invoice_info);
info->cmd = cmd;
info->chanhints = tal(info, struct chanhints);
if (!param(cmd, buffer, params,
p_req("msatoshi", param_msat_or_any, &msatoshi_val),
@@ -769,6 +839,17 @@ static struct command_result *json_invoice(struct command *cmd,
strlen(desc_val));
}
/* Default is expose iff no public channels. */
if (exposeprivate == NULL) {
info->chanhints->expose_all_private = false;
info->chanhints->hints = NULL;
} else {
info->chanhints->expose_all_private = *exposeprivate;
/* FIXME: Support hints! */
info->chanhints->hints = tal_arr(info->chanhints,
struct short_channel_id, 0);
}
if (msatoshi_val
&& amount_msat_greater(*msatoshi_val, chainparams->max_payment)) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
@@ -829,10 +910,8 @@ static struct command_result *json_invoice(struct command *cmd,
if (fallback_scripts)
info->b11->fallbacks = tal_steal(info->b11, fallback_scripts);
log_debug(cmd->ld->log, "exposeprivate = %s",
exposeprivate ? (*exposeprivate ? "TRUE" : "FALSE") : "NULL");
subd_req(cmd, cmd->ld->gossip,
take(towire_gossip_get_incoming_channels(NULL, exposeprivate)),
take(towire_gossip_get_incoming_channels(NULL)),
-1, 0, gossipd_incoming_channels_reply, info);
return command_still_pending(cmd);