diff --git a/lightningd/payalgo.c b/lightningd/payalgo.c index d5d47c63dd63..c421c0b3cef5 100644 --- a/lightningd/payalgo.c +++ b/lightningd/payalgo.c @@ -1,5 +1,6 @@ #include "pay.h" #include "payalgo.h" +#include #include #include #include @@ -9,6 +10,7 @@ #include #include #include +#include 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 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 @@ -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; } @@ -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); @@ -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); @@ -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, @@ -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, @@ -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); } @@ -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 */