mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 18:57:06 +01:00
payalgo: Randomize paths as long as we respect maxfeepercent.
This commit is contained in:
parent
9693843141
commit
61d0b50c54
1 changed files with 40 additions and 10 deletions
|
@ -1,5 +1,6 @@
|
|||
#include "pay.h"
|
||||
#include "payalgo.h"
|
||||
#include <ccan/isaac/isaac64.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <common/bolt11.h>
|
||||
|
@ -9,6 +10,7 @@
|
|||
#include <lightningd/jsonrpc_errors.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/subd.h>
|
||||
#include <sodium/randombytes.h>
|
||||
|
||||
struct pay {
|
||||
/* Parent command. */
|
||||
|
@ -25,8 +27,12 @@ struct pay {
|
|||
double riskfactor;
|
||||
double maxfeepercent;
|
||||
|
||||
/* Number of payment tries */
|
||||
unsigned int tries;
|
||||
/* Number of getroute and sendpay tries */
|
||||
unsigned int getroute_tries;
|
||||
unsigned int sendpay_tries;
|
||||
|
||||
/* Current fuzz we pass into getroute. */
|
||||
double fuzz;
|
||||
|
||||
/* Parent of the current pay attempt. This object is
|
||||
* freed, then allocated at the start of each pay
|
||||
|
@ -37,7 +43,8 @@ struct pay {
|
|||
static void
|
||||
json_pay_success(struct command *cmd,
|
||||
const struct preimage *payment_preimage,
|
||||
unsigned int tries)
|
||||
unsigned int getroute_tries,
|
||||
unsigned int sendpay_tries)
|
||||
{
|
||||
struct json_result *response;
|
||||
|
||||
|
@ -45,7 +52,8 @@ json_pay_success(struct command *cmd,
|
|||
json_object_start(response, NULL);
|
||||
json_add_hex(response, "preimage",
|
||||
payment_preimage, sizeof(*payment_preimage));
|
||||
json_add_num(response, "tries", tries);
|
||||
json_add_num(response, "getroute_tries", getroute_tries);
|
||||
json_add_num(response, "sendpay_tries", sendpay_tries);
|
||||
json_object_end(response);
|
||||
command_success(cmd, response);
|
||||
}
|
||||
|
@ -126,7 +134,8 @@ static void json_pay_sendpay_resolve(const struct sendpay_result *r,
|
|||
|
||||
/* If we succeed, hurray */
|
||||
if (r->succeeded) {
|
||||
json_pay_success(pay->cmd, &r->preimage, pay->tries);
|
||||
json_pay_success(pay->cmd, &r->preimage,
|
||||
pay->getroute_tries, pay->sendpay_tries);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -149,6 +158,7 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
|
|||
u64 msatoshi_sent;
|
||||
u64 fee;
|
||||
double feepercent;
|
||||
bool fee_too_high;
|
||||
struct json_result *data;
|
||||
|
||||
fromwire_gossip_getroute_reply(reply, reply, &route);
|
||||
|
@ -169,7 +179,9 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
|
|||
* and thus losing precision in the below. Currently, OK, as,
|
||||
* payments are limited to 4294967295 msatoshi. */
|
||||
feepercent = ((double) fee) * 100.0 / ((double) pay->msatoshi);
|
||||
if (feepercent > pay->maxfeepercent) {
|
||||
fee_too_high = (feepercent > pay->maxfeepercent);
|
||||
/* compare fuzz to range */
|
||||
if (fee_too_high && pay->fuzz < 0.01) {
|
||||
data = new_json_result(pay);
|
||||
json_object_start(data, NULL);
|
||||
json_add_u64(data, "fee", fee);
|
||||
|
@ -188,6 +200,16 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
|
|||
pay->maxfeepercent);
|
||||
return;
|
||||
}
|
||||
if (fee_too_high) {
|
||||
/* Retry with lower fuzz */
|
||||
pay->fuzz -= 0.15;
|
||||
if (pay->fuzz <= 0.0)
|
||||
pay->fuzz = 0.0;
|
||||
json_pay_try(pay);
|
||||
return;
|
||||
}
|
||||
|
||||
++pay->sendpay_tries;
|
||||
|
||||
send_payment(pay->try_parent,
|
||||
pay->cmd->ld, &pay->payment_hash, route,
|
||||
|
@ -198,6 +220,7 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
|
|||
* false if resolved now. */
|
||||
static bool json_pay_try(struct pay *pay)
|
||||
{
|
||||
u8 *seed;
|
||||
u8 *req;
|
||||
struct command *cmd = pay->cmd;
|
||||
struct timeabs now = time_now();
|
||||
|
@ -215,11 +238,15 @@ static bool json_pay_try(struct pay *pay)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Clear previous sendpay. */
|
||||
/* Clear previous try memory. */
|
||||
pay->try_parent = tal_free(pay->try_parent);
|
||||
pay->try_parent = tal(pay, char);
|
||||
|
||||
++pay->tries;
|
||||
/* Generate random seed */
|
||||
seed = tal_arr(pay->try_parent, u8, ISAAC64_SEED_SZ_MAX);
|
||||
randombytes_buf(seed, tal_len(seed));
|
||||
|
||||
++pay->getroute_tries;
|
||||
|
||||
/* FIXME: use b11->routes */
|
||||
req = towire_gossip_getroute_request(pay->try_parent,
|
||||
|
@ -228,7 +255,8 @@ static bool json_pay_try(struct pay *pay)
|
|||
pay->msatoshi,
|
||||
pay->riskfactor,
|
||||
pay->min_final_cltv_expiry,
|
||||
0, tal_arrz(pay->try_parent, u8, 8));
|
||||
&pay->fuzz,
|
||||
seed);
|
||||
subd_req(pay->try_parent, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay);
|
||||
|
||||
return true;
|
||||
|
@ -326,7 +354,9 @@ static void json_pay(struct command *cmd,
|
|||
}
|
||||
pay->maxfeepercent = maxfeepercent;
|
||||
|
||||
pay->tries = 0;
|
||||
pay->getroute_tries = 0;
|
||||
pay->sendpay_tries = 0;
|
||||
pay->fuzz = 0.75;
|
||||
pay->try_parent = NULL;
|
||||
|
||||
/* Initiate payment */
|
||||
|
|
Loading…
Add table
Reference in a new issue