2017-01-10 06:08:33 +01:00
|
|
|
#include "gossip_control.h"
|
2017-01-10 06:08:33 +01:00
|
|
|
#include "hsm_control.h"
|
2017-01-10 06:07:51 +01:00
|
|
|
#include "lightningd.h"
|
2017-01-10 06:08:33 +01:00
|
|
|
#include "peer_control.h"
|
2017-03-10 11:48:43 +01:00
|
|
|
#include "subd.h"
|
2017-12-15 11:18:54 +01:00
|
|
|
#include <backtrace.h>
|
2017-01-10 06:07:51 +01:00
|
|
|
#include <ccan/array_size/array_size.h>
|
2017-08-28 18:09:01 +02:00
|
|
|
#include <ccan/cast/cast.h>
|
2017-02-24 06:52:56 +01:00
|
|
|
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
|
2018-02-16 03:00:41 +01:00
|
|
|
#include <ccan/daemonize/daemonize.h>
|
2017-01-10 06:07:51 +01:00
|
|
|
#include <ccan/err/err.h>
|
2017-01-10 06:08:33 +01:00
|
|
|
#include <ccan/io/fdpass/fdpass.h>
|
2017-01-10 06:08:33 +01:00
|
|
|
#include <ccan/io/io.h>
|
2017-01-10 06:08:33 +01:00
|
|
|
#include <ccan/noerr/noerr.h>
|
2017-01-10 06:07:51 +01:00
|
|
|
#include <ccan/pipecmd/pipecmd.h>
|
2018-02-20 00:00:09 +01:00
|
|
|
#include <ccan/read_write_all/read_write_all.h>
|
2017-01-10 06:07:51 +01:00
|
|
|
#include <ccan/take/take.h>
|
|
|
|
#include <ccan/tal/grab_file/grab_file.h>
|
|
|
|
#include <ccan/tal/path/path.h>
|
2017-09-15 04:18:52 +02:00
|
|
|
#include <ccan/tal/str/str.h>
|
2018-03-29 04:06:45 +02:00
|
|
|
#include <common/daemon.h>
|
2017-12-15 11:17:54 +01:00
|
|
|
#include <common/memleak.h>
|
2017-08-28 18:04:01 +02:00
|
|
|
#include <common/timeout.h>
|
2017-08-28 18:02:01 +02:00
|
|
|
#include <common/utils.h>
|
|
|
|
#include <common/version.h>
|
2018-02-16 03:00:41 +01:00
|
|
|
#include <errno.h>
|
2018-02-20 00:00:09 +01:00
|
|
|
#include <fcntl.h>
|
2017-08-28 18:04:01 +02:00
|
|
|
#include <lightningd/bitcoind.h>
|
|
|
|
#include <lightningd/chaintopology.h>
|
2018-05-06 15:32:01 +02:00
|
|
|
#include <lightningd/channel_control.h>
|
2018-07-24 08:18:58 +02:00
|
|
|
#include <lightningd/connect_control.h>
|
2017-08-28 18:04:01 +02:00
|
|
|
#include <lightningd/invoice.h>
|
|
|
|
#include <lightningd/jsonrpc.h>
|
|
|
|
#include <lightningd/log.h>
|
2018-04-17 15:31:30 +02:00
|
|
|
#include <lightningd/onchain_control.h>
|
2017-08-28 18:04:01 +02:00
|
|
|
#include <lightningd/options.h>
|
2017-08-29 06:12:04 +02:00
|
|
|
#include <onchaind/onchain_wire.h>
|
2018-01-22 15:59:08 +01:00
|
|
|
#include <signal.h>
|
2017-01-10 06:07:51 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
char *bitcoin_datadir;
|
|
|
|
|
2017-12-15 11:18:54 +01:00
|
|
|
struct backtrace_state *backtrace_state;
|
|
|
|
|
2018-02-20 00:00:09 +01:00
|
|
|
int pid_fd;
|
|
|
|
|
2018-02-18 13:56:46 +01:00
|
|
|
static struct lightningd *new_lightningd(const tal_t *ctx)
|
2017-01-10 06:07:51 +01:00
|
|
|
{
|
|
|
|
struct lightningd *ld = tal(ctx, struct lightningd);
|
|
|
|
|
2017-12-15 11:17:54 +01:00
|
|
|
#if DEVELOPER
|
|
|
|
ld->dev_debug_subdaemon = NULL;
|
|
|
|
ld->dev_disconnect_fd = -1;
|
|
|
|
ld->dev_subdaemon_fail = false;
|
2018-05-07 06:29:22 +02:00
|
|
|
ld->dev_allow_localhost = false;
|
2018-01-29 01:30:15 +01:00
|
|
|
|
2017-12-17 04:17:12 +01:00
|
|
|
if (getenv("LIGHTNINGD_DEV_MEMLEAK"))
|
|
|
|
memleak_init(ld, backtrace_state);
|
2017-12-15 11:17:54 +01:00
|
|
|
#endif
|
|
|
|
|
2017-01-10 06:08:33 +01:00
|
|
|
list_head_init(&ld->peers);
|
2017-06-20 07:53:03 +02:00
|
|
|
htlc_in_map_init(&ld->htlcs_in);
|
|
|
|
htlc_out_map_init(&ld->htlcs_out);
|
2018-02-18 13:56:46 +01:00
|
|
|
ld->log_book = new_log_book(20*1024*1024, LOG_INFORM);
|
|
|
|
ld->log = new_log(ld, ld->log_book, "lightningd(%u):", (int)getpid());
|
2018-01-29 01:30:15 +01:00
|
|
|
ld->logfile = NULL;
|
2017-10-23 07:05:28 +02:00
|
|
|
ld->alias = NULL;
|
|
|
|
ld->rgb = NULL;
|
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
|
|
|
list_head_init(&ld->connects);
|
2018-04-23 12:08:01 +02:00
|
|
|
list_head_init(&ld->fundchannels);
|
2018-03-10 07:41:45 +01:00
|
|
|
list_head_init(&ld->waitsendpay_commands);
|
2018-03-10 08:44:28 +01:00
|
|
|
list_head_init(&ld->sendpay_commands);
|
2018-04-10 08:03:15 +02:00
|
|
|
list_head_init(&ld->close_commands);
|
2018-05-07 06:29:22 +02:00
|
|
|
ld->proposed_wireaddr = tal_arr(ld, struct wireaddr_internal, 0);
|
|
|
|
ld->proposed_listen_announce = tal_arr(ld, enum addr_listen_announce, 0);
|
2017-08-28 18:09:01 +02:00
|
|
|
ld->portnum = DEFAULT_PORT;
|
2018-05-07 05:44:40 +02:00
|
|
|
ld->listen = true;
|
2018-05-07 06:28:12 +02:00
|
|
|
ld->autolisten = true;
|
2018-05-07 05:44:40 +02:00
|
|
|
ld->reconnect = true;
|
2017-08-28 18:09:01 +02:00
|
|
|
timers_init(&ld->timers, time_mono());
|
|
|
|
ld->topology = new_topology(ld, ld->log);
|
2018-02-16 03:00:41 +01:00
|
|
|
ld->daemon = false;
|
2018-07-11 05:11:09 +02:00
|
|
|
ld->config_filename = NULL;
|
2018-02-20 00:00:09 +01:00
|
|
|
ld->pidfile = NULL;
|
2018-03-18 13:22:21 +01:00
|
|
|
ld->ini_autocleaninvoice_cycle = 0;
|
|
|
|
ld->ini_autocleaninvoice_expiredby = 86400;
|
2018-05-10 01:18:24 +02:00
|
|
|
ld->proxyaddr = NULL;
|
|
|
|
ld->use_proxy_always = false;
|
2018-05-10 01:18:24 +02:00
|
|
|
ld->pure_tor_setup = false;
|
2018-05-10 01:18:23 +02:00
|
|
|
ld->tor_service_password = NULL;
|
2018-05-07 01:01:49 +02:00
|
|
|
ld->max_funding_unconfirmed = 2016;
|
|
|
|
|
2017-01-10 06:07:51 +01:00
|
|
|
return ld;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *daemons[] = {
|
2017-08-29 06:12:04 +02:00
|
|
|
"lightning_channeld",
|
|
|
|
"lightning_closingd",
|
2018-07-24 08:18:58 +02:00
|
|
|
"lightning_connectd",
|
2017-08-29 06:12:04 +02:00
|
|
|
"lightning_gossipd",
|
|
|
|
"lightning_hsmd",
|
|
|
|
"lightning_onchaind",
|
|
|
|
"lightning_openingd"
|
2017-01-10 06:07:51 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Check we can run them, and check their versions */
|
2018-01-03 12:05:44 +01:00
|
|
|
void test_daemons(const struct lightningd *ld)
|
2017-01-10 06:07:51 +01:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(daemons); i++) {
|
|
|
|
int outfd;
|
2018-03-15 07:10:20 +01:00
|
|
|
const char *dpath = path_join(tmpctx, ld->daemon_dir, daemons[i]);
|
2017-01-10 06:07:51 +01:00
|
|
|
const char *verstring;
|
|
|
|
pid_t pid = pipecmd(&outfd, NULL, &outfd,
|
|
|
|
dpath, "--version", NULL);
|
|
|
|
|
2017-08-28 18:09:01 +02:00
|
|
|
log_debug(ld->log, "testing %s", dpath);
|
2017-01-10 06:07:51 +01:00
|
|
|
if (pid == -1)
|
|
|
|
err(1, "Could not run %s", dpath);
|
2018-03-15 07:10:20 +01:00
|
|
|
verstring = grab_fd(tmpctx, outfd);
|
2017-01-10 06:07:51 +01:00
|
|
|
if (!verstring)
|
|
|
|
err(1, "Could not get output from %s", dpath);
|
|
|
|
if (!strstarts(verstring, version())
|
|
|
|
|| verstring[strlen(version())] != '\n')
|
|
|
|
errx(1, "%s: bad version '%s'", daemons[i], verstring);
|
|
|
|
}
|
|
|
|
}
|
2018-01-03 12:34:41 +01:00
|
|
|
/* Check if all daemons exist in specified directory. */
|
|
|
|
static bool has_all_daemons(const char* daemon_dir)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
bool missing_daemon = false;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(daemons); ++i) {
|
|
|
|
if (!path_is_file(path_join(tmpctx, daemon_dir, daemons[i]))) {
|
|
|
|
missing_daemon = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return !missing_daemon;
|
|
|
|
}
|
2017-01-10 06:07:51 +01:00
|
|
|
|
|
|
|
static const char *find_my_path(const tal_t *ctx, const char *argv0)
|
|
|
|
{
|
2018-03-15 07:10:20 +01:00
|
|
|
char *me;
|
2017-09-15 04:18:52 +02:00
|
|
|
|
|
|
|
if (strchr(argv0, PATH_SEP)) {
|
|
|
|
const char *path;
|
|
|
|
/* Absolute paths are easy. */
|
|
|
|
if (strstarts(argv0, PATH_SEP_STR))
|
|
|
|
path = argv0;
|
|
|
|
/* It contains a '/', it's relative to current dir. */
|
|
|
|
else
|
|
|
|
path = path_join(tmpctx, path_cwd(tmpctx), argv0);
|
|
|
|
|
|
|
|
me = path_canon(ctx, path);
|
|
|
|
if (!me || access(me, X_OK) != 0)
|
|
|
|
errx(1, "I cannot find myself at %s based on my name %s",
|
|
|
|
path, argv0);
|
|
|
|
} else {
|
|
|
|
/* No /, search path */
|
|
|
|
char **pathdirs;
|
|
|
|
const char *pathenv = getenv("PATH");
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (!pathenv)
|
|
|
|
errx(1, "Cannot find myself: no $PATH set");
|
|
|
|
|
|
|
|
pathdirs = tal_strsplit(tmpctx, pathenv, ":", STR_NO_EMPTY);
|
|
|
|
me = NULL;
|
|
|
|
for (i = 0; pathdirs[i]; i++) {
|
|
|
|
/* This returns NULL if it doesn't exist. */
|
|
|
|
me = path_canon(ctx,
|
|
|
|
path_join(tmpctx, pathdirs[i], argv0));
|
|
|
|
if (me && access(me, X_OK) == 0)
|
|
|
|
break;
|
|
|
|
/* Nope, try again. */
|
|
|
|
me = tal_free(me);
|
|
|
|
}
|
|
|
|
if (!me)
|
|
|
|
errx(1, "Cannot find %s in $PATH", argv0);
|
|
|
|
}
|
2017-01-10 06:07:51 +01:00
|
|
|
|
|
|
|
return path_dirname(ctx, take(me));
|
|
|
|
}
|
2018-01-03 12:34:41 +01:00
|
|
|
static const char *find_my_pkglibexec_path(const tal_t *ctx,
|
|
|
|
const char *my_path TAKES)
|
|
|
|
{
|
|
|
|
const char *pkglibexecdir;
|
|
|
|
pkglibexecdir = path_join(ctx, my_path, BINTOPKGLIBEXECDIR);
|
|
|
|
return path_simplify(ctx, take(pkglibexecdir));
|
|
|
|
}
|
|
|
|
/* Determine the correct daemon dir. */
|
|
|
|
static const char *find_daemon_dir(const tal_t *ctx, const char *argv0)
|
|
|
|
{
|
|
|
|
const char *my_path = find_my_path(ctx, argv0);
|
|
|
|
if (has_all_daemons(my_path))
|
|
|
|
return my_path;
|
|
|
|
return find_my_pkglibexec_path(ctx, take(my_path));
|
|
|
|
}
|
2017-01-10 06:07:51 +01:00
|
|
|
|
2017-04-12 08:52:32 +02:00
|
|
|
static void shutdown_subdaemons(struct lightningd *ld)
|
|
|
|
{
|
|
|
|
struct peer *p;
|
|
|
|
|
2017-11-10 21:21:09 +01:00
|
|
|
db_begin_transaction(ld->wallet->db);
|
2017-04-12 08:52:32 +02:00
|
|
|
/* Let everyone shutdown cleanly. */
|
2017-06-24 08:50:23 +02:00
|
|
|
close(ld->hsm_fd);
|
2017-04-12 08:52:32 +02:00
|
|
|
subd_shutdown(ld->gossip, 10);
|
2018-07-09 13:17:59 +02:00
|
|
|
subd_shutdown(ld->hsm, 10);
|
2017-04-12 08:52:32 +02:00
|
|
|
|
2017-11-10 03:01:10 +01:00
|
|
|
free_htlcs(ld, NULL);
|
|
|
|
|
2018-02-12 11:13:04 +01:00
|
|
|
while ((p = list_top(&ld->peers, struct peer, list)) != NULL) {
|
2018-02-14 02:53:04 +01:00
|
|
|
struct channel *c;
|
2018-02-12 11:13:04 +01:00
|
|
|
|
2018-02-14 02:53:04 +01:00
|
|
|
while ((c = list_top(&p->channels, struct channel, list))
|
|
|
|
!= NULL) {
|
|
|
|
/* Removes itself from list as we free it */
|
2018-02-12 11:13:04 +01:00
|
|
|
tal_free(c);
|
2018-02-14 02:53:04 +01:00
|
|
|
}
|
|
|
|
|
2018-04-23 12:45:10 +02:00
|
|
|
/* Freeing uncommitted channel will free peer. */
|
|
|
|
if (p->uncommitted_channel)
|
|
|
|
tal_free(p->uncommitted_channel);
|
|
|
|
else
|
|
|
|
/* Removes itself from list as we free it */
|
|
|
|
tal_free(p);
|
2018-02-12 11:13:04 +01:00
|
|
|
}
|
2017-11-10 21:21:09 +01:00
|
|
|
db_commit_transaction(ld->wallet->db);
|
2017-04-12 08:52:32 +02:00
|
|
|
}
|
|
|
|
|
2018-03-06 19:27:21 +01:00
|
|
|
const struct chainparams *get_chainparams(const struct lightningd *ld)
|
2017-08-28 18:09:01 +02:00
|
|
|
{
|
2018-03-06 19:27:21 +01:00
|
|
|
return ld->topology->bitcoind->chainparams;
|
2017-08-28 18:09:01 +02:00
|
|
|
}
|
|
|
|
|
2017-11-27 16:20:10 +01:00
|
|
|
static void init_txfilter(struct wallet *w, struct txfilter *filter)
|
|
|
|
{
|
|
|
|
struct ext_key ext;
|
|
|
|
u64 bip32_max_index;
|
|
|
|
|
|
|
|
bip32_max_index = db_get_intvar(w->db, "bip32_max_index", 0);
|
|
|
|
for (u64 i = 0; i <= bip32_max_index; i++) {
|
|
|
|
if (bip32_key_from_parent(w->bip32_base, i, BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
txfilter_add_derkey(filter, ext.pub_key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-26 20:29:58 +01:00
|
|
|
static void daemonize_but_keep_dir(struct lightningd *ld)
|
2018-02-16 03:00:41 +01:00
|
|
|
{
|
|
|
|
/* daemonize moves us into /, but we want to be here */
|
|
|
|
const char *cwd = path_cwd(NULL);
|
|
|
|
|
2018-02-26 20:29:58 +01:00
|
|
|
db_close_for_fork(ld->wallet->db);
|
2018-02-16 03:00:41 +01:00
|
|
|
if (!cwd)
|
|
|
|
fatal("Could not get current directory: %s", strerror(errno));
|
|
|
|
if (!daemonize())
|
|
|
|
fatal("Could not become a daemon: %s", strerror(errno));
|
|
|
|
|
|
|
|
/* Move back: important, since lightning dir may be relative! */
|
|
|
|
if (chdir(cwd) != 0)
|
|
|
|
fatal("Could not return to directory %s: %s",
|
|
|
|
cwd, strerror(errno));
|
|
|
|
|
2018-02-26 20:29:58 +01:00
|
|
|
db_reopen_after_fork(ld->wallet->db);
|
2018-02-16 03:00:41 +01:00
|
|
|
tal_free(cwd);
|
|
|
|
}
|
|
|
|
|
2018-02-20 00:00:09 +01:00
|
|
|
static void pidfile_create(const struct lightningd *ld)
|
|
|
|
{
|
|
|
|
char *pid;
|
|
|
|
|
|
|
|
/* Create PID file */
|
|
|
|
pid_fd = open(ld->pidfile, O_WRONLY|O_CREAT, 0640);
|
|
|
|
if (pid_fd < 0)
|
|
|
|
err(1, "Failed to open PID file");
|
|
|
|
|
|
|
|
/* Lock PID file */
|
|
|
|
if (lockf(pid_fd, F_TLOCK, 0) < 0)
|
|
|
|
/* Problem locking file */
|
|
|
|
err(1, "lightningd already running? Error locking PID file");
|
|
|
|
|
|
|
|
/* Get current PID and write to PID fie */
|
|
|
|
pid = tal_fmt(tmpctx, "%d\n", getpid());
|
|
|
|
write_all(pid_fd, pid, strlen(pid));
|
|
|
|
}
|
|
|
|
|
2018-04-27 03:41:38 +02:00
|
|
|
/* Yuck, we need globals here. */
|
|
|
|
static int (*io_poll_debug)(struct pollfd *, nfds_t, int);
|
|
|
|
static int io_poll_lightningd(struct pollfd *fds, nfds_t nfds, int timeout)
|
|
|
|
{
|
|
|
|
db_assert_no_outstanding_statements();
|
|
|
|
|
|
|
|
return io_poll_debug(fds, nfds, timeout);
|
|
|
|
}
|
|
|
|
|
2018-05-06 15:32:01 +02:00
|
|
|
void notify_new_block(struct lightningd *ld,
|
|
|
|
u32 block_height)
|
|
|
|
{
|
|
|
|
/* Inform our subcomponents individually. */
|
|
|
|
htlcs_notify_new_block(ld, block_height);
|
|
|
|
channel_notify_new_block(ld, block_height);
|
|
|
|
}
|
|
|
|
|
2017-01-10 06:07:51 +01:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2017-09-28 05:26:29 +02:00
|
|
|
struct lightningd *ld;
|
2018-06-04 15:00:05 +02:00
|
|
|
u32 min_blockheight, max_blockheight;
|
2018-07-24 08:18:58 +02:00
|
|
|
int connectd_gossipd_fd;
|
2017-01-10 06:07:51 +01:00
|
|
|
|
2018-05-03 14:20:28 +02:00
|
|
|
setup_locale();
|
2018-03-29 04:06:45 +02:00
|
|
|
daemon_setup(argv[0], log_backtrace_print, log_backtrace_exit);
|
2018-02-18 13:56:46 +01:00
|
|
|
ld = new_lightningd(NULL);
|
2017-09-28 05:41:18 +02:00
|
|
|
|
2018-01-03 12:34:41 +01:00
|
|
|
/* Figure out where our daemons are first. */
|
|
|
|
ld->daemon_dir = find_daemon_dir(ld, argv[0]);
|
|
|
|
if (!ld->daemon_dir)
|
|
|
|
errx(1, "Could not find daemons");
|
2017-01-10 06:07:51 +01:00
|
|
|
|
2017-08-28 18:09:01 +02:00
|
|
|
register_opts(ld);
|
2017-05-24 12:10:16 +02:00
|
|
|
|
2017-02-24 06:52:56 +01:00
|
|
|
/* Handle options and config; move to .lightningd */
|
2018-05-03 14:20:28 +02:00
|
|
|
handle_opts(ld, argc, argv);
|
2017-01-10 06:07:51 +01:00
|
|
|
|
|
|
|
/* Ignore SIGPIPE: we look at our write return values*/
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
|
|
|
/* Make sure we can reach other daemons, and versions match. */
|
|
|
|
test_daemons(ld);
|
|
|
|
|
2017-05-23 22:07:20 +02:00
|
|
|
/* Initialize wallet, now that we are in the correct directory */
|
2018-01-23 00:53:21 +01:00
|
|
|
ld->wallet = wallet_new(ld, ld->log, &ld->timers);
|
2017-11-27 16:20:10 +01:00
|
|
|
ld->owned_txfilter = txfilter_new(ld);
|
2018-02-19 15:20:51 +01:00
|
|
|
ld->topology->wallet = ld->wallet;
|
2017-05-23 22:07:20 +02:00
|
|
|
|
2018-04-27 03:41:38 +02:00
|
|
|
/* We do extra checks in io_loop. */
|
|
|
|
io_poll_debug = io_poll_override(io_poll_lightningd);
|
|
|
|
|
2017-01-10 06:07:51 +01:00
|
|
|
/* Set up HSM. */
|
2018-05-03 14:20:28 +02:00
|
|
|
hsm_init(ld);
|
2017-01-10 06:08:33 +01:00
|
|
|
|
2017-10-23 07:05:28 +02:00
|
|
|
/* Now we know our ID, we can set our color/alias if not already. */
|
|
|
|
setup_color_and_alias(ld);
|
|
|
|
|
2018-07-24 08:18:58 +02:00
|
|
|
/* Set up connect daemon. */
|
|
|
|
connectd_gossipd_fd = connectd_init(ld);
|
|
|
|
|
|
|
|
/* Set up gossip daemon. */
|
|
|
|
gossip_init(ld, connectd_gossipd_fd);
|
2018-04-30 04:08:15 +02:00
|
|
|
|
2017-11-01 02:10:48 +01:00
|
|
|
/* Everything is within a transaction. */
|
|
|
|
db_begin_transaction(ld->wallet->db);
|
|
|
|
|
2018-02-16 17:55:33 +01:00
|
|
|
if (!wallet_network_check(ld->wallet, get_chainparams(ld)))
|
|
|
|
errx(1, "Wallet network check failed.");
|
|
|
|
|
2017-11-27 16:20:10 +01:00
|
|
|
/* Initialize the transaction filter with our pubkeys. */
|
|
|
|
init_txfilter(ld->wallet, ld->owned_txfilter);
|
|
|
|
|
2018-01-14 15:15:30 +01:00
|
|
|
/* Check invoices loaded from the database */
|
|
|
|
if (!wallet_invoice_load(ld->wallet)) {
|
2017-11-01 02:10:48 +01:00
|
|
|
fatal("Could not load invoices from the database");
|
2017-10-04 14:45:00 +02:00
|
|
|
}
|
|
|
|
|
2018-03-18 13:22:21 +01:00
|
|
|
/* Set up invoice autoclean. */
|
|
|
|
wallet_invoice_autoclean(ld->wallet,
|
|
|
|
ld->ini_autocleaninvoice_cycle,
|
|
|
|
ld->ini_autocleaninvoice_expiredby);
|
|
|
|
|
2017-08-17 15:30:24 +02:00
|
|
|
/* Load peers from database */
|
2018-02-12 11:12:55 +01:00
|
|
|
if (!wallet_channels_load_active(ld, ld->wallet))
|
|
|
|
fatal("Could not load channels from the database");
|
2017-08-22 13:19:38 +02:00
|
|
|
|
|
|
|
/* TODO(cdecker) Move this into common location for initialization */
|
2017-08-17 15:30:24 +02:00
|
|
|
struct peer *peer;
|
|
|
|
list_for_each(&ld->peers, peer, list) {
|
2018-02-12 11:12:55 +01:00
|
|
|
struct channel *channel;
|
|
|
|
|
|
|
|
list_for_each(&peer->channels, channel, list) {
|
|
|
|
if (!wallet_htlcs_load_for_channel(ld->wallet,
|
|
|
|
channel,
|
|
|
|
&ld->htlcs_in,
|
|
|
|
&ld->htlcs_out)) {
|
|
|
|
fatal("could not load htlcs for channel");
|
|
|
|
}
|
2017-09-30 14:31:52 +02:00
|
|
|
}
|
|
|
|
}
|
2017-11-01 02:10:48 +01:00
|
|
|
if (!wallet_htlcs_reconnect(ld->wallet, &ld->htlcs_in, &ld->htlcs_out))
|
|
|
|
fatal("could not reconnect htlcs loaded from wallet, wallet may be inconsistent.");
|
|
|
|
|
2018-04-20 14:44:34 +02:00
|
|
|
/* Get the blockheight we are currently at, UINT32_MAX is used to signal
|
|
|
|
* an unitialized wallet and that we should start off of bitcoind's
|
|
|
|
* current height */
|
2018-06-04 15:00:05 +02:00
|
|
|
wallet_blocks_heights(ld->wallet, UINT32_MAX, &min_blockheight, &max_blockheight);
|
2018-04-20 14:44:34 +02:00
|
|
|
|
|
|
|
/* If we were asked to rescan from an absolute height (--rescan < 0)
|
2018-06-04 15:00:05 +02:00
|
|
|
* then just go there. Otherwise compute the diff to our current height,
|
|
|
|
* lowerbounded by 0. */
|
2018-04-20 14:44:34 +02:00
|
|
|
if (ld->config.rescan < 0)
|
2018-06-04 15:00:05 +02:00
|
|
|
max_blockheight = -ld->config.rescan;
|
|
|
|
else if (max_blockheight < (u32)ld->config.rescan)
|
|
|
|
max_blockheight = 0;
|
|
|
|
else if (max_blockheight != UINT32_MAX)
|
|
|
|
max_blockheight -= ld->config.rescan;
|
2018-01-03 06:26:43 +01:00
|
|
|
|
2017-11-01 02:10:48 +01:00
|
|
|
db_commit_transaction(ld->wallet->db);
|
|
|
|
|
2017-11-27 16:20:10 +01:00
|
|
|
/* Initialize block topology (does its own transaction) */
|
2018-06-04 15:00:05 +02:00
|
|
|
setup_topology(ld->topology, &ld->timers, min_blockheight, max_blockheight);
|
2017-11-27 16:20:10 +01:00
|
|
|
|
2017-01-10 06:08:33 +01:00
|
|
|
/* Create RPC socket (if any) */
|
2017-08-28 18:09:01 +02:00
|
|
|
setup_jsonrpc(ld, ld->rpc_filename);
|
2017-01-10 06:07:51 +01:00
|
|
|
|
2018-02-16 03:00:41 +01:00
|
|
|
/* Now we're about to start, become daemon if desired. */
|
|
|
|
if (ld->daemon)
|
2018-02-26 20:29:58 +01:00
|
|
|
daemonize_but_keep_dir(ld);
|
2018-02-16 03:00:41 +01:00
|
|
|
|
2018-04-07 14:42:00 +02:00
|
|
|
/* Create PID file */
|
|
|
|
pidfile_create(ld);
|
|
|
|
|
2018-05-02 04:53:34 +02:00
|
|
|
/* Activate gossip daemon. Needs to be after the initialization of
|
|
|
|
* chaintopology, otherwise we may be asking for uninitialized data. */
|
|
|
|
gossip_activate(ld);
|
|
|
|
|
|
|
|
/* Replay transactions for all running onchainds */
|
|
|
|
onchaind_replay_channels(ld);
|
|
|
|
|
gossipd: rewrite to do the handshake internally.
Now the flow is much simpler from a lightningd POV:
1. If we want to connect to a peer, just send gossipd `gossipctl_reach_peer`.
2. Every new peer, gossipd hands up to lightningd, with global/local features
and the peer fd and a gossip fd using `gossip_peer_connected`
3. If lightningd doesn't want it, it just hands the peerfd and global/local
features back to gossipd using `gossipctl_handle_peer`
4. If a peer sends a non-gossip msg (eg `open_channel`) the gossipd sends
it up using `gossip_peer_nongossip`.
5. If lightningd wants to fund a channel, it simply calls `release_channel`.
Notes:
* There's no more "unique_id": we use the peer id.
* For the moment, we don't ask gossipd when we're told to list peers, so
connected peers without a channel don't appear in the JSON getpeers API.
* We add a `gossipctl_peer_addrhint` for the moment, so you can connect to
a specific ip/port, but using other sources is a TODO.
* We now (correctly) only give up on reaching a peer after we exchange init
messages, which changes the test_disconnect case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-10-11 12:09:49 +02:00
|
|
|
/* Mark ourselves live. */
|
2018-01-24 20:33:47 +01:00
|
|
|
log_info(ld->log, "Server started with public key %s, alias %s (color #%s) and lightningd %s",
|
2018-03-15 05:30:39 +01:00
|
|
|
type_to_string(tmpctx, struct pubkey, &ld->id),
|
2018-03-26 02:08:43 +02:00
|
|
|
json_escape(tmpctx, (const char *)ld->alias)->s,
|
|
|
|
tal_hex(tmpctx, ld->rgb), version());
|
2017-01-10 06:08:33 +01:00
|
|
|
|
2018-01-03 06:26:44 +01:00
|
|
|
/* Start the peers. */
|
|
|
|
activate_peers(ld);
|
|
|
|
|
|
|
|
/* Now kick off topology update, now peers have watches. */
|
|
|
|
begin_topology(ld->topology);
|
|
|
|
|
2018-02-16 03:00:41 +01:00
|
|
|
/* Activate crash log now we're not reporting startup failures. */
|
2018-03-29 04:06:45 +02:00
|
|
|
crashlog = ld->log;
|
2018-02-16 03:00:41 +01:00
|
|
|
|
2017-01-10 06:07:51 +01:00
|
|
|
for (;;) {
|
|
|
|
struct timer *expired;
|
2017-08-28 18:09:01 +02:00
|
|
|
void *v = io_loop(&ld->timers, &expired);
|
2017-01-10 06:07:51 +01:00
|
|
|
|
|
|
|
/* We use io_break(dstate) to shut down. */
|
2017-01-10 06:08:33 +01:00
|
|
|
if (v == ld)
|
2017-01-10 06:07:51 +01:00
|
|
|
break;
|
|
|
|
|
2017-11-01 02:10:48 +01:00
|
|
|
if (expired) {
|
|
|
|
db_begin_transaction(ld->wallet->db);
|
2017-08-28 18:09:01 +02:00
|
|
|
timer_expired(ld, expired);
|
2017-11-01 02:10:48 +01:00
|
|
|
db_commit_transaction(ld->wallet->db);
|
|
|
|
}
|
2017-01-10 06:07:51 +01:00
|
|
|
}
|
|
|
|
|
2017-04-12 08:52:32 +02:00
|
|
|
shutdown_subdaemons(ld);
|
2018-02-20 00:00:09 +01:00
|
|
|
close(pid_fd);
|
|
|
|
remove(ld->pidfile);
|
2017-04-12 08:52:32 +02:00
|
|
|
|
2017-01-10 06:07:51 +01:00
|
|
|
tal_free(ld);
|
|
|
|
opt_free_table();
|
2017-12-15 11:17:54 +01:00
|
|
|
|
|
|
|
#if DEVELOPER
|
|
|
|
memleak_cleanup();
|
|
|
|
#endif
|
2018-03-29 04:06:45 +02:00
|
|
|
daemon_shutdown();
|
2017-01-10 06:07:51 +01:00
|
|
|
return 0;
|
|
|
|
}
|