Browse Source

state: INPUT_CONNECTION_LOST

We used to have a hacky close timeout which would immediately fire
when we'd closed because the connection was down.  Far better to have
a specific "connection lost" input, and have it respond like CMD_CLOSE.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
994addadce
  1. 12
      daemon/peer.c
  2. 4
      daemon/test/test.sh
  3. 51
      state.c
  4. 3
      state_types.h

12
daemon/peer.c

@ -313,20 +313,18 @@ static void peer_disconnect(struct io_conn *conn, struct peer *peer)
} }
/* FIXME: Try to reconnect. */ /* FIXME: Try to reconnect. */
if (peer->cond == PEER_CLOSING if (peer->cond == PEER_CLOSED)
|| peer->cond == PEER_CLOSED)
return; return;
state(peer, peer, CMD_CLOSE, NULL, &outpkt, &broadcast); state(peer, peer, INPUT_CONNECTION_LOST, NULL, &outpkt, &broadcast);
/* Can't send packet, so ignore it. */ assert(!outpkt);
tal_free(outpkt);
if (broadcast) { if (broadcast) {
struct sha256_double txid; struct sha256_double txid;
bitcoin_txid(broadcast, &txid); bitcoin_txid(broadcast, &txid);
/* FIXME: log_struct */ /* FIXME: log_struct */
log_debug(peer->log, "CMD_CLOSE: tx %02x%02x%02x%02x...", log_debug(peer->log, "INPUT_CONN_LOST: tx %02x%02x%02x%02x...",
txid.sha.u.u8[0], txid.sha.u.u8[1], txid.sha.u.u8[0], txid.sha.u.u8[1],
txid.sha.u.u8[2], txid.sha.u.u8[3]); txid.sha.u.u8[2], txid.sha.u.u8[3]);
bitcoind_send_tx(peer->dstate, broadcast); bitcoind_send_tx(peer->dstate, broadcast);
@ -940,7 +938,9 @@ bool peer_watch_our_htlc_outputs(struct peer *peer,
enum state_input tothem_spent, enum state_input tothem_spent,
enum state_input tothem_timeout) enum state_input tothem_timeout)
{ {
if (committed_to_htlcs(peer))
FIXME_STUB(peer); FIXME_STUB(peer);
return false;
} }
bool peer_watch_their_htlc_outputs(struct peer *peer, bool peer_watch_their_htlc_outputs(struct peer *peer,
const struct bitcoin_event *tx, const struct bitcoin_event *tx,

4
daemon/test/test.sh

@ -192,7 +192,7 @@ if [ -n "$TIMEOUT_ANCHOR" ]; then
sleep 2 sleep 2
# It should send out commit tx. # It should send out commit tx.
lcli1 getpeers | $FGREP -w STATE_CLOSE_WAIT_CLOSE_OURCOMMIT lcli1 getpeers | $FGREP -w STATE_CLOSE_WAIT_OURCOMMIT
# Generate a block (should include commit tx) # Generate a block (should include commit tx)
check_tx_spend check_tx_spend
@ -212,7 +212,7 @@ if [ -n "$TIMEOUT_ANCHOR" ]; then
lcli1 dev-mocktime $TIME lcli1 dev-mocktime $TIME
sleep 2 sleep 2
lcli1 getpeers | $FGREP -w STATE_CLOSE_WAIT_CLOSE_SPENDOURS lcli1 getpeers | $FGREP -w STATE_CLOSE_WAIT_SPENDOURS
# Now it should have spent the commit tx. # Now it should have spent the commit tx.
check_tx_spend check_tx_spend

51
state.c

@ -137,7 +137,8 @@ enum command_status state(const tal_t *ctx,
goto err_close_nocleanup; goto err_close_nocleanup;
} }
return next_state(peer, cstatus, STATE_OPEN_WAIT_FOR_ANCHOR); return next_state(peer, cstatus, STATE_OPEN_WAIT_FOR_ANCHOR);
} else if (input_is(input, CMD_CLOSE)) { } else if (input_is(input, CMD_CLOSE)
|| input_is(input, INPUT_CONNECTION_LOST)) {
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto instant_close; goto instant_close;
} else if (input_is_pkt(input)) { } else if (input_is_pkt(input)) {
@ -155,7 +156,8 @@ enum command_status state(const tal_t *ctx,
bitcoin_create_anchor(peer, BITCOIN_ANCHOR_CREATED); bitcoin_create_anchor(peer, BITCOIN_ANCHOR_CREATED);
return next_state(peer, cstatus, return next_state(peer, cstatus,
STATE_OPEN_WAIT_FOR_ANCHOR_CREATE); STATE_OPEN_WAIT_FOR_ANCHOR_CREATE);
} else if (input_is(input, CMD_CLOSE)) { } else if (input_is(input, CMD_CLOSE)
|| input_is(input, INPUT_CONNECTION_LOST)) {
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto instant_close; goto instant_close;
} else if (input_is_pkt(input)) { } else if (input_is_pkt(input)) {
@ -168,7 +170,8 @@ enum command_status state(const tal_t *ctx,
queue_pkt(out, pkt_anchor(ctx, peer)); queue_pkt(out, pkt_anchor(ctx, peer));
return next_state(peer, cstatus, return next_state(peer, cstatus,
STATE_OPEN_WAIT_FOR_COMMIT_SIG); STATE_OPEN_WAIT_FOR_COMMIT_SIG);
} else if (input_is(input, CMD_CLOSE)) { } else if (input_is(input, CMD_CLOSE)
|| input_is(input, INPUT_CONNECTION_LOST)) {
bitcoin_release_anchor(peer, BITCOIN_ANCHOR_CREATED); bitcoin_release_anchor(peer, BITCOIN_ANCHOR_CREATED);
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto instant_close; goto instant_close;
@ -196,7 +199,8 @@ enum command_status state(const tal_t *ctx,
return next_state(peer, cstatus, return next_state(peer, cstatus,
STATE_OPEN_WAITING_THEIRANCHOR); STATE_OPEN_WAITING_THEIRANCHOR);
} else if (input_is(input, CMD_CLOSE)) { } else if (input_is(input, CMD_CLOSE)
|| input_is(input, INPUT_CONNECTION_LOST)) {
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto instant_close; goto instant_close;
} else if (input_is_pkt(input)) { } else if (input_is_pkt(input)) {
@ -221,7 +225,8 @@ enum command_status state(const tal_t *ctx,
BITCOIN_ANCHOR_OTHERSPEND); BITCOIN_ANCHOR_OTHERSPEND);
return next_state(peer, cstatus, return next_state(peer, cstatus,
STATE_OPEN_WAITING_OURANCHOR); STATE_OPEN_WAITING_OURANCHOR);
} else if (input_is(input, CMD_CLOSE)) { } else if (input_is(input, CMD_CLOSE)
|| input_is(input, INPUT_CONNECTION_LOST)) {
bitcoin_release_anchor(peer, INPUT_NONE); bitcoin_release_anchor(peer, INPUT_NONE);
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto instant_close; goto instant_close;
@ -277,6 +282,13 @@ enum command_status state(const tal_t *ctx,
INPUT_NONE); INPUT_NONE);
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_clearing; goto start_clearing;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
/* We no longer care about anchor depth. */
peer_unwatch_anchor_depth(peer,
BITCOIN_ANCHOR_DEPTHOK,
INPUT_NONE);
complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_unilateral_close;
} else if (input_is(input, PKT_CLOSE_CLEARING)) { } else if (input_is(input, PKT_CLOSE_CLEARING)) {
/* We no longer care about anchor depth. */ /* We no longer care about anchor depth. */
peer_unwatch_anchor_depth(peer, peer_unwatch_anchor_depth(peer,
@ -345,6 +357,13 @@ enum command_status state(const tal_t *ctx,
BITCOIN_ANCHOR_TIMEOUT); BITCOIN_ANCHOR_TIMEOUT);
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_clearing; goto start_clearing;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
/* We no longer care about anchor depth. */
peer_unwatch_anchor_depth(peer,
BITCOIN_ANCHOR_DEPTHOK,
BITCOIN_ANCHOR_TIMEOUT);
complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_unilateral_close;
} else if (input_is(input, PKT_CLOSE_CLEARING)) { } else if (input_is(input, PKT_CLOSE_CLEARING)) {
/* We no longer care about anchor depth. */ /* We no longer care about anchor depth. */
peer_unwatch_anchor_depth(peer, peer_unwatch_anchor_depth(peer,
@ -388,6 +407,9 @@ enum command_status state(const tal_t *ctx,
} else if (input_is(input, CMD_CLOSE)) { } else if (input_is(input, CMD_CLOSE)) {
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_clearing; goto start_clearing;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_unilateral_close;
} else if (input_is(input, PKT_CLOSE_CLEARING)) { } else if (input_is(input, PKT_CLOSE_CLEARING)) {
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto accept_clearing; goto accept_clearing;
@ -428,6 +450,8 @@ enum command_status state(const tal_t *ctx,
prio(peer->state, STATE_WAIT_FOR_UPDATE_ACCEPT)); prio(peer->state, STATE_WAIT_FOR_UPDATE_ACCEPT));
} else if (input_is(input, CMD_CLOSE)) { } else if (input_is(input, CMD_CLOSE)) {
goto start_clearing; goto start_clearing;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
goto start_unilateral_close;
} else if (input_is(input, PKT_UPDATE_ADD_HTLC)) { } else if (input_is(input, PKT_UPDATE_ADD_HTLC)) {
change_peer_cond(peer, PEER_CMD_OK, PEER_BUSY); change_peer_cond(peer, PEER_CMD_OK, PEER_BUSY);
goto accept_htlc_add; goto accept_htlc_add;
@ -523,6 +547,10 @@ enum command_status state(const tal_t *ctx,
peer_htlc_aborted(peer); peer_htlc_aborted(peer);
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_clearing; goto start_clearing;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
peer_htlc_aborted(peer);
complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_unilateral_close;
} else if (input_is(input, PKT_CLOSE_CLEARING)) { } else if (input_is(input, PKT_CLOSE_CLEARING)) {
peer_htlc_aborted(peer); peer_htlc_aborted(peer);
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
@ -566,6 +594,10 @@ enum command_status state(const tal_t *ctx,
peer_htlc_aborted(peer); peer_htlc_aborted(peer);
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_clearing; goto start_clearing;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
peer_htlc_aborted(peer);
complete_cmd(peer, &cstatus, CMD_FAIL);
goto start_unilateral_close;
} else if (input_is_pkt(input)) { } else if (input_is_pkt(input)) {
peer_htlc_aborted(peer); peer_htlc_aborted(peer);
complete_cmd(peer, &cstatus, CMD_FAIL); complete_cmd(peer, &cstatus, CMD_FAIL);
@ -600,6 +632,9 @@ enum command_status state(const tal_t *ctx,
} else if (input_is(input, CMD_CLOSE)) { } else if (input_is(input, CMD_CLOSE)) {
peer_htlc_aborted(peer); peer_htlc_aborted(peer);
goto start_clearing; goto start_clearing;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
peer_htlc_aborted(peer);
goto start_unilateral_close;
} else if (input_is(input, PKT_CLOSE_CLEARING)) { } else if (input_is(input, PKT_CLOSE_CLEARING)) {
peer_htlc_aborted(peer); peer_htlc_aborted(peer);
goto accept_clearing; goto accept_clearing;
@ -625,6 +660,8 @@ enum command_status state(const tal_t *ctx,
|| input_is(input, CMD_SEND_HTLC_FULFILL)) { || input_is(input, CMD_SEND_HTLC_FULFILL)) {
err = pkt_err(ctx, "FIXME: cmd during clearing."); err = pkt_err(ctx, "FIXME: cmd during clearing.");
goto err_start_unilateral_close; goto err_start_unilateral_close;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
goto start_unilateral_close;
} else if (input_is_pkt(input)) { } else if (input_is_pkt(input)) {
/* FIXME: We must continue to allow add, fulfill & fail packets */ /* FIXME: We must continue to allow add, fulfill & fail packets */
goto unexpected_pkt; goto unexpected_pkt;
@ -637,6 +674,8 @@ enum command_status state(const tal_t *ctx,
|| input_is(input, CMD_SEND_HTLC_FULFILL)) { || input_is(input, CMD_SEND_HTLC_FULFILL)) {
err = pkt_err(ctx, "FIXME: cmd during clearing."); err = pkt_err(ctx, "FIXME: cmd during clearing.");
goto err_start_unilateral_close; goto err_start_unilateral_close;
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
goto start_unilateral_close;
} else if (input_is_pkt(input)) { } else if (input_is_pkt(input)) {
/* FIXME: We must continue to allow fulfill & fail packets */ /* FIXME: We must continue to allow fulfill & fail packets */
goto unexpected_pkt; goto unexpected_pkt;
@ -667,6 +706,8 @@ enum command_status state(const tal_t *ctx,
/* Offer the new fee. */ /* Offer the new fee. */
queue_pkt(out, pkt_close_signature(ctx, peer)); queue_pkt(out, pkt_close_signature(ctx, peer));
return unchanged_state(cstatus); return unchanged_state(cstatus);
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
goto start_unilateral_close;
} else if (input_is(input, INPUT_CLOSE_COMPLETE_TIMEOUT)) { } else if (input_is(input, INPUT_CLOSE_COMPLETE_TIMEOUT)) {
err = pkt_err(ctx, "Close timed out"); err = pkt_err(ctx, "Close timed out");
goto err_start_unilateral_close; goto err_start_unilateral_close;

3
state_types.h

@ -281,6 +281,9 @@ enum state_input {
CMD_SEND_HTLC_FAIL, CMD_SEND_HTLC_FAIL,
CMD_CLOSE, CMD_CLOSE,
/* Connection lost/timedout with other node. */
INPUT_CONNECTION_LOST,
INPUT_MAX INPUT_MAX
}; };

Loading…
Cancel
Save