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
|
||||
.\" Author: [see the "AUTHOR" section]
|
||||
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
||||
.\" Date: 03/16/2018
|
||||
.\" Date: 03/21/2018
|
||||
.\" Manual: \ \&
|
||||
.\" Source: \ \&
|
||||
.\" Language: English
|
||||
.\"
|
||||
.TH "LIGHTNING\-PAY" "7" "03/16/2018" "\ \&" "\ \&"
|
||||
.TH "LIGHTNING\-PAY" "7" "03/21/2018" "\ \&" "\ \&"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * Define some portability stuff
|
||||
.\" -----------------------------------------------------------------
|
||||
|
@ -31,12 +31,12 @@
|
|||
lightning-pay \- Protocol for sending a payment to a BOLT11 invoice
|
||||
.SH "SYNOPSIS"
|
||||
.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"
|
||||
.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\&.
|
||||
.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
|
||||
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
|
||||
|
@ -122,13 +122,19 @@ field of the error will be routing failure object\&.
|
|||
.sp -1
|
||||
.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
|
||||
field of the error will indicate the actual
|
||||
\fIfee\fR
|
||||
as well as the
|
||||
\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
|
||||
.sp
|
||||
.RS 4
|
||||
|
|
|
@ -8,7 +8,7 @@ lightning-pay - Protocol for sending a payment to a BOLT11 invoice
|
|||
|
||||
SYNOPSIS
|
||||
--------
|
||||
*pay* 'bolt11' ['msatoshi'] ['description'] ['riskfactor'] ['maxfeepercent'] ['retry_for']
|
||||
*pay* 'bolt11' ['msatoshi'] ['description'] ['riskfactor'] ['maxfeepercent'] ['retry_for'] ['maxdelay']
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -24,7 +24,7 @@ The `maxfeepercent' is a percentage of the amount that is to be
|
|||
paid.
|
||||
|
||||
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
|
||||
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
|
||||
the error will be routing failure object.
|
||||
* 205. Unable to find a route.
|
||||
* 206. Route too expensive. 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.
|
||||
* 206. Route too expensive.
|
||||
Either the fee or the needed total locktime for the route
|
||||
exceeds your 'maxfeepercent' or 'maxdelay' settings,
|
||||
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,
|
||||
or already expired at the time you initiated payment.
|
||||
The 'data' field of the error indicates 'now' (the current time)
|
||||
|
|
|
@ -104,6 +104,7 @@ struct pay {
|
|||
u64 msatoshi;
|
||||
double riskfactor;
|
||||
double maxfeepercent;
|
||||
u32 maxdelay;
|
||||
|
||||
/* Number of getroute and sendpay tries */
|
||||
unsigned int getroute_tries;
|
||||
|
@ -407,7 +408,9 @@ static void json_pay_getroute_reply(struct subd *gossip UNUSED,
|
|||
u64 fee;
|
||||
double feepercent;
|
||||
bool fee_too_high;
|
||||
bool delay_too_high;
|
||||
struct json_result *data;
|
||||
char const *err;
|
||||
|
||||
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. */
|
||||
feepercent = ((double) fee) * 100.0 / ((double) pay->msatoshi);
|
||||
fee_too_high = (feepercent > pay->maxfeepercent);
|
||||
delay_too_high = (route[0].delay > pay->maxdelay);
|
||||
/* 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);
|
||||
json_object_start(data, NULL);
|
||||
json_add_u64(data, "msatoshi", pay->msatoshi);
|
||||
json_add_u64(data, "fee", fee);
|
||||
json_add_double(data, "feepercent", feepercent);
|
||||
json_add_u64(data, "msatoshi", pay->msatoshi);
|
||||
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, "sendpay_tries", pay->sendpay_tries);
|
||||
json_add_route(data, "route",
|
||||
route, tal_count(route));
|
||||
json_add_failures(data, "failures", &pay->pay_failures);
|
||||
json_object_end(data);
|
||||
|
||||
command_fail_detailed(pay->cmd, PAY_ROUTE_TOO_EXPENSIVE,
|
||||
data,
|
||||
err = "";
|
||||
if (fee_too_high)
|
||||
err = tal_fmt(pay,
|
||||
"Fee %"PRIu64" is %f%% "
|
||||
"of payment %"PRIu64"; "
|
||||
"max fee requested is %f%%",
|
||||
"max fee requested is %f%%.",
|
||||
fee, feepercent,
|
||||
pay->msatoshi,
|
||||
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;
|
||||
}
|
||||
if (fee_too_high) {
|
||||
if (fee_too_high || delay_too_high) {
|
||||
/* Retry with lower fuzz */
|
||||
pay->fuzz -= 0.15;
|
||||
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 *retryfortok;
|
||||
jsmntok_t *maxdelaytok;
|
||||
double riskfactor = 1.0;
|
||||
double maxfeepercent = 0.5;
|
||||
u64 msatoshi;
|
||||
|
@ -582,6 +604,7 @@ static void json_pay(struct command *cmd,
|
|||
struct bolt11 *b11;
|
||||
char *fail, *b11str, *desc;
|
||||
unsigned int retryfor = 60;
|
||||
unsigned int maxdelay = 500;
|
||||
|
||||
if (!json_get_params(cmd, buffer, params,
|
||||
"bolt11", &bolt11tok,
|
||||
|
@ -590,6 +613,7 @@ static void json_pay(struct command *cmd,
|
|||
"?riskfactor", &riskfactortok,
|
||||
"?maxfeepercent", &maxfeetok,
|
||||
"?retry_for", &retryfortok,
|
||||
"?maxdelay", &maxdelaytok,
|
||||
NULL)) {
|
||||
return;
|
||||
}
|
||||
|
@ -672,14 +696,32 @@ static void json_pay(struct command *cmd,
|
|||
}
|
||||
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->sendpay_tries = 0;
|
||||
/* Higher fuzz increases the potential fees we will pay, since
|
||||
* higher fuzz makes it more likely that high-fee paths get
|
||||
* selected. We start with very high fuzz, but if the
|
||||
* returned route is too expensive for the given
|
||||
* `maxfeepercent` we reduce the fuzz. Starting with high
|
||||
* fuzz means, if the user allows high fee, we can take
|
||||
* `maxfeepercent` or `maxdelay` we reduce the fuzz.
|
||||
* Starting with high
|
||||
* fuzz means, if the user allows high fee/locktime, we can take
|
||||
* advantage of that to increase randomization and
|
||||
* improve privacy somewhat. */
|
||||
pay->fuzz = 0.75;
|
||||
|
|
Loading…
Add table
Reference in a new issue