Files
lightning/daemon/lightningd.c
Rusty Russell b423b33236 protocol: implement close as per BOLT #2.
We don't actually implement closing when we have HTLCs (we should
allow it, as that's what the clearing phase is for), since soon we'll
rewrite HTLC to match the async HTLC protocol of BOLT #2.

Note that this folds the close paths, using a simple check if we have
a close transaction.  That's a slight state layer violation, but
reduces code duplication.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2016-03-24 12:09:41 +10:30

308 lines
8.9 KiB
C

#include "bitcoind.h"
#include "configdir.h"
#include "controlled_time.h"
#include "jsonrpc.h"
#include "lightningd.h"
#include "log.h"
#include "peer.h"
#include "secrets.h"
#include "timeout.h"
#include <ccan/container_of/container_of.h>
#include <ccan/err/err.h>
#include <ccan/io/io.h>
#include <ccan/opt/opt.h>
#include <ccan/tal/str/str.h>
#include <ccan/tal/tal.h>
#include <ccan/timer/timer.h>
#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <version.h>
static char *opt_set_u64(const char *arg, u64 *u)
{
char *endp;
unsigned long long l;
/* This is how the manpage says to do it. Yech. */
errno = 0;
l = strtoull(arg, &endp, 0);
if (*endp || !arg[0])
return tal_fmt(NULL, "'%s' is not a number", arg);
*u = l;
if (errno || *u != l)
return tal_fmt(NULL, "'%s' is out of range", arg);
return NULL;
}
static char *opt_set_u32(const char *arg, u32 *u)
{
char *endp;
unsigned long l;
/* This is how the manpage says to do it. Yech. */
errno = 0;
l = strtoul(arg, &endp, 0);
if (*endp || !arg[0])
return tal_fmt(NULL, "'%s' is not a number", arg);
*u = l;
if (errno || *u != l)
return tal_fmt(NULL, "'%s' is out of range", arg);
return NULL;
}
static void opt_show_u64(char buf[OPT_SHOW_LEN], const u64 *u)
{
snprintf(buf, OPT_SHOW_LEN, "%"PRIu64, *u);
}
static void opt_show_u32(char buf[OPT_SHOW_LEN], const u32 *u)
{
snprintf(buf, OPT_SHOW_LEN, "%"PRIu32, *u);
}
static void config_register_opts(struct lightningd_state *dstate)
{
opt_register_arg("--locktime", opt_set_u32, opt_show_u32,
&dstate->config.rel_locktime,
"Seconds before peer can unilaterally spend funds");
opt_register_arg("--max-locktime", opt_set_u32, opt_show_u32,
&dstate->config.rel_locktime_max,
"Maximum seconds peer can lock up our funds");
opt_register_arg("--anchor-confirms", opt_set_u32, opt_show_u32,
&dstate->config.anchor_confirms,
"Confirmations required for anchor transaction");
opt_register_arg("--max-anchor-confirms", opt_set_u32, opt_show_u32,
&dstate->config.anchor_confirms_max,
"Maximum confirmations other side can wait for anchor transaction");
opt_register_arg("--forever-confirms", opt_set_u32, opt_show_u32,
&dstate->config.forever_confirms,
"Confirmations after which we consider a reorg impossible");
opt_register_arg("--commit-fee", opt_set_u64, opt_show_u64,
&dstate->config.commitment_fee,
"Satoshis to offer for commitment transaction fee");
opt_register_arg("--min-commit-fee", opt_set_u64, opt_show_u64,
&dstate->config.commitment_fee_min,
"Minimum satoshis to accept for commitment transaction fee");
opt_register_arg("--closing-fee", opt_set_u64, opt_show_u64,
&dstate->config.closing_fee,
"Satoshis to use for mutual close transaction fee");
opt_register_arg("--min-expiry", opt_set_u32, opt_show_u32,
&dstate->config.min_expiry,
"Minimum number of seconds to accept an HTLC before expiry");
opt_register_arg("--max-expiry", opt_set_u32, opt_show_u32,
&dstate->config.max_expiry,
"Maximum number of seconds to accept an HTLC before expiry");
opt_register_arg("--bitcoind-poll", opt_set_u32, opt_show_u32,
&dstate->config.poll_seconds,
"Seconds between polling for new transactions");
}
#define MINUTES 60
#define HOURS (60 * MINUTES)
#define DAYS (24 * HOURS)
static void default_config(struct config *config)
{
/* aka. "Dude, where's my coins?" */
config->testnet = true;
/* One day to catch cheating attempts. */
config->rel_locktime = 1 * DAYS;
/* They can have up to 3 days. */
config->rel_locktime_max = 2 * DAYS;
/* We're fairly trusting, under normal circumstances. */
config->anchor_confirms = 3;
/* More than 10 confirms seems overkill. */
config->anchor_confirms_max = 10;
/* At some point, you've got to let it go... */
config->forever_confirms = 100;
/* FIXME: These should float with bitcoind's recommendations! */
/* Pay hefty fee (10x current suggested minimum). */
config->commitment_fee = 50000;
/* Don't accept less than double the current standard fee. */
config->commitment_fee_min = 10000;
/* Use this for mutual close. */
config->closing_fee = 10000;
/* Don't bother me unless I have 6 hours to collect. */
config->min_expiry = 6 * HOURS;
/* Don't lock up channel for more than 5 days. */
config->max_expiry = 5 * DAYS;
config->poll_seconds = 30;
}
static void check_config(struct lightningd_state *dstate)
{
/* BOLT #2:
* The sender MUST set `close_fee` lower than or equal to the
* fee of the final commitment transaction, and MUST set
* `close_fee` to an even number of satoshis.
*/
if (dstate->config.closing_fee > dstate->config.commitment_fee)
fatal("Closing fee %"PRIu64
" can't exceed commitment fee %"PRIu64,
dstate->config.closing_fee,
dstate->config.commitment_fee);
if (dstate->config.closing_fee & 1)
fatal("Closing fee %"PRIu64 "must be even.",
dstate->config.closing_fee);
if (dstate->config.commitment_fee_min > dstate->config.commitment_fee)
fatal("Minumum fee %"PRIu64
" can't exceed commitment fee %"PRIu64,
dstate->config.commitment_fee_min,
dstate->config.commitment_fee);
}
static struct lightningd_state *lightningd_state(void)
{
struct lightningd_state *dstate = tal(NULL, struct lightningd_state);
dstate->log_record = new_log_record(dstate, 20*1024*1024, LOG_INFORM);
dstate->base_log = new_log(dstate, dstate->log_record,
"lightningd(%u):", (int)getpid());
list_head_init(&dstate->peers);
timers_init(&dstate->timers, controlled_time());
txwatch_hash_init(&dstate->txwatches);
txowatch_hash_init(&dstate->txowatches);
dstate->secpctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
default_config(&dstate->config);
list_head_init(&dstate->bitcoin_req);
dstate->bitcoin_req_running = false;
return dstate;
}
/* Tal wrappers for opt. */
static void *opt_allocfn(size_t size)
{
return tal_alloc_(NULL, size, false, TAL_LABEL("opt_allocfn", ""));
}
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);
}
int main(int argc, char *argv[])
{
struct lightningd_state *dstate = lightningd_state();
unsigned int portnum = 0;
err_set_progname(argv[0]);
opt_set_alloc(opt_allocfn, tal_reallocfn, tal_freefn);
if (!streq(protobuf_c_version(), PROTOBUF_C_VERSION))
errx(1, "Compiled against protobuf %s, but have %s",
PROTOBUF_C_VERSION, protobuf_c_version());
opt_register_noarg("--help|-h", opt_usage_and_exit,
"\n"
"A bitcoin lightning daemon.",
"Print this message.");
opt_register_arg("--port", opt_set_uintval, NULL, &portnum,
"Port to bind to (otherwise, dynamic port is used)");
opt_register_arg("--bitcoin-datadir", opt_set_charp, NULL,
&bitcoin_datadir,
"-datadir arg for bitcoin-cli");
opt_register_logging(dstate->base_log);
opt_register_version();
configdir_register_opts(dstate,
&dstate->config_dir, &dstate->rpc_filename);
config_register_opts(dstate);
/* Get any configdir options first. */
opt_early_parse(argc, argv, opt_log_stderr_exit);
/* Move to config dir, to save ourselves the hassle of path manip. */
if (chdir(dstate->config_dir) != 0) {
log_unusual(dstate->base_log, "Creating lightningd dir %s"
" (because chdir gave %s)",
dstate->config_dir, strerror(errno));
if (mkdir(dstate->config_dir, 0700) != 0)
fatal("Could not make directory %s: %s",
dstate->config_dir, strerror(errno));
if (chdir(dstate->config_dir) != 0)
fatal("Could not change directory %s: %s",
dstate->config_dir, strerror(errno));
}
/* Activate crash log now we're in the right place. */
crashlog_activate(dstate->base_log);
/* Now look for config file */
opt_parse_from_config(dstate);
opt_parse(&argc, argv, opt_log_stderr_exit);
if (argc != 1)
errx(1, "no arguments accepted");
check_config(dstate);
check_bitcoind_config(dstate);
/* Create RPC socket (if any) */
setup_jsonrpc(dstate, dstate->rpc_filename);
/* Set up connections from peers. */
setup_listeners(dstate, portnum);
/* Set up node ID and private key. */
secrets_init(dstate);
/* Create timer to do watches. */
setup_watch_timer(dstate);
/* Make sure we use the artificially-controlled time for timers */
io_time_override(controlled_time);
log_info(dstate->base_log, "Hello world!");
for (;;) {
struct timer *expired;
void *v = io_loop(&dstate->timers, &expired);
/* We use io_break(dstate) to shut down. */
if (v == dstate)
break;
/* We use it on a peer when it needs freeing (may be
* NULL if we only broke out due to timer). */
tal_free(v);
if (expired) {
struct timeout *to;
to = container_of(expired, struct timeout, timer);
to->cb(to->arg);
}
}
tal_free(dstate);
opt_free_table();
return 0;
}