Files
palladum-lightning/common/configdir.c
Davide Grilli 26f9698bad fix: correct Palladium chain params and sanitize branding
- bitcoin/chainparams.c:
  - Fix mainnet RPC port 2333 → 2332 (was the P2P port)
  - Fix regtest RPC port 28444 → 12443 (verified against palladiumcore)
  - Add missing testnet entry (tplm, RPC 12332, P2P 19735, P2PKH 127/P2SH 115)
  - Reset when_lightning_became_cool to 1 (no Bitcoin-specific block reference)
  - Add operational notes: Resilience Fork at block 340,000 (2 min blocks),
    Taproot via BIP9 on mainnet / ALWAYS_ACTIVE on regtest

- common/configdir.c:
  - Fix --network help text to list palladium/testnet/regtest
  - Fix --mainnet alias description (bitcoin → palladium)

- configure: make lowdown optional (warning, not fatal); only needed for man pages

- lightningd/: replace all remaining "bitcoind/bitcoin network" log messages
  with "palladiumd/palladium network" (dual_open_control.c, opening_control.c,
  peer_htlcs.c)

- .gitignore: add ccan/config.h.* (PIDs left by build system)
2026-03-11 19:49:23 +01:00

438 lines
12 KiB
C

#include "config.h"
#include <assert.h>
#include <bitcoin/chainparams.h>
#include <ccan/err/err.h>
#include <ccan/opt/opt.h>
#include <ccan/opt/private.h>
#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/path/path.h>
#include <ccan/tal/str/str.h>
#include <common/configdir.h>
#include <common/configvar.h>
#include <common/memleak.h>
#include <common/utils.h>
#include <common/version.h>
int opt_exitcode = 1;
/* The regrettable globals */
static const tal_t *options_ctx;
static struct configvar *current_cv;
/* Override a tal string; frees the old one. */
char *opt_set_talstr(const char *arg, char **p)
{
tal_free(*p);
return opt_set_charp(tal_strdup(options_ctx, arg), p);
}
static char *opt_set_abspath(const char *arg, char **p)
{
tal_free(*p);
return opt_set_charp(path_join(options_ctx, take(path_cwd(NULL)), arg),
p);
}
/* Tal wrappers for opt. */
static void *opt_allocfn(size_t size)
{
return notleak(tal_arr(NULL, char, size));
}
static void *tal_reallocfn(void *ptr, size_t size)
{
if (!ptr)
return opt_allocfn(size);
tal_resize_(&ptr, 1, size, false);
return ptr;
}
static void tal_freefn(void *ptr)
{
tal_free(ptr);
}
static struct configvar **gather_file_configvars(const tal_t *ctx,
enum configvar_src src,
const char *filename,
bool must_exist,
char **setconfig_file,
size_t include_depth)
{
char *contents, **lines;
struct configvar **cvs = tal_arr(ctx, struct configvar *, 0);
contents = grab_file_str(tmpctx, filename);
/* The default config doesn't have to exist, but if the config was
* specified on the command line it has to exist. */
if (!contents) {
if (must_exist)
err(1, "Opening and reading %s", filename);
return cvs;
}
/* First .setconfig file is used for setconfig command */
if (setconfig_file
&& *setconfig_file == NULL
&& strends(filename, ".setconfig")) {
*setconfig_file = tal_strdup(ctx, filename);
}
/* Break into lines. */
lines = tal_strsplit(contents, contents, "\r\n", STR_EMPTY_OK);
for (size_t i = 0; i < tal_count(lines) - 1; i++) {
/* Comments & blank lines*/
if (strstarts(lines[i], "#") || streq(lines[i], ""))
continue;
if (strstarts(lines[i], "include ")) {
const char *included = lines[i] + strlen("include ");
struct configvar **sub;
if (include_depth > 100)
errx(1, "Include loop with %s and %s", filename, included);
/* If relative, it's relative to current config file */
sub = gather_file_configvars(NULL,
src,
path_join(tmpctx,
take(path_dirname(NULL, filename)),
included),
true,
setconfig_file,
include_depth + 1);
cvs = configvar_join(ctx, take(cvs), take(sub));
continue;
}
tal_arr_expand(&cvs,
configvar_new(cvs, src, filename, i+1, lines[i]));
}
return cvs;
}
static char *default_base_configdir(const tal_t *ctx)
{
char *path;
const char *env = getenv("HOME");
if (!env)
return path_cwd(ctx);
path = path_join(ctx, env, ".lightning");
return path;
}
static char *default_rpcfile(const tal_t *ctx)
{
return tal_strdup(ctx, "lightning-rpc");
}
static char *opt_set_network(const char *arg, void *unused)
{
assert(arg != NULL);
/* Ignore if called directly from opt (e.g. lightning-cli) */
if (!current_cv)
return NULL;
if (current_cv->src == CONFIGVAR_NETWORK_CONF)
return "not permitted in network-specific configuration files";
/* Set the global chainparams instance */
chainparams = chainparams_for_network(arg);
if (!chainparams)
return tal_fmt(NULL, "Unknown network name '%s'", arg);
return NULL;
}
static char *opt_set_specific_network(const char *network)
{
return opt_set_network(network, NULL);
}
static bool opt_show_network(char *buf, size_t len, const void *unused)
{
snprintf(buf, len, "%s", chainparams->network_name);
return true;
}
static char *opt_set_config_filename(const char *arg, char **p)
{
/* Ignore if called directly from opt (e.g. lightning-cli) */
if (!current_cv)
return NULL;
if (current_cv->src == CONFIGVAR_CMDLINE)
return opt_set_abspath(arg, p);
return "not permitted in configuration files";
}
static char *opt_set_lightning_dir(const char *arg, char **p)
{
/* Ignore if called directly from opt (e.g. lightning-cli) */
if (!current_cv)
return NULL;
if (current_cv->src == CONFIGVAR_CMDLINE
|| current_cv->src == CONFIGVAR_EXPLICIT_CONF)
return opt_set_abspath(arg, p);
return "not permitted in implicit configuration files";
}
void setup_option_allocators(void)
{
/*~ These functions make ccan/opt use tal for allocations */
opt_set_alloc(opt_allocfn, tal_reallocfn, tal_freefn);
}
static void parse_configvars(struct configvar **cvs,
bool early,
bool full_knowledge,
bool developer)
{
for (size_t i = 0; i < tal_count(cvs); i++) {
const char *problem;
bool should_know;
should_know = full_knowledge;
/* We should always know cmdline args in final parse */
if (!early && cvs[i]->src == CONFIGVAR_CMDLINE)
should_know = true;
current_cv = cvs[i];
problem = configvar_parse(cvs[i],
early,
should_know,
developer);
current_cv = NULL;
if (!problem)
continue;
if (cvs[i]->file) {
errx(opt_exitcode, "Config file %s line %u: %s: %s",
cvs[i]->file, cvs[i]->linenum,
cvs[i]->configline, problem);
} else {
errx(opt_exitcode, "--%s: %s", cvs[i]->configline, problem);
}
}
}
static void finished_arg(int *argc, char **argv, size_t *idx,
bool remove_args)
{
if (!remove_args) {
(*idx)++;
return;
}
memmove(argv + *idx, argv + 1 + *idx, (*argc - *idx) * sizeof(char *));
(*argc)--;
}
/* Now all options are known, we can turn cmdline into configvars */
static struct configvar **gather_cmdline_args(const tal_t *ctx,
int *argc, char **argv,
bool remove_args)
{
struct configvar **cvs = tal_arr(ctx, struct configvar *, 0);
assert(argv[*argc] == NULL);
for (size_t i = 1; argv[i];) {
struct opt_table *ot;
const char *configline, *arg, *optarg;
enum configvar_src src;
bool extra_arg;
/* End of options? */
if (streq(argv[i], "--"))
break;
if (!strstarts(argv[i], "-")) {
i++;
continue;
}
if (strstarts(argv[i], "--")) {
arg = argv[i] + 2;
ot = opt_find_long(arg, &optarg);
src = CONFIGVAR_CMDLINE;
} else {
/* FIXME: We don't handle multiple short
* options here! */
arg = argv[i] + 1;
ot = opt_find_short(arg[0]);
optarg = NULL;
src = CONFIGVAR_CMDLINE_SHORT;
}
if (ot) {
extra_arg = (ot->type & OPT_HASARG) && !optarg;
} else {
/* Unknown (yet!). Guess if next arg is for this! */
extra_arg = ((src == CONFIGVAR_CMDLINE_SHORT
|| !strchr(arg, '='))
&& argv[i+1]
&& !strstarts(argv[i+1], "-"));
}
finished_arg(argc, argv, &i, remove_args);
/* We turn `--foo bar` into `--foo=bar` here */
if (extra_arg) {
configline = tal_fmt(tmpctx, "%s=%s", arg, argv[i]);
finished_arg(argc, argv, &i, remove_args);
} else {
configline = arg;
}
tal_arr_expand(&cvs, configvar_new(cvs, src,
NULL, 0, configline));
}
assert(argv[*argc] == NULL);
return cvs;
}
void minimal_config_opts(const tal_t *ctx,
int argc, char *argv[],
char **config_filename,
char **basedir,
char **config_netdir,
char **rpc_filename)
{
initial_config_opts(tmpctx, &argc, argv, false,
config_filename,
basedir,
config_netdir,
rpc_filename, NULL);
tal_steal(ctx, *config_filename);
tal_steal(ctx, *basedir);
tal_steal(ctx, *config_netdir);
tal_steal(ctx, *rpc_filename);
}
struct configvar **initial_config_opts(const tal_t *ctx,
int *argc, char *argv[],
bool remove_args,
char **config_filename,
char **config_basedir,
char **config_netdir,
char **rpc_filename,
char **setconfig_file)
{
struct configvar **cmdline_cvs, **config_cvs, **cvs;
options_ctx = ctx;
/* This helps opt_usage. */
opt_argv0 = argv[0];
/* Default chain (a global) is bitcoin. */
chainparams = chainparams_for_network("palladium");
/* First, they could specify a config, or base dir. */
*config_filename = NULL;
opt_register_early_arg("--conf=<file>",
opt_set_config_filename,
/* Doesn't show if it's NULL! */
opt_show_charp,
config_filename,
"Specify configuration file");
*config_basedir = default_base_configdir(ctx);
opt_register_early_arg("--lightning-dir=<dir>",
opt_set_lightning_dir, opt_show_charp,
config_basedir,
"Set base directory: network-specific subdirectory is under here");
opt_register_early_arg("--network", opt_set_network, opt_show_network,
NULL,
"Select the network parameters (palladium, testnet,"
" or regtest)");
opt_register_early_noarg("--testnet",
opt_set_specific_network, "testnet",
"Alias for --network=testnet");
opt_register_early_noarg("--testnet4",
opt_set_specific_network, "testnet4",
"Alias for --network=testnet4");
opt_register_early_noarg("--signet",
opt_set_specific_network, "signet",
"Alias for --network=signet");
opt_register_early_noarg("--mainnet",
opt_set_specific_network, "palladium",
"Alias for --network=palladium");
opt_register_early_noarg("--regtest",
opt_set_specific_network, "regtest",
"Alias for --network=regtest");
/* Handle --version (and exit) here too */
opt_register_version();
/* Allow them to override rpc-file too. */
*rpc_filename = default_rpcfile(ctx);
opt_register_early_arg("--rpc-file", opt_set_talstr, opt_show_charp,
rpc_filename,
"Set JSON-RPC socket (or /dev/tty)");
cmdline_cvs = gather_cmdline_args(tmpctx, argc, argv, remove_args);
parse_configvars(cmdline_cvs, true, false, false);
if (setconfig_file)
*setconfig_file = NULL;
/* Base default or direct config can set network */
if (*config_filename) {
config_cvs = gather_file_configvars(NULL,
CONFIGVAR_EXPLICIT_CONF,
*config_filename, true,
setconfig_file, 0);
} else {
struct configvar **base_cvs, **net_cvs;
char *dir = path_join(tmpctx, take(path_cwd(NULL)), *config_basedir);
/* Optional: .lightning/config */
base_cvs = gather_file_configvars(tmpctx,
CONFIGVAR_BASE_CONF,
path_join(tmpctx, dir, "config"),
false,
setconfig_file, 0);
/* This might set network! */
parse_configvars(configvar_join(tmpctx, base_cvs, cmdline_cvs),
true, false, false);
/* Now, we can get network config */
dir = path_join(tmpctx, dir, chainparams->network_name);
net_cvs = gather_file_configvars(tmpctx,
CONFIGVAR_NETWORK_CONF,
path_join(tmpctx, dir, "config"),
false, setconfig_file, 0);
config_cvs = configvar_join(NULL, take(base_cvs), take(net_cvs));
}
cvs = configvar_join(ctx, take(config_cvs), cmdline_cvs);
/* This will be called again, once caller has added their own
* early vars! */
parse_configvars_early(cvs, false);
*config_netdir
= path_join(NULL, *config_basedir, chainparams->network_name);
/* Make sure it's absolute */
*config_netdir = path_join(ctx, take(path_cwd(NULL)), take(*config_netdir));
return cvs;
}
void parse_configvars_early(struct configvar **cvs, bool developer)
{
parse_configvars(cvs, true, false, developer);
}
void parse_configvars_final(struct configvar **cvs,
bool full_knowledge,
bool developer)
{
parse_configvars(cvs, false, full_knowledge, developer);
configvar_finalize_overrides(cvs);
}
bool is_restricted_ignored(const void *fn)
{
return fn == opt_set_specific_network;
}
bool is_restricted_print_if_nonnull(const void *fn)
{
return fn == opt_set_config_filename;
}