diff --git a/CHANGELOG.md b/CHANGELOG.md index 06bdb7472..11a57394d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - plugins: fully enabled, and ready for you to write some! +- plugins: `pay` is now a plugin. - lightning-cli: `help ` finds man pages even if `make install` not run. - JSON API: `waitsendpay` now has an `erring_direction` field. - JSON API: `listpeers` now has a `direction` field in `channels`. - JSON API: `listchannels` now takes a `source` option to filter by node id. +- JSON API: New command `paystatus` gives detailed information on `pay` commands. ### Changed diff --git a/contrib/pylightning/lightning/lightning.py b/contrib/pylightning/lightning/lightning.py index 209168513..9031e8db4 100644 --- a/contrib/pylightning/lightning/lightning.py +++ b/contrib/pylightning/lightning/lightning.py @@ -329,7 +329,7 @@ class LightningRpc(UnixDomainSocketRpc): "description": description, "riskfactor": riskfactor } - return self.call("pay2", payload) + return self.call("pay", payload) def listpayments(self, bolt11=None, payment_hash=None): """ diff --git a/lightningd/Makefile b/lightningd/Makefile index 78cb497a9..a02438f84 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -79,7 +79,6 @@ LIGHTNINGD_SRC := \ lightningd/opening_control.c \ lightningd/options.c \ lightningd/pay.c \ - lightningd/payalgo.c \ lightningd/peer_control.c \ lightningd/peer_htlcs.c \ lightningd/ping.c \ diff --git a/lightningd/payalgo.c b/lightningd/payalgo.c deleted file mode 100644 index e00936b82..000000000 --- a/lightningd/payalgo.c +++ /dev/null @@ -1,702 +0,0 @@ -#include "pay.h" -#include "payalgo.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Record of failures. */ -enum pay_failure_type { - FAIL_UNPARSEABLE_ONION, - FAIL_PAYMENT_REPLY -}; -/* A payment failure. */ -struct pay_failure { - /* Part of pay_failures list of struct pay */ - struct list_node list; - /* The type of payment failure */ - enum pay_failure_type type; - /* A tal_arr of route hops, whose parent is - * this struct */ - struct route_hop *route; - /* The raw onion reply, if TYPE_UNPARSEABLE_ONION, a - * tal_arr whose parent is this struct */ - const u8 *onionreply; - /* The routing failure, if TYPE_PAYMENT_REPLY, a tal - * object whose parent is this struct */ - struct routing_failure *routing_failure; - /* The detail of the routing failure. A tal_arr - * string whose parent is this struct. */ - char *details; -}; - -/* Output a pay failure */ -static void -json_add_failure(struct json_stream *r, char const *n, - const struct pay_failure *f) -{ - struct routing_failure *rf; - json_object_start(r, n); - json_add_string(r, "message", f->details); - switch (f->type) { - case FAIL_UNPARSEABLE_ONION: - json_add_string(r, "type", "FAIL_UNPARSEABLE_ONION"); - json_add_hex_talarr(r, "onionreply", f->onionreply); - break; - - case FAIL_PAYMENT_REPLY: - rf = f->routing_failure; - json_add_string(r, "type", "FAIL_PAYMENT_REPLY"); - json_add_num(r, "erring_index", rf->erring_index); - json_add_num(r, "failcode", (unsigned) rf->failcode); - json_add_pubkey(r, "erring_node", &rf->erring_node); - json_add_short_channel_id(r, "erring_channel", - &rf->erring_channel); - if (rf->channel_update) - json_add_hex_talarr(r, "channel_update", - rf->channel_update); - break; - } - json_add_route(r, "route", f->route, tal_count(f->route)); - json_object_end(r); -} - -/* Output an array of payment failures. */ -static void -json_add_failures(struct json_stream *r, char const *n, - const struct list_head *fs) -{ - struct pay_failure *f; - json_array_start(r, n); - list_for_each(fs, f, list) { - json_add_failure(r, NULL, f); - } - json_array_end(r); -} - -/* Pay command */ -struct pay { - /* Parent command. */ - struct command *cmd; - - /* Bolt11 details */ - struct sha256 payment_hash; - struct pubkey receiver_id; - struct timeabs expiry; - u32 min_final_cltv_expiry; - - /* Command details */ - u64 msatoshi; - double riskfactor; - double maxfeepercent; - u32 maxdelay; - - /* 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 - * attempt to ensure no leaks across long pay attempts */ - char *try_parent; - - /* Current route being attempted. */ - struct route_hop *route; - - /* List of failures to pay. */ - struct list_head pay_failures; - - /* Whether we are attempting payment or not. */ - bool in_sendpay; - - /* Maximum fee that is exempted from the maxfeepercent computation. This - * is mainly useful for tiny transfers for which the leveraged fee would - * be dominated by the forwarding fee. */ - u64 exemptfee; - - /* The description from the bolt11 string */ - const char *description; -}; - -static struct routing_failure * -dup_routing_failure(const tal_t *ctx, const struct routing_failure *fail) -{ - struct routing_failure *nobj = tal(ctx, struct routing_failure); - - nobj->erring_index = fail->erring_index; - nobj->failcode = fail->failcode; - nobj->erring_node = fail->erring_node; - nobj->erring_channel = fail->erring_channel; - if (fail->channel_update) - nobj->channel_update = tal_dup_arr(nobj, u8, - fail->channel_update, - tal_count(fail->channel_update), - 0); - else - nobj->channel_update = NULL; - - return nobj; -} - -/* Add a pay_failure from a sendpay_result */ -static void -add_pay_failure(struct pay *pay, - const struct sendpay_result *r) -{ - struct pay_failure *f = tal(pay, struct pay_failure); - - /* Append to tail */ - list_add_tail(&pay->pay_failures, &f->list); - - switch (r->errorcode) { - case PAY_UNPARSEABLE_ONION: - f->type = FAIL_UNPARSEABLE_ONION; - f->onionreply = tal_dup_arr(f, u8, r->onionreply, - tal_count(r->onionreply), 0); - break; - - case PAY_TRY_OTHER_ROUTE: - f->type = FAIL_PAYMENT_REPLY; - f->routing_failure = dup_routing_failure(f, - r->routing_failure); - break; - - /* All other errors are disallowed */ - default: - abort(); - } - f->details = tal_strdup(f, r->details); - /* Grab the route */ - f->route = tal_steal(f, pay->route); - pay->route = NULL; -} - -static void -json_pay_success(struct pay *pay, - const struct sendpay_result *r) -{ - struct command *cmd = pay->cmd; - struct json_stream *response; - - response = json_stream_success(cmd); - json_object_start(response, NULL); - json_add_payment_fields(response, r->payment); - json_add_num(response, "getroute_tries", pay->getroute_tries); - json_add_num(response, "sendpay_tries", pay->sendpay_tries); - json_add_route(response, "route", - pay->route, tal_count(pay->route)); - json_add_failures(response, "failures", &pay->pay_failures); - json_object_end(response); - was_pending(command_success(cmd, response)); -} - -static void json_pay_failure(struct pay *pay, - const struct sendpay_result *r) -{ - struct json_stream *data; - struct routing_failure *fail; - - assert(!r->succeeded); - - switch (r->errorcode) { - case PAY_IN_PROGRESS: - data = json_stream_fail(pay->cmd, r->errorcode, r->details); - json_object_start(data, NULL); - json_add_num(data, "getroute_tries", pay->getroute_tries); - json_add_num(data, "sendpay_tries", pay->sendpay_tries); - json_add_payment_fields(data, r->payment); - json_add_failures(data, "failures", &pay->pay_failures); - json_object_end(data); - was_pending(command_failed(pay->cmd, data)); - return; - - case PAY_RHASH_ALREADY_USED: - case PAY_STOPPED_RETRYING: - data = json_stream_fail(pay->cmd, r->errorcode, r->details); - json_object_start(data, NULL); - json_add_num(data, "getroute_tries", pay->getroute_tries); - json_add_num(data, "sendpay_tries", pay->sendpay_tries); - json_add_failures(data, "failures", &pay->pay_failures); - json_object_end(data); - was_pending(command_failed(pay->cmd, data)); - return; - - case PAY_UNPARSEABLE_ONION: - /* Impossible case */ - abort(); - - case PAY_DESTINATION_PERM_FAIL: - fail = r->routing_failure; - assert(r->details != NULL); - - data = json_stream_fail(pay->cmd, - r->errorcode, - tal_fmt(tmpctx, "failed: %s (%s)", - onion_type_name(fail->failcode), - r->details)); - json_object_start(data, NULL); - json_add_num(data, "erring_index", - fail->erring_index); - json_add_num(data, "failcode", - (unsigned) fail->failcode); - json_add_pubkey(data, "erring_node", &fail->erring_node); - json_add_short_channel_id(data, "erring_channel", - &fail->erring_channel); - if (fail->channel_update) - json_add_hex_talarr(data, "channel_update", - fail->channel_update); - json_add_failures(data, "failures", &pay->pay_failures); - json_object_end(data); - was_pending(command_failed(pay->cmd, data)); - return; - - case PAY_TRY_OTHER_ROUTE: - /* Impossible case */ - abort(); - return; - } - abort(); -} - -/* Determine if we should delay before retrying. Return a reason - * string, or NULL if we will not retry */ -static const char *should_delay_retry(const tal_t *ctx, - const struct sendpay_result *r) -{ - /* The routing failures WIRE_EXPIRY_TOO_FAR, WIRE_EXPIRY_TOO_SOON, - * and WIRE_FINAL_EXPIRY_TOO_SOON may arise due to disagreement - * between the peers about what the block heights are. So - * delay for those before retrying. */ - if (!r->succeeded && r->errorcode == PAY_TRY_OTHER_ROUTE) { - switch (r->routing_failure->failcode) { - case WIRE_EXPIRY_TOO_FAR: - case WIRE_EXPIRY_TOO_SOON: - case WIRE_FINAL_EXPIRY_TOO_SOON: - return tal_fmt(ctx, - "Possible blockheight disagreement " - "(%s from peer)", - onion_type_name(r->routing_failure->failcode)); - - default: - /* Do nothing */ ; - } - } - - return NULL; -} - -/* Start a payment attempt. */ -static struct command_result *json_pay_try(struct pay *pay); - -/* Used when delaying. */ -static void do_pay_try(struct pay *pay) -{ - log_info(pay->cmd->ld->log, "pay(%p): Try another route", pay); - json_pay_try(pay); -} - -/* Call when sendpay returns to us. */ -static void json_pay_sendpay_resolve(const struct sendpay_result *r, - void *vpay) -{ - struct pay *pay = (struct pay *) vpay; - char const *why; - - pay->in_sendpay = false; - - /* If we succeed, hurray */ - if (r->succeeded) { - log_info(pay->cmd->ld->log, "pay(%p): Success", pay); - json_pay_success(pay, r); - return; - } - - /* We can retry only if it is one of the retryable errors - * below. If it is not, fail now. */ - if (r->errorcode != PAY_UNPARSEABLE_ONION && - r->errorcode != PAY_TRY_OTHER_ROUTE) { - log_info(pay->cmd->ld->log, "pay(%p): Failed, reporting to caller", pay); - json_pay_failure(pay, r); - return; - } - - add_pay_failure(pay, r); - - /* Should retry here, question is whether to retry now or later */ - - why = should_delay_retry(pay->try_parent, r); - if (why) { - /* We have some reason to delay retrying. */ - - log_info(pay->cmd->ld->log, - "pay(%p): Delay before retry: %s", pay, why); - - /* Clear previous try memory. */ - pay->try_parent = tal_free(pay->try_parent); - pay->try_parent = tal(pay, char); - - /* Delay for 3 seconds if needed. FIXME: random - * exponential backoff */ - new_reltimer(&pay->cmd->ld->timers, pay->try_parent, - time_from_sec(3), - &do_pay_try, pay); - } else - do_pay_try(pay); -} - -/* Generates a string describing the route. Route should be a - * tal_arr */ -static char const *stringify_route(const tal_t *ctx, struct route_hop *route) -{ - size_t i; - char *rv = tal_strdup(ctx, "us"); - for (i = 0; i < tal_count(route); ++i) - tal_append_fmt(&rv, " -> %s (%"PRIu64"msat, %"PRIu32"blk) -> %s", - type_to_string(ctx, struct short_channel_id, &route[i].channel_id), - route[i].amount, route[i].delay, - type_to_string(ctx, struct pubkey, &route[i].nodeid)); - return rv; -} - -static void log_route(struct pay *pay, struct route_hop *route) -{ - log_info(pay->cmd->ld->log, "pay(%p): sendpay via route: %s", - pay, stringify_route(tmpctx, route)); -} - -static void json_pay_sendpay_resume(const struct sendpay_result *r, - void *vpay) -{ - struct pay *pay = (struct pay *) vpay; - bool completed = r->succeeded || r->errorcode != PAY_IN_PROGRESS; - - if (completed) - /* Already completed. */ - json_pay_sendpay_resolve(r, pay); - else { - /* Clear previous try memory. */ - pay->try_parent = tal_free(pay->try_parent); - pay->try_parent = tal(pay, char); - - /* Not yet complete? Wait for it. */ - wait_payment(pay->try_parent, pay->cmd->ld, &pay->payment_hash, - json_pay_sendpay_resolve, pay); - } -} - -static void json_pay_getroute_reply(struct subd *gossip UNUSED, - const u8 *reply, const int *fds UNUSED, - struct pay *pay) -{ - struct route_hop *route; - u64 msatoshi_sent; - u64 fee; - double feepercent; - bool fee_too_high; - bool delay_too_high; - struct json_stream *data; - char const *err; - - fromwire_gossip_getroute_reply(reply, reply, &route); - - if (tal_count(route) == 0) { - data = json_stream_fail(pay->cmd, PAY_ROUTE_NOT_FOUND, - "Could not find a route"); - json_object_start(data, NULL); - json_add_num(data, "getroute_tries", pay->getroute_tries); - json_add_num(data, "sendpay_tries", pay->sendpay_tries); - json_add_failures(data, "failures", &pay->pay_failures); - json_object_end(data); - was_pending(command_failed(pay->cmd, data)); - return; - } - - msatoshi_sent = route[0].amount; - fee = msatoshi_sent - pay->msatoshi; - /* Casting u64 to double will lose some precision. The loss of precision - * in feepercent will be like 3.0000..(some dots)..1 % - 3.0 %. - * That loss will not be representable in double. So, it's Okay to - * cast u64 to double for feepercent calculation. */ - feepercent = ((double) fee) * 100.0 / ((double) pay->msatoshi); - fee_too_high = (fee > pay->exemptfee && feepercent > pay->maxfeepercent); - delay_too_high = (route[0].delay > pay->maxdelay); - /* compare fuzz to range */ - if ((fee_too_high || delay_too_high) && pay->fuzz < 0.01) { - err = ""; - if (fee_too_high) - err = tal_fmt(pay, - "Fee %"PRIu64" is %f%% " - "of payment %"PRIu64"; " - "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); - - data = json_stream_fail(pay->cmd, PAY_ROUTE_TOO_EXPENSIVE, err); - 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_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); - - was_pending(command_failed(pay->cmd, data)); - return; - } - if (fee_too_high || delay_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; - - log_route(pay, route); - assert(!pay->route); - pay->route = tal_dup_arr(pay, struct route_hop, route, - tal_count(route), 0); - - pay->in_sendpay = true; - send_payment(pay->try_parent, - pay->cmd->ld, &pay->payment_hash, route, - pay->msatoshi, - pay->description, - &json_pay_sendpay_resume, pay); -} - -/* Start a payment attempt. Return NULL if deferred, otherwise - * command_failed(). */ -static struct command_result *json_pay_try(struct pay *pay) -{ - u8 *req; - struct command *cmd = pay->cmd; - struct timeabs now = time_now(); - u64 maxoverpayment; - u64 overpayment; - - /* If too late anyway, fail now. */ - if (time_after(now, pay->expiry)) { - struct json_stream *data - = json_stream_fail(cmd, PAY_INVOICE_EXPIRED, - "Invoice expired"); - json_object_start(data, NULL); - json_add_num(data, "now", now.ts.tv_sec); - json_add_num(data, "expiry", pay->expiry.ts.tv_sec); - json_add_num(data, "getroute_tries", pay->getroute_tries); - json_add_num(data, "sendpay_tries", pay->sendpay_tries); - json_add_failures(data, "failures", &pay->pay_failures); - json_object_end(data); - return command_failed(cmd, data); - } - - /* Clear previous try memory. */ - pay->try_parent = tal_free(pay->try_parent); - pay->try_parent = tal(pay, char); - - /* Clear route */ - pay->route = tal_free(pay->route); - - /* Generate an overpayment, from fuzz * maxfee. */ - /* Now normally the use of double for money is very bad. - * Note however that a later stage will ensure that - * we do not end up paying more than maxfeepercent - * of the msatoshi we intend to pay. */ - maxoverpayment = ((double) pay->msatoshi * pay->fuzz * pay->maxfeepercent) - / 100.0; - if (maxoverpayment > 0) { - /* We will never generate the maximum computed - * overpayment this way. Maybe OK for most - * purposes. */ - overpayment = pseudorand(maxoverpayment); - } else - overpayment = 0; - - ++pay->getroute_tries; - - /* FIXME: use b11->routes */ - req = towire_gossip_getroute_request(pay->try_parent, - &cmd->ld->id, - &pay->receiver_id, - pay->msatoshi + overpayment, - pay->riskfactor, - pay->min_final_cltv_expiry, - &pay->fuzz, NULL, - ROUTING_MAX_HOPS); - subd_req(pay->try_parent, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay); - - return NULL; -} - -static void json_pay_stop_retrying(struct pay *pay) -{ - struct sendpay_result *sr; - - sr = tal(pay, struct sendpay_result); - sr->succeeded = false; - if (pay->in_sendpay) { - /* Still in sendpay. Return with PAY_IN_PROGRESS */ - sr->errorcode = PAY_IN_PROGRESS; - sr->payment = wallet_payment_by_hash(sr, - pay->cmd->ld->wallet, - &pay->payment_hash); - sr->details = "Stopped retrying during payment attempt; " - "continue monitoring with " - "pay or listpayments"; - } else { - /* Outside sendpay, no ongoing payment */ - sr->errorcode = PAY_STOPPED_RETRYING; - sr->details = "Stopped retrying, no ongoing payment"; - } - json_pay_failure(pay, sr); -} - -static struct command_result *json_pay(struct command *cmd, - const char *buffer, - const jsmntok_t *obj UNNEEDED, - const jsmntok_t *params) -{ - double *riskfactor; - double *maxfeepercent; - u64 *msatoshi; - struct pay *pay = tal(cmd, struct pay); - struct bolt11 *b11; - const char *b11str, *desc; - char *fail; - unsigned int *retryfor; - unsigned int *maxdelay; - unsigned int *exemptfee; - struct command_result *res; - - if (!param(cmd, buffer, params, - p_req("bolt11", param_string, &b11str), - p_opt("msatoshi", param_u64, &msatoshi), - p_opt("description", param_string, &desc), - p_opt_def("riskfactor", param_double, &riskfactor, 1.0), - p_opt_def("maxfeepercent", param_percent, &maxfeepercent, 0.5), - p_opt_def("retry_for", param_number, &retryfor, 60), - p_opt_def("maxdelay", param_number, &maxdelay, - cmd->ld->config.locktime_max), - p_opt_def("exemptfee", param_number, &exemptfee, 5000), - NULL)) - return command_param_failed(); - - b11 = bolt11_decode(pay, b11str, desc, &fail); - if (!b11) { - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "Invalid bolt11: %s", fail); - } - - pay->cmd = cmd; - pay->payment_hash = b11->payment_hash; - pay->receiver_id = b11->receiver_id; - memset(&pay->expiry, 0, sizeof(pay->expiry)); - pay->expiry.ts.tv_sec = b11->timestamp + b11->expiry; - pay->min_final_cltv_expiry = b11->min_final_cltv_expiry; - pay->exemptfee = *exemptfee; - - if (b11->msatoshi) { - if (msatoshi) { - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "msatoshi parameter unnecessary"); - } - msatoshi = b11->msatoshi; - } else { - if (!msatoshi) { - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "msatoshi parameter required"); - } - } - pay->msatoshi = *msatoshi; - pay->riskfactor = *riskfactor * 1000; - pay->maxfeepercent = *maxfeepercent; - - if (*maxdelay < pay->min_final_cltv_expiry) { - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, - "maxdelay (%u) must be greater than " - "min_final_cltv_expiry (%"PRIu32") of " - "invoice", - *maxdelay, pay->min_final_cltv_expiry); - } - 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` 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; - pay->try_parent = NULL; - /* Start with no route */ - pay->route = NULL; - /* Start with no failures */ - list_head_init(&pay->pay_failures); - pay->in_sendpay = false; - pay->description = b11->description; - - /* Initiate payment */ - res = json_pay_try(pay); - if (res) - return res; - - /* Set up timeout. */ - new_reltimer(&cmd->ld->timers, pay, time_from_sec(*retryfor), - &json_pay_stop_retrying, pay); - return command_still_pending(cmd); -} - -static const struct json_command pay_command = { - "pay", - json_pay, - "Send payment specified by {bolt11} with {msatoshi} " - "(ignored if {bolt11} has an amount), " - "{description} (required if {bolt11} uses description hash), " - "{riskfactor} (default 1.0), " - "{maxfeepercent} (default 0.5) the maximum acceptable fee as a percentage (e.g. 0.5 => 0.5%), " - "{exemptfee} (default 5000 msat) disables the maxfeepercent check for fees below the threshold, " - "{retry_for} (default 60) the integer number of seconds before we stop retrying, and " - "{maxdelay} (default 500) the maximum number of blocks we allow the funds to possibly get locked" -}; -AUTODATA(json_command, &pay_command); diff --git a/lightningd/payalgo.h b/lightningd/payalgo.h deleted file mode 100644 index 971b80ba2..000000000 --- a/lightningd/payalgo.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef LIGHTNING_LIGHTNINGD_PAYALGO_H -#define LIGHTNING_LIGHTNINGD_PAYALGO_H -#include "config.h" - -#endif /* LIGHTNING_LIGHTNINGD_PAYALGO_H */ diff --git a/plugins/pay.c b/plugins/pay.c index 943734be0..427dd3eb3 100644 --- a/plugins/pay.c +++ b/plugins/pay.c @@ -926,7 +926,7 @@ static void init(struct plugin_conn *rpc) } static const struct plugin_command commands[] = { { - "pay2", + "pay", "Send payment specified by {bolt11} with {msatoshi}", "Try to send a payment, retrying {retry_for} seconds before giving up", handle_pay diff --git a/tests/test_pay.py b/tests/test_pay.py index 87ff61936..b6f8dd2eb 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -70,18 +70,18 @@ def test_pay_limits(node_factory): # Fee too high. with pytest.raises(RpcError, match=r'Route wanted fee of .* msatoshis') as err: - l1.rpc.call('pay2', {'bolt11': inv['bolt11'], 'msatoshi': 100000, 'maxfeepercent': 0.0001, 'exemptfee': 0}) + l1.rpc.call('pay', {'bolt11': inv['bolt11'], 'msatoshi': 100000, 'maxfeepercent': 0.0001, 'exemptfee': 0}) assert err.value.error['code'] == PAY_ROUTE_TOO_EXPENSIVE # Delay too high. with pytest.raises(RpcError, match=r'Route wanted delay of .* blocks') as err: - l1.rpc.call('pay2', {'bolt11': inv['bolt11'], 'msatoshi': 100000, 'maxdelay': 0}) + l1.rpc.call('pay', {'bolt11': inv['bolt11'], 'msatoshi': 100000, 'maxdelay': 0}) assert err.value.error['code'] == PAY_ROUTE_TOO_EXPENSIVE # This works, because fee is less than exemptfee. - l1.rpc.call('pay2', {'bolt11': inv['bolt11'], 'msatoshi': 100000, 'maxfeepercent': 0.0001, 'exemptfee': 2000}) + l1.rpc.call('pay', {'bolt11': inv['bolt11'], 'msatoshi': 100000, 'maxfeepercent': 0.0001, 'exemptfee': 2000}) def test_pay0(node_factory): diff --git a/tests/test_plugin.py b/tests/test_plugin.py index aacf77606..dcd3165a1 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -114,5 +114,5 @@ def test_pay_plugin(node_factory): l1, l2 = node_factory.line_graph(2) inv = l2.rpc.invoice(123000, 'label', 'description', 3700) - res = l1.rpc.pay2(bolt11=inv['bolt11']) + res = l1.rpc.pay(bolt11=inv['bolt11']) assert res['status'] == 'complete'