mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
state: add async anchor creation.
Actually generating the anchor transaction in my implementation requires interaction with bitcoind, which we want to be async. So add a callback and a new state to wait for it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
0db3c03ed1
commit
ebf2bc57d8
22
state.c
22
state.c
@ -149,9 +149,9 @@ enum command_status state(const tal_t *ctx,
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto err_close_nocleanup;
|
||||
}
|
||||
queue_pkt(out, pkt_anchor(ctx, peer));
|
||||
bitcoin_create_anchor(peer, BITCOIN_ANCHOR_CREATED);
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAIT_FOR_COMMIT_SIG);
|
||||
STATE_OPEN_WAIT_FOR_ANCHOR_CREATE);
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto instant_close;
|
||||
@ -160,6 +160,21 @@ enum command_status state(const tal_t *ctx,
|
||||
goto unexpected_pkt_nocleanup;
|
||||
}
|
||||
break;
|
||||
case STATE_OPEN_WAIT_FOR_ANCHOR_CREATE:
|
||||
if (input_is(input, BITCOIN_ANCHOR_CREATED)) {
|
||||
queue_pkt(out, pkt_anchor(ctx, peer));
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAIT_FOR_COMMIT_SIG);
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
bitcoin_release_anchor(peer, BITCOIN_ANCHOR_CREATED);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto instant_close;
|
||||
} else if (input_is_pkt(input)) {
|
||||
bitcoin_release_anchor(peer, BITCOIN_ANCHOR_CREATED);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto unexpected_pkt_nocleanup;
|
||||
}
|
||||
break;
|
||||
case STATE_OPEN_WAIT_FOR_ANCHOR:
|
||||
if (input_is(input, PKT_OPEN_ANCHOR)) {
|
||||
err = accept_pkt_anchor(ctx, peer, idata->pkt);
|
||||
@ -190,6 +205,7 @@ enum command_status state(const tal_t *ctx,
|
||||
if (input_is(input, PKT_OPEN_COMMIT_SIG)) {
|
||||
err = accept_pkt_open_commit_sig(ctx, peer, idata->pkt);
|
||||
if (err) {
|
||||
bitcoin_release_anchor(peer, INPUT_NONE);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto err_start_unilateral_close;
|
||||
}
|
||||
@ -203,9 +219,11 @@ enum command_status state(const tal_t *ctx,
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAITING_OURANCHOR);
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
bitcoin_release_anchor(peer, INPUT_NONE);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto instant_close;
|
||||
} else if (input_is_pkt(input)) {
|
||||
bitcoin_release_anchor(peer, INPUT_NONE);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto unexpected_pkt_nocleanup;
|
||||
}
|
||||
|
12
state.h
12
state.h
@ -318,9 +318,15 @@ void peer_unwatch_htlc_spend(struct peer *peer,
|
||||
const struct htlc *htlc,
|
||||
enum state_input all_done);
|
||||
|
||||
/* Create a bitcoin anchor tx. */
|
||||
struct bitcoin_tx *bitcoin_anchor(const tal_t *ctx,
|
||||
const struct peer *peer);
|
||||
/* Start creation of the bitcoin anchor tx. */
|
||||
void bitcoin_create_anchor(struct peer *peer, enum state_input done);
|
||||
|
||||
/* We didn't end up broadcasting the anchor: release the utxos.
|
||||
* If done != INPUT_NONE, remove existing create_anchor too. */
|
||||
void bitcoin_release_anchor(struct peer *peer, enum state_input done);
|
||||
|
||||
/* Get the bitcoin anchor tx. */
|
||||
struct bitcoin_tx *bitcoin_anchor(const tal_t *ctx, struct peer *peer);
|
||||
|
||||
/* Create a bitcoin close tx. */
|
||||
struct bitcoin_tx *bitcoin_close(const tal_t *ctx,
|
||||
|
@ -19,6 +19,7 @@ enum state {
|
||||
*/
|
||||
STATE_OPEN_WAIT_FOR_OPEN_NOANCHOR,
|
||||
STATE_OPEN_WAIT_FOR_OPEN_WITHANCHOR,
|
||||
STATE_OPEN_WAIT_FOR_ANCHOR_CREATE,
|
||||
STATE_OPEN_WAIT_FOR_ANCHOR,
|
||||
STATE_OPEN_WAIT_FOR_COMMIT_SIG,
|
||||
STATE_OPEN_WAITING_OURANCHOR,
|
||||
@ -220,6 +221,8 @@ enum state_input {
|
||||
/*
|
||||
* Bitcoin events
|
||||
*/
|
||||
/* Bitcoin anchor tx created. */
|
||||
BITCOIN_ANCHOR_CREATED,
|
||||
/* It reached the required depth. */
|
||||
BITCOIN_ANCHOR_DEPTHOK,
|
||||
/* It didn't reach the required depth in time. */
|
||||
|
@ -122,7 +122,10 @@ struct peer {
|
||||
|
||||
/* Transitory: True if we just declined an HTLC. */
|
||||
bool htlc_declined;
|
||||
|
||||
|
||||
/* Have we created an anchor tx? */
|
||||
bool anchor;
|
||||
|
||||
unsigned int num_htlcs_to_them, num_htlcs_to_us;
|
||||
struct htlc htlcs_to_them[MAX_HTLCS], htlcs_to_us[MAX_HTLCS];
|
||||
|
||||
@ -855,9 +858,11 @@ static bool bitcoin_tx_is(const struct bitcoin_tx *btx, const char *str)
|
||||
return streq((const char *)btx, str);
|
||||
}
|
||||
|
||||
struct bitcoin_tx *bitcoin_anchor(const tal_t *ctx,
|
||||
const struct peer *peer)
|
||||
struct bitcoin_tx *bitcoin_anchor(const tal_t *ctx, struct peer *peer)
|
||||
{
|
||||
if (!peer->anchor)
|
||||
report_trail(peer->trail, "Can't create anchor tx: no anchor!");
|
||||
peer->anchor = false;
|
||||
return bitcoin_tx("anchor");
|
||||
}
|
||||
|
||||
@ -937,6 +942,7 @@ static void peer_init(struct peer *peer,
|
||||
peer->num_rvals_known = 0;
|
||||
peer->error = NULL;
|
||||
peer->htlc_declined = false;
|
||||
peer->anchor = false;
|
||||
memset(peer->core.outputs, 0, sizeof(peer->core.outputs));
|
||||
peer->pkt_data[0] = -1;
|
||||
peer->core.current_command = INPUT_NONE;
|
||||
@ -1188,6 +1194,26 @@ void peer_watch_anchor(struct peer *peer,
|
||||
add_event(peer, otherspent);
|
||||
}
|
||||
|
||||
void bitcoin_create_anchor(struct peer *peer, enum state_input done)
|
||||
{
|
||||
/* We assume this below */
|
||||
assert(done == BITCOIN_ANCHOR_CREATED);
|
||||
if (peer->anchor)
|
||||
report_trail(peer->trail, "Anchor already created?");
|
||||
|
||||
peer->anchor = true;
|
||||
add_event(peer, done);
|
||||
}
|
||||
|
||||
void bitcoin_release_anchor(struct peer *peer, enum state_input done)
|
||||
{
|
||||
if (!peer->anchor)
|
||||
report_trail(peer->trail, "Anchor not created?");
|
||||
|
||||
peer->anchor = false;
|
||||
remove_event(peer, done);
|
||||
}
|
||||
|
||||
void peer_unwatch_anchor_depth(struct peer *peer,
|
||||
enum state_input depthok,
|
||||
enum state_input timeout)
|
||||
@ -1492,6 +1518,9 @@ static const char *check_changes(const struct peer *old, struct peer *new,
|
||||
if (new->current_htlc.htlc.id != -1)
|
||||
return tal_fmt(NULL,
|
||||
"cond CLOSE with pending htlc");
|
||||
if (new->anchor)
|
||||
return tal_fmt(NULL,
|
||||
"cond CLOSE with anchor");
|
||||
}
|
||||
if (new->cond == PEER_CLOSED) {
|
||||
/* FIXME: Move to state core */
|
||||
@ -1736,13 +1765,15 @@ static bool waiting_statepair(enum state a, enum state b)
|
||||
if (a == STATE_OPEN_WAITING_OURANCHOR
|
||||
|| a == STATE_OPEN_WAITING_OURANCHOR_THEYCOMPLETED
|
||||
|| a == STATE_OPEN_WAITING_THEIRANCHOR
|
||||
|| a == STATE_OPEN_WAITING_THEIRANCHOR_THEYCOMPLETED)
|
||||
|| a == STATE_OPEN_WAITING_THEIRANCHOR_THEYCOMPLETED
|
||||
|| a == STATE_OPEN_WAIT_FOR_ANCHOR_CREATE)
|
||||
return true;
|
||||
|
||||
if (b == STATE_OPEN_WAITING_OURANCHOR
|
||||
|| b == STATE_OPEN_WAITING_OURANCHOR_THEYCOMPLETED
|
||||
|| b == STATE_OPEN_WAITING_THEIRANCHOR
|
||||
|| b == STATE_OPEN_WAITING_THEIRANCHOR_THEYCOMPLETED)
|
||||
|| b == STATE_OPEN_WAITING_THEIRANCHOR_THEYCOMPLETED
|
||||
|| b == STATE_OPEN_WAIT_FOR_ANCHOR_CREATE)
|
||||
return true;
|
||||
|
||||
/* We don't need inputs at start of main loop. */
|
||||
@ -2364,6 +2395,7 @@ int main(int argc, char *argv[])
|
||||
|| i == STATE_ERR_ANCHOR_TIMEOUT)
|
||||
a_expect = false;
|
||||
if (i == STATE_OPEN_WAIT_FOR_OPEN_WITHANCHOR
|
||||
|| i == STATE_OPEN_WAIT_FOR_ANCHOR_CREATE
|
||||
|| i == STATE_OPEN_WAIT_FOR_COMMIT_SIG
|
||||
|| i == STATE_OPEN_WAIT_FOR_COMPLETE_OURANCHOR
|
||||
|| i == STATE_OPEN_WAITING_OURANCHOR
|
||||
|
Loading…
Reference in New Issue
Block a user