Skip to content

Commit

Permalink
libplugin: allow check setconfig on all dynamic options.
Browse files Browse the repository at this point in the history
We need to pass through setconfig in check mode, then we need to have libplugin
add (and use!) a `check_only` parameter to all option setting.

Signed-off-by: Rusty Russell <[email protected]>
Changelog-Added: JSON-RPC: `check` `setconfig` on plugin options can now check the config value would be accepted.
  • Loading branch information
rustyrussell committed Mar 20, 2024
1 parent 45fd60e commit 6b2f24a
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 100 deletions.
17 changes: 13 additions & 4 deletions lightningd/configs.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,9 @@ static struct command_result *setconfig_success(struct command *cmd,
struct json_stream *response;
const char **names, *confline;

if (command_check_only(cmd))
return command_check_done(cmd);

names = opt_names_arr(tmpctx, ot);

if (val)
Expand All @@ -584,10 +587,10 @@ static struct command_result *json_setconfig(struct command *cmd,
const char *val;
char *err;

if (!param(cmd, buffer, params,
p_req("config", param_opt_dynamic_config, &ot),
p_opt("val", param_string, &val),
NULL))
if (!param_check(cmd, buffer, params,
p_req("config", param_opt_dynamic_config, &ot),
p_opt("val", param_string, &val),
NULL))
return command_param_failed();

/* We don't handle DYNAMIC MULTI, at least yet! */
Expand All @@ -601,6 +604,9 @@ static struct command_result *json_setconfig(struct command *cmd,
if (is_plugin_opt(ot))
return plugin_set_dynamic_opt(cmd, ot, NULL,
setconfig_success);
/* FIXME: we don't have a check-only mode! */
if (command_check_only(cmd))
return command_check_done(cmd);
err = ot->cb(ot->u.arg);
} else {
assert(ot->type & OPT_HASARG);
Expand All @@ -611,6 +617,9 @@ static struct command_result *json_setconfig(struct command *cmd,
if (is_plugin_opt(ot))
return plugin_set_dynamic_opt(cmd, ot, val,
setconfig_success);
/* FIXME: we don't have a check-only mode! */
if (command_check_only(cmd))
return command_check_done(cmd);
err = ot->cb_arg(val, ot->u.arg);
}

Expand Down
22 changes: 16 additions & 6 deletions lightningd/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -2377,12 +2377,22 @@ struct command_result *plugin_set_dynamic_opt(struct command *cmd,
psr->optname = tal_strdup(psr, ot->names + 2);
psr->success = success;

req = jsonrpc_request_start(cmd, "setconfig",
cmd->id,
plugin->non_numeric_ids,
command_log(cmd),
NULL, plugin_setconfig_done,
psr);
if (command_check_only(cmd)) {
req = jsonrpc_request_start(cmd, "check",
cmd->id,
plugin->non_numeric_ids,
command_log(cmd),
NULL, plugin_setconfig_done,
psr);
json_add_string(req->stream, "command_to_check", "setconfig");
} else {
req = jsonrpc_request_start(cmd, "setconfig",
cmd->id,
plugin->non_numeric_ids,
command_log(cmd),
NULL, plugin_setconfig_done,
psr);
}
json_add_string(req->stream, "config", psr->optname);
if (psr->val)
json_add_string(req->stream, "val", psr->val);
Expand Down
5 changes: 3 additions & 2 deletions plugins/autoclean.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,10 +590,11 @@ static const char *init(struct plugin *p,
}

static char *cycle_seconds_option(struct plugin *plugin, const char *arg,
bool check_only,
void *unused)
{
char *problem = u64_option(plugin, arg, &cycle_seconds);
if (problem)
char *problem = u64_option(plugin, arg, check_only, &cycle_seconds);
if (problem || check_only)
return problem;

/* If timer is not running right now, reset it to new cycle_seconds */
Expand Down
83 changes: 62 additions & 21 deletions plugins/funder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ param_funder_opt(struct command *cmd, const char *name,
opt_str = tal_strndup(cmd, buffer + tok->start,
tok->end - tok->start);

err = funding_option(cmd->plugin, opt_str, *opt);
err = funding_option(cmd->plugin, opt_str, false, *opt);
if (err)
return command_fail_badparam(cmd, name, buffer, tok, err);

Expand All @@ -1249,7 +1249,7 @@ param_policy_mod(struct command *cmd, const char *name,
arg_str = tal_strndup(cmd, buffer + tok->start,
tok->end - tok->start);

err = u64_option(cmd->plugin, arg_str, *mod);
err = u64_option(cmd->plugin, arg_str, false, *mod);
if (err) {
tal_free(err);
if (!parse_amount_sat(&sats, arg_str, strlen(arg_str)))
Expand Down Expand Up @@ -1549,92 +1549,133 @@ const struct plugin_notification notifs[] = {
},
};

static char *option_channel_base(struct plugin *plugin, const char *arg, struct funder_policy *policy)
static char *option_channel_base(struct plugin *plugin, const char *arg,
bool check_only, struct funder_policy *policy)
{
struct amount_msat amt;
u32 cfmbm;

if (!parse_amount_msat(&amt, arg, strlen(arg)))
return tal_fmt(tmpctx, "Unable to parse amount '%s'", arg);

if (!policy->rates)
policy->rates = default_lease_rates(policy);

if (!assign_overflow_u32(&policy->rates->channel_fee_max_base_msat,
amt.millisatoshis)) /* Raw: conversion */
if (!assign_overflow_u32(&cfmbm, amt.millisatoshis)) /* Raw: conversion */
return tal_fmt(tmpctx, "channel_fee_max_base_msat overflowed");

if (!check_only) {
if (!policy->rates)
policy->rates = default_lease_rates(policy);
policy->rates->channel_fee_max_base_msat = cfmbm;
}

return NULL;
}

static char *
option_channel_fee_proportional_thousandths_max(struct plugin *plugin,
const char *arg,
bool check_only,
struct funder_policy *policy)
{
u16 fptm;
char *problem = u16_option(plugin, arg, false, &fptm);

if (problem || check_only)
return problem;

if (!policy->rates)
policy->rates = default_lease_rates(policy);
return u16_option(plugin, arg, &policy->rates->channel_fee_max_proportional_thousandths);
policy->rates->channel_fee_max_proportional_thousandths = fptm;
return NULL;
}

static char *amount_option(struct plugin *plugin, const char *arg, struct amount_sat *amt)
static char *amount_option(struct plugin *plugin, const char *arg, bool check_only,
struct amount_sat *amt)
{
if (!parse_amount_sat(amt, arg, strlen(arg)))
struct amount_sat v;
if (!parse_amount_sat(&v, arg, strlen(arg)))
return tal_fmt(tmpctx, "Unable to parse amount '%s'", arg);

if (!check_only)
*amt = v;
return NULL;
}

static char *option_lease_fee_base(struct plugin *plugin, const char *arg,
bool check_only,
struct funder_policy *policy)
{
struct amount_sat amt;
u32 lfbs;
char *err;
if (!policy->rates)
policy->rates = default_lease_rates(policy);

err = amount_option(plugin, arg, &amt);
err = amount_option(plugin, arg, false, &amt);
if (err)
return err;

if (!assign_overflow_u32(&policy->rates->lease_fee_base_sat,
amt.satoshis)) /* Raw: conversion */
if (!assign_overflow_u32(&lfbs, amt.satoshis)) /* Raw: conversion */
return tal_fmt(tmpctx, "lease_fee_base_sat overflowed");

if (!check_only) {
if (!policy->rates)
policy->rates = default_lease_rates(policy);

policy->rates->lease_fee_base_sat = lfbs;
}

return NULL;
}

static char *option_lease_fee_basis(struct plugin *plugin, const char *arg,
bool check_only,
struct funder_policy *policy)
{
u16 lfb;
char *problem = u16_option(plugin, arg, false, &lfb);

if (problem || check_only)
return problem;

if (!policy->rates)
policy->rates = default_lease_rates(policy);
return u16_option(plugin, arg, &policy->rates->lease_fee_basis);
policy->rates->lease_fee_basis = lfb;
return NULL;
}

static char *option_lease_weight_max(struct plugin *plugin, const char *arg,
bool check_only,
struct funder_policy *policy)
{
u16 fw;
char *problem = u16_option(plugin, arg, false, &fw);

if (problem || check_only)
return problem;

if (!policy->rates)
policy->rates = default_lease_rates(policy);
return u16_option(plugin, arg, &policy->rates->funding_weight);
policy->rates->funding_weight = fw;
return NULL;
}

static char *amount_sat_or_u64_option(struct plugin *plugin,
const char *arg, u64 *amt)
const char *arg,
bool check_only,
u64 *amt)
{
struct amount_sat sats;
char *err;

err = u64_option(plugin, arg, amt);
err = u64_option(plugin, arg, false, &sats.satoshis); /* Raw: want sats below */
if (err) {
tal_free(err);
if (!parse_amount_sat(&sats, arg, strlen(arg)))
return tal_fmt(tmpctx,
"Unable to parse option '%s'",
arg);
}

if (!check_only)
*amt = sats.satoshis; /* Raw: convert to u64 */
}

return NULL;
}
Expand Down
12 changes: 8 additions & 4 deletions plugins/funder_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,22 @@ const char *funder_opt_name(enum funder_opt opt)
abort();
}

char *funding_option(struct plugin *plugin, const char *arg, enum funder_opt *opt)
char *funding_option(struct plugin *plugin, const char *arg, bool check_only, enum funder_opt *opt)
{
enum funder_opt v;
if (streq(arg, "match"))
*opt = MATCH;
v = MATCH;
else if (streq(arg, "available"))
*opt = AVAILABLE;
v = AVAILABLE;
else if (streq(arg, "fixed"))
*opt = FIXED;
v = FIXED;
else
return tal_fmt(tmpctx, "'%s' is not a valid option"
" (match, available, fixed)",
arg);

if (!check_only)
*opt = v;
return NULL;
}

Expand Down
3 changes: 2 additions & 1 deletion plugins/funder_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ const char *funder_policy_desc(const tal_t *ctx,
const struct funder_policy *policy);

/* Convert a cmdline option to a funding_opt */
char *funding_option(struct plugin *plugin, const char *arg, enum funder_opt *opt);
char *funding_option(struct plugin *plugin, const char *arg, bool check_only,
enum funder_opt *opt);

/* Check policy settings, return error if fails */
char *funder_check_policy(const struct funder_policy *policy);
Expand Down
Loading

0 comments on commit 6b2f24a

Please sign in to comment.