lightningd: add force-feerates option.
Useful for regtest and testnet. Sure, you shouldn't use this on mainnet, but I haven't restricted it because our users are usually pretty clever. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Fixes: #1806 Changelog-Added: config: `force_feerates` option to allow overriding feerate estimates (mainly for regtest).
This commit is contained in:
parent
131e79ab91
commit
adab9eb301
|
@ -148,6 +148,8 @@ On success, an object is returned, containing:
|
|||
.IP \[bu]
|
||||
\fBlog-timestamps\fR (boolean, optional): \fBlog-timestamps\fR field from config or cmdline, or default
|
||||
.IP \[bu]
|
||||
\fBforce-feerates\fR (string, optional): \fBforce-feerates\fR field from config or cmdline, if any
|
||||
.IP \[bu]
|
||||
\fBsubdaemon\fR (string, optional): \fBsubdaemon\fR fields from config or cmdline if any (can be more than one)
|
||||
.IP \[bu]
|
||||
\fBtor-service-password\fR (string, optional): \fBtor-service-password\fR field from config or cmdline, if any
|
||||
|
@ -268,4 +270,4 @@ Vincenzo Palazzo \fI<vincenzo.palazzo@protonmail.com\fR> wrote the initial versi
|
|||
|
||||
Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
||||
|
||||
\" SHA256STAMP:f813a777c6e074907980797dafd798a48633469a59e1ac526e2581e2b1a14c83
|
||||
\" SHA256STAMP:4591f6c754162b2dcdf82a36d584a48795752d39a986bc1d39c49e0cdbea440f
|
||||
|
|
|
@ -84,6 +84,7 @@ On success, an object is returned, containing:
|
|||
- **log-prefix** (string, optional): `log-prefix` field from config or cmdline, or default
|
||||
- **log-file** (string, optional): `log-file` field from config or cmdline, or default
|
||||
- **log-timestamps** (boolean, optional): `log-timestamps` field from config or cmdline, or default
|
||||
- **force-feerates** (string, optional): `force-feerates` field from config or cmdline, if any
|
||||
- **subdaemon** (string, optional): `subdaemon` fields from config or cmdline if any (can be more than one)
|
||||
- **tor-service-password** (string, optional): `tor-service-password` field from config or cmdline, if any
|
||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||
|
@ -203,4 +204,4 @@ RESOURCES
|
|||
---------
|
||||
|
||||
Main web site: <https://github.com/ElementsProject/lightning>
|
||||
[comment]: # ( SHA256STAMP:3c3f2cd354ef5b33ad34febd29b04b1861c62d545c6a5b9181eb2b2b3880258f)
|
||||
[comment]: # ( SHA256STAMP:ad98179a7b6254a936d4fde179918b6a975e186adcbc396917a0c2ed2888519e)
|
||||
|
|
|
@ -316,6 +316,21 @@ How long to wait before sending commitment messages to the peer: in
|
|||
theory increasing this would reduce load, but your node would have to be
|
||||
extremely busy node for you to even notice\.
|
||||
|
||||
|
||||
\fBforce-feerates\fR==\fIVALUES\fR
|
||||
Networks like regtest and testnet have unreliable fee estimates: we
|
||||
usually treat them as the minumum (253 sats/kw) if we can't get them\.
|
||||
This allows override of one or more of our standard feerates (see
|
||||
\fBlightning-feerates\fR(7))\. Up to 5 values, separated by '/' can be
|
||||
provided: if fewer are provided, then the final value is used for the
|
||||
remainder\. The values are in per-kw (roughly 1/4 of bitcoind's per-kb
|
||||
values), an in order are "opening", "mutual_close",
|
||||
"unilateral_close", "delayed_to_us", "htlc_resolution", and "penalty"\.
|
||||
|
||||
|
||||
You would usually put this option in the per-chain config file, to avoid
|
||||
setting it on Bitcoin mainnet! e\.g\. \fB~rusty/.lightning/regtest/config\fR\.
|
||||
|
||||
.SH Lightning channel and HTLC options
|
||||
|
||||
\fBlarge-channels\fR
|
||||
|
@ -635,4 +650,4 @@ Main web site: \fIhttps://github.com/ElementsProject/lightning\fR
|
|||
Note: the modules in the ccan/ directory have their own licenses, but
|
||||
the rest of the code is covered by the BSD-style MIT license\.
|
||||
|
||||
\" SHA256STAMP:40c9f5e9e4ee5257e25a1fc196d2c85c3bc5b21d3f390a4e7fafa031c4e7ad5e
|
||||
\" SHA256STAMP:d456e1acd004f9528d8772231afdecff1aaa01d80161c833483f6f078f4c7d70
|
||||
|
|
|
@ -257,6 +257,19 @@ How long to wait before sending commitment messages to the peer: in
|
|||
theory increasing this would reduce load, but your node would have to be
|
||||
extremely busy node for you to even notice.
|
||||
|
||||
**force-feerates**==*VALUES*
|
||||
Networks like regtest and testnet have unreliable fee estimates: we
|
||||
usually treat them as the minumum (253 sats/kw) if we can't get them.
|
||||
This allows override of one or more of our standard feerates (see
|
||||
lightning-feerates(7)). Up to 5 values, separated by '/' can be
|
||||
provided: if fewer are provided, then the final value is used for the
|
||||
remainder. The values are in per-kw (roughly 1/4 of bitcoind's per-kb
|
||||
values), an in order are "opening", "mutual_close",
|
||||
"unilateral_close", "delayed_to_us", "htlc_resolution", and "penalty".
|
||||
|
||||
You would usually put this option in the per-chain config file, to avoid
|
||||
setting it on Bitcoin mainnet! e.g. `~rusty/.lightning/regtest/config`.
|
||||
|
||||
### Lightning channel and HTLC options
|
||||
|
||||
**large-channels**
|
||||
|
|
|
@ -235,6 +235,10 @@
|
|||
"type": "boolean",
|
||||
"description": "`log-timestamps` field from config or cmdline, or default"
|
||||
},
|
||||
"force-feerates": {
|
||||
"type": "string",
|
||||
"description": "force-feerate configuration setting, if any"
|
||||
},
|
||||
"subdaemon": {
|
||||
"type": "string",
|
||||
"description": "`subdaemon` fields from config or cmdline if any (can be more than one)"
|
||||
|
|
|
@ -187,6 +187,12 @@ static void estimatefees_callback(const char *buf, const jsmntok_t *toks,
|
|||
bitcoin_plugin_error(call->bitcoind, buf, toks,
|
||||
"estimatefees",
|
||||
"missing '%s' field", feerate_name(f));
|
||||
/* We still use the bcli plugin for min and max, even with
|
||||
* force_feerates */
|
||||
if (f < tal_count(call->bitcoind->ld->force_feerates)) {
|
||||
feerates[f] = call->bitcoind->ld->force_feerates[f];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* FIXME: We could trawl recent blocks for median fee... */
|
||||
if (!json_to_u32(buf, feeratetok, &feerates[f])) {
|
||||
|
|
|
@ -22,6 +22,7 @@ struct txwatch;
|
|||
|
||||
/* FIXME: move all feerate stuff out to new lightningd/feerate.[ch] files */
|
||||
enum feerate {
|
||||
/* DO NOT REORDER: force-feerates uses this order! */
|
||||
FEERATE_OPENING,
|
||||
FEERATE_MUTUAL_CLOSE,
|
||||
FEERATE_UNILATERAL_CLOSE,
|
||||
|
|
|
@ -290,6 +290,11 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
|
|||
* each invoice we generate has a different set of channels. */
|
||||
ld->rr_counter = 0;
|
||||
|
||||
/*~ Because fee estimates on testnet and regtest are unreliable,
|
||||
* we allow overriding them with --force-feerates, in which
|
||||
* case this is a pointer to an enum feerate-indexed array of values */
|
||||
ld->force_feerates = NULL;
|
||||
|
||||
return ld;
|
||||
}
|
||||
|
||||
|
|
|
@ -199,6 +199,10 @@ struct lightningd {
|
|||
/* RPC response to send once we've shut down. */
|
||||
const char *stop_response;
|
||||
|
||||
/* Used these feerates instead of whatever bcli returns (up to
|
||||
* FEERATE_PENALTY). */
|
||||
u32 *force_feerates;
|
||||
|
||||
#if DEVELOPER
|
||||
/* If we want to debug a subdaemon/plugin. */
|
||||
const char *dev_debug_subprocess;
|
||||
|
|
|
@ -131,6 +131,51 @@ static char *opt_set_mode(const char *arg, mode_t *m)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static char *opt_force_feerates(const char *arg, struct lightningd *ld)
|
||||
{
|
||||
char **vals = tal_strsplit(tmpctx, arg, "/", STR_EMPTY_OK);
|
||||
size_t n;
|
||||
|
||||
/* vals has NULL at end, enum feerate is 0 based */
|
||||
if (tal_count(vals) - 1 > FEERATE_PENALTY + 1)
|
||||
return "Too many values";
|
||||
|
||||
if (!ld->force_feerates)
|
||||
ld->force_feerates = tal_arr(ld, u32, FEERATE_PENALTY + 1);
|
||||
|
||||
n = 0;
|
||||
for (size_t i = 0; i < tal_count(ld->force_feerates); i++) {
|
||||
char *err = opt_set_u32(vals[n], &ld->force_feerates[i]);
|
||||
if (err)
|
||||
return err;
|
||||
fprintf(stderr, "Set feerate %zu based on val %zu\n", i, n);
|
||||
if (vals[n+1])
|
||||
n++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *fmt_force_feerates(const tal_t *ctx, const u32 *force_feerates)
|
||||
{
|
||||
char *ret;
|
||||
size_t last;
|
||||
|
||||
if (!force_feerates)
|
||||
return NULL;
|
||||
|
||||
ret = tal_fmt(ctx, "%i", force_feerates[0]);
|
||||
last = 0;
|
||||
for (size_t i = 1; i < tal_count(force_feerates); i++) {
|
||||
if (force_feerates[i] == force_feerates[i-1])
|
||||
continue;
|
||||
/* Different? Catchup! */
|
||||
for (size_t j = last + 1; j <= i; j++)
|
||||
tal_append_fmt(&ret, "/%i", force_feerates[j]);
|
||||
last = i;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if EXPERIMENTAL_FEATURES
|
||||
static char *opt_set_accept_extra_tlv_types(const char *arg,
|
||||
struct lightningd *ld)
|
||||
|
@ -1003,6 +1048,10 @@ static void register_opts(struct lightningd *ld)
|
|||
"Set the file mode (permissions) for the "
|
||||
"JSON-RPC socket");
|
||||
|
||||
opt_register_arg("--force-feerates",
|
||||
opt_force_feerates, NULL, ld,
|
||||
"Set testnet/regtest feerates in sats perkw, opening/mutual_close/unlateral_close/delayed_to_us/htlc_resolution/penalty: if fewer specified, last number applies to remainder");
|
||||
|
||||
opt_register_arg("--subdaemon", opt_subdaemon, NULL,
|
||||
ld, "Arg specified as SUBDAEMON:PATH. "
|
||||
"Specifies an alternate subdaemon binary. "
|
||||
|
@ -1423,6 +1472,8 @@ static void add_config(struct lightningd *ld,
|
|||
json_add_opt_log_levels(response, ld->log);
|
||||
} else if (opt->cb_arg == (void *)opt_disable_plugin) {
|
||||
json_add_opt_disable_plugins(response, ld->plugins);
|
||||
} else if (opt->cb_arg == (void *)opt_force_feerates) {
|
||||
answer = fmt_force_feerates(name0, ld->force_feerates);
|
||||
} else if (opt->cb_arg == (void *)opt_important_plugin) {
|
||||
/* Do nothing, this is already handled by
|
||||
* opt_add_plugin. */
|
||||
|
|
|
@ -2561,3 +2561,48 @@ def test_getlog(node_factory):
|
|||
# This should not
|
||||
logs = l1.rpc.getlog(level='io')['log']
|
||||
assert [l for l in logs if l['type'] == 'SKIPPED'] == []
|
||||
|
||||
|
||||
def test_force_feerates(node_factory):
|
||||
l1 = node_factory.get_node(options={'force-feerates': 1111})
|
||||
assert l1.rpc.listconfigs()['force-feerates'] == '1111'
|
||||
|
||||
assert l1.rpc.feerates('perkw')['perkw'] == {
|
||||
"opening": 1111,
|
||||
"mutual_close": 1111,
|
||||
"unilateral_close": 1111,
|
||||
"delayed_to_us": 1111,
|
||||
"htlc_resolution": 1111,
|
||||
"penalty": 1111,
|
||||
"min_acceptable": 1875,
|
||||
"max_acceptable": 150000}
|
||||
|
||||
l1.stop()
|
||||
l1.daemon.opts['force-feerates'] = '1111/2222'
|
||||
l1.start()
|
||||
|
||||
assert l1.rpc.listconfigs()['force-feerates'] == '1111/2222'
|
||||
assert l1.rpc.feerates('perkw')['perkw'] == {
|
||||
"opening": 1111,
|
||||
"mutual_close": 2222,
|
||||
"unilateral_close": 2222,
|
||||
"delayed_to_us": 2222,
|
||||
"htlc_resolution": 2222,
|
||||
"penalty": 2222,
|
||||
"min_acceptable": 1875,
|
||||
"max_acceptable": 150000}
|
||||
|
||||
l1.stop()
|
||||
l1.daemon.opts['force-feerates'] = '1111/2222/3333/4444/5555/6666'
|
||||
l1.start()
|
||||
|
||||
assert l1.rpc.listconfigs()['force-feerates'] == '1111/2222/3333/4444/5555/6666'
|
||||
assert l1.rpc.feerates('perkw')['perkw'] == {
|
||||
"opening": 1111,
|
||||
"mutual_close": 2222,
|
||||
"unilateral_close": 3333,
|
||||
"delayed_to_us": 4444,
|
||||
"htlc_resolution": 5555,
|
||||
"penalty": 6666,
|
||||
"min_acceptable": 1875,
|
||||
"max_acceptable": 150000}
|
||||
|
|
Loading…
Reference in New Issue