From c46473e61549e6d927914c8496dfdabea073badf Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 7 Apr 2023 14:13:45 +0930 Subject: [PATCH] lightningd: allow "NNblocks" and "minimum" as feerates. And consolidate descriptions into lightning-feerates(). Signed-off-by: Rusty Russell Changelog-Added: JSON-RPC: `close`, `fundchannel`, `fundpsbt`, `multifundchannel`, `multiwithdraw`, `txprepare`, `upgradewallet`, `withdraw` now allow "minimum" and NN"blocks" as `feerate` (`feerange` for `close`). --- contrib/pyln-testing/pyln/testing/fixtures.py | 2 +- doc/lightning-close.7.md | 11 +---------- doc/lightning-feerates.7.md | 19 +++++++++++++------ doc/lightning-fundchannel.7.md | 13 +++---------- doc/lightning-fundpsbt.7.md | 10 ++-------- doc/lightning-multifundchannel.7.md | 15 ++++----------- doc/lightning-multiwithdraw.7.md | 11 ++--------- doc/lightning-txprepare.7.md | 11 ++--------- doc/lightning-upgradewallet.7.md | 10 ++-------- doc/lightning-withdraw.7.md | 11 ++--------- lightningd/feerate.c | 19 +++++++++++++++++++ lightningd/test/run-jsonrpc.c | 3 +++ tests/test_misc.py | 15 +++++++++++++++ 13 files changed, 69 insertions(+), 81 deletions(-) diff --git a/contrib/pyln-testing/pyln/testing/fixtures.py b/contrib/pyln-testing/pyln/testing/fixtures.py index c70bee6e4..bf3293d24 100644 --- a/contrib/pyln-testing/pyln/testing/fixtures.py +++ b/contrib/pyln-testing/pyln/testing/fixtures.py @@ -295,7 +295,7 @@ def _extra_validator(is_request: bool): return True if not checker.is_type(instance, "string"): return False - if instance in ("urgent", "normal", "slow"): + if instance in ("urgent", "normal", "slow", "minimum"): return True if instance in ("opening", "mutual_close", "unilateral_close", "delayed_to_us", "htlc_resolution", "penalty", "min_acceptable", "max_acceptable"): return True diff --git a/doc/lightning-close.7.md b/doc/lightning-close.7.md index 8107124fb..853df15c6 100644 --- a/doc/lightning-close.7.md +++ b/doc/lightning-close.7.md @@ -66,16 +66,7 @@ unless this flag is passed in. Defaults to false. *feerange* is an optional array [ *min*, *max* ], indicating the minimum and maximum feerates to offer: the peer will obey these if it supports the quick-close protocol. *slow* and *unilateral\_close* are -the defaults. - -Rates are one of the strings *urgent* (aim for next block), *normal* -(next 4 blocks or so) or *slow* (next 100 blocks or so) to use -lightningd's internal estimates, or one of the names from -lightning-feerates(7). Otherwise, they can be numbers with -an optional suffix: *perkw* means the number is interpreted as -satoshi-per-kilosipa (weight), and *perkb* means it is interpreted -bitcoind-style as satoshi-per-kilobyte. Omitting the suffix is -equivalent to *perkb*. +the defaults. See NOTES in lightning-feerates(7) for possible values. Note that the maximum fee will be capped at the final commitment transaction fee (unless the experimental anchor-outputs option is diff --git a/doc/lightning-feerates.7.md b/doc/lightning-feerates.7.md index 3344f4b92..bcda750e5 100644 --- a/doc/lightning-feerates.7.md +++ b/doc/lightning-feerates.7.md @@ -96,13 +96,20 @@ if feerate estimates for that kind of transaction are unavailable. NOTES ----- -Many other commands have a *feerate* parameter, which can be the strings -*urgent*, *normal*, or *slow*. -These are mapped to the **feerates** outputs as: +Many other commands have a *feerate* parameter. This can be: -* *urgent* - equal to *unilateral\_close* -* *normal* - equal to *opening* -* *slow* - equal to *min\_acceptable*. +* One of the strings to use lightningd's internal estimates: + * *urgent* (aim for next block), + * *normal* (next 6 blocks or so) + * *slow* (next 100 blocks or so) + * *minimum* for the lowest value bitcoind will currently accept (added in v23.05) + +* A number, with an optional suffix: + * *blocks* means aim for confirmation in that many blocks (added in v23.05) + * *perkw* means the number is interpreted as satoshi-per-kilosipa (weight) + * *perkb* means it is interpreted bitcoind-style as satoshi-per-kilobyte. + +Omitting the suffix is equivalent to *perkb*. TRIVIA ------ diff --git a/doc/lightning-fundchannel.7.md b/doc/lightning-fundchannel.7.md index 5ee6c46a2..b8c15e842 100644 --- a/doc/lightning-fundchannel.7.md +++ b/doc/lightning-fundchannel.7.md @@ -35,16 +35,9 @@ decimal places ending in *btc*. The value cannot be less than the dust limit, currently set to 546, nor more than 16777215 satoshi (unless large channels were negotiated with the peer). -*feerate* is an optional feerate used for the opening transaction and as -initial feerate for commitment and HTLC transactions. It can be one of -the strings *urgent* (aim for next block), *normal* (next 4 blocks or -so) or *slow* (next 100 blocks or so) to use lightningd's internal -estimates: *normal* is the default. - -Otherwise, *feerate* is a number, with an optional suffix: *perkw* means -the number is interpreted as satoshi-per-kilosipa (weight), and *perkb* -means it is interpreted bitcoind-style as satoshi-per-kilobyte. Omitting -the suffix is equivalent to *perkb*. +*feerate* is an optional feerate used for the opening transaction and +as initial feerate for commitment and HTLC transactions (see NOTES in +lightning-feerates(7)). The default is *normal*. *announce* is an optional flag that triggers whether to announce this channel or not. Defaults to `true`. An unannounced channel is considered diff --git a/doc/lightning-fundpsbt.7.md b/doc/lightning-fundpsbt.7.md index 5e25e4861..eaac0fb05 100644 --- a/doc/lightning-fundpsbt.7.md +++ b/doc/lightning-fundpsbt.7.md @@ -18,14 +18,8 @@ be a whole number, a whole number ending in *sat*, a whole number ending in *000msat*, or a number with 1 to 8 decimal places ending in *btc*. -*feerate* can be one of the feerates listed in lightning-feerates(7), -or one of the strings *urgent* (aim for next block), *normal* (next 4 -blocks or so) or *slow* (next 100 blocks or so) to use lightningd's -internal estimates. It can also be a *feerate* is a number, with an -optional suffix: *perkw* means the number is interpreted as -satoshi-per-kilosipa (weight), and *perkb* means it is interpreted -bitcoind-style as satoshi-per-kilobyte. Omitting the suffix is -equivalent to *perkb*. +*feerate* is an optional feerate: see NOTES in lightning-feerates(7) +for possible values. The default is *normal*. *startweight* is the weight of the transaction before *fundpsbt* has added any inputs. diff --git a/doc/lightning-multifundchannel.7.md b/doc/lightning-multifundchannel.7.md index 2c6b63a02..0203be78e 100644 --- a/doc/lightning-multifundchannel.7.md +++ b/doc/lightning-multifundchannel.7.md @@ -65,17 +65,10 @@ Readiness is indicated by **listpeers** reporting a *state* of There must be at least one entry in *destinations*; it cannot be an empty array. -*feerate* is an optional feerate used for the opening transaction and, if -*commitment\_feerate* is not set, as the initial feerate for -commitment and HTLC transactions. It can be one of -the strings *urgent* (aim for next block), *normal* (next 4 blocks or -so) or *slow* (next 100 blocks or so) to use lightningd's internal -estimates: *normal* is the default. - -Otherwise, *feerate* is a number, with an optional suffix: *perkw* means -the number is interpreted as satoshi-per-kilosipa (weight), and *perkb* -means it is interpreted bitcoind-style as satoshi-per-kilobyte. Omitting -the suffix is equivalent to *perkb*. +*feerate* is an optional feerate used for the opening transaction, and +if *commitment\_feerate* is not set, as initial feerate for commitment +and HTLC transactions. See NOTES in lightning-feerates(7) for possible +values. The default is *normal*. *minconf* specifies the minimum number of confirmations that used outputs should have. Default is 1. diff --git a/doc/lightning-multiwithdraw.7.md b/doc/lightning-multiwithdraw.7.md index ae09c2bdf..a1807c7e8 100644 --- a/doc/lightning-multiwithdraw.7.md +++ b/doc/lightning-multiwithdraw.7.md @@ -21,15 +21,8 @@ a whole number ending in *sat*, a whole number ending in *000msat*, or a number with 1 to 8 decimal places ending in *btc*. -*feerate* is an optional feerate to use. It can be one of the strings -*urgent* (aim for next block), *normal* (next 4 blocks or so) or *slow* -(next 100 blocks or so) to use lightningd's internal estimates: *normal* -is the default. - -Otherwise, *feerate* is a number, with an optional suffix: *perkw* means -the number is interpreted as satoshi-per-kilosipa (weight), and *perkb* -means it is interpreted bitcoind-style as satoshi-per-kilobyte. Omitting -the suffix is equivalent to *perkb*. +*feerate* is an optional feerate: see NOTES in lightning-feerates(7) +for possible values. The default is *normal*. *minconf* specifies the minimum number of confirmations that used outputs should have. Default is 1. diff --git a/doc/lightning-txprepare.7.md b/doc/lightning-txprepare.7.md index 37655098c..62681d142 100644 --- a/doc/lightning-txprepare.7.md +++ b/doc/lightning-txprepare.7.md @@ -29,15 +29,8 @@ all available funds. Otherwise, it is in amount precision; it can be a whole number, a whole number ending in *sat*, a whole number ending in *000msat*, or a number with 1 to 8 decimal places ending in *btc*. -*feerate* is an optional feerate to use. It can be one of the strings -*urgent* (aim for next block), *normal* (next 4 blocks or so) or *slow* -(next 100 blocks or so) to use lightningd's internal estimates: *normal* -is the default. - -Otherwise, *feerate* is a number, with an optional suffix: *perkw* means -the number is interpreted as satoshi-per-kilosipa (weight), and *perkb* -means it is interpreted bitcoind-style as satoshi-per-kilobyte. Omitting -the suffix is equivalent to *perkb*. +*feerate* is an optional feerate to use: see NOTES in lightning-feerates(7) +for possible values. The default is *normal*. *minconf* specifies the minimum number of confirmations that used outputs should have. Default is 1. diff --git a/doc/lightning-upgradewallet.7.md b/doc/lightning-upgradewallet.7.md index 7df504509..a92cf7d04 100644 --- a/doc/lightning-upgradewallet.7.md +++ b/doc/lightning-upgradewallet.7.md @@ -12,14 +12,8 @@ DESCRIPTION `upgradewallet` is a convenience RPC which will spend all p2sh-wrapped Segwit deposits in a wallet into a single Native Segwit P2WPKH address. -*feerate* can be one of the feerates listed in lightning-feerates(7), -or one of the strings *urgent* (aim for next block), *normal* (next 4 -blocks or so) or *slow* (next 100 blocks or so) to use lightningd's -internal estimates. It can also be a *feerate* is a number, with an -optional suffix: *perkw* means the number is interpreted as -satoshi-per-kilosipa (weight), and *perkb* means it is interpreted -bitcoind-style as satoshi-per-kilobyte. Omitting the suffix is -equivalent to *perkb*. +*feerate* is an optional feerate: see NOTES in lightning-feerates(7) +for possible values. The default is *opening*. *reservedok* tells the wallet to include all P2SH-wrapped inputs, including reserved ones. diff --git a/doc/lightning-withdraw.7.md b/doc/lightning-withdraw.7.md index d5e188d09..23ae414ff 100644 --- a/doc/lightning-withdraw.7.md +++ b/doc/lightning-withdraw.7.md @@ -21,15 +21,8 @@ satoshi precision; it can be a whole number, a whole number ending in *sat*, a whole number ending in *000msat*, or a number with 1 to 8 decimal places ending in *btc*. -*feerate* is an optional feerate to use. It can be one of the strings -*urgent* (aim for next block), *normal* (next 4 blocks or so) or *slow* -(next 100 blocks or so) to use lightningd's internal estimates: *normal* -is the default. - -Otherwise, *feerate* is a number, with an optional suffix: *perkw* means -the number is interpreted as satoshi-per-kilosipa (weight), and *perkb* -means it is interpreted bitcoind-style as satoshi-per-kilobyte. Omitting -the suffix is equivalent to *perkb*. +*feerate* is an optional feerate: see NOTES in lightning-feerates(7) +for possible values. The default is *normal*. *minconf* specifies the minimum number of confirmations that used outputs should have. Default is 1. diff --git a/lightningd/feerate.c b/lightningd/feerate.c index d0e0a277b..07a5f5f78 100644 --- a/lightningd/feerate.c +++ b/lightningd/feerate.c @@ -120,6 +120,25 @@ static struct command_result *param_feerate_unchecked(struct command *cmd, } else if (json_tok_streq(buffer, tok, "urgent")) { **feerate = feerate_for_deadline(cmd->ld->topology, 6); return NULL; + } else if (json_tok_streq(buffer, tok, "minimum")) { + **feerate = get_feerate_floor(cmd->ld->topology); + return NULL; + } + + /* Can specify number of blocks as a target */ + if (json_tok_endswith(buffer, tok, "blocks")) { + jsmntok_t base = *tok; + base.end -= strlen("blocks"); + u32 numblocks; + + if (!json_to_number(buffer, &base, &numblocks)) { + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "'%s' should be an integer not '%.*s'", + name, base.end - base.start, + buffer + base.start); + } + **feerate = feerate_for_deadline(cmd->ld->topology, numblocks); + return NULL; } /* It's a number... */ diff --git a/lightningd/test/run-jsonrpc.c b/lightningd/test/run-jsonrpc.c index 87475b204..215130fe1 100644 --- a/lightningd/test/run-jsonrpc.c +++ b/lightningd/test/run-jsonrpc.c @@ -40,6 +40,9 @@ bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, /* Generated stub for fromwire_node_id */ void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED) { fprintf(stderr, "fromwire_node_id called!\n"); abort(); } +/* Generated stub for get_feerate_floor */ +u32 get_feerate_floor(const struct chain_topology *topo UNNEEDED) +{ fprintf(stderr, "get_feerate_floor called!\n"); abort(); } /* Generated stub for htlc_resolution_feerate */ u32 htlc_resolution_feerate(struct chain_topology *topo UNNEEDED) { fprintf(stderr, "htlc_resolution_feerate called!\n"); abort(); } diff --git a/tests/test_misc.py b/tests/test_misc.py index c808fd479..93f177759 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -3282,10 +3282,25 @@ def test_feerate_arg(node_factory): fees["penalty"] = by_blocks[12] fees["unilateral_close"] = by_blocks[6] + fees["2blocks"] = by_blocks[2] + fees["6blocks"] = by_blocks[6] + fees["12blocks"] = by_blocks[12] + fees["100blocks"] = by_blocks[100] + + # Simple interpolation + fees["9blocks"] = (by_blocks[6] + by_blocks[12]) // 2 + for fee, expect in fees.items(): # Put arg in assertion, so it gets printed on failure! assert (l1.rpc.parsefeerate(fee), fee) == ({'perkw': expect}, fee) + # More thorough interpolation + for block in range(12, 100): + # y = y1 + (x-x1)(y2-y1)/(x2-x1) + fee = by_blocks[12] + (block - 12) * (by_blocks[100] - by_blocks[12]) // (100 - 12) + # Rounding error is a thing! + assert abs(l1.rpc.parsefeerate(f"{block}blocks")['perkw'] - fee) <= 1 + @pytest.mark.skip(reason="Fails by intention for creating test gossip stores") def test_create_gossip_mesh(node_factory, bitcoind):