pay: use json_to_listpeers_channels() for local_channel_hints.

Don't parse the listpeers.channels output ourselves: with two extra fields
we can simply reuse json_to_listpeers_channels().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-01-12 11:50:10 +10:30
parent 5d5b9c6812
commit ff2d7e6833
6 changed files with 41 additions and 64 deletions

View file

@ -164,6 +164,10 @@ bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok
bool json_to_txid(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct bitcoin_txid *txid UNNEEDED)
{ fprintf(stderr, "json_to_txid called!\n"); abort(); }
/* Generated stub for json_to_u16 */
bool json_to_u16(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
uint16_t *num UNNEEDED)
{ fprintf(stderr, "json_to_u16 called!\n"); abort(); }
/* Generated stub for json_tok_bin_from_hex */
u8 *json_tok_bin_from_hex(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
{ fprintf(stderr, "json_tok_bin_from_hex called!\n"); abort(); }

View file

@ -170,6 +170,10 @@ bool json_to_short_channel_id(const char *buffer UNNEEDED, const jsmntok_t *tok
bool json_to_txid(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct bitcoin_txid *txid UNNEEDED)
{ fprintf(stderr, "json_to_txid called!\n"); abort(); }
/* Generated stub for json_to_u16 */
bool json_to_u16(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
uint16_t *num UNNEEDED)
{ fprintf(stderr, "json_to_u16 called!\n"); abort(); }
/* Generated stub for json_tok_bin_from_hex */
u8 *json_tok_bin_from_hex(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
{ fprintf(stderr, "json_tok_bin_from_hex called!\n"); abort(); }

View file

@ -2350,73 +2350,39 @@ static struct command_result *
local_channel_hints_listpeers(struct command *cmd, const char *buffer,
const jsmntok_t *toks, struct payment *p)
{
const jsmntok_t *peers, *peer, *channels, *channel, *spendsats, *scid,
*dir, *connected, *max_htlc, *htlcs, *state, *alias, *alias_local;
size_t i, j;
peers = json_get_member(buffer, toks, "peers");
struct listpeers_channel **chans;
if (peers == NULL)
goto done;
/* cppcheck-suppress uninitvar - cppcheck can't undestand these macros. */
json_for_each_arr(i, peer, peers) {
channels = json_get_member(buffer, peer, "channels");
if (channels == NULL)
continue;
chans = json_to_listpeers_channels(tmpctx, buffer, toks);
connected = json_get_member(buffer, peer, "connected");
for (size_t i = 0; i < tal_count(chans); i++) {
struct short_channel_id scid;
bool enabled;
u16 htlc_budget;
json_for_each_arr(j, channel, channels) {
struct channel_hint h;
spendsats = json_get_member(buffer, channel, "spendable_msat");
scid = json_get_member(buffer, channel, "short_channel_id");
/* Filter out local channels if they are
* either a) disconnected, or b) not in normal
* state. */
enabled = chans[i]->connected && streq(chans[i]->state, "CHANNELD_NORMAL");
alias = json_get_member(buffer, channel, "alias");
if (alias != NULL)
alias_local = json_get_member(buffer, alias, "local");
else
alias_local = NULL;
if (chans[i]->scid != NULL)
scid = *chans[i]->scid;
else
scid = *chans[i]->alias[LOCAL];
dir = json_get_member(buffer, channel, "direction");
max_htlc = json_get_member(buffer, channel, "max_accepted_htlcs");
htlcs = json_get_member(buffer, channel, "htlcs");
state = json_get_member(buffer, channel, "state");
if (spendsats == NULL ||
(scid == NULL && alias_local == NULL) ||
dir == NULL || max_htlc == NULL || state == NULL ||
max_htlc->type != JSMN_PRIMITIVE || htlcs == NULL ||
htlcs->type != JSMN_ARRAY)
continue;
/* Take the configured number of max_htlcs and
* subtract any HTLCs that might already be added to
* the channel. This is a best effort estimate and
* mostly considers stuck htlcs, concurrent payments
* may throw us off a bit. */
if (chans[i]->num_htlcs > chans[i]->max_accepted_htlcs)
htlc_budget = 0;
else
htlc_budget = chans[i]->max_accepted_htlcs - chans[i]->num_htlcs;
/* Filter out local channels if they are
* either a) disconnected, or b) not in normal
* state. */
json_to_bool(buffer, connected, &h.enabled);
h.enabled &= json_tok_streq(buffer, state, "CHANNELD_NORMAL");
if (scid != NULL)
json_to_short_channel_id(buffer, scid, &h.scid.scid);
else
json_to_short_channel_id(buffer, alias_local, &h.scid.scid);
json_to_int(buffer, dir, &h.scid.dir);
json_to_msat(buffer, spendsats, &h.estimated_capacity);
/* Take the configured number of max_htlcs and
* subtract any HTLCs that might already be added to
* the channel. This is a best effort estimate and
* mostly considers stuck htlcs, concurrent payments
* may throw us off a bit. */
json_to_u16(buffer, max_htlc, &h.htlc_budget);
h.htlc_budget -= htlcs->size;
h.local = true;
channel_hints_update(p, h.scid.scid, h.scid.dir,
h.enabled, true, &h.estimated_capacity, &h.htlc_budget);
}
channel_hints_update(p, scid, chans[i]->direction, enabled, true,
&chans[i]->spendable_msat, &htlc_budget);
}
done:
payment_continue(p);
return command_still_pending(cmd);
}

View file

@ -1912,7 +1912,9 @@ static struct listpeers_channel *json_to_listpeers_channel(const tal_t *ctx,
*tmsattok = json_get_member(buffer, tok, "total_msat"),
*smsattok =
json_get_member(buffer, tok, "spendable_msat"),
*aliastok = json_get_member(buffer, tok, "alias");
*aliastok = json_get_member(buffer, tok, "alias"),
*max_htlcs = json_get_member(buffer, tok, "max_accepted_htlcs"),
*htlcstok = json_get_member(buffer, tok, "htlcs");
chan = tal(ctx, struct listpeers_channel);
@ -1958,6 +1960,8 @@ static struct listpeers_channel *json_to_listpeers_channel(const tal_t *ctx,
json_to_int(buffer, dirtok, &chan->direction);
json_to_msat(buffer, tmsattok, &chan->total_msat);
json_to_msat(buffer, smsattok, &chan->spendable_msat);
json_to_u16(buffer, max_htlcs, &chan->max_accepted_htlcs);
chan->num_htlcs = htlcstok->size;
return chan;
}
@ -1998,7 +2002,7 @@ struct listpeers_channel **json_to_listpeers_channels(const tal_t *ctx,
struct listpeers_channel **chans;
chans = tal_arr(ctx, struct listpeers_channel *, 0);
json_for_each_obj(i, iter, peerstok)
json_for_each_arr(i, iter, peerstok)
json_add_listpeers_peer(&chans, buffer, iter);
return chans;
}

View file

@ -444,6 +444,8 @@ struct listpeers_channel {
int direction;
struct amount_msat total_msat;
struct amount_msat spendable_msat;
u16 max_accepted_htlcs;
size_t num_htlcs;
/* TODO Add fields as we need them. */
};

View file

@ -122,9 +122,6 @@ void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UN
/* Generated stub for json_strdup */
char *json_strdup(const tal_t *ctx UNNEEDED, const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED)
{ fprintf(stderr, "json_strdup called!\n"); abort(); }
/* Generated stub for json_to_bool */
bool json_to_bool(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, bool *b UNNEEDED)
{ fprintf(stderr, "json_to_bool called!\n"); abort(); }
/* Generated stub for json_to_createonion_response */
struct createonion_response *json_to_createonion_response(const tal_t *ctx UNNEEDED,
const char *buffer UNNEEDED,