Skip to content

Commit 9fd2d3e

Browse files
committed
renepay: add const probability cost
The probability for a success forward of x amount on a channel is now computed as: P_success(x) = b * P_rene(x) where P_rene(x) is the probability distribution proposed by Rene Pickhardt with a uniform distribution on the known liquidity of the channel and 'b' is a new parameter we add in this PR, by the name of "base probability". The "base probability" represents the probability for a channel in the network choosen at random to be able to forward at least 1msat, ie. of being alive, non-depleted and with at least one HTLC slot. We don't know the value of 'b', but for the moment we assume that it is 0.98 and use that as default. As a consequence the probability cost becomes non-linear and non-convex because of the additional constant term: Cost(x) = - log P_success(x) = - log b - - log P_rene(x) = - log b + Cost_rene(x) We currently don't handle well base fees and neither this additional "base probability" but we can as a first approximation linearize the cost function in this way: Cost_linear(x) = (- log b)*x + Cost_rene_linear(x) Changelog-Added: renepay: Add a dev parameter to renepay that represents a constant probability of availability for all channels in the network. Signed-off-by: Lagrang3 <[email protected]>
1 parent 565945b commit 9fd2d3e

File tree

13 files changed

+72
-10
lines changed

13 files changed

+72
-10
lines changed

plugins/renepay/flow.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@ bool flowset_delivers(struct amount_msat *delivers, struct flow **flows)
179179
return true;
180180
}
181181

182+
/* FIXME: pass a pointer to const here */
183+
size_t flowset_size(struct flow **flows)
184+
{
185+
size_t size = 0;
186+
for (size_t i = 0; i < tal_count(flows); i++)
187+
size += tal_count(flows[i]->path);
188+
return size;
189+
}
190+
182191
/* Checks if the flows satisfy the liquidity bounds imposed by the known maximum
183192
* liquidity and pending HTLCs.
184193
*

plugins/renepay/flow.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ bool flowset_fee(struct amount_msat *fee, struct flow **flows);
5555

5656
bool flowset_delivers(struct amount_msat *delivers, struct flow **flows);
5757

58+
/* how many channels are being used */
59+
size_t flowset_size(struct flow **flows);
60+
5861
static inline struct amount_msat flow_delivers(const struct flow *flow)
5962
{
6063
return flow->amount;

plugins/renepay/main.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ static struct command_result *json_pay(struct command *cmd, const char *buf,
184184
u64 *riskfactor_millionths; // delay to proportional proportional fee
185185
u64 *min_prob_success_millionths; // target probability
186186

187+
/* base probability of success, probability for a randomly picked
188+
* channel to be able to forward a payment request of amount greater
189+
* than zero. */
190+
u64 *base_prob_success_millionths;
191+
187192
if (!param(cmd, buf, params,
188193
p_req("invstring", param_invstring, &invstr),
189194
p_opt("amount_msat", param_msat, &msat),
@@ -217,10 +222,19 @@ static struct command_result *json_pay(struct command *cmd, const char *buf,
217222
&riskfactor_millionths, 1), // default is 1e-6
218223
p_opt_dev("dev_min_prob_success", param_millionths,
219224
&min_prob_success_millionths,
220-
900000), // default is 0.9
225+
800000), // default is 0.8
226+
p_opt_dev("dev_base_prob_success", param_millionths,
227+
&base_prob_success_millionths,
228+
980000), // default is 0.98
221229
NULL))
222230
return command_param_failed();
223231

232+
if (*base_prob_success_millionths == 0 ||
233+
*base_prob_success_millionths > 1000000)
234+
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
235+
"Base probability should be a number "
236+
"greater than zero and no greater than 1.");
237+
224238
/* === Parse invoice === */
225239

226240
// FIXME: add support for bolt12 invoices
@@ -315,6 +329,7 @@ static struct command_result *json_pay(struct command *cmd, const char *buf,
315329
*prob_cost_factor_millionths,
316330
*riskfactor_millionths,
317331
*min_prob_success_millionths,
332+
*base_prob_success_millionths,
318333
use_shadow,
319334
cast_const2(const struct route_exclusion**, exclusions));
320335

@@ -352,6 +367,7 @@ static struct command_result *json_pay(struct command *cmd, const char *buf,
352367
*prob_cost_factor_millionths,
353368
*riskfactor_millionths,
354369
*min_prob_success_millionths,
370+
*base_prob_success_millionths,
355371
use_shadow,
356372
cast_const2(const struct route_exclusion**, exclusions)))
357373
return command_fail(

plugins/renepay/mcf.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ struct pay_parameters {
331331

332332
struct amount_msat max_fee;
333333
double min_probability;
334+
double base_probability;
334335
double delay_feefactor;
335336
double base_fee_penalty;
336337
u32 prob_cost_factor;
@@ -501,15 +502,18 @@ static bool linearize_channel(const struct pay_parameters *params,
501502

502503
capacity[0]=a;
503504
cost[0]=0;
505+
assert(params->base_probability > 5e-7);
506+
const double base_prob_factor = -log(params->base_probability);
507+
504508
for(size_t i=1;i<CHANNEL_PARTS;++i)
505509
{
506510
capacity[i] = MIN(params->cap_fraction[i]*(b-a), cap_on_capacity);
507511
cap_on_capacity -= capacity[i];
508512
assert(cap_on_capacity>=0);
509513

510-
cost[i] = params->cost_fraction[i]
514+
cost[i] = (params->cost_fraction[i]*1.0/(b-a) + base_prob_factor)
511515
*params->amount.millisatoshis /* Raw: linearize_channel */
512-
*params->prob_cost_factor*1.0/(b-a);
516+
*params->prob_cost_factor;
513517
}
514518
return true;
515519
}
@@ -1264,6 +1268,7 @@ get_flow_paths(const tal_t *ctx, const struct gossmap *gossmap,
12641268
// how many msats in excess we paid for not having msat accuracy
12651269
// in the MCF solver
12661270
struct amount_msat excess,
1271+
const double base_probability,
12671272

12681273
// error message
12691274
char **fail)
@@ -1437,8 +1442,10 @@ get_flow_paths(const tal_t *ctx, const struct gossmap *gossmap,
14371442
excess = amount_msat(0);
14381443
fp->amount = delivered;
14391444

1445+
14401446
fp->success_prob =
1441-
flow_probability(fp, gossmap, chan_extra_map);
1447+
flow_probability(fp, gossmap, chan_extra_map)
1448+
* pow(base_probability, tal_count(fp->path));
14421449
if (fp->success_prob < 0) {
14431450
if (fail)
14441451
*fail =
@@ -1603,6 +1610,7 @@ struct flow **minflow(const tal_t *ctx, struct gossmap *gossmap,
16031610
struct chan_extra_map *chan_extra_map,
16041611
const bitmap *disabled, struct amount_msat amount,
16051612
struct amount_msat max_fee, double min_probability,
1613+
double base_probability,
16061614
double delay_feefactor, double base_fee_penalty,
16071615
u32 prob_cost_factor, char **fail)
16081616
{
@@ -1647,6 +1655,7 @@ struct flow **minflow(const tal_t *ctx, struct gossmap *gossmap,
16471655
params->delay_feefactor = delay_feefactor;
16481656
params->base_fee_penalty = base_fee_penalty;
16491657
params->prob_cost_factor = prob_cost_factor;
1658+
params->base_probability = base_probability;
16501659

16511660
// build the uncertainty network with linearization and residual arcs
16521661
struct linear_network *linear_network= init_linear_network(this_ctx, params, &errmsg);
@@ -1709,7 +1718,8 @@ struct flow **minflow(const tal_t *ctx, struct gossmap *gossmap,
17091718
// first flow found
17101719
best_flow_paths = get_flow_paths(
17111720
this_ctx, params->gossmap, params->disabled, params->chan_extra_map,
1712-
linear_network, residual_network, excess, &errmsg);
1721+
linear_network, residual_network, excess, params->base_probability,
1722+
&errmsg);
17131723
if (!best_flow_paths) {
17141724
if (fail)
17151725
*fail =
@@ -1720,7 +1730,8 @@ struct flow **minflow(const tal_t *ctx, struct gossmap *gossmap,
17201730

17211731
best_prob_success =
17221732
flowset_probability(this_ctx, best_flow_paths, params->gossmap,
1723-
params->chan_extra_map, &errmsg);
1733+
params->chan_extra_map, &errmsg)
1734+
* pow(params->base_probability, flowset_size(best_flow_paths));
17241735
if (best_prob_success < 0) {
17251736
if (fail)
17261737
*fail =
@@ -1764,7 +1775,8 @@ struct flow **minflow(const tal_t *ctx, struct gossmap *gossmap,
17641775
flow_paths =
17651776
get_flow_paths(this_ctx, params->gossmap, params->disabled,
17661777
params->chan_extra_map, linear_network,
1767-
residual_network, excess, &errmsg);
1778+
residual_network, excess, params->base_probability,
1779+
&errmsg);
17681780
if(!flow_paths)
17691781
{
17701782
// get_flow_paths doesn't fail unless there is a bug.
@@ -1776,7 +1788,8 @@ struct flow **minflow(const tal_t *ctx, struct gossmap *gossmap,
17761788

17771789
double prob_success =
17781790
flowset_probability(this_ctx, flow_paths, params->gossmap,
1779-
params->chan_extra_map, &errmsg);
1791+
params->chan_extra_map, &errmsg)
1792+
* pow(params->base_probability, flowset_size(flow_paths));
17801793
if (prob_success < 0) {
17811794
// flowset_probability doesn't fail unless there is a bug.
17821795
if (fail)

plugins/renepay/mcf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct flow **minflow(const tal_t *ctx, struct gossmap *gossmap,
6161
struct chan_extra_map *chan_extra_map,
6262
const bitmap *disabled, struct amount_msat amount,
6363
struct amount_msat max_fee, double min_probability,
64+
double base_probability,
6465
double delay_feefactor, double base_fee_penalty,
6566
u32 prob_cost_factor, char **fail);
6667
#endif /* LIGHTNING_PLUGINS_RENEPAY_MCF_H */

plugins/renepay/payment.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct payment *payment_new(
3232
u64 prob_cost_factor_millionths,
3333
u64 riskfactor_millionths,
3434
u64 min_prob_success_millionths,
35+
u64 base_prob_success_millionths,
3536
bool use_shadow,
3637
const struct route_exclusion **exclusions)
3738
{
@@ -81,6 +82,7 @@ struct payment *payment_new(
8182
pinfo->prob_cost_factor = prob_cost_factor_millionths / 1e6;
8283
pinfo->delay_feefactor = riskfactor_millionths / 1e6;
8384
pinfo->min_prob_success = min_prob_success_millionths / 1e6;
85+
pinfo->base_prob_success = base_prob_success_millionths / 1e6;
8486
pinfo->use_shadow = use_shadow;
8587

8688

@@ -146,6 +148,7 @@ bool payment_update(
146148
u64 prob_cost_factor_millionths,
147149
u64 riskfactor_millionths,
148150
u64 min_prob_success_millionths,
151+
u64 base_prob_success_millionths,
149152
bool use_shadow,
150153
const struct route_exclusion **exclusions)
151154
{
@@ -170,6 +173,7 @@ bool payment_update(
170173
pinfo->prob_cost_factor = prob_cost_factor_millionths / 1e6;
171174
pinfo->delay_feefactor = riskfactor_millionths / 1e6;
172175
pinfo->min_prob_success = min_prob_success_millionths / 1e6;
176+
pinfo->base_prob_success = base_prob_success_millionths / 1e6;
173177
pinfo->use_shadow = use_shadow;
174178

175179

plugins/renepay/payment.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct payment *payment_new(
117117
u64 prob_cost_factor_millionths,
118118
u64 riskfactor_millionths,
119119
u64 min_prob_success_millionths,
120+
u64 base_prob_success_millionths,
120121
bool use_shadow,
121122
const struct route_exclusion **exclusions);
122123

@@ -131,6 +132,7 @@ bool payment_update(
131132
u64 prob_cost_factor_millionths,
132133
u64 riskfactor_millionths,
133134
u64 min_prob_success_millionths,
135+
u64 base_prob_success_millionths,
134136
bool use_shadow,
135137
const struct route_exclusion **exclusions);
136138

plugins/renepay/payment_info.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ struct payment_info {
6161
double prob_cost_factor;
6262
/* prob. cost = - prob_cost_factor * log prob. */
6363

64+
/* The probability for a channel to be able to forward an amount
65+
* greater than zero. */
66+
double base_prob_success;
67+
6468
/* Penalty for CLTV delays */
6569
double delay_feefactor;
6670

plugins/renepay/routebuilder.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ struct route **get_routes(const tal_t *ctx,
151151
struct route **routes = tal_arr(ctx, struct route *, 0);
152152

153153
double probability_budget = payment_info->min_prob_success;
154+
const double base_probability = payment_info->base_prob_success;
154155
double delay_feefactor = payment_info->delay_feefactor;
155156
const double base_fee_penalty = payment_info->base_fee_penalty;
156157
const double prob_cost_factor = payment_info->prob_cost_factor;
@@ -215,8 +216,11 @@ struct route **get_routes(const tal_t *ctx,
215216
minflow(this_ctx, gossmap, src, dst,
216217
uncertainty_get_chan_extra_map(uncertainty),
217218
disabled_bitmap, amount_to_deliver, feebudget,
218-
probability_budget, delay_feefactor,
219-
base_fee_penalty, prob_cost_factor, &errmsg);
219+
probability_budget,
220+
base_probability,
221+
delay_feefactor,
222+
base_fee_penalty,
223+
prob_cost_factor, &errmsg);
220224
delay_feefactor_updated = false;
221225

222226
if (!flows) {

plugins/renepay/test/run-bottleneck.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ int main(int argc, char *argv[])
202202
AMOUNT_MSAT(100 * 1000 * 1000),
203203
/* max_fee = */ AMOUNT_MSAT(20 * 1000 * 1000),
204204
/* min probability = */ 0.9,
205+
/* base probability = */ 1.0,
205206
/* delay fee factor = */ 1e-6,
206207
/* base fee penalty */ 10,
207208
/* prob cost factor = */ 10, &errmsg);
@@ -239,6 +240,7 @@ int main(int argc, char *argv[])
239240
pinfo.prob_cost_factor = 1e-5;
240241
pinfo.delay_feefactor = 1e-6;
241242
pinfo.min_prob_success = 0.9;
243+
pinfo.base_prob_success = 1.0;
242244
pinfo.use_shadow = false;
243245

244246
randombytes_buf(&preimage, sizeof(preimage));

0 commit comments

Comments
 (0)