Browse Source

mpp: Add CLI option to opt-out of multi-part payments

Several tests are not well-suited for mpp, so I added a CLI option to opt-out
of the MPP support at startup time.
release-0.9.0
Christian Decker 4 years ago
parent
commit
de75d3ac0c
  1. 10
      doc/lightningd-config.5
  2. 8
      doc/lightningd-config.5.md
  3. 3
      lightningd/options.c
  4. 42
      plugins/libplugin-pay.c
  5. 12
      plugins/libplugin-pay.h
  6. 21
      plugins/libplugin.c
  7. 2
      plugins/libplugin.h
  8. 10
      plugins/pay.c

10
doc/lightningd-config.5

@ -378,6 +378,16 @@ up space in the database\.
Control how long invoices must have been expired before they are cleaned
(if \fIautocleaninvoice-cycle\fR is non-zero)\.
Payment control options:
\fBdisable-mpp\fR
Disable the multi-part payment sending support in the \fBpay\fR plugin\. By default
the MPP support is enabled, but it can be desirable to disable in situations
in which each payment should result in a single HTLC being forwarded in the
network\.
.SH Networking options
Note that for simple setups, the implicit \fIautolisten\fR option does the

8
doc/lightningd-config.5.md

@ -309,6 +309,14 @@ up space in the database.
Control how long invoices must have been expired before they are cleaned
(if *autocleaninvoice-cycle* is non-zero).
Payment control options:
**disable-mpp**
Disable the multi-part payment sending support in the `pay` plugin. By default
the MPP support is enabled, but it can be desirable to disable in situations
in which each payment should result in a single HTLC being forwarded in the
network.
### Networking options
Note that for simple setups, the implicit *autolisten* option does the

3
lightningd/options.c

@ -1201,6 +1201,9 @@ static void add_config(struct lightningd *ld,
feature_offered(ld->our_features
->bits[INIT_FEATURE],
OPT_LARGE_CHANNELS));
} else if (opt->cb == (void *)plugin_opt_flag_set) {
/* Noop, they will get added below along with the
* OPT_HASARG options. */
} else {
/* Insert more decodes here! */
assert(!"A noarg option was added but was not handled");

42
plugins/libplugin-pay.c

@ -2082,11 +2082,26 @@ REGISTER_PAYMENT_MODIFIER(waitblockheight, void *, NULL, waitblockheight_cb);
#define MPP_TARGET_MSAT AMOUNT_MSAT(MPP_TARGET_SIZE)
#define MPP_TARGET_FUZZ ( 1 * 1000 * 1000)
static void presplit_cb(void *d, struct payment *p)
static struct presplit_mod_data *presplit_mod_data_init(struct payment *p)
{
struct presplit_mod_data *d;
if (p->parent == NULL) {
d = tal(p, struct presplit_mod_data);
d->disable = false;
return d;
} else {
return payment_mod_presplit_get_data(p->parent);
}
}
static void presplit_cb(struct presplit_mod_data *d, struct payment *p)
{
struct payment *root = payment_root(p);
struct amount_msat amt = root->amount;
if (d->disable)
return payment_continue(p);
if (p->step == PAYMENT_STEP_ONION_PAYLOAD) {
/* We need to tell the last hop the total we're going to
* send. Presplit disables amount fuzzing, so we should always
@ -2166,7 +2181,8 @@ static void presplit_cb(void *d, struct payment *p)
payment_continue(p);
}
REGISTER_PAYMENT_MODIFIER(presplit, void *, NULL, presplit_cb);
REGISTER_PAYMENT_MODIFIER(presplit, struct presplit_mod_data *,
presplit_mod_data_init, presplit_cb);
/*****************************************************************************
* Adaptive splitter -- Split payment if we can't get it through.
@ -2179,9 +2195,25 @@ REGISTER_PAYMENT_MODIFIER(presplit, void *, NULL, presplit_cb);
#define MPP_ADAPTIVE_LOWER_LIMIT AMOUNT_MSAT(100 * 1000)
static void adaptive_splitter_cb(void *d, struct payment *p)
static struct presplit_mod_data *adaptive_splitter_data_init(struct payment *p)
{
struct presplit_mod_data *d;
if (p->parent == NULL) {
d = tal(p, struct presplit_mod_data);
d->disable = false;
return d;
} else {
return payment_mod_presplit_get_data(p->parent);
}
}
static void adaptive_splitter_cb(struct presplit_mod_data *d, struct payment *p)
{
struct payment *root = payment_root(p);
if (d->disable)
return payment_continue(p);
if (p->step == PAYMENT_STEP_ONION_PAYLOAD) {
/* We need to tell the last hop the total we're going to
* send. Presplit disables amount fuzzing, so we should always
@ -2236,5 +2268,5 @@ static void adaptive_splitter_cb(void *d, struct payment *p)
payment_continue(p);
}
REGISTER_PAYMENT_MODIFIER(adaptive_splitter, void *, NULL,
adaptive_splitter_cb);
REGISTER_PAYMENT_MODIFIER(adaptive_splitter, struct presplit_mod_data *,
adaptive_splitter_data_init, adaptive_splitter_cb);

12
plugins/libplugin-pay.h

@ -319,6 +319,14 @@ struct direct_pay_data {
* attempt against the channel hints. */
struct short_channel_id_dir *chan;
};
/* Since presplit and adaptive mpp modifiers share the same information we
* just use the same backing struct. Should they deviate we can create an
* adaptive_splitter_mod_data struct and populate that. */
struct presplit_mod_data {
bool disable;
};
/* List of globally available payment modifiers. */
REGISTER_PAYMENT_MODIFIER_HEADER(retry, struct retry_mod_data);
REGISTER_PAYMENT_MODIFIER_HEADER(routehints, struct routehints_data);
@ -326,8 +334,8 @@ REGISTER_PAYMENT_MODIFIER_HEADER(exemptfee, struct exemptfee_data);
REGISTER_PAYMENT_MODIFIER_HEADER(shadowroute, struct shadow_route_data);
REGISTER_PAYMENT_MODIFIER_HEADER(directpay, struct direct_pay_data);
extern struct payment_modifier waitblockheight_pay_mod;
extern struct payment_modifier presplit_pay_mod;
extern struct payment_modifier adaptive_splitter_pay_mod;
REGISTER_PAYMENT_MODIFIER_HEADER(presplit, struct presplit_mod_data);
REGISTER_PAYMENT_MODIFIER_HEADER(adaptive_splitter, struct presplit_mod_data);
/* For the root payment we can seed the channel_hints with the result from
* `listpeers`, hence avoid channels that we know have insufficient capacity

21
plugins/libplugin.c

@ -862,6 +862,27 @@ char *u32_option(const char *arg, u32 *i)
return NULL;
}
char *bool_option(const char *arg, bool *i)
{
if (!streq(arg, "true") && !streq(arg, "false"))
return tal_fmt(NULL, "'%s' is not a bool, must be \"true\" or \"false\"", arg);
*i = streq(arg, "true");
return NULL;
}
char *flag_option(const char *arg, bool *i)
{
/* We only get called if the flag was provided, so *i should be false
* by default */
assert(*i == false);
if (!streq(arg, "true"))
return tal_fmt(NULL, "Invalid argument '%s' passed to a flag", arg);
*i = true;
return NULL;
}
char *charp_option(const char *arg, char **p)
{
*p = tal_strdup(NULL, arg);

2
plugins/libplugin.h

@ -239,7 +239,9 @@ void plugin_log(struct plugin *p, enum log_level l, const char *fmt, ...) PRINTF
/* Standard helpers */
char *u64_option(const char *arg, u64 *i);
char *u32_option(const char *arg, u32 *i);
char *bool_option(const char *arg, bool *i);
char *charp_option(const char *arg, char **p);
char *flag_option(const char *arg, bool *i);
/* The main plugin runner: append with 0 or more plugin_option(), then NULL. */
void NORETURN LAST_ARG_NULL plugin_main(char *argv[],

10
plugins/pay.c

@ -25,6 +25,8 @@
/* Public key of this node. */
static struct node_id my_id;
static unsigned int maxdelay_default;
static bool disablempp = false;
static LIST_HEAD(pay_status);
static LIST_HEAD(payments);
@ -1955,6 +1957,8 @@ static struct command_result *json_paymod(struct command *cmd,
payment_mod_exemptfee_get_data(p)->amount = *exemptfee;
shadow_route = payment_mod_shadowroute_get_data(p);
payment_mod_presplit_get_data(p)->disable = disablempp;
payment_mod_adaptive_splitter_get_data(p)->disable = disablempp;
/* This is an MPP enabled pay command, disable amount fuzzing. */
shadow_route->fuzz_amount = false;
@ -2004,5 +2008,9 @@ int main(int argc, char *argv[])
{
setup_locale();
plugin_main(argv, init, PLUGIN_RESTARTABLE, NULL, commands,
ARRAY_SIZE(commands), NULL, 0, NULL, 0, NULL);
ARRAY_SIZE(commands), NULL, 0, NULL, 0,
plugin_option("disable-mpp", "flag",
"Disable multi-part payments.",
flag_option, &disablempp),
NULL);
}

Loading…
Cancel
Save