2021-12-04 12:23:56 +01:00
|
|
|
#include "config.h"
|
2020-09-08 06:57:53 +02:00
|
|
|
#include <common/bolt11.h>
|
2022-07-04 05:49:38 +02:00
|
|
|
#include <common/json_parse.h>
|
2020-09-08 06:57:53 +02:00
|
|
|
#include <gossipd/gossipd_wiregen.h>
|
2021-09-16 07:00:42 +02:00
|
|
|
#include <lightningd/channel.h>
|
2021-06-14 23:07:38 +02:00
|
|
|
#include <lightningd/lightningd.h>
|
2020-09-08 06:57:53 +02:00
|
|
|
#include <lightningd/peer_control.h>
|
|
|
|
#include <lightningd/routehint.h>
|
|
|
|
|
|
|
|
static bool scid_in_arr(const struct short_channel_id *scidarr,
|
2024-03-20 02:59:51 +01:00
|
|
|
struct short_channel_id scid)
|
2020-09-08 06:57:53 +02:00
|
|
|
{
|
|
|
|
for (size_t i = 0; i < tal_count(scidarr); i++)
|
2024-03-20 02:59:51 +01:00
|
|
|
if (short_channel_id_eq(scidarr[i], scid))
|
2020-09-08 06:57:53 +02:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct routehint_candidate *
|
|
|
|
routehint_candidates(const tal_t *ctx,
|
|
|
|
struct lightningd *ld,
|
2021-06-14 23:07:38 +02:00
|
|
|
const char *buf,
|
|
|
|
const jsmntok_t *toks,
|
|
|
|
const bool *expose_all_private,
|
2020-09-08 06:57:53 +02:00
|
|
|
const struct short_channel_id *hints,
|
|
|
|
bool *none_public,
|
2021-06-14 23:07:38 +02:00
|
|
|
struct amount_msat *avail_capacity,
|
|
|
|
struct amount_msat *private_capacity,
|
|
|
|
struct amount_msat *deadend_capacity,
|
|
|
|
struct amount_msat *offline_capacity)
|
2020-09-08 06:57:53 +02:00
|
|
|
{
|
2021-06-14 23:07:38 +02:00
|
|
|
struct routehint_candidate *candidates, *privcandidates;
|
|
|
|
const jsmntok_t *t, *arr;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
log_debug(ld->log, "routehint: %.*s",
|
|
|
|
json_tok_full_len(toks),
|
|
|
|
json_tok_full(buf, toks));
|
|
|
|
|
|
|
|
/* We get the full JSON, including result. */
|
|
|
|
t = json_get_member(buf, toks, "result");
|
|
|
|
if (!t)
|
|
|
|
fatal("Missing result from listincoming: %.*s",
|
|
|
|
json_tok_full_len(toks),
|
|
|
|
json_tok_full(buf, toks));
|
|
|
|
arr = json_get_member(buf, t, "incoming");
|
2020-09-08 06:57:53 +02:00
|
|
|
|
|
|
|
candidates = tal_arr(ctx, struct routehint_candidate, 0);
|
2021-06-14 23:07:38 +02:00
|
|
|
privcandidates = tal_arr(tmpctx, struct routehint_candidate, 0);
|
|
|
|
*none_public = true;
|
|
|
|
*deadend_capacity = AMOUNT_MSAT(0);
|
|
|
|
*offline_capacity = AMOUNT_MSAT(0);
|
|
|
|
*avail_capacity = AMOUNT_MSAT(0);
|
|
|
|
*private_capacity = AMOUNT_MSAT(0);
|
|
|
|
|
|
|
|
/* We combine the JSON output which knows the peers' details,
|
|
|
|
* with our internal information */
|
|
|
|
json_for_each_arr(i, t, arr) {
|
|
|
|
struct amount_msat capacity;
|
|
|
|
const char *err;
|
2020-09-08 06:57:53 +02:00
|
|
|
struct routehint_candidate candidate;
|
2022-03-21 01:58:28 +01:00
|
|
|
struct amount_msat fee_base, htlc_max;
|
2021-06-14 23:07:38 +02:00
|
|
|
struct route_info *r;
|
|
|
|
bool is_public;
|
|
|
|
|
|
|
|
r = tal(tmpctx, struct route_info);
|
|
|
|
|
|
|
|
err = json_scan(tmpctx, buf, t,
|
|
|
|
"{id:%"
|
|
|
|
",short_channel_id:%"
|
|
|
|
",fee_base_msat:%"
|
|
|
|
",fee_proportional_millionths:%"
|
|
|
|
",cltv_expiry_delta:%"
|
2022-03-21 01:58:28 +01:00
|
|
|
",htlc_max_msat:%"
|
2021-06-14 23:07:38 +02:00
|
|
|
",incoming_capacity_msat:%"
|
|
|
|
"}",
|
|
|
|
JSON_SCAN(json_to_node_id, &r->pubkey),
|
|
|
|
JSON_SCAN(json_to_short_channel_id,
|
|
|
|
&r->short_channel_id),
|
|
|
|
JSON_SCAN(json_to_msat, &fee_base),
|
|
|
|
JSON_SCAN(json_to_u32,
|
|
|
|
&r->fee_proportional_millionths),
|
|
|
|
JSON_SCAN(json_to_u16, &r->cltv_expiry_delta),
|
2022-03-21 01:58:28 +01:00
|
|
|
JSON_SCAN(json_to_msat, &htlc_max),
|
2021-06-14 23:07:38 +02:00
|
|
|
JSON_SCAN(json_to_msat, &capacity));
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
fatal("Invalid return from listincoming (%s): %.*s",
|
|
|
|
err,
|
|
|
|
json_tok_full_len(toks),
|
|
|
|
json_tok_full(buf, toks));
|
|
|
|
}
|
2020-09-08 06:57:53 +02:00
|
|
|
|
2023-12-13 06:35:43 +01:00
|
|
|
/* Note: listincoming returns real scid or local alias if no real scid. */
|
2024-03-20 02:59:51 +01:00
|
|
|
candidate.c = any_channel_by_scid(ld, r->short_channel_id, true);
|
2021-06-14 23:07:38 +02:00
|
|
|
if (!candidate.c) {
|
2022-03-22 23:59:20 +01:00
|
|
|
log_debug(ld->log, "%s: channel not found in peer %s",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx, r->short_channel_id),
|
|
|
|
fmt_node_id(tmpctx, &r->pubkey));
|
2022-03-22 23:59:20 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2023-12-13 06:35:43 +01:00
|
|
|
/* Check channel is in CHANNELD_NORMAL or CHANNELD_AWAITING_SPLICE */
|
2023-10-02 00:59:51 +02:00
|
|
|
if (!channel_state_can_add_htlc(candidate.c->state)) {
|
2021-06-14 23:07:38 +02:00
|
|
|
log_debug(ld->log, "%s: abnormal channel",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx,
|
|
|
|
r->short_channel_id));
|
2020-09-08 06:57:53 +02:00
|
|
|
continue;
|
2021-06-14 23:07:38 +02:00
|
|
|
}
|
|
|
|
|
2022-03-21 01:58:54 +01:00
|
|
|
/* FIXME: we don't actually check htlc_minimum_msat! */
|
|
|
|
|
2022-03-21 01:58:28 +01:00
|
|
|
/* If they set an htlc_maximum_msat, consider that the
|
|
|
|
* capacity ceiling. We *could* do multiple HTLCs,
|
|
|
|
* but presumably that would defeat the spirit of the
|
|
|
|
* limit anyway */
|
2022-03-22 23:59:20 +01:00
|
|
|
/* FIXME: Present max capacity of multiple channels? */
|
2021-06-14 23:07:38 +02:00
|
|
|
candidate.capacity = channel_amount_receivable(candidate.c);
|
2022-03-21 01:58:28 +01:00
|
|
|
if (amount_msat_greater(candidate.capacity, htlc_max))
|
|
|
|
candidate.capacity = htlc_max;
|
2020-09-08 06:57:53 +02:00
|
|
|
|
2021-06-14 23:07:38 +02:00
|
|
|
/* Now we can tell if it's public. If so (even if it's otherwise
|
|
|
|
* unusable), we *don't* expose private channels! */
|
|
|
|
is_public = (candidate.c->channel_flags
|
|
|
|
& CHANNEL_FLAGS_ANNOUNCE_CHANNEL);
|
|
|
|
|
|
|
|
if (is_public)
|
|
|
|
*none_public = false;
|
|
|
|
|
|
|
|
/* If they explicitly say to expose all private ones, consider
|
|
|
|
* it public. */
|
|
|
|
if (expose_all_private != NULL && *expose_all_private)
|
|
|
|
is_public = true;
|
|
|
|
|
|
|
|
r->fee_base_msat = fee_base.millisatoshis; /* Raw: route_info */
|
|
|
|
/* Could wrap: if so ignore */
|
|
|
|
if (!amount_msat_eq(amount_msat(r->fee_base_msat), fee_base)) {
|
|
|
|
log_debug(ld->log,
|
|
|
|
"Peer charging insane fee %.*s; ignoring",
|
|
|
|
json_tok_full_len(t),
|
|
|
|
json_tok_full(buf, t));
|
2020-09-08 06:57:53 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-06-14 23:07:38 +02:00
|
|
|
/* Consider only hints they gave */
|
|
|
|
if (hints) {
|
|
|
|
log_debug(ld->log, "We have hints!");
|
2022-08-08 21:58:07 +02:00
|
|
|
/* Allow specification by alias, too */
|
2024-03-20 02:59:51 +01:00
|
|
|
if (!scid_in_arr(hints, r->short_channel_id)
|
2022-08-08 21:58:07 +02:00
|
|
|
&& (!candidate.c->alias[REMOTE]
|
2024-03-20 02:59:51 +01:00
|
|
|
|| !scid_in_arr(hints, *candidate.c->alias[REMOTE]))) {
|
2021-06-14 23:07:38 +02:00
|
|
|
log_debug(ld->log, "scid %s not in hints",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx,
|
|
|
|
r->short_channel_id));
|
2021-06-14 23:07:38 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* If they give us a hint, we use even if capacity 0 */
|
2024-09-18 09:34:27 +02:00
|
|
|
} else if (amount_msat_is_zero(capacity)) {
|
2021-06-14 23:07:38 +02:00
|
|
|
log_debug(ld->log, "%s: deadend",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx,
|
|
|
|
r->short_channel_id));
|
2024-09-18 09:33:27 +02:00
|
|
|
if (!amount_msat_accumulate(deadend_capacity,
|
|
|
|
candidate.capacity))
|
2021-06-14 23:07:38 +02:00
|
|
|
fatal("Overflow summing deadend capacity!");
|
|
|
|
continue;
|
|
|
|
}
|
2020-09-08 06:57:53 +02:00
|
|
|
|
|
|
|
/* Is it offline? */
|
|
|
|
if (candidate.c->owner == NULL) {
|
2021-06-14 23:07:38 +02:00
|
|
|
log_debug(ld->log, "%s: offline",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx,
|
|
|
|
r->short_channel_id));
|
2024-09-18 09:33:27 +02:00
|
|
|
if (!amount_msat_accumulate(offline_capacity,
|
|
|
|
candidate.capacity))
|
2020-09-08 06:57:53 +02:00
|
|
|
fatal("Overflow summing offline capacity!");
|
|
|
|
continue;
|
|
|
|
}
|
2021-06-14 23:07:38 +02:00
|
|
|
|
2024-03-18 04:01:06 +01:00
|
|
|
/* BOLT #2:
|
2022-08-08 21:58:07 +02:00
|
|
|
* - if `channel_type` has `option_scid_alias` set:
|
|
|
|
* - MUST NOT use the real `short_channel_id` in
|
|
|
|
* BOLT 11 `r` fields.
|
|
|
|
*/
|
2023-12-13 06:35:43 +01:00
|
|
|
if (channel_has(candidate.c, OPT_SCID_ALIAS)) {
|
|
|
|
if (!candidate.c->alias[REMOTE]) {
|
|
|
|
log_debug(ld->log, "%s: no remote alias (yet?)",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx,
|
|
|
|
r->short_channel_id));
|
2023-12-13 06:35:43 +01:00
|
|
|
continue;
|
|
|
|
}
|
2022-08-08 21:58:07 +02:00
|
|
|
r->short_channel_id = *candidate.c->alias[REMOTE];
|
2023-12-13 06:35:43 +01:00
|
|
|
} else {
|
|
|
|
/* Older code didn't remember type correctly,
|
|
|
|
* or negotiate properly, so best effort here */
|
|
|
|
|
|
|
|
/* Note explicit flag test here: if we're told to expose all
|
|
|
|
* private channels, then "is_public" is forced true */
|
|
|
|
if (candidate.c->alias[REMOTE]
|
|
|
|
/* Use remote alias if it's all we've got, or unannounced channel */
|
|
|
|
&& (!(candidate.c->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL)
|
|
|
|
|| !candidate.c->scid)) {
|
|
|
|
r->short_channel_id = *candidate.c->alias[REMOTE];
|
|
|
|
} else if (candidate.c->scid) {
|
|
|
|
r->short_channel_id = *candidate.c->scid;
|
|
|
|
} else {
|
|
|
|
/* Haven't got remote alias yet? Can't use ut. */
|
|
|
|
log_debug(ld->log, "%s: no alias",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx,
|
|
|
|
r->short_channel_id));
|
2023-12-13 06:35:43 +01:00
|
|
|
continue;
|
|
|
|
}
|
2022-08-08 21:58:07 +02:00
|
|
|
}
|
|
|
|
|
2021-06-14 23:07:38 +02:00
|
|
|
/* OK, finish it and append to one of the arrays. */
|
|
|
|
if (is_public) {
|
|
|
|
log_debug(ld->log, "%s: added to public",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx,
|
|
|
|
r->short_channel_id));
|
2021-06-14 23:07:38 +02:00
|
|
|
candidate.r = tal_steal(candidates, r);
|
|
|
|
tal_arr_expand(&candidates, candidate);
|
2024-09-18 09:33:27 +02:00
|
|
|
if (!amount_msat_accumulate(avail_capacity,
|
|
|
|
candidate.capacity)) {
|
2021-06-14 23:07:38 +02:00
|
|
|
fatal("Overflow summing pub capacities %s + %s",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_amount_msat(tmpctx,
|
|
|
|
*avail_capacity),
|
|
|
|
fmt_amount_msat(tmpctx,
|
|
|
|
candidate.capacity));
|
2021-06-14 23:07:38 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
log_debug(ld->log, "%s: added to private",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_short_channel_id(tmpctx,
|
|
|
|
r->short_channel_id));
|
2021-06-14 23:07:38 +02:00
|
|
|
candidate.r = tal_steal(privcandidates, r);
|
|
|
|
tal_arr_expand(&privcandidates, candidate);
|
2024-09-18 09:33:27 +02:00
|
|
|
if (!amount_msat_accumulate(private_capacity,
|
|
|
|
candidate.capacity)) {
|
2021-06-14 23:07:38 +02:00
|
|
|
fatal("Overflow summing priv capacities %s + %s",
|
2024-03-20 01:47:52 +01:00
|
|
|
fmt_amount_msat(tmpctx,
|
|
|
|
*private_capacity),
|
|
|
|
fmt_amount_msat(tmpctx,
|
|
|
|
candidate.capacity));
|
2021-06-14 23:07:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* By default, only consider private channels if there are
|
|
|
|
* no public channels *at all* */
|
|
|
|
if (expose_all_private == NULL
|
|
|
|
&& tal_count(candidates) == 0 && *none_public) {
|
|
|
|
log_debug(ld->log, "No publics: using private channels");
|
|
|
|
tal_free(candidates);
|
|
|
|
candidates = tal_steal(ctx, privcandidates);
|
|
|
|
*avail_capacity = *private_capacity;
|
|
|
|
/* This reflects *unused* private capacity. */
|
|
|
|
*private_capacity = AMOUNT_MSAT(0);
|
2020-09-08 06:57:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return candidates;
|
|
|
|
}
|