diff --git a/state.c b/state.c index d4ce029d1..010e9e07c 100644 --- a/state.c +++ b/state.c @@ -1,4 +1,5 @@ #include +#include char cmd_requeue; @@ -24,6 +25,15 @@ static inline bool high_priority(enum state state) #define INIT_EFFECT_stop_commands false #define INIT_EFFECT_close_timeout INPUT_NONE #define INIT_EFFECT_in_error NULL +#define INIT_EFFECT_r_value NULL +#define INIT_EFFECT_watch_htlcs NULL +#define INIT_EFFECT_unwatch_htlc NULL +#define INIT_EFFECT_htlc_in_progress NULL +#define INIT_EFFECT_htlc_abandon false +#define INIT_EFFECT_htlc_fulfill false +#define INIT_EFFECT_update_theirsig NULL +#define INIT_EFFECT_watch_htlc_spend NULL +#define INIT_EFFECT_unwatch_htlc_spend NULL void state_effect_init(struct state_effect *effect) { @@ -38,6 +48,15 @@ void state_effect_init(struct state_effect *effect) effect->stop_commands = INIT_EFFECT_stop_commands; effect->close_timeout = INIT_EFFECT_close_timeout; effect->in_error = INIT_EFFECT_in_error; + effect->r_value = INIT_EFFECT_r_value; + effect->watch_htlcs = INIT_EFFECT_watch_htlcs; + effect->unwatch_htlc = INIT_EFFECT_unwatch_htlc; + effect->htlc_in_progress = INIT_EFFECT_htlc_in_progress; + effect->htlc_abandon = INIT_EFFECT_htlc_abandon; + effect->htlc_fulfill = INIT_EFFECT_htlc_fulfill; + effect->update_theirsig = INIT_EFFECT_update_theirsig; + effect->watch_htlc_spend = INIT_EFFECT_watch_htlc_spend; + effect->unwatch_htlc_spend = INIT_EFFECT_unwatch_htlc_spend; } #define set_effect(effect, field, val) \ @@ -71,6 +90,8 @@ enum state state(const enum state state, const struct state_data *sdata, Pkt *decline; struct bitcoin_tx *steal; Pkt *err; + struct htlc_watch *htlcs; + struct htlc_progress *htlcprog; switch (state) { /* @@ -90,8 +111,8 @@ enum state state(const enum state state, const struct state_data *sdata, if (err) goto err_close_nocleanup; return STATE_OPEN_WAIT_FOR_ANCHOR; - } else if (input_is(input, CMD_SEND_UPDATE_ANY)) { - /* Can't do these until we're open. */ + } else if (input_is(input, CMD_SEND_HTLC_UPDATE)) { + /* Can't do this until we're open. */ set_effect(effect, defer, input); return state; } else if (input_is(input, CMD_CLOSE)) { @@ -107,8 +128,8 @@ enum state state(const enum state state, const struct state_data *sdata, goto err_close_nocleanup; set_effect(effect, send, pkt_anchor(effect, sdata)); return STATE_OPEN_WAIT_FOR_COMMIT_SIG; - } else if (input_is(input, CMD_SEND_UPDATE_ANY)) { - /* Can't do these until we're open. */ + } else if (input_is(input, CMD_SEND_HTLC_UPDATE)) { + /* Can't do this until we're open. */ set_effect(effect, defer, input); return state; } else if (input_is(input, CMD_CLOSE)) { @@ -133,8 +154,8 @@ enum state state(const enum state state, const struct state_data *sdata, BITCOIN_ANCHOR_OTHERSPEND)); return STATE_OPEN_WAITING_THEIRANCHOR; - } else if (input_is(input, CMD_SEND_UPDATE_ANY)) { - /* Can't do these until we're open. */ + } else if (input_is(input, CMD_SEND_HTLC_UPDATE)) { + /* Can't do this until we're open. */ set_effect(effect, defer, input); return state; } else if (input_is(input, CMD_CLOSE)) { @@ -159,8 +180,8 @@ enum state state(const enum state state, const struct state_data *sdata, BITCOIN_ANCHOR_THEIRSPEND, BITCOIN_ANCHOR_OTHERSPEND)); return STATE_OPEN_WAITING_OURANCHOR; - } else if (input_is(input, CMD_SEND_UPDATE_ANY)) { - /* Can't do these until we're open. */ + } else if (input_is(input, CMD_SEND_HTLC_UPDATE)) { + /* Can't do this until we're open. */ set_effect(effect, defer, input); return state; } else if (input_is(input, CMD_CLOSE)) { @@ -180,8 +201,8 @@ enum state state(const enum state state, const struct state_data *sdata, /* Ignore until we've hit depth ourselves. */ set_effect(effect, defer, input); return state; - } else if (input_is(input, CMD_SEND_UPDATE_ANY)) { - /* Can't do these until we're open. */ + } else if (input_is(input, CMD_SEND_HTLC_UPDATE)) { + /* Can't do this until we're open. */ set_effect(effect, defer, input); return state; } else if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) { @@ -243,8 +264,8 @@ enum state state(const enum state state, const struct state_data *sdata, /* Ignore until we've hit depth ourselves. */ set_effect(effect, defer, input); return state; - } else if (input_is(input, CMD_SEND_UPDATE_ANY)) { - /* Can't do these until we're open. */ + } else if (input_is(input, CMD_SEND_HTLC_UPDATE)) { + /* Can't do this until we're open. */ set_effect(effect, defer, input); return state; } else if (input_is(input, CMD_CLOSE)) { @@ -289,8 +310,8 @@ enum state state(const enum state state, const struct state_data *sdata, } else if (input_is(input, PKT_OPEN_COMPLETE)) { /* Ready for business! */ return STATE_NORMAL_HIGHPRIO; - } else if (input_is(input, CMD_SEND_UPDATE_ANY)) { - /* Can't do these until we're open. */ + } else if (input_is(input, CMD_SEND_HTLC_UPDATE)) { + /* Can't do this until we're open. */ set_effect(effect, defer, input); return state; } else if (input_is(input, CMD_CLOSE)) { @@ -310,24 +331,34 @@ enum state state(const enum state state, const struct state_data *sdata, if (input_is(input, CMD_SEND_HTLC_UPDATE)) { /* We are to send an HTLC update. */ set_effect(effect, send, - pkt_htlc_update(effect, sdata, idata->cmd)); + pkt_htlc_update(effect, sdata, + idata->htlc_prog)); + set_effect(effect, htlc_in_progress, idata->htlc_prog); return prio(state, STATE_WAIT_FOR_HTLC_ACCEPT); } else if (input_is(input, CMD_SEND_HTLC_FULFILL)) { /* We are to send an HTLC fulfill. */ + /* This gives us the r value (FIXME: type!) */ + set_effect(effect, r_value, + r_value_from_cmd(effect, sdata, idata->htlc)); set_effect(effect, send, - pkt_htlc_fulfill(effect, sdata, idata->cmd)); - return prio(state, STATE_WAIT_FOR_HTLC_ACCEPT); + pkt_htlc_fulfill(effect, sdata, + idata->htlc_prog)); + set_effect(effect, htlc_in_progress, idata->htlc_prog); + return prio(state, STATE_WAIT_FOR_UPDATE_ACCEPT); } else if (input_is(input, CMD_SEND_HTLC_TIMEDOUT)) { /* We are to send an HTLC timedout. */ set_effect(effect, send, - pkt_htlc_timedout(effect, sdata, idata->cmd)); - return prio(state, STATE_WAIT_FOR_HTLC_ACCEPT); + pkt_htlc_timedout(effect, sdata, + idata->htlc_prog)); + set_effect(effect, htlc_in_progress, idata->htlc_prog); + return prio(state, STATE_WAIT_FOR_UPDATE_ACCEPT); } else if (input_is(input, CMD_SEND_HTLC_ROUTEFAIL)) { /* We are to send an HTLC routefail. */ set_effect(effect, send, pkt_htlc_routefail(effect, sdata, - idata->cmd)); - return prio(state, STATE_WAIT_FOR_HTLC_ACCEPT); + idata->htlc_prog)); + set_effect(effect, htlc_in_progress, idata->htlc_prog); + return prio(state, STATE_WAIT_FOR_UPDATE_ACCEPT); } else if (input_is(input, CMD_CLOSE)) { goto start_closing; } else if (input_is(input, PKT_UPDATE_ADD_HTLC)) { @@ -355,15 +386,26 @@ enum state state(const enum state state, const struct state_data *sdata, /* HTLCs can also evoke a refusal. */ if (input_is(input, PKT_UPDATE_DECLINE_HTLC)) { fail_cmd(effect, CMD_SEND_HTLC_UPDATE, idata->pkt); + set_effect(effect, htlc_abandon, true); /* Toggle between high and low priority states. */ return toggle_prio(state, STATE_NORMAL); - } else if (input_is(input, PKT_UPDATE_ADD_HTLC)) { + /* They can't close with an HTLC, so only possible here */ + } else if (input_is(input, PKT_CLOSE)) { + fail_cmd(effect, CMD_SEND_UPDATE_ANY, NULL); + set_effect(effect, htlc_abandon, true); + goto accept_closing; + } + /* Fall thru */ + case STATE_WAIT_FOR_UPDATE_ACCEPT_LOWPRIO: + case STATE_WAIT_FOR_UPDATE_ACCEPT_HIGHPRIO: + if (input_is(input, PKT_UPDATE_ADD_HTLC)) { /* If we're high priority, ignore their packet */ if (high_priority(state)) return state; /* Otherwise, process their request first: defer ours */ requeue_cmd(effect, CMD_SEND_UPDATE_ANY); + set_effect(effect, htlc_abandon, true); goto accept_htlc_update; } else if (input_is(input, PKT_UPDATE_FULFILL_HTLC)) { /* If we're high priority, ignore their packet */ @@ -372,6 +414,7 @@ enum state state(const enum state state, const struct state_data *sdata, /* Otherwise, process their request first: defer ours */ requeue_cmd(effect, CMD_SEND_UPDATE_ANY); + set_effect(effect, htlc_abandon, true); goto accept_htlc_fulfill; } else if (input_is(input, PKT_UPDATE_TIMEDOUT_HTLC)) { /* If we're high priority, ignore their packet */ @@ -380,6 +423,7 @@ enum state state(const enum state state, const struct state_data *sdata, /* Otherwise, process their request first: defer ours */ requeue_cmd(effect, CMD_SEND_UPDATE_ANY); + set_effect(effect, htlc_abandon, true); goto accept_htlc_timedout; } else if (input_is(input, PKT_UPDATE_ROUTEFAIL_HTLC)) { /* If we're high priority, ignore their packet */ @@ -388,31 +432,37 @@ enum state state(const enum state state, const struct state_data *sdata, /* Otherwise, process their request first: defer ours */ requeue_cmd(effect, CMD_SEND_UPDATE_ANY); + set_effect(effect, htlc_abandon, true); goto accept_htlc_routefail; } else if (input_is(input, PKT_UPDATE_ACCEPT)) { + struct signature *sig; err = accept_pkt_update_accept(effect, sdata, - idata->pkt); + idata->pkt, &sig); if (err) { fail_cmd(effect, CMD_SEND_UPDATE_ANY, NULL); goto err_start_unilateral_close; } + set_effect(effect, update_theirsig, sig); set_effect(effect, send, pkt_update_signature(effect, sdata)); + /* HTLC is signed (though old tx not revoked yet!) */ + set_effect(effect, htlc_fulfill, true); return prio(state, STATE_WAIT_FOR_UPDATE_COMPLETE); } else if (input_is(input, BITCOIN_ANCHOR_UNSPENT)) { fail_cmd(effect, CMD_SEND_UPDATE_ANY, NULL); + set_effect(effect, htlc_abandon, true); goto anchor_unspent; } else if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) { fail_cmd(effect, CMD_SEND_UPDATE_ANY, NULL); + set_effect(effect, htlc_abandon, true); goto them_unilateral; } else if (input_is(input, BITCOIN_ANCHOR_OTHERSPEND)) { fail_cmd(effect, CMD_SEND_UPDATE_ANY, NULL); + set_effect(effect, htlc_abandon, true); goto old_commit_spotted; - } else if (input_is(input, PKT_CLOSE)) { - fail_cmd(effect, CMD_SEND_UPDATE_ANY, NULL); - goto accept_closing; } else if (input_is_pkt(input)) { fail_cmd(effect, CMD_SEND_UPDATE_ANY, NULL); + set_effect(effect, htlc_abandon, true); goto unexpected_pkt; } break; @@ -445,26 +495,34 @@ enum state state(const enum state state, const struct state_data *sdata, case STATE_WAIT_FOR_UPDATE_SIG_LOWPRIO: case STATE_WAIT_FOR_UPDATE_SIG_HIGHPRIO: if (input_is(input, PKT_UPDATE_SIGNATURE)) { + struct signature *sig; err = accept_pkt_update_signature(effect, sdata, - idata->pkt); + idata->pkt, &sig); if (err) goto err_start_unilateral_close; + set_effect(effect, update_theirsig, sig); set_effect(effect, send, pkt_update_complete(effect, sdata)); + set_effect(effect, htlc_fulfill, true); /* Toggle between high and low priority states. */ return toggle_prio(state, STATE_NORMAL); } else if (input_is(input, CMD_SEND_UPDATE_ANY)) { set_effect(effect, defer, input); return state; } else if (input_is(input, BITCOIN_ANCHOR_UNSPENT)) { + set_effect(effect, htlc_abandon, true); goto anchor_unspent; } else if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) { + set_effect(effect, htlc_abandon, true); goto them_unilateral; } else if (input_is(input, BITCOIN_ANCHOR_OTHERSPEND)) { + set_effect(effect, htlc_abandon, true); goto old_commit_spotted; } else if (input_is(input, CMD_CLOSE)) { + set_effect(effect, htlc_abandon, true); goto start_closing; } else if (input_is_pkt(input)) { + set_effect(effect, htlc_abandon, true); goto unexpected_pkt; } break; @@ -511,7 +569,11 @@ enum state state(const enum state state, const struct state_data *sdata, bitcoin_watch_delayed(effect, effect->broadcast, BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED)); - /* They could still close. */ + + /* We agreed to close: shouldn't have any HTLCs */ + if (committed_to_htlcs(sdata)) + return STATE_ERR_INTERNAL; + return STATE_CLOSE_WAIT_CLOSE_OURCOMMIT; } fail_cmd(effect, CMD_CLOSE, NULL); @@ -545,51 +607,87 @@ enum state state(const enum state state, const struct state_data *sdata, goto fail_during_close; /* Close states are regular: handle as a group. */ + case STATE_CLOSE_WAIT_HTLCS: case STATE_CLOSE_WAIT_STEAL: case STATE_CLOSE_WAIT_SPENDTHEM: + case STATE_CLOSE_WAIT_SPENDTHEM_WITH_HTLCS: case STATE_CLOSE_WAIT_STEAL_SPENDTHEM: + case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_WITH_HTLCS: case STATE_CLOSE_WAIT_CLOSE: case STATE_CLOSE_WAIT_STEAL_CLOSE: case STATE_CLOSE_WAIT_SPENDTHEM_CLOSE: + case STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_WITH_HTLCS: case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE: + case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_WITH_HTLCS: case STATE_CLOSE_WAIT_STEAL_OURCOMMIT: + case STATE_CLOSE_WAIT_STEAL_OURCOMMIT_WITH_HTLCS: case STATE_CLOSE_WAIT_SPENDTHEM_OURCOMMIT: + case STATE_CLOSE_WAIT_SPENDTHEM_OURCOMMIT_WITH_HTLCS: case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_OURCOMMIT: + case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_OURCOMMIT_WITH_HTLCS: case STATE_CLOSE_WAIT_CLOSE_OURCOMMIT: case STATE_CLOSE_WAIT_STEAL_CLOSE_OURCOMMIT: case STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_OURCOMMIT: + case STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_OURCOMMIT_WITH_HTLCS: case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_OURCOMMIT: + case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_OURCOMMIT_WITH_HTLCS: case STATE_CLOSE_WAIT_STEAL_SPENDOURS: + case STATE_CLOSE_WAIT_STEAL_SPENDOURS_WITH_HTLCS: case STATE_CLOSE_WAIT_SPENDTHEM_SPENDOURS: + case STATE_CLOSE_WAIT_SPENDTHEM_SPENDOURS_WITH_HTLCS: case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_SPENDOURS: + case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_SPENDOURS_WITH_HTLCS: case STATE_CLOSE_WAIT_CLOSE_SPENDOURS: case STATE_CLOSE_WAIT_STEAL_CLOSE_SPENDOURS: case STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_SPENDOURS: + case STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_SPENDOURS_WITH_HTLCS: case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS: + case STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS_WITH_HTLCS: case STATE_CLOSE_WAIT_OURCOMMIT: - case STATE_CLOSE_WAIT_SPENDOURS: { + case STATE_CLOSE_WAIT_OURCOMMIT_WITH_HTLCS: + case STATE_CLOSE_WAIT_SPENDOURS: + case STATE_CLOSE_WAIT_SPENDOURS_WITH_HTLCS: { unsigned int bits, base; + enum state_input closed; - base = (unsigned)STATE_CLOSE_WAIT_STEAL - 1; + base = (unsigned)STATE_CLOSED; bits = (unsigned)state - base; + /* Once we see a steal or spend completely buried, we + * close unless we're still waiting for htlcs*/ + if (bits & STATE_CLOSE_HTLCS_BIT) + closed = STATE_CLOSE_WAIT_HTLCS; + else + closed = STATE_CLOSED; + if ((bits & STATE_CLOSE_STEAL_BIT) && input_is(input, BITCOIN_STEAL_DONE)) { + /* One a steal is complete, we don't care about htlcs + * (we stole them all) */ + if (bits & STATE_CLOSE_HTLCS_BIT) + set_effect(effect, unwatch_htlc, + htlc_unwatch_all(effect, sdata)); return STATE_CLOSED; } if ((bits & STATE_CLOSE_SPENDTHEM_BIT) && input_is(input, BITCOIN_SPEND_THEIRS_DONE)) { - return STATE_CLOSED; + BUILD_ASSERT(!((STATE_CLOSE_WAIT_HTLCS - base) + & STATE_CLOSE_SPENDTHEM_BIT)); + return closed; } if ((bits & STATE_CLOSE_CLOSE_BIT) && input_is(input, BITCOIN_CLOSE_DONE)) { - return STATE_CLOSED; + BUILD_ASSERT(!((STATE_CLOSE_WAIT_HTLCS - base) + & STATE_CLOSE_CLOSE_BIT)); + return closed; } if ((bits & STATE_CLOSE_OURCOMMIT_BIT) && input_is(input, BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED)) { + BUILD_ASSERT(!((STATE_CLOSE_WAIT_HTLCS - base) + & STATE_CLOSE_OURCOMMIT_BIT)); /* Now we need to wait for our commit to be done. */ set_effect(effect, broadcast, bitcoin_spend_ours(effect, sdata)); @@ -603,17 +701,122 @@ enum state state(const enum state state, const struct state_data *sdata, if ((bits & STATE_CLOSE_SPENDOURS_BIT) && input_is(input, BITCOIN_SPEND_OURS_DONE)) { - return STATE_CLOSED; + BUILD_ASSERT(!((STATE_CLOSE_WAIT_HTLCS - base) + & STATE_CLOSE_SPENDOURS_BIT)); + return closed; } - /* Now, other side can always spring a commit transaction on us - * (even if they already have, due to tx malleability) */ + /* If we have htlcs, we can get other inputs... */ + if (bits & STATE_CLOSE_HTLCS_BIT) { + if (input_is(input, INPUT_NO_MORE_HTLCS)) { + /* Clear bit, might lead to STATE_CLOSED. */ + BUILD_ASSERT(((STATE_CLOSE_WAIT_HTLCS - base) + & ~STATE_CLOSE_HTLCS_BIT) + == STATE_CLOSED); + bits &= ~STATE_CLOSE_HTLCS_BIT; + return base + bits; + } else if (input_is(input, BITCOIN_HTLC_TOTHEM_SPENT)) { + /* They revealed R value. */ + set_effect(effect, r_value, + bitcoin_r_value(effect, idata->htlc)); + /* We don't care any more. */ + set_effect(effect, unwatch_htlc, + htlc_unwatch(effect, idata->htlc, + INPUT_NO_MORE_HTLCS)); + return state; + } else if (input_is(input, BITCOIN_HTLC_TOTHEM_TIMEOUT)){ + /* HTLC timed out, spend it back to us. */ + set_effect(effect, broadcast, + bitcoin_htlc_timeout(effect, + sdata, + idata->htlc)); + /* Don't unwatch yet; they could yet + * try to spend, revealing rvalue. */ + + /* We're done when that gets buried. */ + set_effect(effect, watch_htlc_spend, + htlc_spend_watch(effect, + effect->broadcast, + idata->cmd, + BITCOIN_HTLC_RETURN_SPEND_DONE)); + return state; + } else if (input_is(input, CMD_SEND_HTLC_FULFILL)) { + /* This gives us the r value. */ + set_effect(effect, r_value, + r_value_from_cmd(effect, sdata, + idata->htlc)); + /* Spend it... */ + set_effect(effect, broadcast, + bitcoin_htlc_spend(effect, sdata, + idata->htlc)); + /* We're done when it gets buried. */ + set_effect(effect, watch_htlc_spend, + htlc_spend_watch(effect, + effect->broadcast, + idata->cmd, + BITCOIN_HTLC_FULFILL_SPEND_DONE)); + /* Don't care about this one any more. */ + set_effect(effect, unwatch_htlc, + htlc_unwatch(effect, idata->htlc, + INPUT_NO_MORE_HTLCS)); + return state; + } else if (input_is(input, BITCOIN_HTLC_FULFILL_SPEND_DONE)) { + /* Stop watching spend, send + * INPUT_NO_MORE_HTLCS when done. */ + set_effect(effect, unwatch_htlc_spend, + htlc_spend_unwatch(effect, + idata->htlc, + INPUT_NO_MORE_HTLCS)); + return state; + } else if (input_is(input, BITCOIN_HTLC_RETURN_SPEND_DONE)) { + /* Stop watching spend, send + * INPUT_NO_MORE_HTLCS when done. */ + set_effect(effect, unwatch_htlc_spend, + htlc_spend_unwatch(effect, + idata->htlc, + INPUT_NO_MORE_HTLCS)); + + /* Don't need to watch the HTLC output any more, + * either. */ + set_effect(effect, unwatch_htlc, + htlc_unwatch(effect, idata->htlc, + INPUT_NO_MORE_HTLCS)); + return state; + } else if (input_is(input, BITCOIN_HTLC_TOUS_TIMEOUT)) { + /* They can spend, we no longer care + * about this HTLC. */ + set_effect(effect, unwatch_htlc, + htlc_unwatch(effect, idata->htlc, + INPUT_NO_MORE_HTLCS)); + return state; + } + } + + /* If we're just waiting for HTLCs, anything else is an error */ + if (state == STATE_CLOSE_WAIT_HTLCS) + break; + + /* + * Now, other side can always spring a commit transaction on us + * (even if they already have, due to tx malleability). + */ if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) { set_effect(effect, broadcast, - bitcoin_spend_theirs(effect, sdata)); + bitcoin_spend_theirs(effect, sdata, + idata->btc)); set_effect(effect, watch, bitcoin_watch(effect, effect->broadcast, BITCOIN_SPEND_THEIRS_DONE)); + /* HTLC watches. */ + htlcs = htlc_outputs_their_commit(effect, sdata, + idata->btc, + BITCOIN_HTLC_TOUS_TIMEOUT, + BITCOIN_HTLC_TOTHEM_SPENT, + BITCOIN_HTLC_TOTHEM_TIMEOUT); + if (htlcs) { + set_effect(effect, watch_htlcs, htlcs); + bits |= STATE_CLOSE_HTLCS_BIT; + } bits |= STATE_CLOSE_SPENDTHEM_BIT; return base + bits; /* This can happen multiple times: need to steal ALL */ @@ -630,6 +833,7 @@ enum state state(const enum state state, const struct state_data *sdata, return base + bits; } else if (input_is(input, BITCOIN_ANCHOR_UNSPENT)) goto anchor_unspent; + break; } @@ -640,6 +844,13 @@ enum state state(const enum state state, const struct state_data *sdata, case STATE_ERR_ANCHOR_LOST: case STATE_CLOSED: case STATE_MAX: + case STATE_UNUSED_CLOSE_WAIT_STEAL_WITH_HTLCS: + case STATE_UNUSED_CLOSE_WAIT_CLOSE_WITH_HTLCS: + case STATE_UNUSED_CLOSE_WAIT_STEAL_CLOSE_WITH_HTLCS: + case STATE_UNUSED_CLOSE_WAIT_CLOSE_OURCOMMIT_WITH_HTLCS: + case STATE_UNUSED_CLOSE_WAIT_STEAL_CLOSE_OURCOMMIT_WITH_HTLCS: + case STATE_UNUSED_CLOSE_WAIT_CLOSE_SPENDOURS_WITH_HTLCS: + case STATE_UNUSED_CLOSE_WAIT_STEAL_CLOSE_SPENDOURS_WITH_HTLCS: return STATE_ERR_INTERNAL; } @@ -652,7 +863,7 @@ unexpected_pkt: */ /* Don't reply to an error with an error. */ if (input_is(input, PKT_ERROR)) { - set_effect(effect, in_error, tal_steal(effect, idata->pkt)); + set_effect(effect, in_error, set_errpkt(effect, idata->pkt)); goto start_unilateral_close; } err = unexpected_pkt(effect, input); @@ -700,9 +911,21 @@ start_unilateral_close: set_effect(effect, watch, bitcoin_watch_delayed(effect, effect->broadcast, BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED)); + + /* HTLC watches. */ + htlcs = htlc_outputs_our_commit(effect, sdata, effect->broadcast, + BITCOIN_HTLC_TOUS_TIMEOUT, + BITCOIN_HTLC_TOTHEM_SPENT, + BITCOIN_HTLC_TOTHEM_TIMEOUT); + if (htlcs) { + set_effect(effect, watch_htlcs, htlcs); + return STATE_CLOSE_WAIT_OURCOMMIT_WITH_HTLCS; + } return STATE_CLOSE_WAIT_OURCOMMIT; them_unilateral: + assert(input == BITCOIN_ANCHOR_THEIRSPEND); + /* * Bitcoind tells us they did unilateral close. */ @@ -711,14 +934,27 @@ them_unilateral: /* No more inputs, no more commands. */ set_effect(effect, stop_packets, true); set_effect(effect, stop_commands, true); - set_effect(effect, broadcast, bitcoin_spend_theirs(effect, sdata)); + set_effect(effect, broadcast, + bitcoin_spend_theirs(effect, sdata, idata->btc)); set_effect(effect, watch, bitcoin_watch(effect, effect->broadcast, BITCOIN_SPEND_THEIRS_DONE)); + + /* HTLC watches (based on what they broadcast, which *may* be out + * of step with our current state by +/- 1 htlc. */ + htlcs = htlc_outputs_their_commit(effect, sdata, idata->btc, + BITCOIN_HTLC_TOUS_TIMEOUT, + BITCOIN_HTLC_TOTHEM_SPENT, + BITCOIN_HTLC_TOTHEM_TIMEOUT); + if (htlcs) { + set_effect(effect, watch_htlcs, htlcs); + return STATE_CLOSE_WAIT_SPENDTHEM_WITH_HTLCS; + } return STATE_CLOSE_WAIT_SPENDTHEM; accept_htlc_update: - err = accept_pkt_htlc_update(effect, sdata, idata->pkt, &decline); + err = accept_pkt_htlc_update(effect, sdata, idata->pkt, &decline, + &htlcprog); if (err) goto err_start_unilateral_close; if (decline) { @@ -726,34 +962,45 @@ accept_htlc_update: /* Toggle between high/low priority states. */ return toggle_prio(state, STATE_NORMAL); } + set_effect(effect, htlc_in_progress, htlcprog); set_effect(effect, send, pkt_update_accept(effect, sdata)); return prio(state, STATE_WAIT_FOR_UPDATE_SIG); accept_htlc_routefail: - err = accept_pkt_htlc_routefail(effect, sdata, idata->pkt); + err = accept_pkt_htlc_routefail(effect, sdata, idata->pkt, &htlcprog); if (err) goto err_start_unilateral_close; + set_effect(effect, htlc_in_progress, htlcprog); set_effect(effect, send, pkt_update_accept(effect, sdata)); return prio(state, STATE_WAIT_FOR_UPDATE_SIG); accept_htlc_timedout: - err = accept_pkt_htlc_timedout(effect, sdata, idata->pkt); + err = accept_pkt_htlc_timedout(effect, sdata, idata->pkt, &htlcprog); if (err) goto err_start_unilateral_close; + set_effect(effect, htlc_in_progress, htlcprog); set_effect(effect, send, pkt_update_accept(effect, sdata)); return prio(state, STATE_WAIT_FOR_UPDATE_SIG); accept_htlc_fulfill: - err = accept_pkt_htlc_fulfill(effect, sdata, idata->pkt); + err = accept_pkt_htlc_fulfill(effect, sdata, idata->pkt, &htlcprog); if (err) goto err_start_unilateral_close; + set_effect(effect, htlc_in_progress, htlcprog); set_effect(effect, send, pkt_update_accept(effect, sdata)); + set_effect(effect, r_value, r_value_from_pkt(effect, idata->pkt)); return prio(state, STATE_WAIT_FOR_UPDATE_SIG); start_closing: /* * Start a mutual close. */ + /* Protocol doesn't (currently?) allow closing with HTLCs. */ + if (committed_to_htlcs(sdata)) { + fail_cmd(effect, CMD_CLOSE, NULL); + err = pkt_err(effect, "Close forced due to HTLCs"); + goto err_start_unilateral_close; + } set_effect(effect, close_timeout, INPUT_CLOSE_COMPLETE_TIMEOUT); set_effect(effect, watch, @@ -784,6 +1031,10 @@ instant_close: /* FIXME: Should we tell other side we're going? */ set_effect(effect, stop_packets, true); set_effect(effect, stop_commands, true); + + /* We can't have any HTLCs, since we haven't started. */ + if (committed_to_htlcs(sdata)) + return STATE_ERR_INTERNAL; return STATE_CLOSED; fail_during_close: @@ -799,11 +1050,21 @@ fail_during_close: } else if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) { /* A reorganization could make this happen. */ set_effect(effect, broadcast, - bitcoin_spend_theirs(effect, sdata)); + bitcoin_spend_theirs(effect, sdata, idata->btc)); set_effect(effect, watch, bitcoin_watch(effect, effect->broadcast, BITCOIN_SPEND_THEIRS_DONE)); + htlcs = htlc_outputs_their_commit(effect, sdata, idata->btc, + BITCOIN_HTLC_TOUS_TIMEOUT, + BITCOIN_HTLC_TOTHEM_SPENT, + BITCOIN_HTLC_TOTHEM_TIMEOUT); /* Expect either close or spendthem to complete */ + if (htlcs) { + /* FIXME: Make sure caller uses CMD_HTLC_FULFILL again + * if they were in the middle of one! */ + set_effect(effect, watch_htlcs, htlcs); + return STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_WITH_HTLCS; + } return STATE_CLOSE_WAIT_SPENDTHEM_CLOSE; } else if (input_is(input, BITCOIN_ANCHOR_OTHERSPEND)) { steal = bitcoin_steal(effect, sdata, idata->btc); diff --git a/state.h b/state.h index 144f6981a..7f4ad54db 100644 --- a/state.h +++ b/state.h @@ -43,6 +43,31 @@ struct state_effect { /* Error received from other side. */ Pkt *in_error; + /* HTLC we're working on. */ + struct htlc_progress *htlc_in_progress; + + /* Their signature for the new commit tx. */ + struct signature *update_theirsig; + + /* Stop working on HTLC. */ + bool htlc_abandon; + + /* Finished working on HTLC. */ + bool htlc_fulfill; + + /* R value. */ + const struct htlc_rval *r_value; + + /* HTLC outputs to watch. */ + const struct htlc_watch *watch_htlcs; + + /* HTLC output to unwatch. */ + const struct htlc_unwatch *unwatch_htlc; + + /* HTLC spends to watch/unwatch. */ + const struct htlc_spend_watch *watch_htlc_spend; + const struct htlc_spend_watch *unwatch_htlc_spend; + /* FIXME: More to come (for accept_*) */ }; @@ -65,6 +90,8 @@ union input { Pkt *pkt; struct command *cmd; struct bitcoin_event *btc; + struct htlc *htlc; + struct htlc_progress *htlc_prog; }; enum state state(const enum state state, const struct state_data *sdata, @@ -92,15 +119,21 @@ static inline bool input_is(enum state_input a, enum state_input b) return a == b; } +struct signature; + /* Create various kinds of packets, allocated off @ctx */ Pkt *pkt_open(const tal_t *ctx, const struct state_data *sdata); Pkt *pkt_anchor(const tal_t *ctx, const struct state_data *sdata); Pkt *pkt_open_commit_sig(const tal_t *ctx, const struct state_data *sdata); Pkt *pkt_open_complete(const tal_t *ctx, const struct state_data *sdata); -Pkt *pkt_htlc_update(const tal_t *ctx, const struct state_data *sdata, void *data); -Pkt *pkt_htlc_fulfill(const tal_t *ctx, const struct state_data *sdata, void *data); -Pkt *pkt_htlc_timedout(const tal_t *ctx, const struct state_data *sdata, void *data); -Pkt *pkt_htlc_routefail(const tal_t *ctx, const struct state_data *sdata, void *data); +Pkt *pkt_htlc_update(const tal_t *ctx, const struct state_data *sdata, + const struct htlc_progress *htlc_prog); +Pkt *pkt_htlc_fulfill(const tal_t *ctx, const struct state_data *sdata, + const struct htlc_progress *htlc_prog); +Pkt *pkt_htlc_timedout(const tal_t *ctx, const struct state_data *sdata, + const struct htlc_progress *htlc_prog); +Pkt *pkt_htlc_routefail(const tal_t *ctx, const struct state_data *sdata, + const struct htlc_progress *htlc_prog); Pkt *pkt_update_accept(const tal_t *ctx, const struct state_data *sdata); Pkt *pkt_update_signature(const tal_t *ctx, const struct state_data *sdata); Pkt *pkt_update_complete(const tal_t *ctx, const struct state_data *sdata); @@ -124,26 +157,32 @@ Pkt *accept_pkt_open_commit_sig(struct state_effect *effect, Pkt *accept_pkt_htlc_update(struct state_effect *effect, const struct state_data *sdata, const Pkt *pkt, - Pkt **decline); + Pkt **decline, + struct htlc_progress **htlcprog); Pkt *accept_pkt_htlc_routefail(struct state_effect *effect, - const struct state_data *sdata, const Pkt *pkt); + const struct state_data *sdata, const Pkt *pkt, + struct htlc_progress **htlcprog); Pkt *accept_pkt_htlc_timedout(struct state_effect *effect, - const struct state_data *sdata, const Pkt *pkt); + const struct state_data *sdata, const Pkt *pkt, + struct htlc_progress **htlcprog); Pkt *accept_pkt_htlc_fulfill(struct state_effect *effect, - const struct state_data *sdata, const Pkt *pkt); + const struct state_data *sdata, const Pkt *pkt, + struct htlc_progress **htlcprog); Pkt *accept_pkt_update_accept(struct state_effect *effect, - const struct state_data *sdata, const Pkt *pkt); + const struct state_data *sdata, const Pkt *pkt, + struct signature **sig); Pkt *accept_pkt_update_complete(struct state_effect *effect, const struct state_data *sdata, const Pkt *pkt); Pkt *accept_pkt_update_signature(struct state_effect *effect, const struct state_data *sdata, - const Pkt *pkt); + const Pkt *pkt, + struct signature **sig); Pkt *accept_pkt_close(struct state_effect *effect, const struct state_data *sdata, const Pkt *pkt); @@ -158,6 +197,14 @@ Pkt *accept_pkt_simultaneous_close(struct state_effect *effect, Pkt *accept_pkt_close_ack(struct state_effect *effect, const struct state_data *sdata, const Pkt *pkt); +/** + * committed_to_htlcs: do we have any locked-in HTLCs? + * @sdata: the state data for this peer. + * + * If we were to generate a commit tx now, would it have HTLCs in it? + */ +bool committed_to_htlcs(const struct state_data *sdata); + /** * bitcoin_watch_anchor: create a watch for the anchor. * @ctx: context to tal the watch struct off. @@ -230,7 +277,77 @@ struct watch *bitcoin_watch_close(const tal_t *ctx, const struct state_data *sdata, enum state_input done); +/** + * htlc_outputs_our_commit: HTLC outputs from our commit tx to watch. + * @ctx: context to tal the watch struct off. + * @sdata: the state data for this peer. + * @tx: the commitment tx + * @tous_timeout: input to give when a HTLC output to us times out. + * @tothem_spent: input to give when a HTLC output to them is spent. + * @tothem_timeout: input to give when a HTLC output to them times out. + */ +struct htlc_watch *htlc_outputs_our_commit(const tal_t *ctx, + const struct state_data *sdata, + const struct bitcoin_tx *tx, + enum state_input tous_timeout, + enum state_input tothem_spent, + enum state_input tothem_timeout); + +/** + * htlc_outputs_their_commit: HTLC outputs from their commit tx to watch. + * @ctx: context to tal the watch struct off. + * @sdata: the state data for this peer. + * @tx: the commitment tx + * @tous_timeout: input to give when a HTLC output to us times out. + * @tothem_spent: input to give when a HTLC output to them is spent. + * @tothem_timeout: input to give when a HTLC output to them times out. + */ +struct htlc_watch *htlc_outputs_their_commit(const tal_t *ctx, + const struct state_data *sdata, + const struct bitcoin_event *tx, + enum state_input tous_timeout, + enum state_input tothem_spent, + enum state_input tothem_timeout); + +/** + * htlc_unwatch: stop watching an HTLC + * @ctx: context to tal the watch struct off. + * @htlc: the htlc to stop watching + * @all_done: input to give if we're not watching any anymore. + */ +struct htlc_unwatch *htlc_unwatch(const tal_t *ctx, + const struct htlc *htlc, + enum state_input all_done); + +/** + * htlc_unwatch_all: stop watching all HTLCs + * @ctx: context to tal the watch struct off. + * @sdata: the state data for this peer. + */ +struct htlc_unwatch *htlc_unwatch_all(const tal_t *ctx, + const struct state_data *sdata); + +/** + * htlc_spend_watch: watch our spend of an HTLC + * @ctx: context to tal the watch struct off. + * @tx: the commitment tx + * @cmd: the command data. + * @done: input to give when it's completely buried. + */ +struct htlc_spend_watch *htlc_spend_watch(const tal_t *ctx, + const struct bitcoin_tx *tx, + const struct command *cmd, + enum state_input done); +/** + * htlc_spend_unwatch: stop watching an HTLC spend + * @ctx: context to tal the watch struct off. + * @htlc: the htlc to stop watching + * @all_done: input to give if we're not watching anything anymore. + */ +struct htlc_spend_watch *htlc_spend_unwatch(const tal_t *ctx, + 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 state_data *sdata); @@ -245,7 +362,8 @@ struct bitcoin_tx *bitcoin_spend_ours(const tal_t *ctx, /* Create a bitcoin spend tx (to spend their commit's outputs) */ struct bitcoin_tx *bitcoin_spend_theirs(const tal_t *ctx, - const struct state_data *sdata); + const struct state_data *sdata, + const struct bitcoin_event *btc); /* Create a bitcoin steal tx (to steal all their commit's outputs) */ struct bitcoin_tx *bitcoin_steal(const tal_t *ctx, @@ -256,4 +374,14 @@ struct bitcoin_tx *bitcoin_steal(const tal_t *ctx, struct bitcoin_tx *bitcoin_commit(const tal_t *ctx, const struct state_data *sdata); +/* Create a HTLC refund collection */ +struct bitcoin_tx *bitcoin_htlc_timeout(const tal_t *ctx, + const struct state_data *sdata, + const struct htlc *htlc); + +/* Create a HTLC collection */ +struct bitcoin_tx *bitcoin_htlc_spend(const tal_t *ctx, + const struct state_data *sdata, + const struct htlc *htlc); + #endif /* LIGHTNING_STATE_H */ diff --git a/state_types.h b/state_types.h index 0789c22ae..723ec3630 100644 --- a/state_types.h +++ b/state_types.h @@ -3,11 +3,12 @@ /* FIXME: cdump is really dumb, so we put these in their own header. */ #include "lightning.pb-c.h" -#define STATE_CLOSE_STEAL_BIT 1 -#define STATE_CLOSE_SPENDTHEM_BIT 2 -#define STATE_CLOSE_CLOSE_BIT 4 -#define STATE_CLOSE_OURCOMMIT_BIT 8 -#define STATE_CLOSE_SPENDOURS_BIT 16 +#define STATE_CLOSE_HTLCS_BIT 1 +#define STATE_CLOSE_STEAL_BIT 2 +#define STATE_CLOSE_SPENDTHEM_BIT 4 +#define STATE_CLOSE_CLOSE_BIT 8 +#define STATE_CLOSE_OURCOMMIT_BIT 16 +#define STATE_CLOSE_SPENDOURS_BIT 32 enum state { STATE_INIT_NOANCHOR, @@ -36,6 +37,9 @@ enum state { STATE_WAIT_FOR_HTLC_ACCEPT_LOWPRIO, STATE_WAIT_FOR_HTLC_ACCEPT_HIGHPRIO, + STATE_WAIT_FOR_UPDATE_ACCEPT_LOWPRIO, + STATE_WAIT_FOR_UPDATE_ACCEPT_HIGHPRIO, + STATE_WAIT_FOR_UPDATE_COMPLETE_LOWPRIO, STATE_WAIT_FOR_UPDATE_COMPLETE_HIGHPRIO, @@ -50,6 +54,11 @@ enum state { /* They told us to close, waiting for ack msg. */ STATE_WAIT_FOR_CLOSE_ACK, + /* All closed. */ + STATE_CLOSED, + /* Just waiting for HTLCs to resolve. */ + STATE_CLOSE_WAIT_HTLCS, + /* * They can broadcast one or more revoked commit tx, or their latest * commit tx at any time. We respond to revoked commit txs by stealing @@ -88,35 +97,67 @@ enum state { * - steal + mutual_close + spend_ours * - spend_them + mutual_close + spend_ours * - steal + spend_them + mutual_close + spend_ours + * + * Each of these has with-HTLC and without-HTLC variants, except: + * + * 1) We never agree to close with HTLCs, + * 2) We don't care about htlcs if we steal (we steal all outputs). + * + * Now, it is possible for us to CLOSE and them to have an HTLC, + * because we could close partway through negotiation. So, any + * commit tx they publish could introduce HTLCs. + * + * Thus, HTLC variants are only possible with SPENDTHEM, OR + * OURCOMMIT/SPENDOURS, and only no CLOSE (since CLOSE implies no HTLCs). */ STATE_CLOSE_WAIT_STEAL, + STATE_UNUSED_CLOSE_WAIT_STEAL_WITH_HTLCS, STATE_CLOSE_WAIT_SPENDTHEM, + STATE_CLOSE_WAIT_SPENDTHEM_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_SPENDTHEM, + STATE_CLOSE_WAIT_STEAL_SPENDTHEM_WITH_HTLCS, STATE_CLOSE_WAIT_CLOSE, + STATE_UNUSED_CLOSE_WAIT_CLOSE_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_CLOSE, + STATE_UNUSED_CLOSE_WAIT_STEAL_CLOSE_WITH_HTLCS, STATE_CLOSE_WAIT_SPENDTHEM_CLOSE, + STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE, + STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_WITH_HTLCS, STATE_CLOSE_WAIT_OURCOMMIT, + STATE_CLOSE_WAIT_OURCOMMIT_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_OURCOMMIT, + STATE_CLOSE_WAIT_STEAL_OURCOMMIT_WITH_HTLCS, STATE_CLOSE_WAIT_SPENDTHEM_OURCOMMIT, + STATE_CLOSE_WAIT_SPENDTHEM_OURCOMMIT_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_SPENDTHEM_OURCOMMIT, + STATE_CLOSE_WAIT_STEAL_SPENDTHEM_OURCOMMIT_WITH_HTLCS, STATE_CLOSE_WAIT_CLOSE_OURCOMMIT, + STATE_UNUSED_CLOSE_WAIT_CLOSE_OURCOMMIT_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_CLOSE_OURCOMMIT, + STATE_UNUSED_CLOSE_WAIT_STEAL_CLOSE_OURCOMMIT_WITH_HTLCS, STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_OURCOMMIT, + STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_OURCOMMIT_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_OURCOMMIT, + STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_OURCOMMIT_WITH_HTLCS, STATE_CLOSE_WAIT_SPENDOURS, + STATE_CLOSE_WAIT_SPENDOURS_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_SPENDOURS, + STATE_CLOSE_WAIT_STEAL_SPENDOURS_WITH_HTLCS, STATE_CLOSE_WAIT_SPENDTHEM_SPENDOURS, + STATE_CLOSE_WAIT_SPENDTHEM_SPENDOURS_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_SPENDTHEM_SPENDOURS, + STATE_CLOSE_WAIT_STEAL_SPENDTHEM_SPENDOURS_WITH_HTLCS, STATE_CLOSE_WAIT_CLOSE_SPENDOURS, + STATE_UNUSED_CLOSE_WAIT_CLOSE_SPENDOURS_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_CLOSE_SPENDOURS, + STATE_UNUSED_CLOSE_WAIT_STEAL_CLOSE_SPENDOURS_WITH_HTLCS, STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_SPENDOURS, + STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_SPENDOURS_WITH_HTLCS, STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS, - - /* All closed. */ - STATE_CLOSED, + STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS_WITH_HTLCS, /* * Where angels fear to tread. @@ -189,7 +230,13 @@ enum state_input { BITCOIN_ANCHOR_THEIRSPEND, /* Anchor was spent by another commit tx (eg. expired). */ BITCOIN_ANCHOR_OTHERSPEND, - + /* They spent an HTLC to them (revealing R value). */ + BITCOIN_HTLC_TOTHEM_SPENT, + /* HTLC to them timed out, we can get funds now. */ + BITCOIN_HTLC_TOTHEM_TIMEOUT, + /* HTLC to us timed out. */ + BITCOIN_HTLC_TOUS_TIMEOUT, + /* Our spend of their commit tx is completely buried. */ BITCOIN_SPEND_THEIRS_DONE, /* Our spend of our own tx is completely buried. */ @@ -198,6 +245,13 @@ enum state_input { BITCOIN_STEAL_DONE, /* Bitcoin close transaction considered completely buried. */ BITCOIN_CLOSE_DONE, + /* Our HTLC spend is completely buried. */ + BITCOIN_HTLC_FULFILL_SPEND_DONE, + /* Our HTLC refund spend has is completely buried. */ + BITCOIN_HTLC_RETURN_SPEND_DONE, + + /* We are not watching any HTLCs any more. */ + INPUT_NO_MORE_HTLCS, /* * Timeouts.