Browse Source

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 <rusty@rustcorp.com.au>
pull/2938/head
Rusty Russell 5 years ago
committed by Christian Decker
parent
commit
6901732ee0
  1. 28
      common/features.c
  2. 3
      common/features.h
  3. 19
      lightningd/options.c
  4. 14
      tests/test_misc.py

28
common/features.c

@ -1,6 +1,7 @@
#include "features.h"
#include <assert.h>
#include <ccan/array_size/array_size.h>
#include <common/utils.h>
#include <wire/peer_wire.h>
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;
}

3
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,

19
lightningd/options.c

@ -13,6 +13,7 @@
#include <ccan/tal/str/str.h>
#include <common/configdir.h>
#include <common/derive_basepoints.h>
#include <common/features.h>
#include <common/json_command.h>
#include <common/jsonrpc_errors.h>
#include <common/memleak.h>
@ -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

14
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

Loading…
Cancel
Save