diff --git a/plugins/bkpr/test/run-bkpr_db.c b/plugins/bkpr/test/run-bkpr_db.c index e71d7c1d4..731bf4853 100644 --- a/plugins/bkpr/test/run-bkpr_db.c +++ b/plugins/bkpr/test/run-bkpr_db.c @@ -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(); } diff --git a/plugins/bkpr/test/run-recorder.c b/plugins/bkpr/test/run-recorder.c index 7872800be..382631ede 100644 --- a/plugins/bkpr/test/run-recorder.c +++ b/plugins/bkpr/test/run-recorder.c @@ -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(); } diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 02bacca9c..7584319be 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -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); } diff --git a/plugins/libplugin.c b/plugins/libplugin.c index cebee85c6..55d94aa83 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -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; } diff --git a/plugins/libplugin.h b/plugins/libplugin.h index a846317f1..987406151 100644 --- a/plugins/libplugin.h +++ b/plugins/libplugin.h @@ -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. */ }; diff --git a/plugins/test/run-route-overlong.c b/plugins/test/run-route-overlong.c index a22863508..00a806748 100644 --- a/plugins/test/run-route-overlong.c +++ b/plugins/test/run-route-overlong.c @@ -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,