funder: make policy a pointer, most places

This commit is contained in:
niftynei 2021-05-26 18:10:32 -05:00 committed by neil saitug
parent 9e839b177c
commit d6b302b52f
4 changed files with 79 additions and 75 deletions

View File

@ -27,7 +27,7 @@
static struct list_head pending_opens; static struct list_head pending_opens;
/* Current set policy */ /* Current set policy */
static struct funder_policy current_policy; static struct funder_policy *current_policy;
struct pending_open { struct pending_open {
struct list_node list; struct list_node list;
@ -757,7 +757,7 @@ json_funderupdate(struct command *cmd,
u64 *mod; u64 *mod;
enum funder_opt *opt; enum funder_opt *opt;
const char *err; const char *err;
struct funder_policy policy = current_policy; struct funder_policy *policy = current_policy;
if (!param(cmd, buf, params, if (!param(cmd, buf, params,
p_opt("policy", param_funder_opt, &opt), p_opt("policy", param_funder_opt, &opt),
@ -773,32 +773,32 @@ json_funderupdate(struct command *cmd,
return command_param_failed(); return command_param_failed();
if (opt) if (opt)
policy.opt = *opt; policy->opt = *opt;
if (mod) if (mod)
policy.mod = *mod; policy->mod = *mod;
if (min_their_funding) if (min_their_funding)
policy.min_their_funding = *min_their_funding; policy->min_their_funding = *min_their_funding;
if (max_their_funding) if (max_their_funding)
policy.max_their_funding = *max_their_funding; policy->max_their_funding = *max_their_funding;
if (per_channel_min) if (per_channel_min)
policy.per_channel_min = *per_channel_min; policy->per_channel_min = *per_channel_min;
if (per_channel_max) if (per_channel_max)
policy.per_channel_max = *per_channel_max; policy->per_channel_max = *per_channel_max;
if (reserve_tank) if (reserve_tank)
policy.reserve_tank = *reserve_tank; policy->reserve_tank = *reserve_tank;
if (fuzz_factor) if (fuzz_factor)
policy.fuzz_factor = *fuzz_factor; policy->fuzz_factor = *fuzz_factor;
if (fund_probability) if (fund_probability)
policy.fund_probability = *fund_probability; policy->fund_probability = *fund_probability;
err = funder_check_policy(&policy); err = funder_check_policy(policy);
if (err) if (err)
return command_done_err(cmd, JSONRPC2_INVALID_PARAMS, return command_done_err(cmd, JSONRPC2_INVALID_PARAMS,
err, NULL); err, NULL);
current_policy = policy; current_policy = policy;
res = jsonrpc_stream_success(cmd); res = jsonrpc_stream_success(cmd);
policy_to_json(res, &current_policy); policy_to_json(res, current_policy);
return command_finished(cmd, res); return command_finished(cmd, res);
} }
@ -819,7 +819,7 @@ static const char *init(struct plugin *p, const char *b, const jsmntok_t *t)
list_head_init(&pending_opens); list_head_init(&pending_opens);
err = funder_check_policy(&current_policy); err = funder_check_policy(current_policy);
if (err) if (err)
plugin_err(p, "Invalid parameter combination: %s", err); plugin_err(p, "Invalid parameter combination: %s", err);
@ -890,7 +890,7 @@ int main(int argc, char **argv)
setup_locale(); setup_locale();
/* Our default funding policy is fixed (0msat) */ /* Our default funding policy is fixed (0msat) */
current_policy = default_funder_policy(FIXED, 0); current_policy = default_funder_policy(owner, FIXED, 0);
plugin_main(argv, init, PLUGIN_RESTARTABLE, true, plugin_main(argv, init, PLUGIN_RESTARTABLE, true,
NULL, NULL,
@ -902,57 +902,57 @@ int main(int argc, char **argv)
"string", "string",
"Policy to use for dual-funding requests." "Policy to use for dual-funding requests."
" [match, available, fixed]", " [match, available, fixed]",
funding_option, &current_policy.opt), funding_option, &current_policy->opt),
plugin_option("funder-policy-mod", plugin_option("funder-policy-mod",
"string", "string",
"Percent to apply policy at" "Percent to apply policy at"
" (match/available); or amount to fund" " (match/available); or amount to fund"
" (fixed)", " (fixed)",
amount_sat_or_u64_option, amount_sat_or_u64_option,
&current_policy.mod), &current_policy->mod),
plugin_option("funder-min-their-funding", plugin_option("funder-min-their-funding",
"string", "string",
"Minimum funding peer must open with" "Minimum funding peer must open with"
" to activate our policy", " to activate our policy",
amount_option, amount_option,
&current_policy.min_their_funding), &current_policy->min_their_funding),
plugin_option("funder-max-their-funding", plugin_option("funder-max-their-funding",
"string", "string",
"Maximum funding peer may open with" "Maximum funding peer may open with"
" to activate our policy", " to activate our policy",
amount_option, amount_option,
&current_policy.max_their_funding), &current_policy->max_their_funding),
plugin_option("funder-per-channel-min", plugin_option("funder-per-channel-min",
"string", "string",
"Minimum funding we'll add to a channel." "Minimum funding we'll add to a channel."
" If we can't meet this, we don't fund", " If we can't meet this, we don't fund",
amount_option, amount_option,
&current_policy.per_channel_min), &current_policy->per_channel_min),
plugin_option("funder-per-channel-max", plugin_option("funder-per-channel-max",
"string", "string",
"Maximum funding we'll add to a channel." "Maximum funding we'll add to a channel."
" We cap all contributions to this", " We cap all contributions to this",
amount_option, amount_option,
&current_policy.per_channel_max), &current_policy->per_channel_max),
plugin_option("funder-reserve-tank", plugin_option("funder-reserve-tank",
"string", "string",
"Amount of funds we'll always leave" "Amount of funds we'll always leave"
" available.", " available.",
amount_option, amount_option,
&current_policy.reserve_tank), &current_policy->reserve_tank),
plugin_option("funder-fuzz-percent", plugin_option("funder-fuzz-percent",
"int", "int",
"Percent to fuzz the policy contribution by." "Percent to fuzz the policy contribution by."
" Defaults to 5%. Max is 100%", " Defaults to 5%. Max is 100%",
u32_option, u32_option,
&current_policy.fuzz_factor), &current_policy->fuzz_factor),
plugin_option("funder-fund-probability", plugin_option("funder-fund-probability",
"int", "int",
"Percent of requests to consider." "Percent of requests to consider."
" Defaults to 100%. Setting to 0% will" " Defaults to 100%. Setting to 0% will"
" disable dual-funding", " disable dual-funding",
u32_option, u32_option,
&current_policy.fund_probability), &current_policy->fund_probability),
NULL); NULL);
tal_free(owner); tal_free(owner);

View File

@ -35,22 +35,23 @@ char *funding_option(const char *arg, enum funder_opt *opt)
} }
const char *funder_policy_desc(const tal_t *ctx, const char *funder_policy_desc(const tal_t *ctx,
struct funder_policy policy) const struct funder_policy *policy)
{ {
if (policy.opt == FIXED) { if (policy->opt == FIXED) {
struct amount_sat amt = amount_sat(policy.mod); struct amount_sat amt = amount_sat(policy->mod);
return tal_fmt(ctx, "%s (%s)", return tal_fmt(ctx, "%s (%s)",
funder_opt_name(policy.opt), funder_opt_name(policy->opt),
type_to_string(ctx, struct amount_sat, &amt)); type_to_string(ctx, struct amount_sat, &amt));
} else } else
return tal_fmt(ctx, "%s (%"PRIu64"%%)", return tal_fmt(ctx, "%s (%"PRIu64"%%)",
funder_opt_name(policy.opt), policy.mod); funder_opt_name(policy->opt), policy->mod);
/* FIXME: add in more info? */ /* FIXME: add in more info? */
} }
struct funder_policy struct funder_policy *
new_funder_policy(enum funder_opt opt, new_funder_policy(const tal_t *ctx,
enum funder_opt opt,
u64 policy_mod, u64 policy_mod,
struct amount_sat min_their_funding, struct amount_sat min_their_funding,
struct amount_sat max_their_funding, struct amount_sat max_their_funding,
@ -60,26 +61,27 @@ new_funder_policy(enum funder_opt opt,
struct amount_sat reserve_tank, struct amount_sat reserve_tank,
u32 fund_probability) u32 fund_probability)
{ {
struct funder_policy policy; struct funder_policy *policy = tal(ctx, struct funder_policy);
policy.opt = opt; policy->opt = opt;
policy.mod = policy_mod; policy->mod = policy_mod;
policy.min_their_funding = min_their_funding; policy->min_their_funding = min_their_funding;
policy.max_their_funding = max_their_funding; policy->max_their_funding = max_their_funding;
policy.per_channel_min = per_channel_min; policy->per_channel_min = per_channel_min;
policy.per_channel_max = per_channel_max; policy->per_channel_max = per_channel_max;
policy.fuzz_factor = fuzz_factor; policy->fuzz_factor = fuzz_factor;
policy.reserve_tank = reserve_tank; policy->reserve_tank = reserve_tank;
policy.fund_probability = fund_probability; policy->fund_probability = fund_probability;
return policy; return policy;
} }
struct funder_policy struct funder_policy *
default_funder_policy(enum funder_opt policy, default_funder_policy(const tal_t *ctx,
enum funder_opt policy,
u64 policy_mod) u64 policy_mod)
{ {
return new_funder_policy(policy, policy_mod, return new_funder_policy(ctx, policy, policy_mod,
AMOUNT_SAT(10000), AMOUNT_SAT(10000),
AMOUNT_SAT(UINT_MAX), AMOUNT_SAT(UINT_MAX),
AMOUNT_SAT(10000), AMOUNT_SAT(10000),
@ -137,37 +139,37 @@ apply_fuzz(u32 fuzz_factor, struct amount_sat val)
} }
static struct amount_sat static struct amount_sat
apply_policy(struct funder_policy policy, apply_policy(struct funder_policy *policy,
struct amount_sat their_funding, struct amount_sat their_funding,
struct amount_sat available_funds) struct amount_sat available_funds)
{ {
struct amount_sat our_funding; struct amount_sat our_funding;
switch (policy.opt) { switch (policy->opt) {
case MATCH: case MATCH:
/* if this fails, it implies ludicrous funding offer, *and* /* if this fails, it implies ludicrous funding offer, *and*
* > 100% match. Just Say No, kids. */ * > 100% match. Just Say No, kids. */
if (!amount_sat_scale(&our_funding, their_funding, if (!amount_sat_scale(&our_funding, their_funding,
policy.mod / 100.0)) policy->mod / 100.0))
our_funding = AMOUNT_SAT(0); our_funding = AMOUNT_SAT(0);
return our_funding; return our_funding;
case AVAILABLE: case AVAILABLE:
/* Use the 'available_funds' as the starting /* Use the 'available_funds' as the starting
* point for your contribution */ * point for your contribution */
if (!amount_sat_scale(&our_funding, available_funds, if (!amount_sat_scale(&our_funding, available_funds,
policy.mod / 100.0)) policy->mod / 100.0))
abort(); abort();
return our_funding; return our_funding;
case FIXED: case FIXED:
/* Use a static amount */ /* Use a static amount */
return amount_sat(policy.mod); return amount_sat(policy->mod);
} }
abort(); abort();
} }
const char * const char *
calculate_our_funding(struct funder_policy policy, calculate_our_funding(struct funder_policy *policy,
struct node_id id, struct node_id id,
struct amount_sat their_funding, struct amount_sat their_funding,
struct amount_sat available_funds, struct amount_sat available_funds,
@ -177,7 +179,7 @@ calculate_our_funding(struct funder_policy policy,
struct amount_sat avail_channel_space, net_available_funds; struct amount_sat avail_channel_space, net_available_funds;
/* Are we skipping this one? */ /* Are we skipping this one? */
if (pseudorand(100) >= policy.fund_probability) { if (pseudorand(100) >= policy->fund_probability) {
*our_funding = AMOUNT_SAT(0); *our_funding = AMOUNT_SAT(0);
return tal_fmt(tmpctx, return tal_fmt(tmpctx,
"Skipping, failed fund_probability test"); "Skipping, failed fund_probability test");
@ -198,7 +200,7 @@ calculate_our_funding(struct funder_policy policy,
/* Figure out actual available funds, given our requested /* Figure out actual available funds, given our requested
* 'reserve_tank' */ * 'reserve_tank' */
if (!amount_sat_sub(&net_available_funds, available_funds, if (!amount_sat_sub(&net_available_funds, available_funds,
policy.reserve_tank) policy->reserve_tank)
|| amount_sat_eq(net_available_funds, AMOUNT_SAT(0))) { || amount_sat_eq(net_available_funds, AMOUNT_SAT(0))) {
*our_funding = AMOUNT_SAT(0); *our_funding = AMOUNT_SAT(0);
return tal_fmt(tmpctx, "Reserve tank too low." return tal_fmt(tmpctx, "Reserve tank too low."
@ -206,11 +208,11 @@ calculate_our_funding(struct funder_policy policy,
type_to_string(tmpctx, struct amount_sat, type_to_string(tmpctx, struct amount_sat,
&available_funds), &available_funds),
type_to_string(tmpctx, struct amount_sat, type_to_string(tmpctx, struct amount_sat,
&policy.reserve_tank)); &policy->reserve_tank));
} }
/* Are they funding enough ? */ /* Are they funding enough ? */
if (amount_sat_less(their_funding, policy.min_their_funding)) { if (amount_sat_less(their_funding, policy->min_their_funding)) {
*our_funding = AMOUNT_SAT(0); *our_funding = AMOUNT_SAT(0);
return tal_fmt(tmpctx, "Peer's funding too little." return tal_fmt(tmpctx, "Peer's funding too little."
" their_funding %s," " their_funding %s,"
@ -218,11 +220,11 @@ calculate_our_funding(struct funder_policy policy,
type_to_string(tmpctx, struct amount_sat, type_to_string(tmpctx, struct amount_sat,
&their_funding), &their_funding),
type_to_string(tmpctx, struct amount_sat, type_to_string(tmpctx, struct amount_sat,
&policy.min_their_funding)); &policy->min_their_funding));
} }
/* Are they funding too much ? */ /* Are they funding too much ? */
if (amount_sat_greater(their_funding, policy.max_their_funding)) { if (amount_sat_greater(their_funding, policy->max_their_funding)) {
*our_funding = AMOUNT_SAT(0); *our_funding = AMOUNT_SAT(0);
return tal_fmt(tmpctx, "Peer's funding too much." return tal_fmt(tmpctx, "Peer's funding too much."
" their_funding %s," " their_funding %s,"
@ -230,7 +232,7 @@ calculate_our_funding(struct funder_policy policy,
type_to_string(tmpctx, struct amount_sat, type_to_string(tmpctx, struct amount_sat,
&their_funding), &their_funding),
type_to_string(tmpctx, struct amount_sat, type_to_string(tmpctx, struct amount_sat,
&policy.max_their_funding)); &policy->max_their_funding));
} }
/* What's our amount, given our policy */ /* What's our amount, given our policy */
@ -241,7 +243,7 @@ calculate_our_funding(struct funder_policy policy,
return NULL; return NULL;
/* our_funding is probably sane, so let's fuzz this amount a bit */ /* our_funding is probably sane, so let's fuzz this amount a bit */
*our_funding = apply_fuzz(policy.fuzz_factor, *our_funding); *our_funding = apply_fuzz(policy->fuzz_factor, *our_funding);
/* Is our_funding more than we can fit? if so set to avail space */ /* Is our_funding more than we can fit? if so set to avail space */
if (amount_sat_greater(*our_funding, avail_channel_space)) if (amount_sat_greater(*our_funding, avail_channel_space))
@ -249,8 +251,8 @@ calculate_our_funding(struct funder_policy policy,
/* Is our_funding more than we want to fund in a channel? /* Is our_funding more than we want to fund in a channel?
* if so set at our desired per-channel max */ * if so set at our desired per-channel max */
if (amount_sat_greater(*our_funding, policy.per_channel_max)) if (amount_sat_greater(*our_funding, policy->per_channel_max))
*our_funding = policy.per_channel_max; *our_funding = policy->per_channel_max;
/* Is our_funding more than we have available? if so /* Is our_funding more than we have available? if so
* set to max available */ * set to max available */
@ -259,7 +261,7 @@ calculate_our_funding(struct funder_policy policy,
/* Is our_funding less than our per-channel minimum? /* Is our_funding less than our per-channel minimum?
* if so, don't fund */ * if so, don't fund */
if (amount_sat_less(*our_funding, policy.per_channel_min)) { if (amount_sat_less(*our_funding, policy->per_channel_min)) {
*our_funding = AMOUNT_SAT(0); *our_funding = AMOUNT_SAT(0);
return tal_fmt(tmpctx, "Can't meet our min channel requirement." return tal_fmt(tmpctx, "Can't meet our min channel requirement."
" our_funding %s," " our_funding %s,"
@ -267,7 +269,7 @@ calculate_our_funding(struct funder_policy policy,
type_to_string(tmpctx, struct amount_sat, type_to_string(tmpctx, struct amount_sat,
our_funding), our_funding),
type_to_string(tmpctx, struct amount_sat, type_to_string(tmpctx, struct amount_sat,
&policy.per_channel_min)); &policy->per_channel_min));
} }
return NULL; return NULL;

View File

@ -55,8 +55,9 @@ struct funder_policy {
u32 fund_probability; u32 fund_probability;
}; };
struct funder_policy struct funder_policy *
new_funder_policy(enum funder_opt opt, new_funder_policy(const tal_t *ctx,
enum funder_opt opt,
u64 policy_mod, u64 policy_mod,
struct amount_sat min_their_funding, struct amount_sat min_their_funding,
struct amount_sat max_their_funding, struct amount_sat max_their_funding,
@ -67,14 +68,15 @@ new_funder_policy(enum funder_opt opt,
u32 fund_probability); u32 fund_probability);
/* Get a new funder_policy, set to the defaults */ /* Get a new funder_policy, set to the defaults */
struct funder_policy struct funder_policy *
default_funder_policy(enum funder_opt policy, default_funder_policy(const tal_t *ctx,
enum funder_opt policy,
u64 policy_mod); u64 policy_mod);
/* Given the policy and this request's details, figure /* Given the policy and this request's details, figure
* out how much we should contribute to this channel */ * out how much we should contribute to this channel */
const char * const char *
calculate_our_funding(struct funder_policy policy, calculate_our_funding(struct funder_policy *policy,
struct node_id id, struct node_id id,
struct amount_sat their_funding, struct amount_sat their_funding,
struct amount_sat available_funds, struct amount_sat available_funds,
@ -86,7 +88,7 @@ const char *funder_opt_name(enum funder_opt opt);
/* Get a (short, for now) description of the provided policy */ /* Get a (short, for now) description of the provided policy */
const char *funder_policy_desc(const tal_t *ctx, const char *funder_policy_desc(const tal_t *ctx,
const struct funder_policy policy); const struct funder_policy *policy);
/* Convert a cmdline option to a funding_opt */ /* Convert a cmdline option to a funding_opt */
char *funding_option(const char *arg, enum funder_opt *opt); char *funding_option(const char *arg, enum funder_opt *opt);

View File

@ -376,7 +376,7 @@ static void check_fuzzing(struct test_case fuzzcase)
memset(&id, 2, sizeof(struct node_id)); memset(&id, 2, sizeof(struct node_id));
for (size_t i = 0; i < 100; i++) { for (size_t i = 0; i < 100; i++) {
calculate_our_funding(fuzzcase.policy, id, calculate_our_funding(&fuzzcase.policy, id,
fuzzcase.their_funds, fuzzcase.their_funds,
fuzzcase.available_funds, fuzzcase.available_funds,
fuzzcase.channel_max, fuzzcase.channel_max,
@ -393,7 +393,7 @@ static void check_fuzzing(struct test_case fuzzcase)
int main(int argc, const char *argv[]) int main(int argc, const char *argv[])
{ {
struct funder_policy policy; struct funder_policy *policy;
struct node_id id; struct node_id id;
struct amount_sat empty = AMOUNT_SAT(0), our_funds; struct amount_sat empty = AMOUNT_SAT(0), our_funds;
bool ok = true; bool ok = true;
@ -406,7 +406,7 @@ int main(int argc, const char *argv[])
memset(&id, 2, sizeof(struct node_id)); memset(&id, 2, sizeof(struct node_id));
/* Check the default funder policy, at fixed (0msat) */ /* Check the default funder policy, at fixed (0msat) */
policy = default_funder_policy(FIXED, 0); policy = default_funder_policy(tmpctx, FIXED, 0);
err = calculate_our_funding(policy, id, err = calculate_our_funding(policy, id,
AMOUNT_SAT(50000), AMOUNT_SAT(50000),
@ -417,14 +417,14 @@ int main(int argc, const char *argv[])
assert(!err); assert(!err);
for (i = 0; i < ARRAY_SIZE(cases); i++) { for (i = 0; i < ARRAY_SIZE(cases); i++) {
err = calculate_our_funding(cases[i].policy, id, err = calculate_our_funding(&cases[i].policy, id,
cases[i].their_funds, cases[i].their_funds,
cases[i].available_funds, cases[i].available_funds,
cases[i].channel_max, cases[i].channel_max,
&our_funds); &our_funds);
if (!amount_sat_eq(cases[i].exp_our_funds, our_funds)) { if (!amount_sat_eq(cases[i].exp_our_funds, our_funds)) {
fprintf(stderr, "FAIL policy: %s. expected %s, got %s\n", fprintf(stderr, "FAIL policy: %s. expected %s, got %s\n",
funder_policy_desc(NULL, cases[i].policy), funder_policy_desc(NULL, &cases[i].policy),
type_to_string(NULL, struct amount_sat, type_to_string(NULL, struct amount_sat,
&cases[i].exp_our_funds), &cases[i].exp_our_funds),
type_to_string(NULL, struct amount_sat, type_to_string(NULL, struct amount_sat,
@ -434,7 +434,7 @@ int main(int argc, const char *argv[])
if (cases[i].expect_err != (err != NULL)) { if (cases[i].expect_err != (err != NULL)) {
fprintf(stderr, "FAIL policy: %s. expected %serr," fprintf(stderr, "FAIL policy: %s. expected %serr,"
" got %s\n", " got %s\n",
funder_policy_desc(NULL, cases[i].policy), funder_policy_desc(NULL, &cases[i].policy),
cases[i].expect_err ? "" : "no ", cases[i].expect_err ? "" : "no ",
err ? err : "no err"); err ? err : "no err");
ok = false; ok = false;
@ -450,7 +450,7 @@ int main(int argc, const char *argv[])
flipcase.policy.fund_probability = flips; flipcase.policy.fund_probability = flips;
for (i = 0; i < 100 * flips; i++) { for (i = 0; i < 100 * flips; i++) {
calculate_our_funding(flipcase.policy, id, calculate_our_funding(&flipcase.policy, id,
flipcase.their_funds, flipcase.their_funds,
flipcase.available_funds, flipcase.available_funds,
flipcase.channel_max, flipcase.channel_max,