mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
bitcoind: serialize requests.
bitcoind has a limit of 16 requests at once, by default, so our simplest solution is to serialize them. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
980d0d2bf1
commit
5b9f8d8bbd
@ -36,6 +36,7 @@ static char **gather_args(const tal_t *ctx, const char *cmd, va_list ap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct bitcoin_cli {
|
struct bitcoin_cli {
|
||||||
|
struct list_node list;
|
||||||
struct lightningd_state *dstate;
|
struct lightningd_state *dstate;
|
||||||
int fd;
|
int fd;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
@ -65,9 +66,12 @@ 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 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;
|
||||||
|
|
||||||
/* 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);
|
||||||
@ -86,9 +90,35 @@ static void bcli_finished(struct io_conn *conn, struct bitcoin_cli *bcli)
|
|||||||
bcli->args[0], bcli->args[1], WEXITSTATUS(status),
|
bcli->args[0], bcli->args[1], WEXITSTATUS(status),
|
||||||
(int)bcli->output_bytes, bcli->output);
|
(int)bcli->output_bytes, bcli->output);
|
||||||
|
|
||||||
assert(bcli->dstate->bitcoind_in_progress);
|
log_debug(dstate->base_log, "reaped %u: %s", ret, bcli->args[1]);
|
||||||
bcli->dstate->bitcoind_in_progress--;
|
dstate->bitcoin_req_running = false;
|
||||||
bcli->process(bcli);
|
bcli->process(bcli);
|
||||||
|
|
||||||
|
next_bcli(dstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void next_bcli(struct lightningd_state *dstate)
|
||||||
|
{
|
||||||
|
struct bitcoin_cli *bcli;
|
||||||
|
struct io_conn *conn;
|
||||||
|
|
||||||
|
if (dstate->bitcoin_req_running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bcli = list_pop(&dstate->bitcoin_req, struct bitcoin_cli, list);
|
||||||
|
if (!bcli)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug(bcli->dstate->base_log, "starting: %s", bcli->args[1]);
|
||||||
|
|
||||||
|
bcli->pid = pipecmdarr(&bcli->fd, NULL, &bcli->fd, bcli->args);
|
||||||
|
if (bcli->pid < 0)
|
||||||
|
fatal("%s exec failed: %s", bcli->args[0], strerror(errno));
|
||||||
|
|
||||||
|
dstate->bitcoin_req_running = true;
|
||||||
|
conn = io_new_conn(dstate, bcli->fd, output_init, bcli);
|
||||||
|
tal_steal(conn, bcli);
|
||||||
|
io_set_finish(conn, bcli_finished, bcli);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -99,7 +129,6 @@ start_bitcoin_cli(struct lightningd_state *dstate,
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
struct bitcoin_cli *bcli = tal(dstate, struct bitcoin_cli);
|
struct bitcoin_cli *bcli = tal(dstate, struct bitcoin_cli);
|
||||||
struct io_conn *conn;
|
|
||||||
|
|
||||||
bcli->dstate = dstate;
|
bcli->dstate = dstate;
|
||||||
bcli->process = process;
|
bcli->process = process;
|
||||||
@ -109,14 +138,8 @@ start_bitcoin_cli(struct lightningd_state *dstate,
|
|||||||
bcli->args = gather_args(bcli, cmd, ap);
|
bcli->args = gather_args(bcli, cmd, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
bcli->pid = pipecmdarr(&bcli->fd, NULL, &bcli->fd, bcli->args);
|
list_add_tail(&dstate->bitcoin_req, &bcli->list);
|
||||||
if (bcli->pid < 0)
|
next_bcli(dstate);
|
||||||
fatal("%s exec failed: %s", bcli->args[0], strerror(errno));
|
|
||||||
|
|
||||||
conn = io_new_conn(dstate, bcli->fd, output_init, bcli);
|
|
||||||
tal_steal(conn, bcli);
|
|
||||||
dstate->bitcoind_in_progress++;
|
|
||||||
io_set_finish(conn, bcli_finished, bcli);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_importaddress(struct bitcoin_cli *bcli)
|
static void process_importaddress(struct bitcoin_cli *bcli)
|
||||||
|
@ -127,7 +127,8 @@ static struct lightningd_state *lightningd_state(void)
|
|||||||
dstate->secpctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
dstate->secpctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
||||||
| SECP256K1_CONTEXT_SIGN);
|
| SECP256K1_CONTEXT_SIGN);
|
||||||
default_config(&dstate->config);
|
default_config(&dstate->config);
|
||||||
dstate->bitcoind_in_progress = 0;
|
list_head_init(&dstate->bitcoin_req);
|
||||||
|
dstate->bitcoin_req_running = false;
|
||||||
return dstate;
|
return dstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,11 +62,12 @@ struct lightningd_state {
|
|||||||
/* This is us. */
|
/* This is us. */
|
||||||
struct pubkey id;
|
struct pubkey id;
|
||||||
|
|
||||||
/* Number of bitcoind commands outstanding. */
|
|
||||||
unsigned int bitcoind_in_progress;
|
|
||||||
|
|
||||||
/* Transactions/txos we are watching. */
|
/* Transactions/txos we are watching. */
|
||||||
struct txwatch_hash txwatches;
|
struct txwatch_hash txwatches;
|
||||||
struct txowatch_hash txowatches;
|
struct txowatch_hash txowatches;
|
||||||
|
|
||||||
|
/* Outstanding bitcoind requests. */
|
||||||
|
struct list_head bitcoin_req;
|
||||||
|
bool bitcoin_req_running;
|
||||||
};
|
};
|
||||||
#endif /* LIGHTNING_DAEMON_LIGHTNING_H */
|
#endif /* LIGHTNING_DAEMON_LIGHTNING_H */
|
||||||
|
@ -213,10 +213,9 @@ static struct timeout watch_timeout;
|
|||||||
|
|
||||||
static void start_poll_transactions(struct lightningd_state *dstate)
|
static void start_poll_transactions(struct lightningd_state *dstate)
|
||||||
{
|
{
|
||||||
if (dstate->bitcoind_in_progress != 0) {
|
if (!list_empty(&dstate->bitcoin_req)) {
|
||||||
log_unusual(dstate->base_log,
|
log_unusual(dstate->base_log,
|
||||||
"Delaying start poll: %u commands in progress",
|
"Delaying start poll: commands in progress");
|
||||||
dstate->bitcoind_in_progress);
|
|
||||||
} else
|
} else
|
||||||
bitcoind_poll_transactions(dstate, watched_transaction);
|
bitcoind_poll_transactions(dstate, watched_transaction);
|
||||||
refresh_timeout(dstate, &watch_timeout);
|
refresh_timeout(dstate, &watch_timeout);
|
||||||
|
Loading…
Reference in New Issue
Block a user