From 6901732ee05b31a8796fbe297144e437b8789744 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 29 Aug 2019 10:31:55 +0930 Subject: [PATCH] lightningd: create --list-features-only which lists what features we support. This allows the lightning-rfc protocol tests to automatically query what features we support. Signed-off-by: Rusty Russell --- common/features.c | 28 ++++++++++++++++++++++++++++ common/features.h | 3 +++ lightningd/options.c | 19 +++++++++++++++++-- tests/test_misc.py | 14 +++++++++++++- 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/common/features.c b/common/features.c index 358b53900..a4c07251b 100644 --- a/common/features.c +++ b/common/features.c @@ -1,6 +1,7 @@ #include "features.h" #include #include +#include #include static const u32 our_localfeatures[] = { @@ -150,3 +151,30 @@ bool global_feature_negotiated(const u8 *gfeatures, size_t f) return feature_supported(f, our_globalfeatures, ARRAY_SIZE(our_globalfeatures)); } + +static const char *feature_name(const tal_t *ctx, size_t f) +{ + static const char *fnames[] = { + "option_data_loss_protect", + "option_initial_routing_sync", + "option_upfront_shutdown_script", + "option_gossip_queries", + "option_var_onion_optin", + "option_gossip_queries_ex" }; + + assert(f / 2 < ARRAY_SIZE(fnames)); + return tal_fmt(ctx, "%s/%s", + fnames[f / 2], (f & 1) ? "odd" : "even"); +} + +const char **list_supported_features(const tal_t *ctx) +{ + const char **list = tal_arr(ctx, const char *, 0); + + /* The local/global number spaces are to be distinct, so this works */ + for (size_t i = 0; i < ARRAY_SIZE(our_localfeatures); i++) + tal_arr_expand(&list, feature_name(list, our_localfeatures[i])); + for (size_t i = 0; i < ARRAY_SIZE(our_globalfeatures); i++) + tal_arr_expand(&list, feature_name(list, our_globalfeatures[i])); + return list; +} diff --git a/common/features.h b/common/features.h index cd6bea624..59584ee8d 100644 --- a/common/features.h +++ b/common/features.h @@ -18,6 +18,9 @@ bool feature_offered(const u8 *features, size_t f); bool local_feature_negotiated(const u8 *lfeatures, size_t f); bool global_feature_negotiated(const u8 *gfeatures, size_t f); +/* Return a list of what features we advertize. */ +const char **list_supported_features(const tal_t *ctx); + /* BOLT #9: * * Flags are numbered from the least-significant bit, at bit 0 (i.e. 0x1, diff --git a/lightningd/options.c b/lightningd/options.c index 1647969e4..84112edea 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -723,6 +724,14 @@ static char *test_subdaemons_and_exit(struct lightningd *ld) return NULL; } +static char *list_features_and_exit(struct lightningd *ld) +{ + const char **features = list_supported_features(ld); + for (size_t i = 0; i < tal_count(features); i++) + printf("%s\n", features[i]); + exit(0); +} + static char *opt_lightningd_usage(struct lightningd *ld) { /* Reload config so that --help has the correct network defaults @@ -783,7 +792,8 @@ static char *opt_set_conf(const char *arg, struct lightningd *ld) return NULL; } -/* Just enough parsing to find config file. */ +/* Just enough parsing to find config file, and other maintenance options + * which don't want us to create the lightning dir */ static void handle_minimal_config_opts(struct lightningd *ld, int argc, char *argv[]) { @@ -796,6 +806,9 @@ static void handle_minimal_config_opts(struct lightningd *ld, opt_set_talstr, opt_show_charp, &ld->config_dir, "Set working directory. All other files are relative to this"); + opt_register_early_noarg("--list-features-only", + list_features_and_exit, + ld, opt_hidden); /* Handle --version (and exit) here too: don't create lightning-dir for this */ opt_register_version(); @@ -1133,7 +1146,9 @@ static void add_config(struct lightningd *ld, const char *answer = NULL; if (opt->type & OPT_NOARG) { - if (opt->cb == (void *)opt_usage_and_exit + if (opt->desc == opt_hidden) { + /* Ignore hidden options (deprecated) */ + } else if (opt->cb == (void *)opt_usage_and_exit || opt->cb == (void *)version_and_exit /* These two show up as --network= */ || opt->cb == (void *)opt_set_testnet diff --git a/tests/test_misc.py b/tests/test_misc.py index 0707ce610..027d1ae32 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -3,7 +3,7 @@ from fixtures import * # noqa: F401,F403 from flaky import flaky # noqa: F401 from lightning import RpcError from threading import Event -from utils import DEVELOPER, TIMEOUT, VALGRIND, sync_blockheight, only_one, wait_for, TailableProc +from utils import DEVELOPER, TIMEOUT, VALGRIND, sync_blockheight, only_one, wait_for, TailableProc, EXPERIMENTAL_FEATURES from ephemeral_port_reserve import reserve import json @@ -1435,3 +1435,15 @@ def test_dev_demux(node_factory): with pytest.raises(RpcError): l1.rpc.call('dev', {'subcommand': 'crash'}) + + +def test_list_features_only(node_factory): + features = subprocess.check_output(['lightningd/lightningd', + '--list-features-only']).decode('utf-8').splitlines() + expected = ['option_data_loss_protect/odd', + 'option_initial_routing_sync/odd', + 'option_upfront_shutdown_script/odd', + 'option_gossip_queries/odd'] + if EXPERIMENTAL_FEATURES: + expected.append('option_gossip_queries_ex/odd') + assert features == expected