mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
5052f0763f
It was weird not to have a capacity associated with localmods channels, and fixing it has some very nice side effects. Now the gossmap_chan_get_capacity() call never fails (we prevented reading of channels from gossmap in the partially-written case already), so we make it return the capacity. We do this in msat, because that's what all the callers want. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
199 lines
5.8 KiB
C
199 lines
5.8 KiB
C
#include "config.h"
|
|
#include <plugins/renepay/renepayconfig.h>
|
|
#include <plugins/renepay/uncertainty.h>
|
|
|
|
void uncertainty_route_success(struct uncertainty *uncertainty,
|
|
const struct route *route)
|
|
{
|
|
if (!route->hops)
|
|
return;
|
|
|
|
for (size_t i = 0; i < tal_count(route->hops); i++) {
|
|
const struct route_hop *hop = &route->hops[i];
|
|
struct short_channel_id_dir scidd = {hop->scid, hop->direction};
|
|
|
|
// FIXME: check errors here, report back
|
|
chan_extra_sent_success(uncertainty->chan_extra_map, &scidd,
|
|
route->hops[i].amount);
|
|
}
|
|
}
|
|
void uncertainty_remove_htlcs(struct uncertainty *uncertainty,
|
|
const struct route *route)
|
|
{
|
|
// FIXME: how could we get the route details of a sendpay that we did
|
|
// not send?
|
|
if (!route->hops)
|
|
return;
|
|
|
|
const size_t pathlen = tal_count(route->hops);
|
|
for (size_t i = 0; i < pathlen; i++) {
|
|
const struct route_hop *hop = &route->hops[i];
|
|
struct short_channel_id_dir scidd = {hop->scid, hop->direction};
|
|
|
|
// FIXME: check error
|
|
chan_extra_remove_htlc(uncertainty->chan_extra_map, &scidd,
|
|
hop->amount);
|
|
}
|
|
}
|
|
|
|
void uncertainty_commit_htlcs(struct uncertainty *uncertainty,
|
|
const struct route *route)
|
|
{
|
|
// FIXME: how could we get the route details of a sendpay that we did
|
|
// not send?
|
|
if (!route->hops)
|
|
return;
|
|
|
|
const size_t pathlen = tal_count(route->hops);
|
|
for (size_t i = 0; i < pathlen; i++) {
|
|
const struct route_hop *hop = &route->hops[i];
|
|
struct short_channel_id_dir scidd = {hop->scid, hop->direction};
|
|
|
|
// FIXME: check error
|
|
chan_extra_commit_htlc(uncertainty->chan_extra_map, &scidd,
|
|
hop->amount);
|
|
}
|
|
}
|
|
|
|
void uncertainty_channel_can_send(struct uncertainty *uncertainty,
|
|
struct short_channel_id scid, int direction)
|
|
{
|
|
struct short_channel_id_dir scidd = {scid, direction};
|
|
// FIXME: check error
|
|
chan_extra_can_send(uncertainty->chan_extra_map, &scidd);
|
|
}
|
|
void uncertainty_channel_cannot_send(struct uncertainty *uncertainty,
|
|
struct short_channel_id scid,
|
|
int direction)
|
|
{
|
|
struct short_channel_id_dir scidd = {scid, direction};
|
|
// FIXME: check error
|
|
chan_extra_cannot_send(uncertainty->chan_extra_map, &scidd);
|
|
}
|
|
|
|
int uncertainty_update(struct uncertainty *uncertainty, struct gossmap *gossmap)
|
|
{
|
|
/* Each channel in chan_extra_map should be either in gossmap or in
|
|
* local_gossmods. */
|
|
assert(uncertainty);
|
|
struct chan_extra_map *chan_extra_map = uncertainty->chan_extra_map;
|
|
assert(chan_extra_map);
|
|
struct chan_extra **del_list = tal_arr(NULL, struct chan_extra*, 0);
|
|
struct chan_extra_map_iter it;
|
|
for (struct chan_extra *ch = chan_extra_map_first(chan_extra_map, &it);
|
|
ch; ch = chan_extra_map_next(chan_extra_map, &it)) {
|
|
|
|
/* If we cannot find that channel in the gossmap, add it to the
|
|
* delete list. */
|
|
if (!gossmap_find_chan(gossmap, &ch->scid))
|
|
tal_arr_expand(&del_list, ch);
|
|
}
|
|
for(size_t i=0;i<tal_count(del_list);i++) {
|
|
chan_extra_map_del(chan_extra_map, del_list[i]);
|
|
del_list[i] = tal_free(del_list[i]);
|
|
}
|
|
del_list = tal_free(del_list);
|
|
|
|
|
|
/* For each channel in the gossmap, create a extra data in
|
|
* chan_extra_map */
|
|
int skipped_count = 0;
|
|
for (struct gossmap_chan *chan = gossmap_first_chan(gossmap); chan;
|
|
chan = gossmap_next_chan(gossmap, chan)) {
|
|
struct short_channel_id scid = gossmap_chan_scid(gossmap, chan);
|
|
struct chan_extra *ce =
|
|
chan_extra_map_get(chan_extra_map, scid);
|
|
if (!ce) {
|
|
struct amount_msat cap_msat;
|
|
|
|
cap_msat = gossmap_chan_get_capacity(gossmap, chan);
|
|
if (!new_chan_extra(chan_extra_map, scid,
|
|
cap_msat)) {
|
|
/* If the new chan_extra cannot be created we
|
|
* skip this channel. */
|
|
skipped_count++;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
assert(chan_extra_map_count(chan_extra_map) + skipped_count ==
|
|
gossmap_num_chans(gossmap));
|
|
return skipped_count;
|
|
}
|
|
|
|
struct uncertainty *uncertainty_new(const tal_t *ctx)
|
|
{
|
|
struct uncertainty *uncertainty = tal(ctx, struct uncertainty);
|
|
if (uncertainty == NULL)
|
|
goto function_fail;
|
|
|
|
uncertainty->chan_extra_map = tal(uncertainty, struct chan_extra_map);
|
|
if (uncertainty->chan_extra_map == NULL)
|
|
goto function_fail;
|
|
|
|
chan_extra_map_init(uncertainty->chan_extra_map);
|
|
|
|
return uncertainty;
|
|
|
|
function_fail:
|
|
return tal_free(uncertainty);
|
|
}
|
|
|
|
struct chan_extra_map *
|
|
uncertainty_get_chan_extra_map(struct uncertainty *uncertainty)
|
|
{
|
|
// TODO: do we really need this function?
|
|
return uncertainty->chan_extra_map;
|
|
}
|
|
|
|
/* Add channel to the Uncertainty Network if it doesn't already exist. */
|
|
const struct chan_extra *
|
|
uncertainty_add_channel(struct uncertainty *uncertainty,
|
|
const struct short_channel_id scid,
|
|
struct amount_msat capacity)
|
|
{
|
|
const struct chan_extra *ce =
|
|
chan_extra_map_get(uncertainty->chan_extra_map, scid);
|
|
if (ce)
|
|
return ce;
|
|
|
|
return new_chan_extra(uncertainty->chan_extra_map, scid, capacity);
|
|
}
|
|
|
|
bool uncertainty_set_liquidity(struct uncertainty *uncertainty,
|
|
const struct short_channel_id_dir *scidd,
|
|
struct amount_msat min,
|
|
struct amount_msat max)
|
|
{
|
|
// FIXME check error
|
|
enum renepay_errorcode err = chan_extra_set_liquidity(
|
|
uncertainty->chan_extra_map, scidd, min, max);
|
|
|
|
return err == RENEPAY_NOERROR;
|
|
}
|
|
|
|
struct chan_extra *uncertainty_find_channel(struct uncertainty *uncertainty,
|
|
const struct short_channel_id scid)
|
|
{
|
|
return chan_extra_map_get(uncertainty->chan_extra_map, scid);
|
|
}
|
|
|
|
enum renepay_errorcode uncertainty_relax(struct uncertainty *uncertainty,
|
|
double seconds)
|
|
{
|
|
assert(seconds >= 0);
|
|
const double fraction = MIN(seconds / TIMER_FORGET_SEC, 1.0);
|
|
struct chan_extra_map *chan_extra_map =
|
|
uncertainty_get_chan_extra_map(uncertainty);
|
|
struct chan_extra_map_iter it;
|
|
for (struct chan_extra *ce = chan_extra_map_first(chan_extra_map, &it);
|
|
ce; ce = chan_extra_map_next(chan_extra_map, &it)) {
|
|
enum renepay_errorcode err =
|
|
chan_extra_relax_fraction(ce, fraction);
|
|
|
|
if (err)
|
|
return err;
|
|
}
|
|
return RENEPAY_NOERROR;
|
|
}
|