mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 18:11:28 +01:00
cdaad1bf2a
This is more thorough than the minimal one required for getroute(), including the feerates and cltv deltas. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
159 lines
4.7 KiB
C
159 lines
4.7 KiB
C
#include "config.h"
|
|
#include <ccan/err/err.h>
|
|
#include <common/gossmap.h>
|
|
#include <common/gossmods_listpeerchannels.h>
|
|
#include <common/node_id.h>
|
|
#include <plugins/libplugin.h>
|
|
|
|
void gossmod_add_localchan(struct gossmap_localmods *mods,
|
|
const struct node_id *self,
|
|
const struct node_id *peer,
|
|
const struct short_channel_id_dir *scidd,
|
|
struct amount_msat min,
|
|
struct amount_msat max,
|
|
struct amount_msat fee_base,
|
|
u32 fee_proportional,
|
|
u32 cltv_delta,
|
|
bool enabled,
|
|
const char *buf UNUSED,
|
|
const jsmntok_t *chantok UNUSED,
|
|
void *cbarg UNUSED)
|
|
{
|
|
/* FIXME: features? */
|
|
gossmap_local_addchan(mods, self, peer, &scidd->scid, NULL);
|
|
|
|
gossmap_local_updatechan(mods, &scidd->scid, min, max,
|
|
fee_base.millisatoshis, /* Raw: gossmap */
|
|
fee_proportional,
|
|
cltv_delta,
|
|
enabled,
|
|
scidd->dir);
|
|
}
|
|
|
|
struct gossmap_localmods *
|
|
gossmods_from_listpeerchannels_(const tal_t *ctx,
|
|
const struct node_id *self,
|
|
const char *buf,
|
|
const jsmntok_t *toks,
|
|
void (*cb)(struct gossmap_localmods *mods,
|
|
const struct node_id *self,
|
|
const struct node_id *peer,
|
|
const struct short_channel_id_dir *scidd,
|
|
struct amount_msat min,
|
|
struct amount_msat max,
|
|
struct amount_msat fee_base,
|
|
u32 fee_proportional,
|
|
u32 cltv_delta,
|
|
bool enabled,
|
|
const char *buf,
|
|
const jsmntok_t *chantok,
|
|
void *cbarg),
|
|
void *cbarg)
|
|
{
|
|
struct gossmap_localmods *mods = gossmap_localmods_new(ctx);
|
|
const jsmntok_t *channels, *channel;
|
|
size_t i;
|
|
|
|
channels = json_get_member(buf, toks, "channels");
|
|
json_for_each_arr(i, channel, channels) {
|
|
struct short_channel_id_dir scidd;
|
|
struct short_channel_id alias;
|
|
bool enabled;
|
|
struct node_id dst;
|
|
struct amount_msat spendable, receivable, fee_base[NUM_SIDES], htlc_min[NUM_SIDES], htlc_max[NUM_SIDES];
|
|
u32 fee_proportional[NUM_SIDES], cltv_delta[NUM_SIDES];
|
|
const char *state, *err;
|
|
|
|
/* scid/direction and alias may not exist. */
|
|
scidd.scid.u64 = 0;
|
|
alias.u64 = 0;
|
|
|
|
/* We do this to note if we have no remote update. */
|
|
fee_proportional[REMOTE] = -1U;
|
|
|
|
err = json_scan(tmpctx, buf, channel,
|
|
"{short_channel_id?:%,"
|
|
"direction?:%,"
|
|
"spendable_msat?:%,"
|
|
"receivable_msat?:%,"
|
|
"peer_connected:%,"
|
|
"state:%,"
|
|
"peer_id:%,"
|
|
"updates?:{"
|
|
"local"
|
|
":{fee_base_msat:%,"
|
|
"fee_proportional_millionths:%,"
|
|
"htlc_minimum_msat:%,"
|
|
"htlc_maximum_msat:%,"
|
|
"cltv_expiry_delta:%},"
|
|
"remote?"
|
|
":{fee_base_msat:%,"
|
|
"fee_proportional_millionths:%,"
|
|
"htlc_minimum_msat:%,"
|
|
"htlc_maximum_msat:%,"
|
|
"cltv_expiry_delta:%}},"
|
|
"alias?:{local:%}}",
|
|
JSON_SCAN(json_to_short_channel_id, &scidd.scid),
|
|
JSON_SCAN(json_to_int, &scidd.dir),
|
|
JSON_SCAN(json_to_msat, &spendable),
|
|
JSON_SCAN(json_to_msat, &receivable),
|
|
JSON_SCAN(json_to_bool, &enabled),
|
|
JSON_SCAN_TAL(tmpctx, json_strdup, &state),
|
|
JSON_SCAN(json_to_node_id, &dst),
|
|
JSON_SCAN(json_to_msat, &fee_base[LOCAL]),
|
|
JSON_SCAN(json_to_u32, &fee_proportional[LOCAL]),
|
|
JSON_SCAN(json_to_msat, &htlc_min[LOCAL]),
|
|
JSON_SCAN(json_to_msat, &htlc_max[LOCAL]),
|
|
JSON_SCAN(json_to_u32, &cltv_delta[LOCAL]),
|
|
JSON_SCAN(json_to_msat, &fee_base[REMOTE]),
|
|
JSON_SCAN(json_to_u32, &fee_proportional[REMOTE]),
|
|
JSON_SCAN(json_to_msat, &htlc_min[REMOTE]),
|
|
JSON_SCAN(json_to_msat, &htlc_max[REMOTE]),
|
|
JSON_SCAN(json_to_u32, &cltv_delta[REMOTE]),
|
|
JSON_SCAN(json_to_short_channel_id, &alias));
|
|
if (err) {
|
|
errx(1, "Bad listpeerchannels.channels %zu: %s",
|
|
i, err);
|
|
}
|
|
|
|
/* Use alias if no scid. Note: if alias is set, direction is present */
|
|
if (scidd.scid.u64 == 0 && alias.u64 != 0)
|
|
scidd.scid = alias;
|
|
|
|
/* Unusable if no scid (yet) */
|
|
if (scidd.scid.u64 == 0)
|
|
continue;
|
|
|
|
/* Disable if in bad state (it's already false if not connected) */
|
|
if (!streq(state, "CHANNELD_NORMAL")
|
|
&& !streq(state, "CHANNELD_AWAITING_SPLICE"))
|
|
enabled = false;
|
|
|
|
/* Cut htlc max to spendable. */
|
|
if (amount_msat_less(spendable, htlc_max[LOCAL]))
|
|
htlc_max[LOCAL] = spendable;
|
|
|
|
/* We add both directions */
|
|
cb(mods, self, &dst, &scidd, htlc_min[LOCAL], htlc_max[LOCAL],
|
|
fee_base[LOCAL], fee_proportional[LOCAL], cltv_delta[LOCAL],
|
|
enabled, buf, channel, cbarg);
|
|
|
|
/* If we didn't have a remote update, it's not usable yet */
|
|
if (fee_proportional[REMOTE] == -1U)
|
|
continue;
|
|
|
|
scidd.dir = !scidd.dir;
|
|
|
|
/* Cut htlc max to receivable. */
|
|
if (amount_msat_less(receivable, htlc_max[REMOTE]))
|
|
htlc_max[REMOTE] = receivable;
|
|
|
|
cb(mods, self, &dst, &scidd, htlc_min[REMOTE], htlc_max[REMOTE],
|
|
fee_base[REMOTE], fee_proportional[REMOTE], cltv_delta[REMOTE],
|
|
enabled, buf, channel, cbarg);
|
|
}
|
|
|
|
return mods;
|
|
}
|
|
|