Browse Source

daemon/bitcoind: wean off struct lightningd_state.

We want to use this in the new daemon, so use 'struct bitcoind'
everywhere.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
e6efcdf5bd
  1. 158
      daemon/bitcoind.c
  2. 87
      daemon/bitcoind.h
  3. 52
      daemon/chaintopology.c
  4. 4
      daemon/lightningd.c
  5. 8
      daemon/lightningd.h
  6. 12
      daemon/options.c
  7. 1
      lightningd/Makefile
  8. 4
      lightningd/lightningd.c

158
daemon/bitcoind.c

@ -24,19 +24,26 @@
char *bitcoin_datadir; char *bitcoin_datadir;
static char **gather_args(struct lightningd_state *dstate, static char **gather_args(struct bitcoind *bitcoind,
const tal_t *ctx, const char *cmd, va_list ap) const tal_t *ctx, const char *cmd, va_list ap)
{ {
size_t n = 0; size_t n = 0;
char **args = tal_arr(ctx, char *, 3); char **args = tal_arr(ctx, char *, 3);
args[n++] = BITCOIN_CLI; args[n++] = BITCOIN_CLI;
if (dstate->config.regtest) switch (bitcoind->testmode) {
case BITCOIND_REGTEST:
args[n++] = "-regtest=1"; args[n++] = "-regtest=1";
else break;
args[n++] = tal_fmt(args, "-testnet=%u", dstate->testnet); case BITCOIND_TESTNET:
if (bitcoin_datadir) { args[n++] = "-testnet=1";
args[n++] = tal_fmt(args, "-datadir=%s", bitcoin_datadir); break;
case BITCOIND_MAINNET:
args[n++] = "-testnet=0";
break;
}
if (bitcoind->datadir) {
args[n++] = tal_fmt(args, "-datadir=%s", bitcoind->datadir);
tal_resize(&args, n + 1); tal_resize(&args, n + 1);
} }
args[n++] = cast_const(char *, cmd); args[n++] = cast_const(char *, cmd);
@ -52,7 +59,7 @@ static char **gather_args(struct lightningd_state *dstate,
struct bitcoin_cli { struct bitcoin_cli {
struct list_node list; struct list_node list;
struct lightningd_state *dstate; struct bitcoind *bitcoind;
int fd; int fd;
int *exitstatus; int *exitstatus;
pid_t pid; pid_t pid;
@ -83,7 +90,7 @@ static struct io_plan *output_init(struct io_conn *conn, struct bitcoin_cli *bcl
return read_more(conn, bcli); return read_more(conn, bcli);
} }
static void next_bcli(struct lightningd_state *dstate); static void next_bcli(struct bitcoind *bitcoind);
/* For printing: simple string of args. */ /* For printing: simple string of args. */
static char *bcli_args(struct bitcoin_cli *bcli) static char *bcli_args(struct bitcoin_cli *bcli)
@ -101,7 +108,7 @@ static char *bcli_args(struct bitcoin_cli *bcli)
static void bcli_finished(struct io_conn *conn, struct bitcoin_cli *bcli) static void bcli_finished(struct io_conn *conn, struct bitcoin_cli *bcli)
{ {
int ret, status; int ret, status;
struct lightningd_state *dstate = bcli->dstate; struct bitcoind *bitcoind = bcli->bitcoind;
/* FIXME: If we waited for SIGCHILD, this could never hang! */ /* FIXME: If we waited for SIGCHILD, this could never hang! */
ret = waitpid(bcli->pid, &status, 0); ret = waitpid(bcli->pid, &status, 0);
@ -124,33 +131,33 @@ static void bcli_finished(struct io_conn *conn, struct bitcoin_cli *bcli)
} else } else
*bcli->exitstatus = WEXITSTATUS(status); *bcli->exitstatus = WEXITSTATUS(status);
log_debug(dstate->base_log, "reaped %u: %s", ret, bcli_args(bcli)); log_debug(bitcoind->log, "reaped %u: %s", ret, bcli_args(bcli));
dstate->bitcoin_req_running = false; bitcoind->req_running = false;
bcli->process(bcli); bcli->process(bcli);
next_bcli(dstate); next_bcli(bitcoind);
} }
static void next_bcli(struct lightningd_state *dstate) static void next_bcli(struct bitcoind *bitcoind)
{ {
struct bitcoin_cli *bcli; struct bitcoin_cli *bcli;
struct io_conn *conn; struct io_conn *conn;
if (dstate->bitcoin_req_running) if (bitcoind->req_running)
return; return;
bcli = list_pop(&dstate->bitcoin_req, struct bitcoin_cli, list); bcli = list_pop(&bitcoind->pending, struct bitcoin_cli, list);
if (!bcli) if (!bcli)
return; return;
log_debug(bcli->dstate->base_log, "starting: %s", bcli_args(bcli)); log_debug(bcli->bitcoind->log, "starting: %s", bcli_args(bcli));
bcli->pid = pipecmdarr(&bcli->fd, NULL, &bcli->fd, bcli->args); bcli->pid = pipecmdarr(&bcli->fd, NULL, &bcli->fd, bcli->args);
if (bcli->pid < 0) if (bcli->pid < 0)
fatal("%s exec failed: %s", bcli->args[0], strerror(errno)); fatal("%s exec failed: %s", bcli->args[0], strerror(errno));
dstate->bitcoin_req_running = true; bitcoind->req_running = true;
conn = io_new_conn(dstate, bcli->fd, output_init, bcli); conn = io_new_conn(bitcoind, bcli->fd, output_init, bcli);
tal_steal(conn, bcli); tal_steal(conn, bcli);
io_set_finish(conn, bcli_finished, bcli); io_set_finish(conn, bcli_finished, bcli);
} }
@ -175,7 +182,7 @@ static void remove_stopper(struct bitcoin_cli *bcli)
/* If ctx is non-NULL, and is freed before we return, we don't call process() */ /* If ctx is non-NULL, and is freed before we return, we don't call process() */
static void static void
start_bitcoin_cli(struct lightningd_state *dstate, start_bitcoin_cli(struct bitcoind *bitcoind,
const tal_t *ctx, const tal_t *ctx,
void (*process)(struct bitcoin_cli *), void (*process)(struct bitcoin_cli *),
bool nonzero_exit_ok, bool nonzero_exit_ok,
@ -183,9 +190,9 @@ start_bitcoin_cli(struct lightningd_state *dstate,
char *cmd, ...) char *cmd, ...)
{ {
va_list ap; va_list ap;
struct bitcoin_cli *bcli = tal(dstate, struct bitcoin_cli); struct bitcoin_cli *bcli = tal(bitcoind, struct bitcoin_cli);
bcli->dstate = dstate; bcli->bitcoind = bitcoind;
bcli->process = process; bcli->process = process;
bcli->cb = cb; bcli->cb = cb;
bcli->cb_arg = cb_arg; bcli->cb_arg = cb_arg;
@ -203,11 +210,11 @@ start_bitcoin_cli(struct lightningd_state *dstate,
else else
bcli->exitstatus = NULL; bcli->exitstatus = NULL;
va_start(ap, cmd); va_start(ap, cmd);
bcli->args = gather_args(dstate, bcli, cmd, ap); bcli->args = gather_args(bitcoind, bcli, cmd, ap);
va_end(ap); va_end(ap);
list_add_tail(&dstate->bitcoin_req, &bcli->list); list_add_tail(&bitcoind->pending, &bcli->list);
next_bcli(dstate); next_bcli(bitcoind);
} }
static void process_estimatefee_6(struct bitcoin_cli *bcli) static void process_estimatefee_6(struct bitcoin_cli *bcli)
@ -215,7 +222,7 @@ static void process_estimatefee_6(struct bitcoin_cli *bcli)
double fee; double fee;
char *p, *end; char *p, *end;
u64 fee_rate; u64 fee_rate;
void (*cb)(struct lightningd_state *, u64, void *) = bcli->cb; void (*cb)(struct bitcoind *, u64, void *) = bcli->cb;
p = tal_strndup(bcli, bcli->output, bcli->output_bytes); p = tal_strndup(bcli, bcli->output, bcli->output_bytes);
fee = strtod(p, &end); fee = strtod(p, &end);
@ -224,7 +231,7 @@ static void process_estimatefee_6(struct bitcoin_cli *bcli)
bcli_args(bcli), p); bcli_args(bcli), p);
if (fee < 0) { if (fee < 0) {
log_unusual(bcli->dstate->base_log, log_unusual(bcli->bitcoind->log,
"Unable to estimate fee"); "Unable to estimate fee");
fee_rate = 0; fee_rate = 0;
} else { } else {
@ -233,7 +240,7 @@ static void process_estimatefee_6(struct bitcoin_cli *bcli)
fee_rate = fee * 100000000; fee_rate = fee * 100000000;
} }
cb(bcli->dstate, fee_rate, bcli->cb_arg); cb(bcli->bitcoind, fee_rate, bcli->cb_arg);
} }
static void process_estimatefee_2(struct bitcoin_cli *bcli) static void process_estimatefee_2(struct bitcoin_cli *bcli)
@ -241,7 +248,7 @@ static void process_estimatefee_2(struct bitcoin_cli *bcli)
double fee; double fee;
char *p, *end; char *p, *end;
u64 fee_rate; u64 fee_rate;
void (*cb)(struct lightningd_state *, u64, void *) = bcli->cb; void (*cb)(struct bitcoind *, u64, void *) = bcli->cb;
p = tal_strndup(bcli, bcli->output, bcli->output_bytes); p = tal_strndup(bcli, bcli->output, bcli->output_bytes);
fee = strtod(p, &end); fee = strtod(p, &end);
@ -251,45 +258,45 @@ static void process_estimatefee_2(struct bitcoin_cli *bcli)
/* Don't know at 2? Try 6... */ /* Don't know at 2? Try 6... */
if (fee < 0) { if (fee < 0) {
start_bitcoin_cli(bcli->dstate, NULL, process_estimatefee_6, start_bitcoin_cli(bcli->bitcoind, NULL, process_estimatefee_6,
false, bcli->cb, bcli->cb_arg, false, bcli->cb, bcli->cb_arg,
"estimatefee", "6", NULL); "estimatefee", "6", NULL);
return; return;
} }
fee_rate = fee * 100000000; fee_rate = fee * 100000000;
cb(bcli->dstate, fee_rate, bcli->cb_arg); cb(bcli->bitcoind, fee_rate, bcli->cb_arg);
} }
void bitcoind_estimate_fee_(struct lightningd_state *dstate, void bitcoind_estimate_fee_(struct bitcoind *bitcoind,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
u64, void *), u64, void *),
void *arg) void *arg)
{ {
start_bitcoin_cli(dstate, NULL, process_estimatefee_2, false, cb, arg, start_bitcoin_cli(bitcoind, NULL, process_estimatefee_2, false, cb, arg,
"estimatefee", "2", NULL); "estimatefee", "2", NULL);
} }
static void process_sendrawtx(struct bitcoin_cli *bcli) static void process_sendrawtx(struct bitcoin_cli *bcli)
{ {
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
int, const char *msg, void *) = bcli->cb; int, const char *msg, void *) = bcli->cb;
const char *msg = tal_strndup(bcli, (char *)bcli->output, const char *msg = tal_strndup(bcli, (char *)bcli->output,
bcli->output_bytes); bcli->output_bytes);
log_debug(bcli->dstate->base_log, "sendrawtx exit %u, gave %s", log_debug(bcli->bitcoind->log, "sendrawtx exit %u, gave %s",
*bcli->exitstatus, msg); *bcli->exitstatus, msg);
cb(bcli->dstate, *bcli->exitstatus, msg, bcli->cb_arg); cb(bcli->bitcoind, *bcli->exitstatus, msg, bcli->cb_arg);
} }
void bitcoind_sendrawtx_(struct peer *peer, void bitcoind_sendrawtx_(struct peer *peer,
struct lightningd_state *dstate, struct bitcoind *bitcoind,
const char *hextx, const char *hextx,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
int exitstatus, const char *msg, void *), int exitstatus, const char *msg, void *),
void *arg) void *arg)
{ {
start_bitcoin_cli(dstate, NULL, process_sendrawtx, true, cb, arg, start_bitcoin_cli(bitcoind, NULL, process_sendrawtx, true, cb, arg,
"sendrawtransaction", hextx, NULL); "sendrawtransaction", hextx, NULL);
} }
@ -299,11 +306,11 @@ static void process_chaintips(struct bitcoin_cli *bcli)
bool valid; bool valid;
size_t i; size_t i;
struct sha256_double tip; struct sha256_double tip;
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
struct sha256_double *tipid, struct sha256_double *tipid,
void *arg) = bcli->cb; void *arg) = bcli->cb;
log_debug(bcli->dstate->base_log, "Got getchaintips result"); log_debug(bcli->bitcoind->log, "Got getchaintips result");
tokens = json_parse_input(bcli->output, bcli->output_bytes, &valid); tokens = json_parse_input(bcli->output, bcli->output_bytes, &valid);
if (!tokens) if (!tokens)
@ -323,7 +330,7 @@ static void process_chaintips(struct bitcoin_cli *bcli)
const jsmntok_t *hash = json_get_member(bcli->output, t, "hash"); const jsmntok_t *hash = json_get_member(bcli->output, t, "hash");
if (!json_tok_streq(bcli->output, status, "active")) { if (!json_tok_streq(bcli->output, status, "active")) {
log_debug(bcli->dstate->base_log, log_debug(bcli->bitcoind->log,
"Ignoring chaintip %.*s status %.*s", "Ignoring chaintip %.*s status %.*s",
hash->end - hash->start, hash->end - hash->start,
bcli->output + hash->start, bcli->output + hash->start,
@ -332,7 +339,7 @@ static void process_chaintips(struct bitcoin_cli *bcli)
continue; continue;
} }
if (valid) { if (valid) {
log_unusual(bcli->dstate->base_log, log_unusual(bcli->bitcoind->log,
"%s: Two active chaintips? %.*s", "%s: Two active chaintips? %.*s",
bcli_args(bcli), bcli_args(bcli),
(int)bcli->output_bytes, bcli->output); (int)bcli->output_bytes, bcli->output);
@ -350,37 +357,23 @@ static void process_chaintips(struct bitcoin_cli *bcli)
fatal("%s: gave no active chaintips (%.*s)?", fatal("%s: gave no active chaintips (%.*s)?",
bcli_args(bcli), (int)bcli->output_bytes, bcli->output); bcli_args(bcli), (int)bcli->output_bytes, bcli->output);
cb(bcli->dstate, &tip, bcli->cb_arg); cb(bcli->bitcoind, &tip, bcli->cb_arg);
} }
void bitcoind_get_chaintip_(struct lightningd_state *dstate, void bitcoind_get_chaintip_(struct bitcoind *bitcoind,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
const struct sha256_double *tipid, const struct sha256_double *tipid,
void *arg), void *arg),
void *arg) void *arg)
{ {
start_bitcoin_cli(dstate, NULL, process_chaintips, false, cb, arg, start_bitcoin_cli(bitcoind, NULL, process_chaintips, false, cb, arg,
"getchaintips", NULL); "getchaintips", NULL);
} }
struct normalizing {
u32 mediantime;
struct sha256_double prevblk, blkid;
struct sha256_double *txids;
size_t i;
void (*cb)(struct lightningd_state *dstate,
struct sha256_double *blkid,
struct sha256_double *prevblock,
struct sha256_double *txids,
u32 mediantime,
void *arg);
void *cb_arg;
};
static void process_rawblock(struct bitcoin_cli *bcli) static void process_rawblock(struct bitcoin_cli *bcli)
{ {
struct bitcoin_block *blk; struct bitcoin_block *blk;
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
struct bitcoin_block *blk, struct bitcoin_block *blk,
void *arg) = bcli->cb; void *arg) = bcli->cb;
@ -391,12 +384,12 @@ static void process_rawblock(struct bitcoin_cli *bcli)
bcli_args(bcli), bcli_args(bcli),
(int)bcli->output_bytes, (char *)bcli->output); (int)bcli->output_bytes, (char *)bcli->output);
cb(bcli->dstate, blk, bcli->cb_arg); cb(bcli->bitcoind, blk, bcli->cb_arg);
} }
void bitcoind_getrawblock_(struct lightningd_state *dstate, void bitcoind_getrawblock_(struct bitcoind *bitcoind,
const struct sha256_double *blockid, const struct sha256_double *blockid,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
struct bitcoin_block *blk, struct bitcoin_block *blk,
void *arg), void *arg),
void *arg) void *arg)
@ -404,7 +397,7 @@ void bitcoind_getrawblock_(struct lightningd_state *dstate,
char hex[hex_str_size(sizeof(*blockid))]; char hex[hex_str_size(sizeof(*blockid))];
bitcoin_blkid_to_hex(blockid, hex, sizeof(hex)); bitcoin_blkid_to_hex(blockid, hex, sizeof(hex));
start_bitcoin_cli(dstate, NULL, process_rawblock, false, cb, arg, start_bitcoin_cli(bitcoind, NULL, process_rawblock, false, cb, arg,
"getblock", hex, "false", NULL); "getblock", hex, "false", NULL);
} }
@ -412,7 +405,7 @@ static void process_getblockcount(struct bitcoin_cli *bcli)
{ {
u32 blockcount; u32 blockcount;
char *p, *end; char *p, *end;
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
u32 blockcount, u32 blockcount,
void *arg) = bcli->cb; void *arg) = bcli->cb;
@ -422,23 +415,23 @@ static void process_getblockcount(struct bitcoin_cli *bcli)
fatal("%s: gave non-numeric blockcount %s", fatal("%s: gave non-numeric blockcount %s",
bcli_args(bcli), p); bcli_args(bcli), p);
cb(bcli->dstate, blockcount, bcli->cb_arg); cb(bcli->bitcoind, blockcount, bcli->cb_arg);
} }
void bitcoind_getblockcount_(struct lightningd_state *dstate, void bitcoind_getblockcount_(struct bitcoind *bitcoind,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
u32 blockcount, u32 blockcount,
void *arg), void *arg),
void *arg) void *arg)
{ {
start_bitcoin_cli(dstate, NULL, process_getblockcount, false, cb, arg, start_bitcoin_cli(bitcoind, NULL, process_getblockcount, false, cb, arg,
"getblockcount", NULL); "getblockcount", NULL);
} }
static void process_getblockhash(struct bitcoin_cli *bcli) static void process_getblockhash(struct bitcoin_cli *bcli)
{ {
struct sha256_double blkid; struct sha256_double blkid;
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
const struct sha256_double *blkid, const struct sha256_double *blkid,
void *arg) = bcli->cb; void *arg) = bcli->cb;
@ -449,12 +442,12 @@ static void process_getblockhash(struct bitcoin_cli *bcli)
bcli_args(bcli), (int)bcli->output_bytes, bcli->output); bcli_args(bcli), (int)bcli->output_bytes, bcli->output);
} }
cb(bcli->dstate, &blkid, bcli->cb_arg); cb(bcli->bitcoind, &blkid, bcli->cb_arg);
} }
void bitcoind_getblockhash_(struct lightningd_state *dstate, void bitcoind_getblockhash_(struct bitcoind *bitcoind,
u32 height, u32 height,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
const struct sha256_double *blkid, const struct sha256_double *blkid,
void *arg), void *arg),
void *arg) void *arg)
@ -462,6 +455,19 @@ void bitcoind_getblockhash_(struct lightningd_state *dstate,
char str[STR_MAX_CHARS(height)]; char str[STR_MAX_CHARS(height)];
sprintf(str, "%u", height); sprintf(str, "%u", height);
start_bitcoin_cli(dstate, NULL, process_getblockhash, false, cb, arg, start_bitcoin_cli(bitcoind, NULL, process_getblockhash, false, cb, arg,
"getblockhash", str, NULL); "getblockhash", str, NULL);
} }
struct bitcoind *new_bitcoind(const tal_t *ctx, struct log *log)
{
struct bitcoind *bitcoind = tal(ctx, struct bitcoind);
bitcoind->testmode = BITCOIND_TESTNET;
bitcoind->datadir = NULL;
bitcoind->log = log;
bitcoind->req_running = false;
list_head_init(&bitcoind->pending);
return bitcoind;
}

87
daemon/bitcoind.h

@ -1,7 +1,9 @@
#ifndef LIGHTNING_DAEMON_BITCOIND_H #ifndef LIGHTNING_DAEMON_BITCOIND_H
#define LIGHTNING_DAEMON_BITCOIND_H #define LIGHTNING_DAEMON_BITCOIND_H
#include "config.h" #include "config.h"
#include <ccan/list/list.h>
#include <ccan/short_types/short_types.h> #include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
#include <ccan/typesafe_cb/typesafe_cb.h> #include <ccan/typesafe_cb/typesafe_cb.h>
#include <stdbool.h> #include <stdbool.h>
@ -11,91 +13,114 @@ struct ripemd160;
struct bitcoin_tx; struct bitcoin_tx;
struct peer; struct peer;
struct bitcoin_block; struct bitcoin_block;
enum bitcoind_mode {
BITCOIND_MAINNET = 1,
BITCOIND_TESTNET,
BITCOIND_REGTEST
};
struct bitcoind {
/* What mode are we in. */
enum bitcoind_mode testmode;
/* -datadir arg for bitcoin-cli. */ /* -datadir arg for bitcoin-cli. */
extern char *bitcoin_datadir; char *datadir;
/* Where to do logging. */
struct log *log;
/* Are we currently running a bitcoind request (it's ratelimited) */
bool req_running;
/* Pending requests. */
struct list_head pending;
};
struct bitcoind *new_bitcoind(const tal_t *ctx, struct log *log);
void bitcoind_estimate_fee_(struct lightningd_state *dstate, void bitcoind_estimate_fee_(struct bitcoind *bitcoind,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
u64, void *), u64, void *),
void *arg); void *arg);
#define bitcoind_estimate_fee(dstate, cb, arg) \ #define bitcoind_estimate_fee(bitcoind_, cb, arg) \
bitcoind_estimate_fee_((dstate), \ bitcoind_estimate_fee_((bitcoind_), \
typesafe_cb_preargs(void, void *, \ typesafe_cb_preargs(void, void *, \
(cb), (arg), \ (cb), (arg), \
struct lightningd_state *, \ struct bitcoind *, \
u64), \ u64), \
(arg)) (arg))
void bitcoind_sendrawtx_(struct peer *peer, void bitcoind_sendrawtx_(struct peer *peer,
struct lightningd_state *dstate, struct bitcoind *bitcoind,
const char *hextx, const char *hextx,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
int exitstatus, const char *msg, void *), int exitstatus, const char *msg, void *),
void *arg); void *arg);
#define bitcoind_sendrawtx(peer_, dstate, hextx, cb, arg) \ #define bitcoind_sendrawtx(peer_, bitcoind_, hextx, cb, arg) \
bitcoind_sendrawtx_((peer_), (dstate), (hextx), \ bitcoind_sendrawtx_((peer_), (bitcoind_), (hextx), \
typesafe_cb_preargs(void, void *, \ typesafe_cb_preargs(void, void *, \
(cb), (arg), \ (cb), (arg), \
struct lightningd_state *, \ struct bitcoind *, \
int, const char *), \ int, const char *), \
(arg)) (arg))
void bitcoind_get_chaintip_(struct lightningd_state *dstate, void bitcoind_get_chaintip_(struct bitcoind *bitcoind,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
const struct sha256_double *tipid, const struct sha256_double *tipid,
void *arg), void *arg),
void *arg); void *arg);
#define bitcoind_get_chaintip(dstate, cb, arg) \ #define bitcoind_get_chaintip(bitcoind_, cb, arg) \
bitcoind_get_chaintip_((dstate), \ bitcoind_get_chaintip_((bitcoind_), \
typesafe_cb_preargs(void, void *, \ typesafe_cb_preargs(void, void *, \
(cb), (arg), \ (cb), (arg), \
struct lightningd_state *, \ struct bitcoind *, \
const struct sha256_double *), \ const struct sha256_double *), \
(arg)) (arg))
void bitcoind_getblockcount_(struct lightningd_state *dstate, void bitcoind_getblockcount_(struct bitcoind *bitcoind,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
u32 blockcount, u32 blockcount,
void *arg), void *arg),
void *arg); void *arg);
#define bitcoind_getblockcount(dstate, cb, arg) \ #define bitcoind_getblockcount(bitcoind_, cb, arg) \
bitcoind_getblockcount_((dstate), \ bitcoind_getblockcount_((bitcoind_), \
typesafe_cb_preargs(void, void *, \ typesafe_cb_preargs(void, void *, \
(cb), (arg), \ (cb), (arg), \
struct lightningd_state *, \ struct bitcoind *, \
u32 blockcount), \ u32 blockcount), \
(arg)) (arg))
void bitcoind_getblockhash_(struct lightningd_state *dstate, void bitcoind_getblockhash_(struct bitcoind *bitcoind,
u32 height, u32 height,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
const struct sha256_double *blkid, const struct sha256_double *blkid,
void *arg), void *arg),
void *arg); void *arg);
#define bitcoind_getblockhash(dstate, height, cb, arg) \ #define bitcoind_getblockhash(bitcoind_, height, cb, arg) \
bitcoind_getblockhash_((dstate), \ bitcoind_getblockhash_((bitcoind_), \
(height), \ (height), \
typesafe_cb_preargs(void, void *, \ typesafe_cb_preargs(void, void *, \
(cb), (arg), \ (cb), (arg), \
struct lightningd_state *, \ struct bitcoind *, \
const struct sha256_double *), \ const struct sha256_double *), \
(arg)) (arg))
void bitcoind_getrawblock_(struct lightningd_state *dstate, void bitcoind_getrawblock_(struct bitcoind *bitcoind,
const struct sha256_double *blockid, const struct sha256_double *blockid,
void (*cb)(struct lightningd_state *dstate, void (*cb)(struct bitcoind *bitcoind,
struct bitcoin_block *blk, struct bitcoin_block *blk,
void *arg), void *arg),
void *arg); void *arg);
#define bitcoind_getrawblock(dstate, blkid, cb, arg) \ #define bitcoind_getrawblock(bitcoind_, blkid, cb, arg) \
bitcoind_getrawblock_((dstate), (blkid), \ bitcoind_getrawblock_((bitcoind_), (blkid), \
typesafe_cb_preargs(void, void *, \ typesafe_cb_preargs(void, void *, \
(cb), (arg), \ (cb), (arg), \
struct lightningd_state *, \ struct bitcoind *, \
struct bitcoin_block *), \ struct bitcoin_block *), \
(arg)) (arg))
#endif /* LIGHTNING_DAEMON_BITCOIND_H */ #endif /* LIGHTNING_DAEMON_BITCOIND_H */

52
daemon/chaintopology.c

@ -233,10 +233,12 @@ struct txs_to_broadcast {
}; };
/* We just sent the last entry in txs[]. Shrink and send the next last. */ /* We just sent the last entry in txs[]. Shrink and send the next last. */
static void broadcast_remainder(struct lightningd_state *dstate, static void broadcast_remainder(struct bitcoind *bitcoind,
int exitstatus, const char *msg, int exitstatus, const char *msg,
struct txs_to_broadcast *txs) struct txs_to_broadcast *txs)
{ {
struct lightningd_state *dstate = tal_parent(bitcoind);
/* These are expected. */ /* These are expected. */
if (strstr(msg, "txn-mempool-conflict") if (strstr(msg, "txn-mempool-conflict")
|| strstr(msg, "transaction already in block chain")) || strstr(msg, "transaction already in block chain"))
@ -256,7 +258,7 @@ static void broadcast_remainder(struct lightningd_state *dstate,
} }
/* Broadcast next one. */ /* Broadcast next one. */
bitcoind_sendrawtx(NULL, dstate, txs->txs[txs->cursor], bitcoind_sendrawtx(NULL, bitcoind, txs->txs[txs->cursor],
broadcast_remainder, txs); broadcast_remainder, txs);
} }
@ -293,7 +295,7 @@ static void rebroadcast_txs(struct lightningd_state *dstate,
/* Let this do the dirty work. */ /* Let this do the dirty work. */
txs->cursor = (size_t)-1; txs->cursor = (size_t)-1;
broadcast_remainder(dstate, 0, "", txs); broadcast_remainder(dstate->bitcoind, 0, "", txs);
} }
static void destroy_outgoing_tx(struct outgoing_tx *otx) static void destroy_outgoing_tx(struct outgoing_tx *otx)
@ -301,7 +303,7 @@ static void destroy_outgoing_tx(struct outgoing_tx *otx)
list_del_from(&otx->peer->outgoing_txs, &otx->list); list_del_from(&otx->peer->outgoing_txs, &otx->list);
} }
static void broadcast_done(struct lightningd_state *dstate, static void broadcast_done(struct bitcoind *bitcoind,
int exitstatus, const char *msg, int exitstatus, const char *msg,
struct outgoing_tx *otx) struct outgoing_tx *otx)
{ {
@ -331,9 +333,10 @@ void broadcast_tx(struct peer *peer, const struct bitcoin_tx *tx,
log_add_struct(peer->log, " (tx %s)", struct sha256_double, &otx->txid); log_add_struct(peer->log, " (tx %s)", struct sha256_double, &otx->txid);
if (peer->dstate->dev_no_broadcast) if (peer->dstate->dev_no_broadcast)
broadcast_done(peer->dstate, 0, "dev_no_broadcast", otx); broadcast_done(peer->dstate->bitcoind,
0, "dev_no_broadcast", otx);
else else
bitcoind_sendrawtx(peer, peer->dstate, otx->hextx, bitcoind_sendrawtx(peer, peer->dstate->bitcoind, otx->hextx,
broadcast_done, otx); broadcast_done, otx);
} }
@ -354,9 +357,9 @@ static void free_blocks(struct lightningd_state *dstate, struct block *b)
} }
} }
static void update_fee(struct lightningd_state *dstate, u64 rate, u64 *feerate) static void update_fee(struct bitcoind *bitcoind, u64 rate, u64 *feerate)
{ {
log_debug(dstate->base_log, "Feerate %"PRIu64" -> %"PRIu64, log_debug(bitcoind->log, "Feerate %"PRIu64" -> %"PRIu64,
rate, *feerate); rate, *feerate);
*feerate = rate; *feerate = rate;
} }
@ -384,7 +387,8 @@ static void topology_changed(struct lightningd_state *dstate,
rebroadcast_txs(dstate, NULL); rebroadcast_txs(dstate, NULL);
/* Once per new block head, update fee estimate. */ /* Once per new block head, update fee estimate. */
bitcoind_estimate_fee(dstate, update_fee, &dstate->topology->feerate); bitcoind_estimate_fee(dstate->bitcoind,
update_fee, &dstate->topology->feerate);
} }
static struct block *new_block(struct lightningd_state *dstate, static struct block *new_block(struct lightningd_state *dstate,
@ -414,10 +418,11 @@ static struct block *new_block(struct lightningd_state *dstate,
return b; return b;
} }
static void gather_blocks(struct lightningd_state *dstate, static void gather_blocks(struct bitcoind *bitcoind,
struct bitcoin_block *blk, struct bitcoin_block *blk,
struct block *next) struct block *next)
{ {
struct lightningd_state *dstate = tal_parent(bitcoind);
struct topology *topo = dstate->topology; struct topology *topo = dstate->topology;
struct block *b, *prev; struct block *b, *prev;
@ -426,7 +431,7 @@ static void gather_blocks(struct lightningd_state *dstate,
/* Recurse if we need prev. */ /* Recurse if we need prev. */
prev = block_map_get(&topo->block_map, &blk->hdr.prev_hash); prev = block_map_get(&topo->block_map, &blk->hdr.prev_hash);
if (!prev) { if (!prev) {
bitcoind_getrawblock(dstate, &blk->hdr.prev_hash, bitcoind_getrawblock(dstate->bitcoind, &blk->hdr.prev_hash,
gather_blocks, b); gather_blocks, b);
return; return;
} }
@ -436,15 +441,16 @@ static void gather_blocks(struct lightningd_state *dstate,
next_topology_timer(dstate); next_topology_timer(dstate);
} }
static void check_chaintip(struct lightningd_state *dstate, static void check_chaintip(struct bitcoind *bitcoind,
const struct sha256_double *tipid, const struct sha256_double *tipid,
void *arg) void *arg)
{ {
struct lightningd_state *dstate = tal_parent(bitcoind);
struct topology *topo = dstate->topology; struct topology *topo = dstate->topology;
/* 0 is the main tip. */ /* 0 is the main tip. */
if (!structeq(tipid, &topo->tip->blkid)) if (!structeq(tipid, &topo->tip->blkid))
bitcoind_getrawblock(dstate, tipid, gather_blocks, bitcoind_getrawblock(dstate->bitcoind, tipid, gather_blocks,
(struct block *)NULL); (struct block *)NULL);
else else
/* Next! */ /* Next! */
@ -453,18 +459,19 @@ static void check_chaintip(struct lightningd_state *dstate,
static void start_poll_chaintip(struct lightningd_state *dstate) static void start_poll_chaintip(struct lightningd_state *dstate)
{ {
if (!list_empty(&dstate->bitcoin_req)) { if (!list_empty(&dstate->bitcoind->pending)) {
log_unusual(dstate->base_log, log_unusual(dstate->base_log,
"Delaying start poll: commands in progress"); "Delaying start poll: commands in progress");
next_topology_timer(dstate); next_topology_timer(dstate);
} else } else
bitcoind_get_chaintip(dstate, check_chaintip, NULL); bitcoind_get_chaintip(dstate->bitcoind, check_chaintip, NULL);
} }
static void init_topo(struct lightningd_state *dstate, static void init_topo(struct bitcoind *bitcoind,
struct bitcoin_block *blk, struct bitcoin_block *blk,
ptrint_t *p) ptrint_t *p)
{ {
struct lightningd_state *dstate = tal_parent(bitcoind);
struct topology *topo = dstate->topology; struct topology *topo = dstate->topology;
topo->root = new_block(dstate, blk, NULL); topo->root = new_block(dstate, blk, NULL);
@ -473,19 +480,20 @@ static void init_topo(struct lightningd_state *dstate,
topo->tip = topo->root; topo->tip = topo->root;
/* Now grab chaintip immediately. */ /* Now grab chaintip immediately. */
bitcoind_get_chaintip(dstate, check_chaintip, NULL); bitcoind_get_chaintip(dstate->bitcoind, check_chaintip, NULL);
} }
static void get_init_block(struct lightningd_state *dstate, static void get_init_block(struct bitcoind *bitcoind,
const struct sha256_double *blkid, const struct sha256_double *blkid,
ptrint_t *blknum) ptrint_t *blknum)
{ {
bitcoind_getrawblock(dstate, blkid, init_topo, blknum); bitcoind_getrawblock(bitcoind, blkid, init_topo, blknum);
} }
static void get_init_blockhash(struct lightningd_state *dstate, u32 blockcount, static void get_init_blockhash(struct bitcoind *bitcoind, u32 blockcount,
void *unused) void *unused)
{ {
struct lightningd_state *dstate = tal_parent(bitcoind);
u32 start; u32 start;
struct peer *peer; struct peer *peer;
@ -502,7 +510,7 @@ static void get_init_blockhash(struct lightningd_state *dstate, u32 blockcount,
} }
/* Start topology from 100 blocks back. */ /* Start topology from 100 blocks back. */
bitcoind_getblockhash(dstate, start, get_init_block, int2ptr(start)); bitcoind_getblockhash(bitcoind, start, get_init_block, int2ptr(start));
} }
u32 get_tx_mediantime(struct lightningd_state *dstate, u32 get_tx_mediantime(struct lightningd_state *dstate,
@ -607,7 +615,7 @@ void setup_topology(struct lightningd_state *dstate)
dstate->topology->startup = true; dstate->topology->startup = true;
dstate->topology->feerate = 0; dstate->topology->feerate = 0;
bitcoind_getblockcount(dstate, get_init_blockhash, NULL); bitcoind_getblockcount(dstate->bitcoind, get_init_blockhash, NULL);
/* Once it gets topology, it calls io_break() and we return. */ /* Once it gets topology, it calls io_break() and we return. */
io_loop(NULL, NULL); io_loop(NULL, NULL);

4
daemon/lightningd.c

@ -43,12 +43,10 @@ static struct lightningd_state *lightningd_state(void)
timers_init(&dstate->timers, time_mono()); timers_init(&dstate->timers, time_mono());
txwatch_hash_init(&dstate->txwatches); txwatch_hash_init(&dstate->txwatches);
txowatch_hash_init(&dstate->txowatches); txowatch_hash_init(&dstate->txowatches);
list_head_init(&dstate->bitcoin_req);
list_head_init(&dstate->wallet); list_head_init(&dstate->wallet);
list_head_init(&dstate->addresses); list_head_init(&dstate->addresses);
dstate->dev_never_routefail = false; dstate->dev_never_routefail = false;
dstate->dev_no_broadcast = false; dstate->dev_no_broadcast = false;
dstate->bitcoin_req_running = false;
dstate->rstate = new_routing_state(dstate, dstate->base_log); dstate->rstate = new_routing_state(dstate, dstate->base_log);
dstate->reexec = NULL; dstate->reexec = NULL;
dstate->external_ip = NULL; dstate->external_ip = NULL;
@ -70,6 +68,8 @@ int main(int argc, char *argv[])
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN); | SECP256K1_CONTEXT_SIGN);
dstate->bitcoind = new_bitcoind(dstate, dstate->base_log);
/* Handle options and config; move to .lightningd */ /* Handle options and config; move to .lightningd */
register_opts(dstate); register_opts(dstate);
handle_opts(dstate, argc, argv); handle_opts(dstate, argc, argv);

8
daemon/lightningd.h

@ -10,9 +10,6 @@
/* Various adjustable things. */ /* Various adjustable things. */
struct config { struct config {
/* Are we on regtest? */
bool regtest;
/* How long do we want them to lock up their funds? (blocks) */ /* How long do we want them to lock up their funds? (blocks) */
u32 locktime_blocks; u32 locktime_blocks;
@ -117,9 +114,8 @@ struct lightningd_state {
struct txwatch_hash txwatches; struct txwatch_hash txwatches;
struct txowatch_hash txowatches; struct txowatch_hash txowatches;
/* Outstanding bitcoind requests. */ /* Our tame bitcoind. */
struct list_head bitcoin_req; struct bitcoind *bitcoind;
bool bitcoin_req_running;
/* Wallet addresses we maintain. */ /* Wallet addresses we maintain. */
struct list_head wallet; struct list_head wallet;

12
daemon/options.c

@ -128,10 +128,16 @@ static void opt_show_u16(char buf[OPT_SHOW_LEN], const u16 *u)
snprintf(buf, OPT_SHOW_LEN, "%u", *u); snprintf(buf, OPT_SHOW_LEN, "%u", *u);
} }
static char *opt_set_regtest(struct bitcoind *bitcoind)
{
bitcoind->testmode = BITCOIND_REGTEST;
return NULL;
}
static void config_register_opts(struct lightningd_state *dstate) static void config_register_opts(struct lightningd_state *dstate)
{ {
opt_register_noarg("--bitcoind-regtest", opt_set_bool, opt_register_noarg("--bitcoind-regtest", opt_set_regtest,
&dstate->config.regtest, dstate->bitcoind,
"Bitcoind is in regtest mode"); "Bitcoind is in regtest mode");
opt_register_arg("--locktime-blocks", opt_set_u32, opt_show_u32, opt_register_arg("--locktime-blocks", opt_set_u32, opt_show_u32,
&dstate->config.locktime_blocks, &dstate->config.locktime_blocks,
@ -458,7 +464,7 @@ void register_opts(struct lightningd_state *dstate)
opt_register_arg("--port", opt_set_u16, opt_show_u16, &dstate->portnum, opt_register_arg("--port", opt_set_u16, opt_show_u16, &dstate->portnum,
"Port to bind to (0 means don't listen)"); "Port to bind to (0 means don't listen)");
opt_register_arg("--bitcoin-datadir", opt_set_charp, NULL, opt_register_arg("--bitcoin-datadir", opt_set_charp, NULL,
&bitcoin_datadir, &dstate->bitcoind->datadir,
"-datadir arg for bitcoin-cli"); "-datadir arg for bitcoin-cli");
opt_register_logging(dstate->base_log); opt_register_logging(dstate->base_log);
opt_register_version(); opt_register_version();

1
lightningd/Makefile

@ -9,6 +9,7 @@ lightningd-all: lightningd/lightningd lightningd/lightningd_hsm lightningd/light
default: lightningd-all default: lightningd-all
LIGHTNINGD_OLD_SRC := \ LIGHTNINGD_OLD_SRC := \
daemon/bitcoind.c \
daemon/broadcast.c \ daemon/broadcast.c \
daemon/configdir.c \ daemon/configdir.c \
daemon/dns.c \ daemon/dns.c \

4
lightningd/lightningd.c

@ -13,6 +13,7 @@
#include <ccan/take/take.h> #include <ccan/take/take.h>
#include <ccan/tal/grab_file/grab_file.h> #include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/path/path.h> #include <ccan/tal/path/path.h>
#include <daemon/bitcoind.h>
#include <daemon/chaintopology.h> #include <daemon/chaintopology.h>
#include <daemon/invoice.h> #include <daemon/invoice.h>
#include <daemon/jsonrpc.h> #include <daemon/jsonrpc.h>
@ -89,12 +90,10 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
timers_init(&ld->dstate.timers, time_mono()); timers_init(&ld->dstate.timers, time_mono());
txwatch_hash_init(&ld->dstate.txwatches); txwatch_hash_init(&ld->dstate.txwatches);
txowatch_hash_init(&ld->dstate.txowatches); txowatch_hash_init(&ld->dstate.txowatches);
list_head_init(&ld->dstate.bitcoin_req);
list_head_init(&ld->dstate.wallet); list_head_init(&ld->dstate.wallet);
list_head_init(&ld->dstate.addresses); list_head_init(&ld->dstate.addresses);
ld->dstate.dev_never_routefail = false; ld->dstate.dev_never_routefail = false;
ld->dstate.dev_no_broadcast = false; ld->dstate.dev_no_broadcast = false;
ld->dstate.bitcoin_req_running = false;
ld->dstate.reexec = NULL; ld->dstate.reexec = NULL;
ld->dstate.external_ip = NULL; ld->dstate.external_ip = NULL;
ld->dstate.announce = NULL; ld->dstate.announce = NULL;
@ -170,6 +169,7 @@ int main(int argc, char *argv[])
bool newdir; bool newdir;
err_set_progname(argv[0]); err_set_progname(argv[0]);
ld->dstate.bitcoind = new_bitcoind(ld, ld->log);
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN); | SECP256K1_CONTEXT_SIGN);

Loading…
Cancel
Save