Skip to content

Commit

Permalink
payalgo: Randomize paths as long as we respect maxfeepercent.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZmnSCPxj committed Feb 16, 2018
1 parent 5099930 commit 7356ce0
Showing 1 changed file with 40 additions and 10 deletions.
50 changes: 40 additions & 10 deletions lightningd/payalgo.c
Original file line number Diff line number Diff line change
@@ -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>
Expand All @@ -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. */
Expand All @@ -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 inefficiency we pass into getroute. */
double inefficiency;

/* Parent of the current pay attempt. This object is
* freed, then allocated at the start of each pay
Expand All @@ -37,15 +43,17 @@ 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;

response = new_json_result(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);
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -156,6 +165,7 @@ static void json_pay_getroute_reply(struct subd *gossip,
u64 msatoshi_sent;
u64 fee;
double feepercent;
bool fee_too_high;
struct json_result *data;

fromwire_gossip_getroute_reply(reply, reply, NULL, &route);
Expand All @@ -176,7 +186,9 @@ static void json_pay_getroute_reply(struct subd *gossip,
* 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 inefficiency to range */
if (fee_too_high && pay->inefficiency < 0.01) {
data = new_json_result(pay);
json_object_start(data, NULL);
json_add_u64(data, "fee", fee);
Expand All @@ -195,6 +207,16 @@ static void json_pay_getroute_reply(struct subd *gossip,
pay->maxfeepercent);
return;
}
if (fee_too_high) {
/* Retry with lower inefficiency */
pay->inefficiency -= 0.15;
if (pay->inefficiency <= 0.0)
pay->inefficiency = 0.0;
json_pay_try(pay);
return;
}

++pay->sendpay_tries;

send_payment(pay->try_parent,
pay->cmd->ld, &pay->payment_hash, route,
Expand All @@ -204,14 +226,19 @@ static void json_pay_getroute_reply(struct subd *gossip,
/* Start a payment attempt */
static void json_pay_try(struct pay *pay)
{
u8 *seed;
u8 *req;
struct command *cmd = pay->cmd;

/* 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,
Expand All @@ -220,7 +247,8 @@ static void json_pay_try(struct pay *pay)
pay->msatoshi,
pay->riskfactor,
pay->min_final_cltv_expiry,
0, tal_arrz(pay->try_parent, u8, 8));
pay->inefficiency,
seed);
subd_req(pay->try_parent, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay);
}

Expand Down Expand Up @@ -316,7 +344,9 @@ static void json_pay(struct command *cmd,
}
pay->maxfeepercent = maxfeepercent;

pay->tries = 0;
pay->getroute_tries = 0;
pay->sendpay_tries = 0;
pay->inefficiency = 0.75;
pay->try_parent = NULL;

/* Initiate payment */
Expand Down

0 comments on commit 7356ce0

Please sign in to comment.