From aab83e729b93d6ce2e2b4702681aaba71462bec8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 23 Nov 2019 12:16:40 +1030 Subject: [PATCH] lightningd: change config-dir from plugin / wallet / hsm POV into subdir Changelog-changed: .lightningd plugins and files moved into / subdir Changelog-changed: WARNING: If you don't have a config file, you now may need to specify the network to lightning-cli Signed-off-by: Rusty Russell --- README.md | 4 +- cli/lightning-cli.c | 13 +++--- cli/test/run-large-input.c | 9 ++++ cli/test/run-remove-hint.c | 9 +++- common/configdir.c | 50 ++++++++++++---------- common/configdir.h | 9 ++-- contrib/pyln-testing/pyln/testing/utils.py | 18 ++++---- devtools/checkchannels.c | 14 +++--- doc/PLUGINS.md | 4 +- doc/lightningd-config.5 | 7 ++- doc/lightningd-config.5.md | 7 ++- lightningd/lightningd.h | 4 +- lightningd/options.c | 26 ++++++----- lightningd/peer_control.c | 2 +- lightningd/plugin.c | 4 +- tests/test_connection.py | 6 +-- tests/test_gossip.py | 16 +++---- tests/test_misc.py | 32 +++++++++----- tests/test_plugin.py | 5 ++- tests/test_wallet.py | 2 +- 20 files changed, 143 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index 8ee807bb9..d9fcfbd30 100644 --- a/README.md +++ b/README.md @@ -190,8 +190,8 @@ interfaces) for more sophisticated use. `lightningd` can be configured either by passing options via the command line, or via a configuration file. Command line options will always override the values in the configuration file. -To use a configuration file, create a file named `config` within your lightning directory -(eg. `~/.lightning/config`). See `man -l doc/lightningd-config.5`. +To use a configuration file, create a file named `config` within your top-level lightning directory or network subdirectory +(eg. `~/.lightning/config` or `~/.lightning/bitcoin/config`). See `man -l doc/lightningd-config.5`. ## Further information diff --git a/cli/lightning-cli.c b/cli/lightning-cli.c index e827ad090..108307048 100644 --- a/cli/lightning-cli.c +++ b/cli/lightning-cli.c @@ -431,7 +431,7 @@ int main(int argc, char *argv[]) jsmntok_t *toks; const jsmntok_t *result, *error, *id; const tal_t *ctx = tal(NULL, char); - char *config_filename, *lightning_dir, *rpc_filename; + char *config_filename, *lightning_dir, *net_dir, *rpc_filename; jsmn_parser parser; int parserr; enum format format = DEFAULT_FORMAT; @@ -446,7 +446,8 @@ int main(int argc, char *argv[]) setup_option_allocators(); initial_config_opts(ctx, argc, argv, - &config_filename, &lightning_dir, &rpc_filename); + &config_filename, &lightning_dir, &net_dir, + &rpc_filename); opt_register_noarg("--help|-h", opt_usage_and_exit, " [...]", "Show this message. Use the command help (without hyphens -- \"lightning-cli help\") to get a list of all RPC commands"); @@ -491,9 +492,9 @@ int main(int argc, char *argv[]) tal_free(page); } - if (chdir(lightning_dir) != 0) + if (chdir(net_dir) != 0) err(ERROR_TALKING_TO_LIGHTNINGD, "Moving into '%s'", - lightning_dir); + net_dir); fd = socket(AF_UNIX, SOCK_STREAM, 0); if (strlen(rpc_filename) + 1 > sizeof(addr.sun_path)) @@ -627,8 +628,6 @@ int main(int argc, char *argv[]) default: abort(); } - tal_free(lightning_dir); - tal_free(rpc_filename); tal_free(ctx); opt_free_table(); return 0; @@ -641,8 +640,6 @@ int main(int argc, char *argv[]) print_json(resp, error, ""); printf("\n"); } - tal_free(lightning_dir); - tal_free(rpc_filename); tal_free(ctx); opt_free_table(); return 1; diff --git a/cli/test/run-large-input.c b/cli/test/run-large-input.c index f1791de7d..4af125b8c 100644 --- a/cli/test/run-large-input.c +++ b/cli/test/run-large-input.c @@ -15,6 +15,7 @@ int test_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); int test_getpid(void); int test_printf(const char *format, ...); +int test_chdir(const char *path); #define main test_main #define read test_read @@ -22,6 +23,7 @@ int test_printf(const char *format, ...); #define connect test_connect #define getpid test_getpid #define printf test_printf +#define chdir test_chdir #include "../lightning-cli.c" #undef main @@ -79,6 +81,11 @@ int test_printf(const char *fmt UNUSED, ...) return 0; } +int test_chdir(const char *path) +{ + return 0; +} + static char *response; static size_t response_off, max_read_return; @@ -140,5 +147,7 @@ int main(int argc UNUSED, char *argv[]) max_read_return = -1; assert(test_main(3, fake_argv) == 0); tal_free(response); + assert(!taken_any()); + take_cleanup(); return 0; } diff --git a/cli/test/run-remove-hint.c b/cli/test/run-remove-hint.c index cd0b6040d..8db904c19 100644 --- a/cli/test/run-remove-hint.c +++ b/cli/test/run-remove-hint.c @@ -17,6 +17,7 @@ int test_connect(int sockfd, const struct sockaddr *addr, int test_getpid(void); int test_printf(const char *format, ...); int test_fputc(int c, FILE *stream); +int test_chdir(const char *path); #define main test_main #define read test_read @@ -25,6 +26,7 @@ int test_fputc(int c, FILE *stream); #define getpid test_getpid #define printf test_printf #define fputc test_fputc +#define chdir test_chdir #include "../lightning-cli.c" #undef main @@ -106,6 +108,11 @@ int test_fputc(int c, FILE *stream) return (unsigned)c; } +int test_chdir(const char *path) +{ + return 0; +} + int main(int argc UNUSED, char *argv[]) { setup_locale(); @@ -114,7 +121,6 @@ int main(int argc UNUSED, char *argv[]) output = tal_strdup(NULL, ""); assert(test_main(3, fake_argv) == 0); - assert(!taken_any()); assert(streq(output, "channels=\n" "\n" @@ -130,6 +136,7 @@ int main(int argc UNUSED, char *argv[]) "num_channels=1\n" "num_connected=1\n")); tal_free(output); + assert(!taken_any()); take_cleanup(); return 0; } diff --git a/common/configdir.c b/common/configdir.c index 4ff069768..00a138615 100644 --- a/common/configdir.c +++ b/common/configdir.c @@ -204,14 +204,14 @@ void setup_option_allocators(void) } /* network is NULL for parsing top-level config file. */ -static void parse_implied_config_file(const char *config_dir, +static void parse_implied_config_file(const char *config_basedir, const char *network, bool early) { const char *dir, *filename; - if (config_dir) - dir = path_join(NULL, take(path_cwd(NULL)), config_dir); + if (config_basedir) + dir = path_join(NULL, take(path_cwd(NULL)), config_basedir); else dir = default_base_configdir(NULL); @@ -227,7 +227,7 @@ static void parse_implied_config_file(const char *config_dir, * Otherwise we read /config then //config */ void parse_config_files(const char *config_filename, - const char *config_dir, + const char *config_basedir, bool early) { if (config_filename) { @@ -235,14 +235,15 @@ void parse_config_files(const char *config_filename, return; } - parse_implied_config_file(config_dir, NULL, early); - parse_implied_config_file(config_dir, chainparams->network_name, early); + parse_implied_config_file(config_basedir, NULL, early); + parse_implied_config_file(config_basedir, chainparams->network_name, early); } void initial_config_opts(const tal_t *ctx, int argc, char *argv[], char **config_filename, - char **config_dir, + char **config_basedir, + char **config_netdir, char **rpc_filename) { options_ctx = ctx; @@ -255,11 +256,11 @@ void initial_config_opts(const tal_t *ctx, "Specify configuration file"); /* Cmdline can also set lightning-dir. */ - *config_dir = NULL; + *config_basedir = NULL; opt_register_early_arg("--lightning-dir=", - opt_set_talstr, NULL, - config_dir, - "Set working directory. All other files are relative to this"); + opt_set_abspath, NULL, + config_basedir, + "Set base directory: network-specific subdirectory is under here"); /* Handle --version (and exit) here too */ opt_register_version(); @@ -277,19 +278,19 @@ void initial_config_opts(const tal_t *ctx, if (!*config_filename) { opt_register_early_arg("--lightning-dir=", opt_ignore, opt_show_charp, - config_dir, - "Set working directory. All other files are relative to this"); + config_basedir, + "Set base directory: network-specific subdirectory is under here"); } else { opt_register_early_arg("--lightning-dir=", - opt_set_talstr, NULL, - config_dir, - "Set working directory. All other files are relative to this"); + opt_set_abspath, NULL, + config_basedir, + "Set base directory: network-specific subdirectory is under here"); } /* Now, config file (or cmdline) can set network and lightning-dir */ /* We need to know network early, so we can set defaults (which normal - * options can change) and default config_dir */ + * options can change) and default config_netdir */ opt_register_early_arg("--network", opt_set_network, opt_show_network, NULL, "Select the network parameters (bitcoin, testnet," @@ -308,7 +309,7 @@ void initial_config_opts(const tal_t *ctx, if (*config_filename) parse_include(*config_filename, true, true); else - parse_implied_config_file(*config_dir, NULL, true); + parse_implied_config_file(*config_basedir, NULL, true); opt_early_parse_incomplete(argc, argv, opt_log_stderr_exit); /* We use a global (in common/utils.h) for the chainparams. @@ -316,11 +317,14 @@ void initial_config_opts(const tal_t *ctx, if (!chainparams) chainparams = chainparams_for_network("testnet"); - if (!*config_dir) - *config_dir = default_base_configdir(ctx); + if (!*config_basedir) + *config_basedir = default_base_configdir(ctx); + + *config_netdir + = path_join(NULL, *config_basedir, chainparams->network_name); /* Make sure it's absolute */ - *config_dir = path_join(ctx, take(path_cwd(NULL)), take(*config_dir)); + *config_netdir = path_join(ctx, take(path_cwd(NULL)), take(*config_netdir)); /* Now, reset and ignore those options from now on. */ opt_free_table(); @@ -330,8 +334,8 @@ void initial_config_opts(const tal_t *ctx, "Specify configuration file"); opt_register_early_arg("--lightning-dir=", opt_ignore, opt_show_charp, - config_dir, - "Set working directory. All other files are relative to this"); + config_basedir, + "Set base directory: network-specific subdirectory is under here"); opt_register_early_arg("--network", opt_ignore, opt_show_network, NULL, "Select the network parameters (bitcoin, testnet," diff --git a/common/configdir.h b/common/configdir.h index e630b83fe..a077c132a 100644 --- a/common/configdir.h +++ b/common/configdir.h @@ -13,14 +13,15 @@ void setup_option_allocators(void); void initial_config_opts(const tal_t *ctx, int argc, char *argv[], char **config_filename, - char **config_dir, + char **config_basedir, + char **config_netdir, char **rpc_filename); /* If they specify --conf, we just read that. - * If they specify --lightning-dir, we just read /config. - * Otherwise, we read ../config (toplevel), and config (network-level) */ + * Otherwise, we read basedir/config (toplevel), and basedir//config + * (network-level) */ void parse_config_files(const char *config_filename, - const char *config_dir, + const char *config_basedir, bool early); /* For listconfigs to access. */ diff --git a/contrib/pyln-testing/pyln/testing/utils.py b/contrib/pyln-testing/pyln/testing/utils.py index e2a319064..901babdd8 100644 --- a/contrib/pyln-testing/pyln/testing/utils.py +++ b/contrib/pyln-testing/pyln/testing/utils.py @@ -478,7 +478,7 @@ class LightningD(TailableProc): 'lightning-dir': lightning_dir, 'addr': '127.0.0.1:{}'.format(port), 'allow-deprecated-apis': 'false', - 'network': env('TEST_NETWORK', 'regtest'), + 'network': TEST_NETWORK, 'ignore-fee-limits': 'false', 'bitcoin-rpcuser': BITCOIND_CONFIG['rpcuser'], 'bitcoin-rpcpassword': BITCOIND_CONFIG['rpcpassword'], @@ -487,13 +487,13 @@ class LightningD(TailableProc): for k, v in opts.items(): self.opts[k] = v - if not os.path.exists(lightning_dir): - os.makedirs(lightning_dir) + if not os.path.exists(os.path.join(lightning_dir, TEST_NETWORK)): + os.makedirs(os.path.join(lightning_dir, TEST_NETWORK)) # Last 32-bytes of final part of dir -> seed. seed = (bytes(re.search('([^/]+)/*$', lightning_dir).group(1), encoding='utf-8') + bytes(32))[:32] if not random_hsm: - with open(os.path.join(lightning_dir, 'hsm_secret'), 'wb') as f: + with open(os.path.join(lightning_dir, TEST_NETWORK, 'hsm_secret'), 'wb') as f: f.write(seed) if DEVELOPER: self.opts['dev-fast-gossip'] = None @@ -551,7 +551,7 @@ class LightningNode(object): self.allow_bad_gossip = allow_bad_gossip self.db = db - socket_path = os.path.join(lightning_dir, "lightning-rpc").format(node_id) + socket_path = os.path.join(lightning_dir, TEST_NETWORK, "lightning-rpc").format(node_id) self.rpc = LightningRpc(socket_path, self.executor) self.daemon = LightningD( @@ -560,7 +560,7 @@ class LightningNode(object): ) # If we have a disconnect string, dump it to a file for daemon. if disconnect: - self.daemon.disconnect_file = os.path.join(lightning_dir, "dev_disconnect") + self.daemon.disconnect_file = os.path.join(lightning_dir, TEST_NETWORK, "dev_disconnect") with open(self.daemon.disconnect_file, "w") as f: f.write("\n".join(disconnect)) self.daemon.opts["dev-disconnect"] = "dev_disconnect" @@ -632,7 +632,7 @@ class LightningNode(object): # Assumes node is stopped! def db_manip(self, query): - db = sqlite3.connect(os.path.join(self.daemon.lightning_dir, "lightningd.sqlite3")) + db = sqlite3.connect(os.path.join(self.daemon.lightning_dir, TEST_NETWORK, "lightningd.sqlite3")) db.row_factory = sqlite3.Row c = db.cursor() c.execute(query) @@ -984,7 +984,7 @@ class NodeFactory(object): # Get the DB backend DSN we should be using for this test and this # node. - db = self.db_provider.get_db(lightning_dir, self.testname, node_id) + db = self.db_provider.get_db(os.path.join(lightning_dir, TEST_NETWORK), self.testname, node_id) node = self.node_cls( node_id, lightning_dir, self.bitcoind, self.executor, db=db, port=port, options=options, **kwargs @@ -995,7 +995,7 @@ class NodeFactory(object): self.nodes.append(node) if dbfile: - out = open(os.path.join(node.daemon.lightning_dir, + out = open(os.path.join(node.daemon.lightning_dir, TEST_NETWORK, 'lightningd.sqlite3'), 'xb') with lzma.open(os.path.join('tests/data', dbfile), 'rb') as f: out.write(f.read()) diff --git a/devtools/checkchannels.c b/devtools/checkchannels.c index 9bd558872..769b11e52 100644 --- a/devtools/checkchannels.c +++ b/devtools/checkchannels.c @@ -111,13 +111,14 @@ static void copy_column(void *dst, size_t size, int main(int argc, char *argv[]) { - char *config_dir, *config_filename, *rpc_filename, *hsmfile, *dbfile; + char *config_dir, *net_dir, *config_filename, *rpc_filename, *hsmfile, *dbfile; sqlite3 *sql; sqlite3_stmt *stmt; int flags = SQLITE_OPEN_READONLY, dberr; struct secret *hsm_secret; bool verbose = false; size_t num, num_ok; + const tal_t *top_ctx = tal(NULL, char); setup_locale(); wally_init(0); @@ -125,8 +126,9 @@ int main(int argc, char *argv[]) setup_option_allocators(); - initial_config_opts(NULL, argc, argv, - &config_filename, &config_dir, &rpc_filename); + initial_config_opts(top_ctx, argc, argv, + &config_filename, &config_dir, &net_dir, + &rpc_filename); opt_register_noarg("-v|--verbose", opt_set_bool, &verbose, "Print everything"); @@ -135,8 +137,8 @@ int main(int argc, char *argv[]) if (argc != 1) errx(1, "no arguments accepted"); - hsmfile = path_join(config_dir, config_dir, "hsm_secret"); - dbfile = path_join(config_dir, config_dir, "lightningd.sqlite3"); + hsmfile = path_join(top_ctx, net_dir, "hsm_secret"); + dbfile = path_join(top_ctx, net_dir, "lightningd.sqlite3"); dberr = sqlite3_open_v2(dbfile, &sql, flags, NULL); if (dberr != SQLITE_OK) @@ -235,5 +237,5 @@ int main(int argc, char *argv[]) printf("\nCheck passed!\n"); else errx(1, "%zu channels incorrect.", num - num_ok); - tal_free(config_dir); + tal_free(top_ctx); } diff --git a/doc/PLUGINS.md b/doc/PLUGINS.md index b6aa40317..0aaeac4e8 100644 --- a/doc/PLUGINS.md +++ b/doc/PLUGINS.md @@ -35,7 +35,7 @@ plugin dirs, usually `/usr/local/libexec/c-lightning/plugins` and lightningd --plugin=/path/to/plugin1 --plugin=path/to/plugin2 ``` -`lightningd` run your plugins from the `--lightning-dir`, then +`lightningd` run your plugins from the `--lightning-dir`/networkname, then will write JSON-RPC requests to the plugin's `stdin` and will read replies from its `stdout`. To initialize the plugin two RPC methods are required: @@ -132,7 +132,7 @@ simple JSON object containing the options: "greeting": "World" }, "configuration": { - "lightning-dir": "/home/user/.lightning", + "lightning-dir": "/home/user/.lightning/testnet", "rpc-file": "lightning-rpc", "startup": true } diff --git a/doc/lightningd-config.5 b/doc/lightningd-config.5 index eb5ccaf63..6f1ffbed6 100644 --- a/doc/lightningd-config.5 +++ b/doc/lightningd-config.5 @@ -65,6 +65,7 @@ Bitcoin control options: \fBnetwork\fR=\fINETWORK\fR Select the network parameters (\fIbitcoin\fR, \fItestnet\fR, or \fIregtest\fR)\. +This is not valid within the per-network configuration file\. \fBtestnet\fR @@ -117,7 +118,9 @@ wrong\. \fBlightning-dir\fR=\fIDIR\fR Sets the working directory\. All files (except \fI--conf\fR and -\fI--lightning-dir\fR on the command line) are relative to this\. +\fI--lightning-dir\fR on the command line) are relative to this\. This +is only valid on the command-line, or in a configuration file specified +by \fI--conf\fR\. \fBpid-file\fR=\fIPATH\fR @@ -196,7 +199,7 @@ Sets configuration file, and disable reading the normal general and network ones\. If this is a relative path, it is relative to the starting directory, not \fBlightning-dir\fR (unlike other paths)\. \fIPATH\fR must exist and be readable (we allow missing files in the default case)\. Using this inside -a configuration file is meaningless\. +a configuration file is invalid\. \fBwallet\fR=\fIDSN\fR diff --git a/doc/lightningd-config.5.md b/doc/lightningd-config.5.md index ba3d156f6..324fcbd35 100644 --- a/doc/lightningd-config.5.md +++ b/doc/lightningd-config.5.md @@ -61,6 +61,7 @@ Bitcoin control options: **network**=*NETWORK* Select the network parameters (*bitcoin*, *testnet*, or *regtest*). +This is not valid within the per-network configuration file. **testnet** Alias for *network=testnet*. @@ -102,7 +103,9 @@ wrong. **lightning-dir**=*DIR* Sets the working directory. All files (except *--conf* and -*--lightning-dir* on the command line) are relative to this. +*--lightning-dir* on the command line) are relative to this. This +is only valid on the command-line, or in a configuration file specified +by *--conf*. **pid-file**=*PATH* Specify pid file to write to. @@ -155,7 +158,7 @@ Sets configuration file, and disable reading the normal general and network ones. If this is a relative path, it is relative to the starting directory, not **lightning-dir** (unlike other paths). *PATH* must exist and be readable (we allow missing files in the default case). Using this inside -a configuration file is meaningless. +a configuration file is invalid. **wallet**=*DSN* Identify the location of the wallet. This is a fully qualified data source diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index 51187aadb..90c2b5e03 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -85,8 +85,8 @@ struct lightningd { int pid_fd; - /* Our config dir, and rpc file */ - char *config_dir; + /* Our config basedir, network directory, and rpc file */ + char *config_basedir, *config_netdir; /* Location of the RPC socket. */ char *rpc_filename; diff --git a/lightningd/options.c b/lightningd/options.c index 27a4c8539..7eea1585f 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -912,7 +912,8 @@ void handle_early_opts(struct lightningd *ld, int argc, char *argv[]) /*~ This does enough parsing to get us the base configuration options */ initial_config_opts(ld, argc, argv, &ld->config_filename, - &ld->config_dir, + &ld->config_basedir, + &ld->config_netdir, &ld->rpc_filename); /* Copy in default config, to be modified by further options */ @@ -923,7 +924,7 @@ void handle_early_opts(struct lightningd *ld, int argc, char *argv[]) /* Now we can initialize wallet_dsn */ ld->wallet_dsn = tal_fmt(ld, "sqlite3://%s/lightningd.sqlite3", - ld->config_dir); + ld->config_netdir); /* Set default PID file name to be per-network */ ld->pidfile = tal_fmt(ld, "lightningd-%s.pid", @@ -931,15 +932,20 @@ void handle_early_opts(struct lightningd *ld, int argc, char *argv[]) /*~ Move into config dir: this eases path manipulation and also * gives plugins a good place to store their stuff. */ - if (chdir(ld->config_dir) != 0) { + if (chdir(ld->config_netdir) != 0) { log_unusual(ld->log, "Creating configuration directory %s", - ld->config_dir); - if (mkdir(ld->config_dir, 0700) != 0) + ld->config_netdir); + /* We assume home dir exists, so only create two. */ + if (mkdir(ld->config_basedir, 0700) != 0 && errno != EEXIST) fatal("Could not make directory %s: %s", - ld->config_dir, strerror(errno)); - if (chdir(ld->config_dir) != 0) + ld->config_basedir, + strerror(errno)); + if (mkdir(ld->config_netdir, 0700) != 0) + fatal("Could not make directory %s: %s", + ld->config_netdir, strerror(errno)); + if (chdir(ld->config_netdir) != 0) fatal("Could not change directory %s: %s", - ld->config_dir, strerror(errno)); + ld->config_netdir, strerror(errno)); } /*~ The ccan/opt code requires registration then parsing; we @@ -948,7 +954,7 @@ void handle_early_opts(struct lightningd *ld, int argc, char *argv[]) /* Now look inside config file(s), but only handle the early * options (testnet, plugins etc), others may be added on-demand */ - parse_config_files(ld->config_filename, ld->config_dir, true); + parse_config_files(ld->config_filename, ld->config_basedir, true); /* Early cmdline options now override config file options. */ opt_early_parse_incomplete(argc, argv, opt_log_stderr_exit); @@ -962,7 +968,7 @@ void handle_opts(struct lightningd *ld, int argc, char *argv[]) /* Now look for config file, but only handle non-early * options, early ones have been parsed in * handle_early_opts */ - parse_config_files(ld->config_filename, ld->config_dir, false); + parse_config_files(ld->config_filename, ld->config_basedir, false); /* Now parse cmdline, which overrides config. */ opt_parse(&argc, argv, opt_log_stderr_exit); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index a75d79818..22806dca7 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -1708,7 +1708,7 @@ static struct command_result *json_getinfo(struct command *cmd, wallet_total_forward_fees(cmd->ld->wallet), "msatoshi_fees_collected", "fees_collected_msat"); - json_add_string(response, "lightning-dir", cmd->ld->config_dir); + json_add_string(response, "lightning-dir", cmd->ld->config_netdir); if (!cmd->ld->topology->bitcoind->synced) json_add_string(response, "warning_bitcoind_sync", diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 55fc5f538..7bd023469 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -971,7 +971,7 @@ void plugins_init(struct plugins *plugins, const char *dev_plugin_debug) struct jsonrpc_request *req; plugins->pending_manifests = 0; - plugins->default_dir = path_join(plugins, plugins->ld->config_dir, "plugins"); + plugins->default_dir = path_join(plugins, plugins->ld->config_basedir, "plugins"); plugins_add_default_dir(plugins); setenv("LIGHTNINGD_PLUGIN", "1", 1); @@ -1049,7 +1049,7 @@ plugin_populate_init_request(struct plugin *plugin, struct jsonrpc_request *req) /* Add .params.configuration */ json_object_start(req->stream, "configuration"); - json_add_string(req->stream, "lightning-dir", ld->config_dir); + json_add_string(req->stream, "lightning-dir", ld->config_netdir); json_add_string(req->stream, "rpc-file", ld->rpc_filename); json_add_bool(req->stream, "startup", plugin->plugins->startup); json_add_string(req->stream, "network", chainparams->network_name); diff --git a/tests/test_connection.py b/tests/test_connection.py index 9474ac32c..9abc6e492 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -429,8 +429,8 @@ def test_connect_stresstest(node_factory, executor): # Hack l3 into a clone of l2, to stress reconnect code. l3.stop() - shutil.copyfile(os.path.join(l2.daemon.lightning_dir, 'hsm_secret'), - os.path.join(l3.daemon.lightning_dir, 'hsm_secret')) + shutil.copyfile(os.path.join(l2.daemon.lightning_dir, TEST_NETWORK, 'hsm_secret'), + os.path.join(l3.daemon.lightning_dir, TEST_NETWORK, 'hsm_secret')) l3.start() l3.info = l3.rpc.getinfo() @@ -1847,7 +1847,7 @@ def test_dataloss_protection(node_factory, bitcoind): l2.stop() # Save copy of the db. - dbpath = os.path.join(l2.daemon.lightning_dir, "lightningd.sqlite3") + dbpath = os.path.join(l2.daemon.lightning_dir, TEST_NETWORK, "lightningd.sqlite3") orig_db = open(dbpath, "rb").read() l2.start() diff --git a/tests/test_gossip.py b/tests/test_gossip.py index 27df804bd..159a37986 100644 --- a/tests/test_gossip.py +++ b/tests/test_gossip.py @@ -912,7 +912,7 @@ def test_gossip_addresses(node_factory, bitcoind): def test_gossip_store_load(node_factory): """Make sure we can read canned gossip store""" l1 = node_factory.get_node(start=False) - with open(os.path.join(l1.daemon.lightning_dir, 'gossip_store'), 'wb') as f: + with open(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store'), 'wb') as f: f.write(bytearray.fromhex("07" # GOSSIP_STORE_VERSION "000001b0" # len "fea676e8" # csum @@ -944,7 +944,7 @@ def test_gossip_store_load(node_factory): def test_gossip_store_load_announce_before_update(node_factory): """Make sure we can read canned gossip store with node_announce before update. This happens when a channel_update gets replaced, leaving node_announce before it""" l1 = node_factory.get_node(start=False) - with open(os.path.join(l1.daemon.lightning_dir, 'gossip_store'), 'wb') as f: + with open(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store'), 'wb') as f: f.write(bytearray.fromhex("07" # GOSSIP_STORE_VERSION "000001b0" # len "fea676e8" # csum @@ -987,7 +987,7 @@ def test_gossip_store_load_announce_before_update(node_factory): def test_gossip_store_load_amount_truncated(node_factory): """Make sure we can read canned gossip store with truncated amount""" l1 = node_factory.get_node(start=False, allow_broken_log=True) - with open(os.path.join(l1.daemon.lightning_dir, 'gossip_store'), 'wb') as f: + with open(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store'), 'wb') as f: f.write(bytearray.fromhex("07" # GOSSIP_STORE_VERSION "000001b0" # len "fea676e8" # csum @@ -999,7 +999,7 @@ def test_gossip_store_load_amount_truncated(node_factory): # May preceed the Started msg waited for in 'start'. wait_for(lambda: l1.daemon.is_in_log(r'gossip_store: dangling channel_announcement. Moving to gossip_store.corrupt and truncating')) wait_for(lambda: l1.daemon.is_in_log(r'gossip_store: Read 0/0/0/0 cannounce/cupdate/nannounce/cdelete from store \(0 deleted\) in 1 bytes')) - assert os.path.exists(os.path.join(l1.daemon.lightning_dir, 'gossip_store.corrupt')) + assert os.path.exists(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store.corrupt')) # Extra sanity check if we can. if DEVELOPER: @@ -1359,7 +1359,7 @@ def test_gossip_store_compact_noappend(node_factory, bitcoind): l2 = setup_gossip_store_test(node_factory, bitcoind) # It should truncate this, not leave junk! - with open(os.path.join(l2.daemon.lightning_dir, 'gossip_store.tmp'), 'wb') as f: + with open(os.path.join(l2.daemon.lightning_dir, TEST_NETWORK, 'gossip_store.tmp'), 'wb') as f: f.write(bytearray.fromhex("07deadbeef")) l2.rpc.call('dev-compact-gossip-store') @@ -1411,7 +1411,7 @@ def test_gossip_store_load_no_channel_update(node_factory): l1 = node_factory.get_node(start=False, allow_broken_log=True) # A channel announcement with no channel_update. - with open(os.path.join(l1.daemon.lightning_dir, 'gossip_store'), 'wb') as f: + with open(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store'), 'wb') as f: f.write(bytearray.fromhex("07" # GOSSIP_STORE_VERSION "000001b0" # len "fea676e8" # csum @@ -1433,12 +1433,12 @@ def test_gossip_store_load_no_channel_update(node_factory): # May preceed the Started msg waited for in 'start'. wait_for(lambda: l1.daemon.is_in_log('gossip_store: Unupdated channel_announcement at 1. Moving to gossip_store.corrupt and truncating')) - assert os.path.exists(os.path.join(l1.daemon.lightning_dir, 'gossip_store.corrupt')) + assert os.path.exists(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store.corrupt')) # This should actually result in an empty store. l1.rpc.call('dev-compact-gossip-store') - with open(os.path.join(l1.daemon.lightning_dir, 'gossip_store'), "rb") as f: + with open(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store'), "rb") as f: assert bytearray(f.read()) == bytearray.fromhex("07") diff --git a/tests/test_misc.py b/tests/test_misc.py index c56567e36..b8ea32c79 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -77,7 +77,7 @@ def test_db_upgrade(node_factory): assert(upgrades[0]['lightning_version'] == version) # Try resetting to earlier db state. - os.unlink(os.path.join(l1.daemon.lightning_dir, "lightningd.sqlite3")) + os.unlink(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "lightningd.sqlite3")) l1.db_manip("CREATE TABLE version (version INTEGER);") l1.db_manip("INSERT INTO version VALUES (1);") @@ -714,7 +714,7 @@ def test_address(node_factory): # Now test UNIX domain binding. l1.stop() - l1.daemon.opts['bind-addr'] = os.path.join(l1.daemon.lightning_dir, "sock") + l1.daemon.opts['bind-addr'] = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "sock") l1.start() l2 = node_factory.get_node() @@ -723,7 +723,7 @@ def test_address(node_factory): # 'addr' with local socket works too. l1.stop() del l1.daemon.opts['bind-addr'] - l1.daemon.opts['addr'] = os.path.join(l1.daemon.lightning_dir, "sock") + l1.daemon.opts['addr'] = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "sock") # start expects a port, so we open-code here. l1.daemon.start() @@ -851,6 +851,7 @@ def test_cli(node_factory): l1 = node_factory.get_node() out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), 'help']).decode('utf-8') @@ -859,6 +860,7 @@ def test_cli(node_factory): # Test JSON output. out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), '-J', @@ -869,6 +871,7 @@ def test_cli(node_factory): # Test keyword input (autodetect) out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), '-J', @@ -878,6 +881,7 @@ def test_cli(node_factory): # Test keyword input (forced) out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), '-J', '-k', @@ -887,6 +891,7 @@ def test_cli(node_factory): # Test ordered input (autodetect) out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), '-J', @@ -896,6 +901,7 @@ def test_cli(node_factory): # Test ordered input (forced) out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), '-J', '-o', @@ -908,6 +914,7 @@ def test_cli(node_factory): # This will error due to missing parameters. # We want to check if lightningd will crash. out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), '-J', '-o', @@ -918,6 +925,7 @@ def test_cli(node_factory): # Test it escapes JSON completely in both method and params. # cli turns " into \", reply turns that into \\\". out = subprocess.run(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), 'x"[]{}'], @@ -925,11 +933,13 @@ def test_cli(node_factory): assert 'Unknown command \'x\\\\\\"[]{}\'' in out.stdout.decode('utf-8') subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), 'invoice', '123000', 'l"[]{}', 'd"[]{}']).decode('utf-8') # Check label is correct, and also that cli's keyword parsing works. out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), '-k', @@ -961,23 +971,26 @@ def test_daemon_option(node_factory): l1.stop() os.unlink(l1.rpc.socket_path) - subprocess.run(l1.daemon.cmd_line + ['--daemon', '--log-file={}/log-daemon'.format(l1.daemon.lightning_dir)], env=l1.daemon.env, + logfname = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "log-daemon") + subprocess.run(l1.daemon.cmd_line + ['--daemon', '--log-file={}'.format(logfname)], env=l1.daemon.env, check=True) # Test some known output (wait for rpc to be ready) wait_for(lambda: os.path.exists(l1.rpc.socket_path)) out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), 'help']).decode('utf-8') assert 'help [command]\n List available commands, or give verbose help on one {command}' in out subprocess.run(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}'.format(l1.daemon.lightning_dir), 'stop'], check=True) # It should not complain that subdaemons aren't children. - with open('{}/log-daemon'.format(l1.daemon.lightning_dir), 'r') as f: + with open(logfname, 'r') as f: assert 'No child process' not in f.read() @@ -1374,8 +1387,8 @@ def test_feerates(node_factory): def test_logging(node_factory): # Since we redirect, node.start() will fail: do manually. l1 = node_factory.get_node(options={'log-file': 'logfile'}, may_fail=True, start=False) - logpath = os.path.join(l1.daemon.lightning_dir, 'logfile') - logpath_moved = os.path.join(l1.daemon.lightning_dir, 'logfile_moved') + logpath = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'logfile') + logpath_moved = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'logfile_moved') l1.daemon.rpcproxy.start() l1.daemon.opts['bitcoin-rpcport'] = l1.daemon.rpcproxy.rpcport @@ -1402,7 +1415,7 @@ def test_crashlog(node_factory): l1 = node_factory.get_node(may_fail=True, allow_broken_log=True) def has_crash_log(n): - files = os.listdir(n.daemon.lightning_dir) + files = os.listdir(os.path.join(n.daemon.lightning_dir, TEST_NETWORK)) crashfiles = [f for f in files if 'crash.log' in f] return len(crashfiles) > 0 @@ -1419,7 +1432,7 @@ def test_configfile_before_chdir(node_factory): olddir = os.getcwd() # as lightning_dir ends in /, basename and dirname don't work as expected. os.chdir(os.path.dirname(l1.daemon.lightning_dir[:-1])) - config = os.path.join(os.path.basename(l1.daemon.lightning_dir[:-1]), "test_configfile") + config = os.path.join(os.path.basename(l1.daemon.lightning_dir[:-1]), TEST_NETWORK, "test_configfile") # Test both an early arg and a normal arg. with open(config, 'wb') as f: f.write(b'always-use-proxy=true\n') @@ -1788,7 +1801,6 @@ def test_config_in_subdir(node_factory): l1 = node_factory.get_node(start=False) subdir = os.path.join(l1.daemon.opts.get("lightning-dir"), "regtest") - os.makedirs(subdir) with open(os.path.join(subdir, "config"), 'w') as f: f.write('alias=test_config_in_subdir') l1.start() diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 163b8694a..caa325ea9 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -2,7 +2,7 @@ from collections import OrderedDict from fixtures import * # noqa: F401,F403 from flaky import flaky # noqa: F401 from lightning import RpcError, Millisatoshi -from utils import DEVELOPER, only_one, sync_blockheight, TIMEOUT, wait_for, EXPERIMENTAL_FEATURES +from utils import DEVELOPER, only_one, sync_blockheight, TIMEOUT, wait_for, EXPERIMENTAL_FEATURES, TEST_NETWORK import json import os @@ -316,7 +316,7 @@ def test_db_hook(node_factory, executor): l1.stop() # Databases should be identical. - db1 = sqlite3.connect(os.path.join(l1.daemon.lightning_dir, 'lightningd.sqlite3')) + db1 = sqlite3.connect(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'lightningd.sqlite3')) db2 = sqlite3.connect(dbfile) assert [x for x in db1.iterdump()] == [x for x in db2.iterdump()] @@ -333,6 +333,7 @@ def test_utf8_passthrough(node_factory, executor): # Now, try native. out = subprocess.check_output(['cli/lightning-cli', + '--network={}'.format(TEST_NETWORK), '--lightning-dir={}' .format(l1.daemon.lightning_dir), 'utf8', 'ナンセンス 1杯']).decode('utf-8') diff --git a/tests/test_wallet.py b/tests/test_wallet.py index 3e1bc1349..c7ba53da1 100644 --- a/tests/test_wallet.py +++ b/tests/test_wallet.py @@ -611,7 +611,7 @@ def test_hsm_secret_encryption(node_factory): def test_hsmtool_secret_decryption(node_factory): l1 = node_factory.get_node() password = "reckless\n" - hsm_path = os.path.join(l1.daemon.lightning_dir, "hsm_secret") + hsm_path = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "hsm_secret") # We need to simulate a terminal to use termios in `lightningd`. master_fd, slave_fd = os.openpty()