mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 10:46:58 +01:00
parent
1133820ad6
commit
26f7014813
3 changed files with 72 additions and 20 deletions
|
@ -2,12 +2,12 @@
|
||||||
.\" Title: lightning-pay
|
.\" Title: lightning-pay
|
||||||
.\" Author: [see the "AUTHOR" section]
|
.\" Author: [see the "AUTHOR" section]
|
||||||
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
||||||
.\" Date: 03/16/2018
|
.\" Date: 03/21/2018
|
||||||
.\" Manual: \ \&
|
.\" Manual: \ \&
|
||||||
.\" Source: \ \&
|
.\" Source: \ \&
|
||||||
.\" Language: English
|
.\" Language: English
|
||||||
.\"
|
.\"
|
||||||
.TH "LIGHTNING\-PAY" "7" "03/16/2018" "\ \&" "\ \&"
|
.TH "LIGHTNING\-PAY" "7" "03/21/2018" "\ \&" "\ \&"
|
||||||
.\" -----------------------------------------------------------------
|
.\" -----------------------------------------------------------------
|
||||||
.\" * Define some portability stuff
|
.\" * Define some portability stuff
|
||||||
.\" -----------------------------------------------------------------
|
.\" -----------------------------------------------------------------
|
||||||
|
@ -31,12 +31,12 @@
|
||||||
lightning-pay \- Protocol for sending a payment to a BOLT11 invoice
|
lightning-pay \- Protocol for sending a payment to a BOLT11 invoice
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
.sp
|
.sp
|
||||||
\fBpay\fR \fIbolt11\fR [\fImsatoshi\fR] [\fIdescription\fR] [\fIriskfactor\fR] [\fImaxfeepercent\fR] [\fIretry_for\fR]
|
\fBpay\fR \fIbolt11\fR [\fImsatoshi\fR] [\fIdescription\fR] [\fIriskfactor\fR] [\fImaxfeepercent\fR] [\fIretry_for\fR] [\fImaxdelay\fR]
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
.sp
|
.sp
|
||||||
The \fBpay\fR RPC command attempts to find a route to the given destination, and send the funds it asks for\&. If the \fIbolt11\fR does not contain an amount, \fImsatoshi\fR is required, otherwise if it is specified it must be \fInull\fR\&. If \fIbolt11\fR contains a description hash (\fIh\fR field) \fIdescription\fR is required, otherwise it is unused\&. The \fIriskfactor\fR is described in detail in lightning\-getroute(7), and defaults to 1\&.0\&. The \fImaxfeepercent\fR limits the money paid in fees, and defaults to 0\&.5\&. The \(oqmaxfeepercent\(cq is a percentage of the amount that is to be paid\&.
|
The \fBpay\fR RPC command attempts to find a route to the given destination, and send the funds it asks for\&. If the \fIbolt11\fR does not contain an amount, \fImsatoshi\fR is required, otherwise if it is specified it must be \fInull\fR\&. If \fIbolt11\fR contains a description hash (\fIh\fR field) \fIdescription\fR is required, otherwise it is unused\&. The \fIriskfactor\fR is described in detail in lightning\-getroute(7), and defaults to 1\&.0\&. The \fImaxfeepercent\fR limits the money paid in fees, and defaults to 0\&.5\&. The \(oqmaxfeepercent\(cq is a percentage of the amount that is to be paid\&.
|
||||||
.sp
|
.sp
|
||||||
The \fBpay\fR RPC command will randomize routes slightly, as long as the route achieves the targeted \fImaxfeepercent\fR\&.
|
The \fBpay\fR RPC command will randomize routes slightly, as long as the route achieves the targeted \fImaxfeepercent\fR and \fImaxdelay\fR\&.
|
||||||
.sp
|
.sp
|
||||||
The response will occur when the payment fails or succeeds\&. Once a payment has succeeded, calls to \fBpay\fR with the same \fIbolt11\fR will succeed immediately\&.
|
The response will occur when the payment fails or succeeds\&. Once a payment has succeeded, calls to \fBpay\fR with the same \fIbolt11\fR will succeed immediately\&.
|
||||||
.sp
|
.sp
|
||||||
|
@ -122,13 +122,19 @@ field of the error will be routing failure object\&.
|
||||||
.sp -1
|
.sp -1
|
||||||
.IP \(bu 2.3
|
.IP \(bu 2.3
|
||||||
.\}
|
.\}
|
||||||
206\&. Route too expensive\&. The
|
206\&. Route too expensive\&. Either the fee or the needed total locktime for the route exceeds your
|
||||||
|
\fImaxfeepercent\fR
|
||||||
|
or
|
||||||
|
\fImaxdelay\fR
|
||||||
|
settings, respectively\&. The
|
||||||
\fIdata\fR
|
\fIdata\fR
|
||||||
field of the error will indicate the actual
|
field of the error will indicate the actual
|
||||||
\fIfee\fR
|
\fIfee\fR
|
||||||
as well as the
|
as well as the
|
||||||
\fIfeepercent\fR
|
\fIfeepercent\fR
|
||||||
percentage that the fee has of the destination payment amount\&.
|
percentage that the fee has of the destination payment amount\&. It will also indicate the actual
|
||||||
|
\fIdelay\fR
|
||||||
|
along the route\&.
|
||||||
.RE
|
.RE
|
||||||
.sp
|
.sp
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|
|
@ -8,7 +8,7 @@ lightning-pay - Protocol for sending a payment to a BOLT11 invoice
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
*pay* 'bolt11' ['msatoshi'] ['description'] ['riskfactor'] ['maxfeepercent'] ['retry_for']
|
*pay* 'bolt11' ['msatoshi'] ['description'] ['riskfactor'] ['maxfeepercent'] ['retry_for'] ['maxdelay']
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
@ -24,7 +24,7 @@ The `maxfeepercent' is a percentage of the amount that is to be
|
||||||
paid.
|
paid.
|
||||||
|
|
||||||
The *pay* RPC command will randomize routes slightly, as long as the
|
The *pay* RPC command will randomize routes slightly, as long as the
|
||||||
route achieves the targeted 'maxfeepercent'.
|
route achieves the targeted 'maxfeepercent' and 'maxdelay'.
|
||||||
|
|
||||||
The response will occur when the payment fails or succeeds. Once a
|
The response will occur when the payment fails or succeeds. Once a
|
||||||
payment has succeeded, calls to *pay* with the same 'bolt11' will
|
payment has succeeded, calls to *pay* with the same 'bolt11' will
|
||||||
|
@ -65,10 +65,14 @@ The following error codes may occur:
|
||||||
* 203. Permanent failure at destination. The 'data' field of
|
* 203. Permanent failure at destination. The 'data' field of
|
||||||
the error will be routing failure object.
|
the error will be routing failure object.
|
||||||
* 205. Unable to find a route.
|
* 205. Unable to find a route.
|
||||||
* 206. Route too expensive. The 'data' field of the error will
|
* 206. Route too expensive.
|
||||||
indicate the actual 'fee' as well as the 'feepercent'
|
Either the fee or the needed total locktime for the route
|
||||||
percentage that the fee has of the destination payment
|
exceeds your 'maxfeepercent' or 'maxdelay' settings,
|
||||||
amount.
|
respectively.
|
||||||
|
The 'data' field of the error will indicate the actual 'fee'
|
||||||
|
as well as the 'feepercent' percentage that the fee has of the
|
||||||
|
destination payment amount.
|
||||||
|
It will also indicate the actual 'delay' along the route.
|
||||||
* 207. Invoice expired. Payment took too long before expiration,
|
* 207. Invoice expired. Payment took too long before expiration,
|
||||||
or already expired at the time you initiated payment.
|
or already expired at the time you initiated payment.
|
||||||
The 'data' field of the error indicates 'now' (the current time)
|
The 'data' field of the error indicates 'now' (the current time)
|
||||||
|
|
|
@ -104,6 +104,7 @@ struct pay {
|
||||||
u64 msatoshi;
|
u64 msatoshi;
|
||||||
double riskfactor;
|
double riskfactor;
|
||||||
double maxfeepercent;
|
double maxfeepercent;
|
||||||
|
u32 maxdelay;
|
||||||
|
|
||||||
/* Number of getroute and sendpay tries */
|
/* Number of getroute and sendpay tries */
|
||||||
unsigned int getroute_tries;
|
unsigned int getroute_tries;
|
||||||
|
@ -407,7 +408,9 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
|
||||||
u64 fee;
|
u64 fee;
|
||||||
double feepercent;
|
double feepercent;
|
||||||
bool fee_too_high;
|
bool fee_too_high;
|
||||||
|
bool delay_too_high;
|
||||||
struct json_result *data;
|
struct json_result *data;
|
||||||
|
char const *err;
|
||||||
|
|
||||||
fromwire_gossip_getroute_reply(reply, reply, &route);
|
fromwire_gossip_getroute_reply(reply, reply, &route);
|
||||||
|
|
||||||
|
@ -434,30 +437,48 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
|
||||||
* payments are limited to 4294967295 msatoshi. */
|
* payments are limited to 4294967295 msatoshi. */
|
||||||
feepercent = ((double) fee) * 100.0 / ((double) pay->msatoshi);
|
feepercent = ((double) fee) * 100.0 / ((double) pay->msatoshi);
|
||||||
fee_too_high = (feepercent > pay->maxfeepercent);
|
fee_too_high = (feepercent > pay->maxfeepercent);
|
||||||
|
delay_too_high = (route[0].delay > pay->maxdelay);
|
||||||
/* compare fuzz to range */
|
/* compare fuzz to range */
|
||||||
if (fee_too_high && pay->fuzz < 0.01) {
|
if ((fee_too_high || delay_too_high) && pay->fuzz < 0.01) {
|
||||||
data = new_json_result(pay);
|
data = new_json_result(pay);
|
||||||
json_object_start(data, NULL);
|
json_object_start(data, NULL);
|
||||||
|
json_add_u64(data, "msatoshi", pay->msatoshi);
|
||||||
json_add_u64(data, "fee", fee);
|
json_add_u64(data, "fee", fee);
|
||||||
json_add_double(data, "feepercent", feepercent);
|
json_add_double(data, "feepercent", feepercent);
|
||||||
json_add_u64(data, "msatoshi", pay->msatoshi);
|
|
||||||
json_add_double(data, "maxfeepercent", pay->maxfeepercent);
|
json_add_double(data, "maxfeepercent", pay->maxfeepercent);
|
||||||
|
json_add_u64(data, "delay", (u64) route[0].delay);
|
||||||
|
json_add_num(data, "maxdelay", pay->maxdelay);
|
||||||
json_add_num(data, "getroute_tries", pay->getroute_tries);
|
json_add_num(data, "getroute_tries", pay->getroute_tries);
|
||||||
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
|
json_add_num(data, "sendpay_tries", pay->sendpay_tries);
|
||||||
|
json_add_route(data, "route",
|
||||||
|
route, tal_count(route));
|
||||||
json_add_failures(data, "failures", &pay->pay_failures);
|
json_add_failures(data, "failures", &pay->pay_failures);
|
||||||
json_object_end(data);
|
json_object_end(data);
|
||||||
|
|
||||||
command_fail_detailed(pay->cmd, PAY_ROUTE_TOO_EXPENSIVE,
|
err = "";
|
||||||
data,
|
if (fee_too_high)
|
||||||
|
err = tal_fmt(pay,
|
||||||
"Fee %"PRIu64" is %f%% "
|
"Fee %"PRIu64" is %f%% "
|
||||||
"of payment %"PRIu64"; "
|
"of payment %"PRIu64"; "
|
||||||
"max fee requested is %f%%",
|
"max fee requested is %f%%.",
|
||||||
fee, feepercent,
|
fee, feepercent,
|
||||||
pay->msatoshi,
|
pay->msatoshi,
|
||||||
pay->maxfeepercent);
|
pay->maxfeepercent);
|
||||||
|
if (fee_too_high && delay_too_high)
|
||||||
|
err = tal_fmt(pay, "%s ", err);
|
||||||
|
if (delay_too_high)
|
||||||
|
err = tal_fmt(pay,
|
||||||
|
"%s"
|
||||||
|
"Delay (locktime) is %"PRIu32" blocks; "
|
||||||
|
"max delay requested is %u.",
|
||||||
|
err, route[0].delay, pay->maxdelay);
|
||||||
|
|
||||||
|
|
||||||
|
command_fail_detailed(pay->cmd, PAY_ROUTE_TOO_EXPENSIVE,
|
||||||
|
data, "%s", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fee_too_high) {
|
if (fee_too_high || delay_too_high) {
|
||||||
/* Retry with lower fuzz */
|
/* Retry with lower fuzz */
|
||||||
pay->fuzz -= 0.15;
|
pay->fuzz -= 0.15;
|
||||||
if (pay->fuzz <= 0.0)
|
if (pay->fuzz <= 0.0)
|
||||||
|
@ -575,6 +596,7 @@ static void json_pay(struct command *cmd,
|
||||||
{
|
{
|
||||||
jsmntok_t *bolt11tok, *msatoshitok, *desctok, *riskfactortok, *maxfeetok;
|
jsmntok_t *bolt11tok, *msatoshitok, *desctok, *riskfactortok, *maxfeetok;
|
||||||
jsmntok_t *retryfortok;
|
jsmntok_t *retryfortok;
|
||||||
|
jsmntok_t *maxdelaytok;
|
||||||
double riskfactor = 1.0;
|
double riskfactor = 1.0;
|
||||||
double maxfeepercent = 0.5;
|
double maxfeepercent = 0.5;
|
||||||
u64 msatoshi;
|
u64 msatoshi;
|
||||||
|
@ -582,6 +604,7 @@ static void json_pay(struct command *cmd,
|
||||||
struct bolt11 *b11;
|
struct bolt11 *b11;
|
||||||
char *fail, *b11str, *desc;
|
char *fail, *b11str, *desc;
|
||||||
unsigned int retryfor = 60;
|
unsigned int retryfor = 60;
|
||||||
|
unsigned int maxdelay = 500;
|
||||||
|
|
||||||
if (!json_get_params(cmd, buffer, params,
|
if (!json_get_params(cmd, buffer, params,
|
||||||
"bolt11", &bolt11tok,
|
"bolt11", &bolt11tok,
|
||||||
|
@ -590,6 +613,7 @@ static void json_pay(struct command *cmd,
|
||||||
"?riskfactor", &riskfactortok,
|
"?riskfactor", &riskfactortok,
|
||||||
"?maxfeepercent", &maxfeetok,
|
"?maxfeepercent", &maxfeetok,
|
||||||
"?retry_for", &retryfortok,
|
"?retry_for", &retryfortok,
|
||||||
|
"?maxdelay", &maxdelaytok,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -672,14 +696,32 @@ static void json_pay(struct command *cmd,
|
||||||
}
|
}
|
||||||
pay->maxfeepercent = maxfeepercent;
|
pay->maxfeepercent = maxfeepercent;
|
||||||
|
|
||||||
|
if (maxdelaytok
|
||||||
|
&& !json_tok_number(buffer, maxdelaytok, &maxdelay)) {
|
||||||
|
command_fail(cmd, "'%.*s' is not a valid double",
|
||||||
|
maxdelaytok->end - maxdelaytok->start,
|
||||||
|
buffer + maxdelaytok->start);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (maxdelay < pay->min_final_cltv_expiry) {
|
||||||
|
command_fail(cmd,
|
||||||
|
"maxdelay (%u) must be greater than "
|
||||||
|
"min_final_cltv_expiry (%"PRIu32") of "
|
||||||
|
"invoice",
|
||||||
|
maxdelay, pay->min_final_cltv_expiry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pay->maxdelay = maxdelay;
|
||||||
|
|
||||||
pay->getroute_tries = 0;
|
pay->getroute_tries = 0;
|
||||||
pay->sendpay_tries = 0;
|
pay->sendpay_tries = 0;
|
||||||
/* Higher fuzz increases the potential fees we will pay, since
|
/* Higher fuzz increases the potential fees we will pay, since
|
||||||
* higher fuzz makes it more likely that high-fee paths get
|
* higher fuzz makes it more likely that high-fee paths get
|
||||||
* selected. We start with very high fuzz, but if the
|
* selected. We start with very high fuzz, but if the
|
||||||
* returned route is too expensive for the given
|
* returned route is too expensive for the given
|
||||||
* `maxfeepercent` we reduce the fuzz. Starting with high
|
* `maxfeepercent` or `maxdelay` we reduce the fuzz.
|
||||||
* fuzz means, if the user allows high fee, we can take
|
* Starting with high
|
||||||
|
* fuzz means, if the user allows high fee/locktime, we can take
|
||||||
* advantage of that to increase randomization and
|
* advantage of that to increase randomization and
|
||||||
* improve privacy somewhat. */
|
* improve privacy somewhat. */
|
||||||
pay->fuzz = 0.75;
|
pay->fuzz = 0.75;
|
||||||
|
|
Loading…
Add table
Reference in a new issue