#include "bitcoind.h" #include "chaintopology.h" #include "db.h" #include "invoice.h" #include "irc_announce.h" #include "jsonrpc.h" #include "lightningd.h" #include "log.h" #include "options.h" #include "p2p_announce.h" #include "peer.h" #include "routing.h" #include "secrets.h" #include "timeout.h" #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include static struct lightningd_state *lightningd_state(void) { struct lightningd_state *dstate = tal(NULL, struct lightningd_state); dstate->log_book = new_log_book(dstate, 20*1024*1024, LOG_INFORM); dstate->base_log = new_log(dstate, dstate->log_book, "lightningd(%u):", (int)getpid()); list_head_init(&dstate->peers); list_head_init(&dstate->pay_commands); dstate->portnum = 0; dstate->testnet = true; timers_init(&dstate->timers, time_mono()); txwatch_hash_init(&dstate->txwatches); txowatch_hash_init(&dstate->txowatches); list_head_init(&dstate->bitcoin_req); list_head_init(&dstate->wallet); list_head_init(&dstate->addresses); dstate->dev_never_routefail = false; dstate->dev_no_broadcast = false; dstate->bitcoin_req_running = false; dstate->nodes = empty_node_map(dstate); dstate->reexec = NULL; dstate->external_ip = NULL; dstate->announce = NULL; list_head_init(&dstate->broadcast_queue); dstate->invoices = invoices_init(dstate); return dstate; } int main(int argc, char *argv[]) { struct lightningd_state *dstate = lightningd_state(); err_set_progname(argv[0]); if (!streq(protobuf_c_version(), PROTOBUF_C_VERSION)) errx(1, "Compiled against protobuf %s, but have %s", PROTOBUF_C_VERSION, protobuf_c_version()); secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); /* Handle options and config; move to .lightningd */ handle_opts(dstate, argc, argv); /* Activate crash log now we're in the right place. */ crashlog_activate(dstate->base_log); /* Ignore SIGPIPE: we look at our write return values*/ signal(SIGPIPE, SIG_IGN); /* Set up node ID and private key. */ secrets_init(dstate); new_node(dstate, &dstate->id); /* Read or create database. */ db_init(dstate); /* Initialize block topology. */ setup_topology(dstate); /* Create RPC socket (if any) */ setup_jsonrpc(dstate, dstate->rpc_filename); /* Set up connections from peers (if dstate->portnum is set) */ setup_listeners(dstate); /* set up IRC peer discovery */ if (dstate->config.use_irc) setup_irc_connection(dstate); /* set up P2P gossip protocol */ setup_p2p_announce(dstate); log_info(dstate->base_log, "Hello world!"); /* If we loaded peers from database, reconnect now. */ reconnect_peers(dstate); /* And send out anchors again if we're waiting. */ rebroadcast_anchors(dstate); for (;;) { struct timer *expired; void *v = io_loop(&dstate->timers, &expired); /* We use io_break(dstate) to shut down. */ if (v == dstate) break; if (expired) timer_expired(dstate, expired); else cleanup_peers(dstate); } if (dstate->reexec) { int fd; log_unusual(dstate->base_log, "Restart at user request"); fflush(stdout); fflush(stderr); /* Manually close all fds (or near enough!) */ for (fd = 3; fd < 1024; fd++) close(fd); if (dstate->dev_never_routefail) { size_t n = tal_count(dstate->reexec); tal_resizez(&dstate->reexec, n+1); dstate->reexec[n-1] = "--dev-no-routefail"; } execvp(dstate->reexec[0], dstate->reexec); fatal("Exec '%s' failed: %s", dstate->reexec[0], strerror(errno)); } tal_free(dstate); opt_free_table(); return 0; }