Browse Source

lightningd: change config-dir from plugin / wallet / hsm POV into <network> subdir

Changelog-changed: .lightningd plugins and files moved into <network>/ 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 <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
aab83e729b
  1. 4
      README.md
  2. 13
      cli/lightning-cli.c
  3. 9
      cli/test/run-large-input.c
  4. 9
      cli/test/run-remove-hint.c
  5. 50
      common/configdir.c
  6. 9
      common/configdir.h
  7. 18
      contrib/pyln-testing/pyln/testing/utils.py
  8. 14
      devtools/checkchannels.c
  9. 4
      doc/PLUGINS.md
  10. 7
      doc/lightningd-config.5
  11. 7
      doc/lightningd-config.5.md
  12. 4
      lightningd/lightningd.h
  13. 26
      lightningd/options.c
  14. 2
      lightningd/peer_control.c
  15. 4
      lightningd/plugin.c
  16. 6
      tests/test_connection.py
  17. 16
      tests/test_gossip.py
  18. 32
      tests/test_misc.py
  19. 5
      tests/test_plugin.py
  20. 2
      tests/test_wallet.py

4
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. `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. 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 To use a configuration file, create a file named `config` within your top-level lightning directory or network subdirectory
(eg. `~/.lightning/config`). See `man -l doc/lightningd-config.5`. (eg. `~/.lightning/config` or `~/.lightning/bitcoin/config`). See `man -l doc/lightningd-config.5`.
## Further information ## Further information

13
cli/lightning-cli.c

@ -431,7 +431,7 @@ int main(int argc, char *argv[])
jsmntok_t *toks; jsmntok_t *toks;
const jsmntok_t *result, *error, *id; const jsmntok_t *result, *error, *id;
const tal_t *ctx = tal(NULL, char); 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; jsmn_parser parser;
int parserr; int parserr;
enum format format = DEFAULT_FORMAT; enum format format = DEFAULT_FORMAT;
@ -446,7 +446,8 @@ int main(int argc, char *argv[])
setup_option_allocators(); setup_option_allocators();
initial_config_opts(ctx, argc, argv, 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, opt_register_noarg("--help|-h", opt_usage_and_exit,
"<command> [<params>...]", "Show this message. Use the command help (without hyphens -- \"lightning-cli help\") to get a list of all RPC commands"); "<command> [<params>...]", "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); tal_free(page);
} }
if (chdir(lightning_dir) != 0) if (chdir(net_dir) != 0)
err(ERROR_TALKING_TO_LIGHTNINGD, "Moving into '%s'", err(ERROR_TALKING_TO_LIGHTNINGD, "Moving into '%s'",
lightning_dir); net_dir);
fd = socket(AF_UNIX, SOCK_STREAM, 0); fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (strlen(rpc_filename) + 1 > sizeof(addr.sun_path)) if (strlen(rpc_filename) + 1 > sizeof(addr.sun_path))
@ -627,8 +628,6 @@ int main(int argc, char *argv[])
default: default:
abort(); abort();
} }
tal_free(lightning_dir);
tal_free(rpc_filename);
tal_free(ctx); tal_free(ctx);
opt_free_table(); opt_free_table();
return 0; return 0;
@ -641,8 +640,6 @@ int main(int argc, char *argv[])
print_json(resp, error, ""); print_json(resp, error, "");
printf("\n"); printf("\n");
} }
tal_free(lightning_dir);
tal_free(rpc_filename);
tal_free(ctx); tal_free(ctx);
opt_free_table(); opt_free_table();
return 1; return 1;

9
cli/test/run-large-input.c

@ -15,6 +15,7 @@ int test_connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen); socklen_t addrlen);
int test_getpid(void); int test_getpid(void);
int test_printf(const char *format, ...); int test_printf(const char *format, ...);
int test_chdir(const char *path);
#define main test_main #define main test_main
#define read test_read #define read test_read
@ -22,6 +23,7 @@ int test_printf(const char *format, ...);
#define connect test_connect #define connect test_connect
#define getpid test_getpid #define getpid test_getpid
#define printf test_printf #define printf test_printf
#define chdir test_chdir
#include "../lightning-cli.c" #include "../lightning-cli.c"
#undef main #undef main
@ -79,6 +81,11 @@ int test_printf(const char *fmt UNUSED, ...)
return 0; return 0;
} }
int test_chdir(const char *path)
{
return 0;
}
static char *response; static char *response;
static size_t response_off, max_read_return; static size_t response_off, max_read_return;
@ -140,5 +147,7 @@ int main(int argc UNUSED, char *argv[])
max_read_return = -1; max_read_return = -1;
assert(test_main(3, fake_argv) == 0); assert(test_main(3, fake_argv) == 0);
tal_free(response); tal_free(response);
assert(!taken_any());
take_cleanup();
return 0; return 0;
} }

9
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_getpid(void);
int test_printf(const char *format, ...); int test_printf(const char *format, ...);
int test_fputc(int c, FILE *stream); int test_fputc(int c, FILE *stream);
int test_chdir(const char *path);
#define main test_main #define main test_main
#define read test_read #define read test_read
@ -25,6 +26,7 @@ int test_fputc(int c, FILE *stream);
#define getpid test_getpid #define getpid test_getpid
#define printf test_printf #define printf test_printf
#define fputc test_fputc #define fputc test_fputc
#define chdir test_chdir
#include "../lightning-cli.c" #include "../lightning-cli.c"
#undef main #undef main
@ -106,6 +108,11 @@ int test_fputc(int c, FILE *stream)
return (unsigned)c; return (unsigned)c;
} }
int test_chdir(const char *path)
{
return 0;
}
int main(int argc UNUSED, char *argv[]) int main(int argc UNUSED, char *argv[])
{ {
setup_locale(); setup_locale();
@ -114,7 +121,6 @@ int main(int argc UNUSED, char *argv[])
output = tal_strdup(NULL, ""); output = tal_strdup(NULL, "");
assert(test_main(3, fake_argv) == 0); assert(test_main(3, fake_argv) == 0);
assert(!taken_any());
assert(streq(output, "channels=\n" assert(streq(output, "channels=\n"
"\n" "\n"
@ -130,6 +136,7 @@ int main(int argc UNUSED, char *argv[])
"num_channels=1\n" "num_channels=1\n"
"num_connected=1\n")); "num_connected=1\n"));
tal_free(output); tal_free(output);
assert(!taken_any());
take_cleanup(); take_cleanup();
return 0; return 0;
} }

50
common/configdir.c

@ -204,14 +204,14 @@ void setup_option_allocators(void)
} }
/* network is NULL for parsing top-level config file. */ /* 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, const char *network,
bool early) bool early)
{ {
const char *dir, *filename; const char *dir, *filename;
if (config_dir) if (config_basedir)
dir = path_join(NULL, take(path_cwd(NULL)), config_dir); dir = path_join(NULL, take(path_cwd(NULL)), config_basedir);
else else
dir = default_base_configdir(NULL); dir = default_base_configdir(NULL);
@ -227,7 +227,7 @@ static void parse_implied_config_file(const char *config_dir,
* Otherwise we read <lightning-dir>/config then <lightning-dir>/<network>/config * Otherwise we read <lightning-dir>/config then <lightning-dir>/<network>/config
*/ */
void parse_config_files(const char *config_filename, void parse_config_files(const char *config_filename,
const char *config_dir, const char *config_basedir,
bool early) bool early)
{ {
if (config_filename) { if (config_filename) {
@ -235,14 +235,15 @@ void parse_config_files(const char *config_filename,
return; return;
} }
parse_implied_config_file(config_dir, NULL, early); parse_implied_config_file(config_basedir, NULL, early);
parse_implied_config_file(config_dir, chainparams->network_name, early); parse_implied_config_file(config_basedir, chainparams->network_name, early);
} }
void initial_config_opts(const tal_t *ctx, void initial_config_opts(const tal_t *ctx,
int argc, char *argv[], int argc, char *argv[],
char **config_filename, char **config_filename,
char **config_dir, char **config_basedir,
char **config_netdir,
char **rpc_filename) char **rpc_filename)
{ {
options_ctx = ctx; options_ctx = ctx;
@ -255,11 +256,11 @@ void initial_config_opts(const tal_t *ctx,
"Specify configuration file"); "Specify configuration file");
/* Cmdline can also set lightning-dir. */ /* Cmdline can also set lightning-dir. */
*config_dir = NULL; *config_basedir = NULL;
opt_register_early_arg("--lightning-dir=<dir>", opt_register_early_arg("--lightning-dir=<dir>",
opt_set_talstr, NULL, opt_set_abspath, NULL,
config_dir, config_basedir,
"Set working directory. All other files are relative to this"); "Set base directory: network-specific subdirectory is under here");
/* Handle --version (and exit) here too */ /* Handle --version (and exit) here too */
opt_register_version(); opt_register_version();
@ -277,19 +278,19 @@ void initial_config_opts(const tal_t *ctx,
if (!*config_filename) { if (!*config_filename) {
opt_register_early_arg("--lightning-dir=<dir>", opt_register_early_arg("--lightning-dir=<dir>",
opt_ignore, opt_show_charp, opt_ignore, opt_show_charp,
config_dir, config_basedir,
"Set working directory. All other files are relative to this"); "Set base directory: network-specific subdirectory is under here");
} else { } else {
opt_register_early_arg("--lightning-dir=<dir>", opt_register_early_arg("--lightning-dir=<dir>",
opt_set_talstr, NULL, opt_set_abspath, NULL,
config_dir, config_basedir,
"Set working directory. All other files are relative to this"); "Set base directory: network-specific subdirectory is under here");
} }
/* Now, config file (or cmdline) can set network and lightning-dir */ /* Now, config file (or cmdline) can set network and lightning-dir */
/* We need to know network early, so we can set defaults (which normal /* 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, opt_register_early_arg("--network", opt_set_network, opt_show_network,
NULL, NULL,
"Select the network parameters (bitcoin, testnet," "Select the network parameters (bitcoin, testnet,"
@ -308,7 +309,7 @@ void initial_config_opts(const tal_t *ctx,
if (*config_filename) if (*config_filename)
parse_include(*config_filename, true, true); parse_include(*config_filename, true, true);
else 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); opt_early_parse_incomplete(argc, argv, opt_log_stderr_exit);
/* We use a global (in common/utils.h) for the chainparams. /* 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) if (!chainparams)
chainparams = chainparams_for_network("testnet"); chainparams = chainparams_for_network("testnet");
if (!*config_dir) if (!*config_basedir)
*config_dir = default_base_configdir(ctx); *config_basedir = default_base_configdir(ctx);
*config_netdir
= path_join(NULL, *config_basedir, chainparams->network_name);
/* Make sure it's absolute */ /* 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. */ /* Now, reset and ignore those options from now on. */
opt_free_table(); opt_free_table();
@ -330,8 +334,8 @@ void initial_config_opts(const tal_t *ctx,
"Specify configuration file"); "Specify configuration file");
opt_register_early_arg("--lightning-dir=<dir>", opt_register_early_arg("--lightning-dir=<dir>",
opt_ignore, opt_show_charp, opt_ignore, opt_show_charp,
config_dir, config_basedir,
"Set working directory. All other files are relative to this"); "Set base directory: network-specific subdirectory is under here");
opt_register_early_arg("--network", opt_ignore, opt_show_network, opt_register_early_arg("--network", opt_ignore, opt_show_network,
NULL, NULL,
"Select the network parameters (bitcoin, testnet," "Select the network parameters (bitcoin, testnet,"

9
common/configdir.h

@ -13,14 +13,15 @@ void setup_option_allocators(void);
void initial_config_opts(const tal_t *ctx, void initial_config_opts(const tal_t *ctx,
int argc, char *argv[], int argc, char *argv[],
char **config_filename, char **config_filename,
char **config_dir, char **config_basedir,
char **config_netdir,
char **rpc_filename); char **rpc_filename);
/* If they specify --conf, we just read that. /* If they specify --conf, we just read that.
* If they specify --lightning-dir, we just read <lightning_dir>/config. * Otherwise, we read basedir/config (toplevel), and basedir/<network>/config
* Otherwise, we read ../config (toplevel), and config (network-level) */ * (network-level) */
void parse_config_files(const char *config_filename, void parse_config_files(const char *config_filename,
const char *config_dir, const char *config_basedir,
bool early); bool early);
/* For listconfigs to access. */ /* For listconfigs to access. */

18
contrib/pyln-testing/pyln/testing/utils.py

@ -478,7 +478,7 @@ class LightningD(TailableProc):
'lightning-dir': lightning_dir, 'lightning-dir': lightning_dir,
'addr': '127.0.0.1:{}'.format(port), 'addr': '127.0.0.1:{}'.format(port),
'allow-deprecated-apis': 'false', 'allow-deprecated-apis': 'false',
'network': env('TEST_NETWORK', 'regtest'), 'network': TEST_NETWORK,
'ignore-fee-limits': 'false', 'ignore-fee-limits': 'false',
'bitcoin-rpcuser': BITCOIND_CONFIG['rpcuser'], 'bitcoin-rpcuser': BITCOIND_CONFIG['rpcuser'],
'bitcoin-rpcpassword': BITCOIND_CONFIG['rpcpassword'], 'bitcoin-rpcpassword': BITCOIND_CONFIG['rpcpassword'],
@ -487,13 +487,13 @@ class LightningD(TailableProc):
for k, v in opts.items(): for k, v in opts.items():
self.opts[k] = v self.opts[k] = v
if not os.path.exists(lightning_dir): if not os.path.exists(os.path.join(lightning_dir, TEST_NETWORK)):
os.makedirs(lightning_dir) os.makedirs(os.path.join(lightning_dir, TEST_NETWORK))
# Last 32-bytes of final part of dir -> seed. # Last 32-bytes of final part of dir -> seed.
seed = (bytes(re.search('([^/]+)/*$', lightning_dir).group(1), encoding='utf-8') + bytes(32))[:32] seed = (bytes(re.search('([^/]+)/*$', lightning_dir).group(1), encoding='utf-8') + bytes(32))[:32]
if not random_hsm: 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) f.write(seed)
if DEVELOPER: if DEVELOPER:
self.opts['dev-fast-gossip'] = None self.opts['dev-fast-gossip'] = None
@ -551,7 +551,7 @@ class LightningNode(object):
self.allow_bad_gossip = allow_bad_gossip self.allow_bad_gossip = allow_bad_gossip
self.db = db 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.rpc = LightningRpc(socket_path, self.executor)
self.daemon = LightningD( self.daemon = LightningD(
@ -560,7 +560,7 @@ class LightningNode(object):
) )
# If we have a disconnect string, dump it to a file for daemon. # If we have a disconnect string, dump it to a file for daemon.
if disconnect: 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: with open(self.daemon.disconnect_file, "w") as f:
f.write("\n".join(disconnect)) f.write("\n".join(disconnect))
self.daemon.opts["dev-disconnect"] = "dev_disconnect" self.daemon.opts["dev-disconnect"] = "dev_disconnect"
@ -632,7 +632,7 @@ class LightningNode(object):
# Assumes node is stopped! # Assumes node is stopped!
def db_manip(self, query): 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 db.row_factory = sqlite3.Row
c = db.cursor() c = db.cursor()
c.execute(query) c.execute(query)
@ -984,7 +984,7 @@ class NodeFactory(object):
# Get the DB backend DSN we should be using for this test and this # Get the DB backend DSN we should be using for this test and this
# node. # 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 = self.node_cls(
node_id, lightning_dir, self.bitcoind, self.executor, db=db, node_id, lightning_dir, self.bitcoind, self.executor, db=db,
port=port, options=options, **kwargs port=port, options=options, **kwargs
@ -995,7 +995,7 @@ class NodeFactory(object):
self.nodes.append(node) self.nodes.append(node)
if dbfile: 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') 'lightningd.sqlite3'), 'xb')
with lzma.open(os.path.join('tests/data', dbfile), 'rb') as f: with lzma.open(os.path.join('tests/data', dbfile), 'rb') as f:
out.write(f.read()) out.write(f.read())

14
devtools/checkchannels.c

@ -111,13 +111,14 @@ static void copy_column(void *dst, size_t size,
int main(int argc, char *argv[]) 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 *sql;
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
int flags = SQLITE_OPEN_READONLY, dberr; int flags = SQLITE_OPEN_READONLY, dberr;
struct secret *hsm_secret; struct secret *hsm_secret;
bool verbose = false; bool verbose = false;
size_t num, num_ok; size_t num, num_ok;
const tal_t *top_ctx = tal(NULL, char);
setup_locale(); setup_locale();
wally_init(0); wally_init(0);
@ -125,8 +126,9 @@ int main(int argc, char *argv[])
setup_option_allocators(); setup_option_allocators();
initial_config_opts(NULL, argc, argv, initial_config_opts(top_ctx, argc, argv,
&config_filename, &config_dir, &rpc_filename); &config_filename, &config_dir, &net_dir,
&rpc_filename);
opt_register_noarg("-v|--verbose", opt_set_bool, &verbose, opt_register_noarg("-v|--verbose", opt_set_bool, &verbose,
"Print everything"); "Print everything");
@ -135,8 +137,8 @@ int main(int argc, char *argv[])
if (argc != 1) if (argc != 1)
errx(1, "no arguments accepted"); errx(1, "no arguments accepted");
hsmfile = path_join(config_dir, config_dir, "hsm_secret"); hsmfile = path_join(top_ctx, net_dir, "hsm_secret");
dbfile = path_join(config_dir, config_dir, "lightningd.sqlite3"); dbfile = path_join(top_ctx, net_dir, "lightningd.sqlite3");
dberr = sqlite3_open_v2(dbfile, &sql, flags, NULL); dberr = sqlite3_open_v2(dbfile, &sql, flags, NULL);
if (dberr != SQLITE_OK) if (dberr != SQLITE_OK)
@ -235,5 +237,5 @@ int main(int argc, char *argv[])
printf("\nCheck passed!\n"); printf("\nCheck passed!\n");
else else
errx(1, "%zu channels incorrect.", num - num_ok); errx(1, "%zu channels incorrect.", num - num_ok);
tal_free(config_dir); tal_free(top_ctx);
} }

4
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 --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 write JSON-RPC requests to the plugin's `stdin` and
will read replies from its `stdout`. To initialize the plugin two RPC will read replies from its `stdout`. To initialize the plugin two RPC
methods are required: methods are required:
@ -132,7 +132,7 @@ simple JSON object containing the options:
"greeting": "World" "greeting": "World"
}, },
"configuration": { "configuration": {
"lightning-dir": "/home/user/.lightning", "lightning-dir": "/home/user/.lightning/testnet",
"rpc-file": "lightning-rpc", "rpc-file": "lightning-rpc",
"startup": true "startup": true
} }

7
doc/lightningd-config.5

@ -65,6 +65,7 @@ Bitcoin control options:
\fBnetwork\fR=\fINETWORK\fR \fBnetwork\fR=\fINETWORK\fR
Select the network parameters (\fIbitcoin\fR, \fItestnet\fR, or \fIregtest\fR)\. Select the network parameters (\fIbitcoin\fR, \fItestnet\fR, or \fIregtest\fR)\.
This is not valid within the per-network configuration file\.
\fBtestnet\fR \fBtestnet\fR
@ -117,7 +118,9 @@ wrong\.
\fBlightning-dir\fR=\fIDIR\fR \fBlightning-dir\fR=\fIDIR\fR
Sets the working directory\. All files (except \fI--conf\fR and 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 \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 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 \fBlightning-dir\fR (unlike other paths)\. \fIPATH\fR must exist and be
readable (we allow missing files in the default case)\. Using this inside 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 \fBwallet\fR=\fIDSN\fR

7
doc/lightningd-config.5.md

@ -61,6 +61,7 @@ Bitcoin control options:
**network**=*NETWORK* **network**=*NETWORK*
Select the network parameters (*bitcoin*, *testnet*, or *regtest*). Select the network parameters (*bitcoin*, *testnet*, or *regtest*).
This is not valid within the per-network configuration file.
**testnet** **testnet**
Alias for *network=testnet*. Alias for *network=testnet*.
@ -102,7 +103,9 @@ wrong.
**lightning-dir**=*DIR* **lightning-dir**=*DIR*
Sets the working directory. All files (except *--conf* and 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* **pid-file**=*PATH*
Specify pid file to write to. 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 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 **lightning-dir** (unlike other paths). *PATH* must exist and be
readable (we allow missing files in the default case). Using this inside readable (we allow missing files in the default case). Using this inside
a configuration file is meaningless. a configuration file is invalid.
**wallet**=*DSN* **wallet**=*DSN*
Identify the location of the wallet. This is a fully qualified data source Identify the location of the wallet. This is a fully qualified data source

4
lightningd/lightningd.h

@ -85,8 +85,8 @@ struct lightningd {
int pid_fd; int pid_fd;
/* Our config dir, and rpc file */ /* Our config basedir, network directory, and rpc file */
char *config_dir; char *config_basedir, *config_netdir;
/* Location of the RPC socket. */ /* Location of the RPC socket. */
char *rpc_filename; char *rpc_filename;

26
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 */ /*~ This does enough parsing to get us the base configuration options */
initial_config_opts(ld, argc, argv, initial_config_opts(ld, argc, argv,
&ld->config_filename, &ld->config_filename,
&ld->config_dir, &ld->config_basedir,
&ld->config_netdir,
&ld->rpc_filename); &ld->rpc_filename);
/* Copy in default config, to be modified by further options */ /* 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 */ /* Now we can initialize wallet_dsn */
ld->wallet_dsn = tal_fmt(ld, "sqlite3://%s/lightningd.sqlite3", 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 */ /* Set default PID file name to be per-network */
ld->pidfile = tal_fmt(ld, "lightningd-%s.pid", 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 /*~ Move into config dir: this eases path manipulation and also
* gives plugins a good place to store their stuff. */ * 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", log_unusual(ld->log, "Creating configuration directory %s",
ld->config_dir); ld->config_netdir);
if (mkdir(ld->config_dir, 0700) != 0) /* 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", fatal("Could not make directory %s: %s",
ld->config_dir, strerror(errno)); ld->config_basedir,
if (chdir(ld->config_dir) != 0) 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", 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 /*~ 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 /* Now look inside config file(s), but only handle the early
* options (testnet, plugins etc), others may be added on-demand */ * 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. */ /* Early cmdline options now override config file options. */
opt_early_parse_incomplete(argc, argv, opt_log_stderr_exit); 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 /* Now look for config file, but only handle non-early
* options, early ones have been parsed in * options, early ones have been parsed in
* handle_early_opts */ * 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. */ /* Now parse cmdline, which overrides config. */
opt_parse(&argc, argv, opt_log_stderr_exit); opt_parse(&argc, argv, opt_log_stderr_exit);

2
lightningd/peer_control.c

@ -1708,7 +1708,7 @@ static struct command_result *json_getinfo(struct command *cmd,
wallet_total_forward_fees(cmd->ld->wallet), wallet_total_forward_fees(cmd->ld->wallet),
"msatoshi_fees_collected", "msatoshi_fees_collected",
"fees_collected_msat"); "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) if (!cmd->ld->topology->bitcoind->synced)
json_add_string(response, "warning_bitcoind_sync", json_add_string(response, "warning_bitcoind_sync",

4
lightningd/plugin.c

@ -971,7 +971,7 @@ void plugins_init(struct plugins *plugins, const char *dev_plugin_debug)
struct jsonrpc_request *req; struct jsonrpc_request *req;
plugins->pending_manifests = 0; 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); plugins_add_default_dir(plugins);
setenv("LIGHTNINGD_PLUGIN", "1", 1); setenv("LIGHTNINGD_PLUGIN", "1", 1);
@ -1049,7 +1049,7 @@ plugin_populate_init_request(struct plugin *plugin, struct jsonrpc_request *req)
/* Add .params.configuration */ /* Add .params.configuration */
json_object_start(req->stream, "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_string(req->stream, "rpc-file", ld->rpc_filename);
json_add_bool(req->stream, "startup", plugin->plugins->startup); json_add_bool(req->stream, "startup", plugin->plugins->startup);
json_add_string(req->stream, "network", chainparams->network_name); json_add_string(req->stream, "network", chainparams->network_name);

6
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. # Hack l3 into a clone of l2, to stress reconnect code.
l3.stop() l3.stop()
shutil.copyfile(os.path.join(l2.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, 'hsm_secret')) os.path.join(l3.daemon.lightning_dir, TEST_NETWORK, 'hsm_secret'))
l3.start() l3.start()
l3.info = l3.rpc.getinfo() l3.info = l3.rpc.getinfo()
@ -1847,7 +1847,7 @@ def test_dataloss_protection(node_factory, bitcoind):
l2.stop() l2.stop()
# Save copy of the db. # 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() orig_db = open(dbpath, "rb").read()
l2.start() l2.start()

16
tests/test_gossip.py

@ -912,7 +912,7 @@ def test_gossip_addresses(node_factory, bitcoind):
def test_gossip_store_load(node_factory): def test_gossip_store_load(node_factory):
"""Make sure we can read canned gossip store""" """Make sure we can read canned gossip store"""
l1 = node_factory.get_node(start=False) 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 f.write(bytearray.fromhex("07" # GOSSIP_STORE_VERSION
"000001b0" # len "000001b0" # len
"fea676e8" # csum "fea676e8" # csum
@ -944,7 +944,7 @@ def test_gossip_store_load(node_factory):
def test_gossip_store_load_announce_before_update(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""" """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) 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 f.write(bytearray.fromhex("07" # GOSSIP_STORE_VERSION
"000001b0" # len "000001b0" # len
"fea676e8" # csum "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): def test_gossip_store_load_amount_truncated(node_factory):
"""Make sure we can read canned gossip store with truncated amount""" """Make sure we can read canned gossip store with truncated amount"""
l1 = node_factory.get_node(start=False, allow_broken_log=True) 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 f.write(bytearray.fromhex("07" # GOSSIP_STORE_VERSION
"000001b0" # len "000001b0" # len
"fea676e8" # csum "fea676e8" # csum
@ -999,7 +999,7 @@ def test_gossip_store_load_amount_truncated(node_factory):
# May preceed the Started msg waited for in 'start'. # 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: 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')) 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. # Extra sanity check if we can.
if DEVELOPER: if DEVELOPER:
@ -1359,7 +1359,7 @@ def test_gossip_store_compact_noappend(node_factory, bitcoind):
l2 = setup_gossip_store_test(node_factory, bitcoind) l2 = setup_gossip_store_test(node_factory, bitcoind)
# It should truncate this, not leave junk! # 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")) f.write(bytearray.fromhex("07deadbeef"))
l2.rpc.call('dev-compact-gossip-store') 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) l1 = node_factory.get_node(start=False, allow_broken_log=True)
# A channel announcement with no channel_update. # 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 f.write(bytearray.fromhex("07" # GOSSIP_STORE_VERSION
"000001b0" # len "000001b0" # len
"fea676e8" # csum "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'. # 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')) 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. # This should actually result in an empty store.
l1.rpc.call('dev-compact-gossip-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") assert bytearray(f.read()) == bytearray.fromhex("07")

32
tests/test_misc.py

@ -77,7 +77,7 @@ def test_db_upgrade(node_factory):
assert(upgrades[0]['lightning_version'] == version) assert(upgrades[0]['lightning_version'] == version)
# Try resetting to earlier db state. # 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("CREATE TABLE version (version INTEGER);")
l1.db_manip("INSERT INTO version VALUES (1);") l1.db_manip("INSERT INTO version VALUES (1);")
@ -714,7 +714,7 @@ def test_address(node_factory):
# Now test UNIX domain binding. # Now test UNIX domain binding.
l1.stop() 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() l1.start()
l2 = node_factory.get_node() l2 = node_factory.get_node()
@ -723,7 +723,7 @@ def test_address(node_factory):
# 'addr' with local socket works too. # 'addr' with local socket works too.
l1.stop() l1.stop()
del l1.daemon.opts['bind-addr'] 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. # start expects a port, so we open-code here.
l1.daemon.start() l1.daemon.start()
@ -851,6 +851,7 @@ def test_cli(node_factory):
l1 = node_factory.get_node() l1 = node_factory.get_node()
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'help']).decode('utf-8') 'help']).decode('utf-8')
@ -859,6 +860,7 @@ def test_cli(node_factory):
# Test JSON output. # Test JSON output.
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'-J', '-J',
@ -869,6 +871,7 @@ def test_cli(node_factory):
# Test keyword input (autodetect) # Test keyword input (autodetect)
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'-J', '-J',
@ -878,6 +881,7 @@ def test_cli(node_factory):
# Test keyword input (forced) # Test keyword input (forced)
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'-J', '-k', '-J', '-k',
@ -887,6 +891,7 @@ def test_cli(node_factory):
# Test ordered input (autodetect) # Test ordered input (autodetect)
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'-J', '-J',
@ -896,6 +901,7 @@ def test_cli(node_factory):
# Test ordered input (forced) # Test ordered input (forced)
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'-J', '-o', '-J', '-o',
@ -908,6 +914,7 @@ def test_cli(node_factory):
# This will error due to missing parameters. # This will error due to missing parameters.
# We want to check if lightningd will crash. # We want to check if lightningd will crash.
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'-J', '-o', '-J', '-o',
@ -918,6 +925,7 @@ def test_cli(node_factory):
# Test it escapes JSON completely in both method and params. # Test it escapes JSON completely in both method and params.
# cli turns " into \", reply turns that into \\\". # cli turns " into \", reply turns that into \\\".
out = subprocess.run(['cli/lightning-cli', out = subprocess.run(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'x"[]{}'], 'x"[]{}'],
@ -925,11 +933,13 @@ def test_cli(node_factory):
assert 'Unknown command \'x\\\\\\"[]{}\'' in out.stdout.decode('utf-8') assert 'Unknown command \'x\\\\\\"[]{}\'' in out.stdout.decode('utf-8')
subprocess.check_output(['cli/lightning-cli', subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'invoice', '123000', 'l"[]{}', 'd"[]{}']).decode('utf-8') 'invoice', '123000', 'l"[]{}', 'd"[]{}']).decode('utf-8')
# Check label is correct, and also that cli's keyword parsing works. # Check label is correct, and also that cli's keyword parsing works.
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'-k', '-k',
@ -961,23 +971,26 @@ def test_daemon_option(node_factory):
l1.stop() l1.stop()
os.unlink(l1.rpc.socket_path) 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) check=True)
# Test some known output (wait for rpc to be ready) # Test some known output (wait for rpc to be ready)
wait_for(lambda: os.path.exists(l1.rpc.socket_path)) wait_for(lambda: os.path.exists(l1.rpc.socket_path))
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'help']).decode('utf-8') 'help']).decode('utf-8')
assert 'help [command]\n List available commands, or give verbose help on one {command}' in out assert 'help [command]\n List available commands, or give verbose help on one {command}' in out
subprocess.run(['cli/lightning-cli', subprocess.run(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}'.format(l1.daemon.lightning_dir), '--lightning-dir={}'.format(l1.daemon.lightning_dir),
'stop'], check=True) 'stop'], check=True)
# It should not complain that subdaemons aren't children. # 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() assert 'No child process' not in f.read()
@ -1374,8 +1387,8 @@ def test_feerates(node_factory):
def test_logging(node_factory): def test_logging(node_factory):
# Since we redirect, node.start() will fail: do manually. # Since we redirect, node.start() will fail: do manually.
l1 = node_factory.get_node(options={'log-file': 'logfile'}, may_fail=True, start=False) l1 = node_factory.get_node(options={'log-file': 'logfile'}, may_fail=True, start=False)
logpath = os.path.join(l1.daemon.lightning_dir, 'logfile') logpath = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'logfile')
logpath_moved = os.path.join(l1.daemon.lightning_dir, 'logfile_moved') logpath_moved = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'logfile_moved')
l1.daemon.rpcproxy.start() l1.daemon.rpcproxy.start()
l1.daemon.opts['bitcoin-rpcport'] = l1.daemon.rpcproxy.rpcport 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) l1 = node_factory.get_node(may_fail=True, allow_broken_log=True)
def has_crash_log(n): 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] crashfiles = [f for f in files if 'crash.log' in f]
return len(crashfiles) > 0 return len(crashfiles) > 0
@ -1419,7 +1432,7 @@ def test_configfile_before_chdir(node_factory):
olddir = os.getcwd() olddir = os.getcwd()
# as lightning_dir ends in /, basename and dirname don't work as expected. # as lightning_dir ends in /, basename and dirname don't work as expected.
os.chdir(os.path.dirname(l1.daemon.lightning_dir[:-1])) 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. # Test both an early arg and a normal arg.
with open(config, 'wb') as f: with open(config, 'wb') as f:
f.write(b'always-use-proxy=true\n') 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) l1 = node_factory.get_node(start=False)
subdir = os.path.join(l1.daemon.opts.get("lightning-dir"), "regtest") subdir = os.path.join(l1.daemon.opts.get("lightning-dir"), "regtest")
os.makedirs(subdir)
with open(os.path.join(subdir, "config"), 'w') as f: with open(os.path.join(subdir, "config"), 'w') as f:
f.write('alias=test_config_in_subdir') f.write('alias=test_config_in_subdir')
l1.start() l1.start()

5
tests/test_plugin.py

@ -2,7 +2,7 @@ from collections import OrderedDict
from fixtures import * # noqa: F401,F403 from fixtures import * # noqa: F401,F403
from flaky import flaky # noqa: F401 from flaky import flaky # noqa: F401
from lightning import RpcError, Millisatoshi 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 json
import os import os
@ -316,7 +316,7 @@ def test_db_hook(node_factory, executor):
l1.stop() l1.stop()
# Databases should be identical. # 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) db2 = sqlite3.connect(dbfile)
assert [x for x in db1.iterdump()] == [x for x in db2.iterdump()] 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. # Now, try native.
out = subprocess.check_output(['cli/lightning-cli', out = subprocess.check_output(['cli/lightning-cli',
'--network={}'.format(TEST_NETWORK),
'--lightning-dir={}' '--lightning-dir={}'
.format(l1.daemon.lightning_dir), .format(l1.daemon.lightning_dir),
'utf8', 'ナンセンス 1杯']).decode('utf-8') 'utf8', 'ナンセンス 1杯']).decode('utf-8')

2
tests/test_wallet.py

@ -611,7 +611,7 @@ def test_hsm_secret_encryption(node_factory):
def test_hsmtool_secret_decryption(node_factory): def test_hsmtool_secret_decryption(node_factory):
l1 = node_factory.get_node() l1 = node_factory.get_node()
password = "reckless\n" 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`. # We need to simulate a terminal to use termios in `lightningd`.
master_fd, slave_fd = os.openpty() master_fd, slave_fd = os.openpty()

Loading…
Cancel
Save