mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-23 15:00:34 +01:00
askrene: don't have get_flow_paths() handle htlc_max, htlc_min and extra millisats.
We don't actually hit the htlc_max cases, since the flow code already constrains us to that. And handling htlc_min is better done in the caller, where diagnostics are better (basically, we should eliminate them, and if that means no route, give a clear error message). And the refinement step can handle any extra millisats from rounding. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
f0331cd82e
commit
db29a2d6b5
2 changed files with 10 additions and 76 deletions
|
@ -297,6 +297,11 @@ static void add_reservation(struct reservations *r,
|
||||||
* push us again over capacity or htlc_maximum_msat.
|
* push us again over capacity or htlc_maximum_msat.
|
||||||
*
|
*
|
||||||
* We may have to reduce the flow amount in response to these.
|
* We may have to reduce the flow amount in response to these.
|
||||||
|
*
|
||||||
|
* We also check for going below htlc_maximum_msat at this point: this
|
||||||
|
* is unusual and means it's small, so we just remove that flow if
|
||||||
|
* this happens, as we can make it up by buffing up the other flows
|
||||||
|
* (or, it's simply impossible).
|
||||||
*/
|
*/
|
||||||
static const char *constrain_flow(const tal_t *ctx,
|
static const char *constrain_flow(const tal_t *ctx,
|
||||||
struct route_query *rq,
|
struct route_query *rq,
|
||||||
|
|
|
@ -194,7 +194,6 @@
|
||||||
static const double CHANNEL_PIVOTS[]={0,0.5,0.8,0.95};
|
static const double CHANNEL_PIVOTS[]={0,0.5,0.8,0.95};
|
||||||
|
|
||||||
static const s64 INFINITE = INT64_MAX;
|
static const s64 INFINITE = INT64_MAX;
|
||||||
static const u64 INFINITE_MSAT = UINT64_MAX;
|
|
||||||
static const u32 INVALID_INDEX = 0xffffffff;
|
static const u32 INVALID_INDEX = 0xffffffff;
|
||||||
static const s64 MU_MAX = 101;
|
static const s64 MU_MAX = 101;
|
||||||
|
|
||||||
|
@ -1102,16 +1101,10 @@ static struct flow **
|
||||||
get_flow_paths(const tal_t *ctx,
|
get_flow_paths(const tal_t *ctx,
|
||||||
const struct route_query *rq,
|
const struct route_query *rq,
|
||||||
const struct linear_network *linear_network,
|
const struct linear_network *linear_network,
|
||||||
const struct residual_network *residual_network,
|
const struct residual_network *residual_network)
|
||||||
|
|
||||||
// how many msats in excess we paid for not having msat accuracy
|
|
||||||
// in the MCF solver
|
|
||||||
struct amount_msat excess)
|
|
||||||
{
|
{
|
||||||
struct flow **flows = tal_arr(ctx,struct flow*,0);
|
struct flow **flows = tal_arr(ctx,struct flow*,0);
|
||||||
|
|
||||||
assert(amount_msat_less(excess, AMOUNT_MSAT(1000)));
|
|
||||||
|
|
||||||
const size_t max_num_chans = gossmap_max_chan_idx(rq->gossmap);
|
const size_t max_num_chans = gossmap_max_chan_idx(rq->gossmap);
|
||||||
struct chan_flow *chan_flow = tal_arrz(tmpctx,struct chan_flow,max_num_chans);
|
struct chan_flow *chan_flow = tal_arrz(tmpctx,struct chan_flow,max_num_chans);
|
||||||
|
|
||||||
|
@ -1167,13 +1160,6 @@ get_flow_paths(const tal_t *ctx,
|
||||||
rq->gossmap, chan_flow, node_idx, balance,
|
rq->gossmap, chan_flow, node_idx, balance,
|
||||||
prev_chan, prev_dir, prev_idx);
|
prev_chan, prev_dir, prev_idx);
|
||||||
|
|
||||||
/* For each route we will compute the highest htlc_min
|
|
||||||
* and the smallest htlc_max and use those to constraint
|
|
||||||
* the flow we will allocate. */
|
|
||||||
struct amount_msat sup_htlc_min = AMOUNT_MSAT_INIT(0),
|
|
||||||
inf_htlc_max =
|
|
||||||
AMOUNT_MSAT_INIT(INFINITE_MSAT);
|
|
||||||
|
|
||||||
s64 delta=-balance[node_idx];
|
s64 delta=-balance[node_idx];
|
||||||
int length = 0;
|
int length = 0;
|
||||||
delta = MIN(delta,balance[final_idx]);
|
delta = MIN(delta,balance[final_idx]);
|
||||||
|
@ -1192,44 +1178,9 @@ get_flow_paths(const tal_t *ctx,
|
||||||
|
|
||||||
delta=MIN(delta,chan_flow[c_idx].half[dir]);
|
delta=MIN(delta,chan_flow[c_idx].half[dir]);
|
||||||
length++;
|
length++;
|
||||||
|
|
||||||
/* obtain the supremum htlc_min along the route
|
|
||||||
*/
|
|
||||||
sup_htlc_min = amount_msat_max(
|
|
||||||
sup_htlc_min, gossmap_chan_htlc_min(c, dir));
|
|
||||||
|
|
||||||
/* obtain the infimum htlc_max along the route
|
|
||||||
*/
|
|
||||||
inf_htlc_max = amount_msat_min(
|
|
||||||
inf_htlc_max, gossmap_chan_htlc_max(c, dir));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 htlc_max=inf_htlc_max.millisatoshis/1000;/* Raw: need htlc_max in sats to do arithmetic operations.*/
|
struct flow *fp = tal(flows,struct flow);
|
||||||
s64 htlc_min=(sup_htlc_min.millisatoshis+999)/1000;/* Raw: need htlc_min in sats to do arithmetic operations.*/
|
|
||||||
|
|
||||||
if (htlc_min > htlc_max) {
|
|
||||||
/* htlc_min is too big or htlc_max is too small,
|
|
||||||
* we cannot send `delta` along this route.
|
|
||||||
*
|
|
||||||
* FIXME: We try anyways because failing
|
|
||||||
* channels will be blacklisted downstream. */
|
|
||||||
htlc_min = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we divide this route into different flows make it
|
|
||||||
* random to avoid routing nodes making correlations. */
|
|
||||||
if (delta > htlc_max) {
|
|
||||||
// FIXME: choosing a number in the range
|
|
||||||
// [htlc_min, htlc_max] or
|
|
||||||
// [0.5 htlc_max, htlc_max]
|
|
||||||
// The choice of the fraction was completely
|
|
||||||
// arbitrary.
|
|
||||||
delta = pseudorand_interval(
|
|
||||||
MAX(htlc_min, (htlc_max * 50) / 100),
|
|
||||||
htlc_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct flow *fp = tal(tmpctx,struct flow);
|
|
||||||
fp->path = tal_arr(fp,const struct gossmap_chan *,length);
|
fp->path = tal_arr(fp,const struct gossmap_chan *,length);
|
||||||
fp->dirs = tal_arr(fp,int,length);
|
fp->dirs = tal_arr(fp,int,length);
|
||||||
|
|
||||||
|
@ -1257,29 +1208,12 @@ get_flow_paths(const tal_t *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(delta>0);
|
assert(delta>0);
|
||||||
|
fp->delivers = amount_msat(delta*1000);
|
||||||
// substract the excess of msats for not having msat
|
|
||||||
// accuracy
|
|
||||||
struct amount_msat delivered = amount_msat(delta*1000);
|
|
||||||
if (!amount_msat_sub(&delivered, delivered, excess)) {
|
|
||||||
plugin_err(rq->plugin, "Unable to subtract excess %s from %s",
|
|
||||||
fmt_amount_msat(tmpctx, excess),
|
|
||||||
fmt_amount_msat(tmpctx, delivered));
|
|
||||||
}
|
|
||||||
excess = amount_msat(0);
|
|
||||||
fp->delivers = delivered;
|
|
||||||
|
|
||||||
// add fp to flows
|
// add fp to flows
|
||||||
tal_arr_expand(&flows, fp);
|
tal_arr_expand(&flows, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Establish ownership. */
|
|
||||||
for(size_t i=0;i<tal_count(flows);++i)
|
|
||||||
{
|
|
||||||
flows[i] = tal_steal(flows,flows[i]);
|
|
||||||
assert(flows[i]);
|
|
||||||
}
|
|
||||||
return flows;
|
return flows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1358,11 +1292,7 @@ struct flow **minflow(const tal_t *ctx,
|
||||||
* For example if we are trying to pay 1M sats our precision could be
|
* For example if we are trying to pay 1M sats our precision could be
|
||||||
* set to 1000sat, then channels that had capacity for 3M sats become 3k
|
* set to 1000sat, then channels that had capacity for 3M sats become 3k
|
||||||
* flow units. */
|
* flow units. */
|
||||||
const u64 pay_amount_msats = params->amount.millisatoshis % 1000; /* Raw: minflow */
|
const u64 pay_amount_sats = (params->amount.millisatoshis + 999)/1000; /* Raw: minflow */
|
||||||
const u64 pay_amount_sats = params->amount.millisatoshis/1000 /* Raw: minflow */
|
|
||||||
+ (pay_amount_msats ? 1 : 0);
|
|
||||||
const struct amount_msat excess
|
|
||||||
= amount_msat(pay_amount_msats ? 1000 - pay_amount_msats : 0);
|
|
||||||
|
|
||||||
if (!find_feasible_flow(linear_network, residual_network,
|
if (!find_feasible_flow(linear_network, residual_network,
|
||||||
source_idx, target_idx, pay_amount_sats)) {
|
source_idx, target_idx, pay_amount_sats)) {
|
||||||
|
@ -1381,7 +1311,6 @@ struct flow **minflow(const tal_t *ctx,
|
||||||
* Actual amounts considering fees are computed for every
|
* Actual amounts considering fees are computed for every
|
||||||
* channel in the routes. */
|
* channel in the routes. */
|
||||||
flow_paths = get_flow_paths(tmpctx, rq,
|
flow_paths = get_flow_paths(tmpctx, rq,
|
||||||
linear_network, residual_network, excess);
|
linear_network, residual_network);
|
||||||
return flow_paths;
|
return flow_paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue