2024-08-07 11:19:54 +09:30
|
|
|
#ifndef LIGHTNING_PLUGINS_ASKRENE_MCF_H
|
|
|
|
#define LIGHTNING_PLUGINS_ASKRENE_MCF_H
|
|
|
|
/* Eduardo Quintela's (lagrang3@protonmail.com) Min Cost Flow implementation
|
|
|
|
* from renepay, as modified to fit askrene */
|
|
|
|
#include "config.h"
|
|
|
|
#include <common/amount.h>
|
|
|
|
#include <common/gossmap.h>
|
|
|
|
|
2024-08-07 11:19:55 +09:30
|
|
|
struct route_query;
|
2024-08-07 11:19:54 +09:30
|
|
|
|
|
|
|
/**
|
|
|
|
* optimal_payment_flow - API for min cost flow function(s).
|
|
|
|
* @ctx: context to allocate returned flows from
|
askrene: calculate prob_cost_factor using ratio of typical mainnet channel.
During "test_real_data", then only successes with reduced fees were 92 on "mu=10", and only
1 on "mu=30": the rest went to mu=100 and failed.
I tried numerous approaches, and in the end, opted for the simplest:
The typical range of probability costs looks likes:
min = 0, max = 924196240, mean = 10509.4, stddev = 1.9e+06
The typical range of linear fee costs looks like:
min = 0, max = 101000000, mean = 81894.6, stddev = 2.6e+06
This implies a k factor of 8 makes the two comparable.
This makes the two numbers comparable, and thus makes "mu" much more
effective. Here are the number of different mu values we succeeded at:
87 mu=0
90 mu=10
42 mu=20
24 mu=30
17 mu=40
19 mu=50
19 mu=60
11 mu=70
95 mu=80
19 mu=90
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-10-11 21:30:40 +10:30
|
|
|
* @rq: the route_query we're processing (for logging)
|
2024-08-07 11:19:54 +09:30
|
|
|
* @source: the source to start from
|
|
|
|
* @target: the target to pay
|
|
|
|
* @amount: the amount we want to reach @target
|
2024-08-07 11:19:54 +09:30
|
|
|
* @mu: 0 = corresponds to only probabilities, 100 corresponds to only fee.
|
2024-08-07 11:19:54 +09:30
|
|
|
*
|
|
|
|
* @delay_feefactor converts 1 block delay into msat, as if it were an additional
|
|
|
|
* fee. So if a CLTV delay on a node is 5 blocks, that's treated as if it
|
|
|
|
* were a fee of 5 * @delay_feefactor.
|
|
|
|
*
|
|
|
|
* Return a series of subflows which deliver amount to target, or NULL.
|
|
|
|
*/
|
2024-08-07 11:19:55 +09:30
|
|
|
struct flow **minflow(const tal_t *ctx,
|
|
|
|
const struct route_query *rq,
|
2024-08-07 11:19:54 +09:30
|
|
|
const struct gossmap_node *source,
|
|
|
|
const struct gossmap_node *target,
|
2024-08-07 11:19:54 +09:30
|
|
|
struct amount_msat amount,
|
|
|
|
u32 mu,
|
askrene: fix base fee.
I noticed this in the logs:
plugin-cln-askrene: notify msg unusual: The flows had a fee of 151950msat, greater than max of 53697msat, retrying with mu of 10%...
plugin-cln-askrene: notify msg unusual: The flows had a fee of 220126msat, greater than max of 53697msat, retrying with mu of 20%...
We would expect increasing mu to *reduce* the fee!
Turns out that our linear fee is a bad terrible approximation, because I
was using base_fee_penalty of 10.0.
|
| / __ <- real fee, with base: fee = base + propfee * amount.
| / __/
| _//
| __/
| __/_/
|/ _/
| _/ <- linearized fee: fee = linear * amount
|/
+-----------------------------------
These cross over where linear = propfee + base / amount. Assume we split the
payment into 10 parts, this implies that the base_fee_penalty should be 10 / amount
(this gives a slight penalty to the normal case, but that's ok).
This gives better results, too: we get down to 650099 sats in fees, vs 801613
before.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-10-11 21:30:40 +10:30
|
|
|
double delay_feefactor);
|
2024-10-11 21:30:40 +10:30
|
|
|
|
|
|
|
/* To sanity check: this is the approximation mcf uses for the cost
|
|
|
|
* of each channel. */
|
|
|
|
struct amount_msat linear_flow_cost(const struct flow *flow,
|
|
|
|
struct amount_msat total_amount,
|
|
|
|
double delay_feefactor);
|
|
|
|
|
2024-08-07 11:19:54 +09:30
|
|
|
#endif /* LIGHTNING_PLUGINS_ASKRENE_MCF_H */
|