mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-18 22:54:25 +01:00
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>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
"<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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 <lightning-dir>/config then <lightning-dir>/<network>/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=<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=<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=<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=<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,"
|
||||
|
||||
@@ -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 <lightning_dir>/config.
|
||||
* Otherwise, we read ../config (toplevel), and config (network-level) */
|
||||
* Otherwise, we read basedir/config (toplevel), and basedir/<network>/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. */
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user