mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-11 09:04:21 +01:00
state: trim unused states.
Now we never enter the state machine if we're dealing with on-chain transactions. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
233
daemon/peer.c
233
daemon/peer.c
@@ -119,6 +119,21 @@ static void set_current_command(struct peer *peer,
|
||||
peer->curr_cmd.jsoncmd = jsoncmd;
|
||||
}
|
||||
|
||||
static void peer_breakdown(struct peer *peer)
|
||||
{
|
||||
/* If we have a closing tx, use it. */
|
||||
if (peer->closing.their_sig) {
|
||||
log_unusual(peer->log, "Peer breakdown: sending close tx");
|
||||
broadcast_tx(peer, bitcoin_close(peer));
|
||||
/* If we have a signed commit tx (maybe not if we just offered
|
||||
* anchor), use it. */
|
||||
} else if (peer->us.commit->sig) {
|
||||
log_unusual(peer->log, "Peer breakdown: sending commit tx");
|
||||
broadcast_tx(peer, bitcoin_commit(peer));
|
||||
} else
|
||||
log_info(peer->log, "Peer breakdown: nothing to do");
|
||||
}
|
||||
|
||||
static void state_single(struct peer *peer,
|
||||
const enum state_input input,
|
||||
const union input *idata)
|
||||
@@ -157,8 +172,11 @@ static void state_single(struct peer *peer,
|
||||
if (peer->cond == PEER_CLOSED)
|
||||
io_wake(peer);
|
||||
|
||||
if (peer->state == STATE_ERR_BREAKDOWN)
|
||||
peer_breakdown(peer);
|
||||
|
||||
/* FIXME: Some of these should just result in this peer being killed? */
|
||||
if (state_is_error(peer->state)) {
|
||||
else if (state_is_error(peer->state)) {
|
||||
log_broken(peer->log, "Entered error state %s",
|
||||
state_name(peer->state));
|
||||
fatal("Peer entered error state");
|
||||
@@ -223,7 +241,7 @@ static void queue_input(struct peer *peer,
|
||||
}
|
||||
|
||||
/* All unrevoked commit txs must have no HTLCs in them. */
|
||||
bool committed_to_htlcs(const struct peer *peer)
|
||||
static bool committed_to_htlcs(const struct peer *peer)
|
||||
{
|
||||
const struct commit_info *i;
|
||||
|
||||
@@ -358,21 +376,6 @@ static void destroy_peer(struct peer *peer)
|
||||
list_del_from(&peer->dstate->peers, &peer->list);
|
||||
}
|
||||
|
||||
static void peer_breakdown(struct peer *peer)
|
||||
{
|
||||
/* If we have a closing tx, use it. */
|
||||
if (peer->closing.their_sig) {
|
||||
log_unusual(peer->log, "Peer breakdown: sending close tx");
|
||||
broadcast_tx(peer, bitcoin_close(peer));
|
||||
/* If we have a signed commit tx (maybe not if we just offered
|
||||
* anchor), use it. */
|
||||
} else if (peer->us.commit->sig) {
|
||||
log_unusual(peer->log, "Peer breakdown: sending commit tx");
|
||||
broadcast_tx(peer, bitcoin_commit(peer));
|
||||
} else
|
||||
log_info(peer->log, "Peer breakdown: nothing to do");
|
||||
}
|
||||
|
||||
static void peer_disconnect(struct io_conn *conn, struct peer *peer)
|
||||
{
|
||||
log_info(peer->log, "Disconnected");
|
||||
@@ -397,7 +400,8 @@ static void peer_disconnect(struct io_conn *conn, struct peer *peer)
|
||||
if (peer->cond == PEER_CLOSED)
|
||||
return;
|
||||
|
||||
peer_breakdown(peer);
|
||||
if (peer->state != STATE_ERR_BREAKDOWN)
|
||||
peer_breakdown(peer);
|
||||
}
|
||||
|
||||
static struct peer *new_peer(struct lightningd_state *dstate,
|
||||
@@ -674,9 +678,6 @@ struct anchor_watch {
|
||||
struct peer *peer;
|
||||
enum state_input depthok;
|
||||
enum state_input timeout;
|
||||
enum state_input unspent;
|
||||
enum state_input theyspent;
|
||||
enum state_input otherspent;
|
||||
|
||||
/* If timeout != INPUT_NONE, this is the timer. */
|
||||
struct oneshot *timer;
|
||||
@@ -687,6 +688,7 @@ static void anchor_depthchange(struct peer *peer, unsigned int depth,
|
||||
void *unused)
|
||||
{
|
||||
struct anchor_watch *w = peer->anchor.watches;
|
||||
|
||||
/* Still waiting for it to reach depth? */
|
||||
if (w->depthok != INPUT_NONE) {
|
||||
if (depth >= peer->us.mindepth) {
|
||||
@@ -696,13 +698,9 @@ static void anchor_depthchange(struct peer *peer, unsigned int depth,
|
||||
w->timer = tal_free(w->timer);
|
||||
state_event(peer, in, NULL);
|
||||
}
|
||||
} else {
|
||||
if (depth == 0 && w->unspent != INPUT_NONE) {
|
||||
enum state_input in = w->unspent;
|
||||
w->unspent = INPUT_NONE;
|
||||
state_event(peer, in, NULL);
|
||||
}
|
||||
}
|
||||
} else if (depth == 0)
|
||||
/* FIXME: Report losses! */
|
||||
fatal("Funding transaction was unspent!");
|
||||
}
|
||||
|
||||
/* Yay, segwit! We can just compare txids, even though we don't have both
|
||||
@@ -1347,8 +1345,6 @@ static void anchor_spent(struct peer *peer,
|
||||
|
||||
/* No longer call into the state machine. */
|
||||
peer->anchor.watches->depthok = INPUT_NONE;
|
||||
/* FIXME: Catch unspending of anchor, report issue. */
|
||||
peer->anchor.watches->unspent = INPUT_NONE;
|
||||
}
|
||||
|
||||
static void anchor_timeout(struct anchor_watch *w)
|
||||
@@ -1362,10 +1358,7 @@ static void anchor_timeout(struct anchor_watch *w)
|
||||
|
||||
void peer_watch_anchor(struct peer *peer,
|
||||
enum state_input depthok,
|
||||
enum state_input timeout,
|
||||
enum state_input unspent,
|
||||
enum state_input theyspent,
|
||||
enum state_input otherspent)
|
||||
enum state_input timeout)
|
||||
{
|
||||
struct anchor_watch *w;
|
||||
|
||||
@@ -1374,9 +1367,6 @@ void peer_watch_anchor(struct peer *peer,
|
||||
w->peer = peer;
|
||||
w->depthok = depthok;
|
||||
w->timeout = timeout;
|
||||
w->unspent = unspent;
|
||||
w->theyspent = theyspent;
|
||||
w->otherspent = otherspent;
|
||||
|
||||
watch_txid(w, peer, &peer->anchor.txid, anchor_depthchange, NULL);
|
||||
watch_txo(w, peer, &peer->anchor.txid, 0, anchor_spent, NULL);
|
||||
@@ -1418,78 +1408,6 @@ void peer_unwatch_anchor_depth(struct peer *peer,
|
||||
peer->anchor.watches = tal_free(peer->anchor.watches);
|
||||
}
|
||||
|
||||
static void commit_tx_depth(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
ptrint_t *canspend)
|
||||
{
|
||||
u32 mediantime;
|
||||
|
||||
log_debug(peer->log, "Commit tx reached depth %i", depth);
|
||||
/* FIXME: Handle locktime in blocks, as well as seconds! */
|
||||
|
||||
/* Fell out of a block? */
|
||||
if (depth == 0)
|
||||
return;
|
||||
|
||||
mediantime = get_tx_mediantime(peer->dstate, txid);
|
||||
assert(mediantime);
|
||||
|
||||
if (get_tip_mediantime(peer->dstate) > mediantime
|
||||
+ rel_locktime_to_seconds(&peer->them.locktime)) {
|
||||
/* Free this watch; we're done */
|
||||
peer->cur_commit.watch = tal_free(peer->cur_commit.watch);
|
||||
state_event(peer, ptr2int(canspend), NULL);
|
||||
} else
|
||||
log_debug(peer->log, "... still CSV locked (mediantime %u, need %u + %u)",
|
||||
get_tip_mediantime(peer->dstate),
|
||||
mediantime,
|
||||
rel_locktime_to_seconds(&peer->them.locktime));
|
||||
}
|
||||
|
||||
/* We should map back from commit_tx permutation to figure out what happened. */
|
||||
static void our_commit_spent(struct peer *peer,
|
||||
const struct bitcoin_tx *commit_tx,
|
||||
size_t input_num,
|
||||
struct commit_info *info)
|
||||
{
|
||||
/* FIXME: do something useful here, if HTLCs spent */
|
||||
}
|
||||
|
||||
/* FIXME: We tell bitcoind to watch all the outputs, which is overkill */
|
||||
static void watch_commit_outputs(struct peer *peer, const struct bitcoin_tx *tx)
|
||||
{
|
||||
varint_t i;
|
||||
struct sha256_double txid;
|
||||
|
||||
bitcoin_txid(tx, &txid);
|
||||
for (i = 0; i < tx->output_count; i++) {
|
||||
watch_txo(peer, peer, &txid, i, our_commit_spent,
|
||||
peer->us.commit);
|
||||
}
|
||||
}
|
||||
|
||||
/* Watch the commit tx until our side is spendable. */
|
||||
void peer_watch_delayed(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
enum state_input canspend)
|
||||
{
|
||||
/* We only ever spend the last one. */
|
||||
assert(tx == peer->us.commit->tx);
|
||||
peer->cur_commit.watch = watch_tx(tx, peer, tx, commit_tx_depth,
|
||||
int2ptr(canspend));
|
||||
|
||||
watch_commit_outputs(peer, tx);
|
||||
}
|
||||
|
||||
static void spend_tx_done(struct peer *peer, unsigned int depth,
|
||||
const struct sha256_double *txid,
|
||||
ptrint_t *done)
|
||||
{
|
||||
log_debug(peer->log, "tx reached depth %u", depth);
|
||||
if (depth >= peer->dstate->config.forever_confirms)
|
||||
state_event(peer, ptr2int(done), NULL);
|
||||
}
|
||||
|
||||
uint64_t commit_tx_fee(const struct bitcoin_tx *commit, uint64_t anchor_satoshis)
|
||||
{
|
||||
uint64_t i, total = 0;
|
||||
@@ -1501,14 +1419,6 @@ uint64_t commit_tx_fee(const struct bitcoin_tx *commit, uint64_t anchor_satoshis
|
||||
return anchor_satoshis - total;
|
||||
}
|
||||
|
||||
/* Watch this tx until it's buried enough to be forgotten. */
|
||||
void peer_watch_tx(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
enum state_input done)
|
||||
{
|
||||
watch_tx(tx, peer, tx, spend_tx_done, int2ptr(done));
|
||||
}
|
||||
|
||||
struct bitcoin_tx *peer_create_close_tx(struct peer *peer, u64 fee)
|
||||
{
|
||||
struct channel_state cstate;
|
||||
@@ -1576,99 +1486,11 @@ void peer_calculate_close_fee(struct peer *peer)
|
||||
assert(!(peer->closing.our_fee & 1));
|
||||
}
|
||||
|
||||
bool peer_has_close_sig(const struct peer *peer)
|
||||
{
|
||||
return peer->closing.their_sig;
|
||||
}
|
||||
|
||||
static void send_close_timeout(struct peer *peer)
|
||||
{
|
||||
/* FIXME: Remove any close_tx watches! */
|
||||
state_event(peer, INPUT_CLOSE_COMPLETE_TIMEOUT, NULL);
|
||||
}
|
||||
|
||||
void peer_watch_close(struct peer *peer,
|
||||
enum state_input done, enum state_input timedout)
|
||||
{
|
||||
/* We save some work by assuming these. */
|
||||
assert(done == BITCOIN_CLOSE_DONE);
|
||||
|
||||
/* FIXME: We can't send CLOSE, so timeout immediately */
|
||||
if (!peer->conn) {
|
||||
assert(timedout == INPUT_CLOSE_COMPLETE_TIMEOUT);
|
||||
oneshot_timeout(peer->dstate, peer, 0,
|
||||
send_close_timeout, peer);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Give them a reasonable time to respond. */
|
||||
/* FIXME: config? */
|
||||
if (timedout != INPUT_NONE) {
|
||||
assert(timedout == INPUT_CLOSE_COMPLETE_TIMEOUT);
|
||||
peer->close_watch_timeout
|
||||
= oneshot_timeout(peer->dstate, peer, 120,
|
||||
send_close_timeout, peer);
|
||||
}
|
||||
|
||||
/* anchor_spent will get called, we match against close_tx there. */
|
||||
}
|
||||
void peer_unwatch_close_timeout(struct peer *peer, enum state_input timedout)
|
||||
{
|
||||
assert(peer->close_watch_timeout);
|
||||
peer->close_watch_timeout = tal_free(peer->close_watch_timeout);
|
||||
}
|
||||
bool peer_watch_our_htlc_outputs(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
enum state_input tous_timeout,
|
||||
enum state_input tothem_spent,
|
||||
enum state_input tothem_timeout)
|
||||
{
|
||||
if (committed_to_htlcs(peer))
|
||||
FIXME_STUB(peer);
|
||||
return false;
|
||||
}
|
||||
bool peer_watch_their_htlc_outputs(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
enum state_input tous_timeout,
|
||||
enum state_input tothem_spent,
|
||||
enum state_input tothem_timeout)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
}
|
||||
void peer_unwatch_htlc_output(struct peer *peer,
|
||||
const struct htlc_onchain *htlc_onchain,
|
||||
enum state_input all_done)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
}
|
||||
void peer_unwatch_all_htlc_outputs(struct peer *peer)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
}
|
||||
void peer_watch_htlc_spend(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
const struct htlc_onchain *htlc_onchain,
|
||||
enum state_input done)
|
||||
{
|
||||
/* FIXME! */
|
||||
}
|
||||
void peer_unwatch_htlc_spend(struct peer *peer,
|
||||
const struct htlc_onchain *htlc_onchain,
|
||||
enum state_input all_done)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
}
|
||||
void peer_unexpected_pkt(struct peer *peer, const Pkt *pkt)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
}
|
||||
|
||||
/* An on-chain transaction revealed an R value. */
|
||||
void peer_tx_revealed_r_value(struct peer *peer, const struct htlc_onchain *htlc_onchain)
|
||||
{
|
||||
FIXME_STUB(peer);
|
||||
}
|
||||
|
||||
void peer_watch_htlcs_cleared(struct peer *peer,
|
||||
enum state_input all_done)
|
||||
{
|
||||
@@ -2477,6 +2299,7 @@ static void json_disconnect(struct command *cmd,
|
||||
* one side to freak out. We just ensure we ignore it. */
|
||||
log_debug(peer->log, "Pretending connection is closed");
|
||||
peer->fake_close = true;
|
||||
peer->state = STATE_ERR_BREAKDOWN;
|
||||
peer_breakdown(peer);
|
||||
|
||||
command_success(cmd, null_response(cmd));
|
||||
|
||||
521
state.c
521
state.c
@@ -39,14 +39,6 @@ static enum command_status unchanged_state(enum command_status cstatus)
|
||||
return cstatus;
|
||||
}
|
||||
|
||||
/* This may not actually change the state. */
|
||||
static enum command_status next_state_bits(struct peer *peer,
|
||||
enum command_status cstatus,
|
||||
unsigned int bits)
|
||||
{
|
||||
return next_state_nocheck(peer, cstatus, BITS_TO_STATE(bits));
|
||||
}
|
||||
|
||||
static void set_peer_cond(struct peer *peer, enum state_peercond cond)
|
||||
{
|
||||
assert(peer->cond != cond);
|
||||
@@ -91,7 +83,6 @@ enum command_status state(struct peer *peer,
|
||||
const union input *idata,
|
||||
const struct bitcoin_tx **broadcast)
|
||||
{
|
||||
const struct bitcoin_tx *tx;
|
||||
Pkt *err;
|
||||
enum command_status cstatus = CMD_NONE;
|
||||
|
||||
@@ -121,16 +112,15 @@ enum command_status state(struct peer *peer,
|
||||
err = accept_pkt_open(peer, idata->pkt);
|
||||
if (err) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto err_close_nocleanup;
|
||||
goto err_breakdown;
|
||||
}
|
||||
return next_state(peer, cstatus, STATE_OPEN_WAIT_FOR_ANCHOR);
|
||||
} else if (input_is(input, CMD_CLOSE)
|
||||
|| input_is(input, INPUT_CONNECTION_LOST)) {
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto instant_close;
|
||||
goto breakdown;
|
||||
} else if (input_is_pkt(input)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto unexpected_pkt_nocleanup;
|
||||
goto unexpected_pkt;
|
||||
}
|
||||
break;
|
||||
case STATE_OPEN_WAIT_FOR_OPEN_WITHANCHOR:
|
||||
@@ -138,18 +128,17 @@ enum command_status state(struct peer *peer,
|
||||
err = accept_pkt_open(peer, idata->pkt);
|
||||
if (err) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto err_close_nocleanup;
|
||||
goto err_breakdown;
|
||||
}
|
||||
bitcoin_create_anchor(peer, BITCOIN_ANCHOR_CREATED);
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAIT_FOR_ANCHOR_CREATE);
|
||||
} else if (input_is(input, CMD_CLOSE)
|
||||
|| input_is(input, INPUT_CONNECTION_LOST)) {
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto instant_close;
|
||||
goto breakdown;
|
||||
} else if (input_is_pkt(input)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto unexpected_pkt_nocleanup;
|
||||
goto unexpected_pkt;
|
||||
}
|
||||
break;
|
||||
case STATE_OPEN_WAIT_FOR_ANCHOR_CREATE:
|
||||
@@ -157,15 +146,14 @@ enum command_status state(struct peer *peer,
|
||||
queue_pkt_anchor(peer);
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAIT_FOR_COMMIT_SIG);
|
||||
} else if (input_is(input, CMD_CLOSE)
|
||||
|| input_is(input, INPUT_CONNECTION_LOST)) {
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
bitcoin_release_anchor(peer, BITCOIN_ANCHOR_CREATED);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto instant_close;
|
||||
goto breakdown;
|
||||
} else if (input_is_pkt(input)) {
|
||||
bitcoin_release_anchor(peer, BITCOIN_ANCHOR_CREATED);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto unexpected_pkt_nocleanup;
|
||||
goto unexpected_pkt;
|
||||
}
|
||||
break;
|
||||
case STATE_OPEN_WAIT_FOR_ANCHOR:
|
||||
@@ -173,25 +161,21 @@ enum command_status state(struct peer *peer,
|
||||
err = accept_pkt_anchor(peer, idata->pkt);
|
||||
if (err) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto err_close_nocleanup;
|
||||
goto err_breakdown;
|
||||
}
|
||||
queue_pkt_open_commit_sig(peer);
|
||||
peer_watch_anchor(peer,
|
||||
BITCOIN_ANCHOR_DEPTHOK,
|
||||
BITCOIN_ANCHOR_TIMEOUT,
|
||||
BITCOIN_ANCHOR_UNSPENT,
|
||||
BITCOIN_ANCHOR_THEIRSPEND,
|
||||
BITCOIN_ANCHOR_OTHERSPEND);
|
||||
BITCOIN_ANCHOR_TIMEOUT);
|
||||
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAITING_THEIRANCHOR);
|
||||
} else if (input_is(input, CMD_CLOSE)
|
||||
|| input_is(input, INPUT_CONNECTION_LOST)) {
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto instant_close;
|
||||
goto breakdown;
|
||||
} else if (input_is_pkt(input)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto unexpected_pkt_nocleanup;
|
||||
goto unexpected_pkt;
|
||||
}
|
||||
break;
|
||||
case STATE_OPEN_WAIT_FOR_COMMIT_SIG:
|
||||
@@ -200,26 +184,22 @@ enum command_status state(struct peer *peer,
|
||||
if (err) {
|
||||
bitcoin_release_anchor(peer, INPUT_NONE);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
}
|
||||
queue_tx_broadcast(broadcast, bitcoin_anchor(peer));
|
||||
peer_watch_anchor(peer,
|
||||
BITCOIN_ANCHOR_DEPTHOK,
|
||||
INPUT_NONE,
|
||||
BITCOIN_ANCHOR_UNSPENT,
|
||||
BITCOIN_ANCHOR_THEIRSPEND,
|
||||
BITCOIN_ANCHOR_OTHERSPEND);
|
||||
INPUT_NONE);
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAITING_OURANCHOR);
|
||||
} else if (input_is(input, CMD_CLOSE)
|
||||
|| input_is(input, INPUT_CONNECTION_LOST)) {
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
bitcoin_release_anchor(peer, INPUT_NONE);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto instant_close;
|
||||
goto breakdown;
|
||||
} else if (input_is_pkt(input)) {
|
||||
bitcoin_release_anchor(peer, INPUT_NONE);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto unexpected_pkt_nocleanup;
|
||||
goto unexpected_pkt;
|
||||
}
|
||||
break;
|
||||
case STATE_OPEN_WAITING_OURANCHOR:
|
||||
@@ -231,7 +211,7 @@ enum command_status state(struct peer *peer,
|
||||
peer_unwatch_anchor_depth(peer,
|
||||
BITCOIN_ANCHOR_DEPTHOK,
|
||||
INPUT_NONE);
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
}
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAITING_OURANCHOR_THEYCOMPLETED);
|
||||
@@ -246,19 +226,6 @@ enum command_status state(struct peer *peer,
|
||||
}
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAIT_FOR_COMPLETE_OURANCHOR);
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_UNSPENT)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto anchor_unspent;
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) {
|
||||
/* We no longer care about anchor depth. */
|
||||
peer_unwatch_anchor_depth(peer,
|
||||
BITCOIN_ANCHOR_DEPTHOK,
|
||||
INPUT_NONE);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto them_unilateral;
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_OTHERSPEND)) {
|
||||
/* This should be impossible. */
|
||||
return next_state(peer, cstatus, STATE_ERR_INFORMATION_LEAK);
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
/* We no longer care about anchor depth. */
|
||||
peer_unwatch_anchor_depth(peer,
|
||||
@@ -266,13 +233,6 @@ enum command_status state(struct peer *peer,
|
||||
INPUT_NONE);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
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)) {
|
||||
/* We no longer care about anchor depth. */
|
||||
peer_unwatch_anchor_depth(peer,
|
||||
@@ -298,7 +258,7 @@ enum command_status state(struct peer *peer,
|
||||
peer_unwatch_anchor_depth(peer,
|
||||
BITCOIN_ANCHOR_DEPTHOK,
|
||||
BITCOIN_ANCHOR_TIMEOUT);
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
}
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAITING_THEIRANCHOR_THEYCOMPLETED);
|
||||
@@ -317,20 +277,6 @@ enum command_status state(struct peer *peer,
|
||||
}
|
||||
return next_state(peer, cstatus,
|
||||
STATE_OPEN_WAIT_FOR_COMPLETE_THEIRANCHOR);
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_UNSPENT)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto anchor_unspent;
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_OTHERSPEND)) {
|
||||
/* This should be impossible. */
|
||||
return next_state(peer, cstatus,
|
||||
STATE_ERR_INFORMATION_LEAK);
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) {
|
||||
/* 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 them_unilateral;
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
/* We no longer care about anchor depth. */
|
||||
peer_unwatch_anchor_depth(peer,
|
||||
@@ -338,13 +284,6 @@ enum command_status state(struct peer *peer,
|
||||
BITCOIN_ANCHOR_TIMEOUT);
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
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)) {
|
||||
/* We no longer care about anchor depth. */
|
||||
peer_unwatch_anchor_depth(peer,
|
||||
@@ -372,23 +311,9 @@ enum command_status state(struct peer *peer,
|
||||
complete_cmd(peer, &cstatus, CMD_SUCCESS);
|
||||
return next_state(peer, cstatus, STATE_NORMAL);
|
||||
}
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_UNSPENT)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto anchor_unspent;
|
||||
/* Nobody should be able to spend anchor, except via the
|
||||
* commit txs. */
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_OTHERSPEND)) {
|
||||
return next_state(peer, cstatus,
|
||||
STATE_ERR_INFORMATION_LEAK);
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto them_unilateral;
|
||||
} else if (input_is(input, CMD_CLOSE)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
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)) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto accept_clearing;
|
||||
@@ -433,7 +358,7 @@ enum command_status state(struct peer *peer,
|
||||
err = accept_pkt_revocation(peer, idata->pkt);
|
||||
if (err) {
|
||||
complete_cmd(peer, &cstatus, CMD_FAIL);
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
}
|
||||
complete_cmd(peer, &cstatus, CMD_SUCCESS);
|
||||
return next_state(peer, cstatus, STATE_NORMAL);
|
||||
@@ -444,32 +369,24 @@ enum command_status state(struct peer *peer,
|
||||
} else if (input_is(input, PKT_UPDATE_ADD_HTLC)) {
|
||||
err = accept_pkt_htlc_add(peer, idata->pkt);
|
||||
if (err)
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, PKT_UPDATE_FULFILL_HTLC)) {
|
||||
err = accept_pkt_htlc_fulfill(peer, idata->pkt);
|
||||
if (err)
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, PKT_UPDATE_FAIL_HTLC)) {
|
||||
err = accept_pkt_htlc_fail(peer, idata->pkt);
|
||||
if (err)
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, PKT_UPDATE_COMMIT)) {
|
||||
err = accept_pkt_commit(peer, idata->pkt);
|
||||
if (err)
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
queue_pkt_revocation(peer);
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) {
|
||||
goto them_unilateral;
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_OTHERSPEND)) {
|
||||
goto old_commit_spotted;
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_UNSPENT)) {
|
||||
goto anchor_unspent;
|
||||
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
|
||||
goto start_unilateral_close;
|
||||
} else if (input_is(input, PKT_CLOSE_CLEARING)) {
|
||||
goto accept_clearing;
|
||||
} else if (input_is_pkt(input)) {
|
||||
@@ -481,7 +398,7 @@ enum command_status state(struct peer *peer,
|
||||
if (input_is(input, PKT_CLOSE_CLEARING)) {
|
||||
err = accept_pkt_close_clearing(peer, idata->pkt);
|
||||
if (err)
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
|
||||
/* Notify us when there are no more htlcs in
|
||||
* either commit tx */
|
||||
@@ -492,9 +409,7 @@ enum command_status state(struct peer *peer,
|
||||
} else if (input_is(input, CMD_SEND_HTLC_FAIL)
|
||||
|| input_is(input, CMD_SEND_HTLC_FULFILL)) {
|
||||
err = pkt_err(peer, "FIXME: cmd during clearing.");
|
||||
goto err_start_unilateral_close;
|
||||
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
|
||||
goto start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
} else if (input_is_pkt(input)) {
|
||||
/* FIXME: We must continue to allow add, fulfill & fail packets */
|
||||
goto unexpected_pkt;
|
||||
@@ -506,9 +421,7 @@ enum command_status state(struct peer *peer,
|
||||
} else if (input_is(input, CMD_SEND_HTLC_FAIL)
|
||||
|| input_is(input, CMD_SEND_HTLC_FULFILL)) {
|
||||
err = pkt_err(peer, "FIXME: cmd during clearing.");
|
||||
goto err_start_unilateral_close;
|
||||
} else if (input_is(input, INPUT_CONNECTION_LOST)) {
|
||||
goto start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
} else if (input_is_pkt(input)) {
|
||||
/* FIXME: We must continue to allow fulfill & fail packets */
|
||||
goto unexpected_pkt;
|
||||
@@ -520,7 +433,7 @@ enum command_status state(struct peer *peer,
|
||||
err = accept_pkt_close_sig(peer, idata->pkt,
|
||||
&acked, &we_agree);
|
||||
if (err)
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
|
||||
/* Are we about to offer the same fee they did? */
|
||||
if (we_agree) {
|
||||
@@ -531,9 +444,6 @@ enum command_status state(struct peer *peer,
|
||||
|
||||
/* Do fees now match? */
|
||||
if (acked) {
|
||||
peer_unwatch_close_timeout(peer,
|
||||
INPUT_CLOSE_COMPLETE_TIMEOUT);
|
||||
|
||||
/* Send close TX. */
|
||||
queue_tx_broadcast(broadcast,
|
||||
bitcoin_close(peer));
|
||||
@@ -546,245 +456,21 @@ enum command_status state(struct peer *peer,
|
||||
/* Offer the new fee. */
|
||||
queue_pkt_close_signature(peer);
|
||||
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)) {
|
||||
err = pkt_err(peer, "Close timed out");
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
} else if (input_is_pkt(input)) {
|
||||
goto unexpected_pkt;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Close states are regular: handle as a group. */
|
||||
case STATE_CLOSE_WAIT_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_CLOSE:
|
||||
case STATE_CLOSE_WAIT_STEAL_CLOSE:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL_OURCOMMIT:
|
||||
case STATE_CLOSE_WAIT_STEAL_OURCOMMIT_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_OURCOMMIT:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_OURCOMMIT_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_OURCOMMIT:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_OURCOMMIT_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_CLOSE_OURCOMMIT:
|
||||
case STATE_CLOSE_WAIT_STEAL_CLOSE_OURCOMMIT:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE_OURCOMMIT:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE_OURCOMMIT_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE_OURCOMMIT:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE_OURCOMMIT_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL_SPENDOURS:
|
||||
case STATE_CLOSE_WAIT_STEAL_SPENDOURS_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_SPENDOURS:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_SPENDOURS_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_SPENDOURS:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_SPENDOURS_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_CLOSE_SPENDOURS:
|
||||
case STATE_CLOSE_WAIT_STEAL_CLOSE_SPENDOURS:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE_SPENDOURS:
|
||||
case STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE_SPENDOURS_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE_SPENDOURS:
|
||||
case STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE_SPENDOURS_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_OURCOMMIT:
|
||||
case STATE_CLOSE_WAIT_OURCOMMIT_WITH_HTLCS:
|
||||
case STATE_CLOSE_WAIT_SPENDOURS:
|
||||
case STATE_CLOSE_WAIT_SPENDOURS_WITH_HTLCS: {
|
||||
unsigned int bits;
|
||||
enum state_input closed;
|
||||
|
||||
bits = STATE_TO_BITS(peer->state);
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Our steal is deep enough to forget? */
|
||||
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)
|
||||
peer_unwatch_all_htlc_outputs(peer);
|
||||
return next_state(peer, cstatus, STATE_CLOSED);
|
||||
}
|
||||
|
||||
/* Their commit is buried deep enough to forget? */
|
||||
if ((bits & STATE_CLOSE_THEIRCOMMIT_BIT)
|
||||
&& input_is(input, BITCOIN_THEIRCOMMIT_DONE)) {
|
||||
BUILD_ASSERT(!(STATE_TO_BITS(STATE_CLOSE_WAIT_HTLCS)
|
||||
& STATE_CLOSE_THEIRCOMMIT_BIT));
|
||||
return next_state(peer, cstatus, closed);
|
||||
}
|
||||
|
||||
/* Mutual close deep enough to forget? */
|
||||
if ((bits & STATE_CLOSE_CLOSE_BIT)
|
||||
&& input_is(input, BITCOIN_CLOSE_DONE)) {
|
||||
BUILD_ASSERT(!(STATE_TO_BITS(STATE_CLOSE_WAIT_HTLCS)
|
||||
& STATE_CLOSE_CLOSE_BIT));
|
||||
return next_state(peer, cstatus, closed);
|
||||
}
|
||||
|
||||
/* Our commit deep enough to spend our output? */
|
||||
if ((bits & STATE_CLOSE_OURCOMMIT_BIT)
|
||||
&& input_is(input, BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED)) {
|
||||
BUILD_ASSERT(!(STATE_TO_BITS(STATE_CLOSE_WAIT_HTLCS)
|
||||
& STATE_CLOSE_OURCOMMIT_BIT));
|
||||
/* FIXME: If our output was dust, just fire when
|
||||
* ourcommit deep enough to forget. */
|
||||
tx = bitcoin_spend_ours(peer);
|
||||
/* Now we need to wait for our commit to be done. */
|
||||
queue_tx_broadcast(broadcast, tx);
|
||||
peer_watch_tx(peer, tx, BITCOIN_SPEND_OURS_DONE);
|
||||
bits &= ~STATE_CLOSE_OURCOMMIT_BIT;
|
||||
bits |= STATE_CLOSE_SPENDOURS_BIT;
|
||||
return next_state(peer, cstatus, BITS_TO_STATE(bits));
|
||||
}
|
||||
|
||||
/* Our spend of ourcommit is deep enough to forget? */
|
||||
if ((bits & STATE_CLOSE_SPENDOURS_BIT)
|
||||
&& input_is(input, BITCOIN_SPEND_OURS_DONE)) {
|
||||
BUILD_ASSERT(!(STATE_TO_BITS(STATE_CLOSE_WAIT_HTLCS)
|
||||
& STATE_CLOSE_SPENDOURS_BIT));
|
||||
return next_state(peer, cstatus, closed);
|
||||
}
|
||||
|
||||
/* 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((BITS_TO_STATE(STATE_TO_BITS(STATE_CLOSE_WAIT_HTLCS) & ~STATE_CLOSE_HTLCS_BIT)) == STATE_CLOSED);
|
||||
bits &= ~STATE_CLOSE_HTLCS_BIT;
|
||||
return next_state(peer, cstatus,
|
||||
BITS_TO_STATE(bits));
|
||||
} else if (input_is(input, BITCOIN_HTLC_TOTHEM_SPENT)) {
|
||||
/* They revealed R value. */
|
||||
peer_tx_revealed_r_value(peer,
|
||||
idata->htlc_onchain);
|
||||
/* We don't care any more. */
|
||||
peer_unwatch_htlc_output(peer,
|
||||
idata->htlc_onchain,
|
||||
INPUT_NO_MORE_HTLCS);
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, BITCOIN_HTLC_TOTHEM_TIMEOUT)){
|
||||
tx = bitcoin_htlc_timeout(peer,
|
||||
idata->htlc_onchain);
|
||||
/* HTLC timed out, spend it back to us. */
|
||||
queue_tx_broadcast(broadcast, tx);
|
||||
/* Don't unwatch yet; they could yet
|
||||
* try to spend, revealing rvalue. */
|
||||
|
||||
/* We're done when that gets buried. */
|
||||
peer_watch_htlc_spend(peer, tx,
|
||||
idata->htlc_onchain,
|
||||
BITCOIN_HTLC_RETURN_SPEND_DONE);
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, INPUT_RVALUE)) {
|
||||
tx = bitcoin_htlc_spend(peer,
|
||||
idata->htlc_onchain);
|
||||
|
||||
/* Spend it... */
|
||||
queue_tx_broadcast(broadcast, tx);
|
||||
/* We're done when it gets buried. */
|
||||
peer_watch_htlc_spend(peer, tx,
|
||||
idata->htlc_onchain,
|
||||
BITCOIN_HTLC_FULFILL_SPEND_DONE);
|
||||
/* Don't care about this one any more. */
|
||||
peer_unwatch_htlc_output(peer,
|
||||
idata->htlc_onchain,
|
||||
INPUT_NO_MORE_HTLCS);
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, BITCOIN_HTLC_FULFILL_SPEND_DONE)) {
|
||||
/* Stop watching spend, send
|
||||
* INPUT_NO_MORE_HTLCS when done. */
|
||||
peer_unwatch_htlc_spend(peer,
|
||||
idata->htlc_onchain,
|
||||
INPUT_NO_MORE_HTLCS);
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, BITCOIN_HTLC_RETURN_SPEND_DONE)) {
|
||||
/* Stop watching spend, send
|
||||
* INPUT_NO_MORE_HTLCS when done. */
|
||||
peer_unwatch_htlc_spend(peer,
|
||||
idata->htlc_onchain,
|
||||
INPUT_NO_MORE_HTLCS);
|
||||
|
||||
/* Don't need to watch the HTLC output any more,
|
||||
* either. */
|
||||
peer_unwatch_htlc_output(peer,
|
||||
idata->htlc_onchain,
|
||||
INPUT_NO_MORE_HTLCS);
|
||||
return unchanged_state(cstatus);
|
||||
} else if (input_is(input, BITCOIN_HTLC_TOUS_TIMEOUT)) {
|
||||
/* They can spend, we no longer care
|
||||
* about this HTLC. */
|
||||
peer_unwatch_htlc_output(peer,
|
||||
idata->htlc_onchain,
|
||||
INPUT_NO_MORE_HTLCS);
|
||||
return unchanged_state(cstatus);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're just waiting for HTLCs, anything else is an error */
|
||||
if (peer->state == STATE_CLOSE_WAIT_HTLCS)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Now, other side can always spring a commit transaction on
|
||||
* us (they might have two valid ones, if they didn't send
|
||||
* revocation preimage yet, so always allow it).
|
||||
*/
|
||||
if (input_is(input, BITCOIN_ANCHOR_THEIRSPEND)) {
|
||||
peer_watch_tx(peer, idata->tx, BITCOIN_THEIRCOMMIT_DONE);
|
||||
|
||||
/* HTLC watches: if any, set HTLCs bit. */
|
||||
if (peer_watch_their_htlc_outputs(peer, idata->tx,
|
||||
BITCOIN_HTLC_TOUS_TIMEOUT,
|
||||
BITCOIN_HTLC_TOTHEM_SPENT,
|
||||
BITCOIN_HTLC_TOTHEM_TIMEOUT))
|
||||
bits |= STATE_CLOSE_HTLCS_BIT;
|
||||
|
||||
bits |= STATE_CLOSE_THEIRCOMMIT_BIT;
|
||||
return next_state_bits(peer, cstatus, bits);
|
||||
/* This can happen multiple times: need to steal ALL */
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_OTHERSPEND)) {
|
||||
tx = bitcoin_steal(peer, idata->ci);
|
||||
if (!tx)
|
||||
return next_state(peer, cstatus,
|
||||
STATE_ERR_INFORMATION_LEAK);
|
||||
queue_tx_broadcast(broadcast, tx);
|
||||
peer_watch_tx(peer, tx, BITCOIN_STEAL_DONE);
|
||||
bits |= STATE_CLOSE_STEAL_BIT;
|
||||
return next_state_bits(peer, cstatus, bits);
|
||||
} else if (input_is(input, BITCOIN_ANCHOR_UNSPENT))
|
||||
goto anchor_unspent;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Should never happen. */
|
||||
case STATE_ERR_INTERNAL:
|
||||
case STATE_ERR_INFORMATION_LEAK:
|
||||
case STATE_ERR_ANCHOR_TIMEOUT:
|
||||
case STATE_ERR_ANCHOR_LOST:
|
||||
case STATE_ERR_BREAKDOWN:
|
||||
case STATE_CLOSE_WAIT_CLOSE:
|
||||
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:
|
||||
case STATE_CLOSE_ONCHAIN_CHEATED:
|
||||
case STATE_CLOSE_ONCHAIN_THEIR_UNILATERAL:
|
||||
case STATE_CLOSE_ONCHAIN_OUR_UNILATERAL:
|
||||
@@ -796,108 +482,18 @@ enum command_status state(struct peer *peer,
|
||||
return next_state(peer, cstatus, STATE_ERR_INTERNAL);
|
||||
|
||||
unexpected_pkt:
|
||||
/*
|
||||
* We got a weird packet, so we need to close unilaterally.
|
||||
*/
|
||||
peer_unexpected_pkt(peer, idata->pkt);
|
||||
|
||||
/* Don't reply to an error with an error. */
|
||||
if (input_is(input, PKT_ERROR)) {
|
||||
goto start_unilateral_close;
|
||||
if (!input_is(input, PKT_ERROR)) {
|
||||
goto breakdown;
|
||||
}
|
||||
err = pkt_err_unexpected(peer, idata->pkt);
|
||||
goto err_start_unilateral_close;
|
||||
|
||||
unexpected_pkt_nocleanup:
|
||||
/*
|
||||
* Unexpected packet, but nothing sent to chain yet, so no cleanup.
|
||||
*/
|
||||
/* Don't reply to an error with an error. */
|
||||
if (input_is(input, PKT_ERROR)) {
|
||||
goto close_nocleanup;
|
||||
}
|
||||
err = pkt_err_unexpected(peer, idata->pkt);
|
||||
goto err_close_nocleanup;
|
||||
|
||||
anchor_unspent:
|
||||
/*
|
||||
* Bitcoind tells us anchor got double-spent. If we double-spent it
|
||||
* then we're malfunctioning. If they double-spent it, then they
|
||||
* managed to cheat us: post_to_reddit();
|
||||
*/
|
||||
return next_state(peer, cstatus, STATE_ERR_ANCHOR_LOST);
|
||||
|
||||
err_close_nocleanup:
|
||||
/*
|
||||
* Something went wrong, but we haven't sent anything to the blockchain
|
||||
* so there's nothing to clean up.
|
||||
*/
|
||||
|
||||
err_breakdown:
|
||||
queue_pkt_err(peer, err);
|
||||
|
||||
close_nocleanup:
|
||||
change_peer_cond(peer, PEER_CMD_OK, PEER_CLOSED);
|
||||
return next_state(peer, cstatus, STATE_CLOSED);
|
||||
|
||||
err_start_unilateral_close:
|
||||
/*
|
||||
* They timed out, or were broken; we are going to close unilaterally.
|
||||
*/
|
||||
queue_pkt_err(peer, err);
|
||||
|
||||
start_unilateral_close:
|
||||
/*
|
||||
* Close unilaterally.
|
||||
*/
|
||||
|
||||
/* No more inputs, no more commands. */
|
||||
set_peer_cond(peer, PEER_CLOSED);
|
||||
|
||||
/*
|
||||
* If they sent us a close tx, that's always cheaper than
|
||||
* broadcasting our last commit tx, and our funds are not
|
||||
* timelocked.
|
||||
*/
|
||||
if (peer_has_close_sig(peer)) {
|
||||
queue_tx_broadcast(broadcast, bitcoin_close(peer));
|
||||
return next_state(peer, cstatus, STATE_CLOSE_WAIT_CLOSE);
|
||||
}
|
||||
|
||||
tx = bitcoin_commit(peer);
|
||||
queue_tx_broadcast(broadcast, tx);
|
||||
peer_watch_delayed(peer, tx, BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED);
|
||||
|
||||
/* HTLC watches. */
|
||||
if (peer_watch_our_htlc_outputs(peer, tx,
|
||||
BITCOIN_HTLC_TOUS_TIMEOUT,
|
||||
BITCOIN_HTLC_TOTHEM_SPENT,
|
||||
BITCOIN_HTLC_TOTHEM_TIMEOUT))
|
||||
return next_state(peer, cstatus,
|
||||
STATE_CLOSE_WAIT_OURCOMMIT_WITH_HTLCS);
|
||||
|
||||
return next_state(peer, cstatus, STATE_CLOSE_WAIT_OURCOMMIT);
|
||||
|
||||
them_unilateral:
|
||||
assert(input == BITCOIN_ANCHOR_THEIRSPEND);
|
||||
|
||||
/*
|
||||
* Bitcoind tells us they did unilateral close.
|
||||
*/
|
||||
queue_pkt_err(peer, pkt_err(peer, "Commit tx noticed"));
|
||||
|
||||
/* No more inputs, no more commands. */
|
||||
set_peer_cond(peer, PEER_CLOSED);
|
||||
peer_watch_tx(peer, idata->tx, BITCOIN_THEIRCOMMIT_DONE);
|
||||
|
||||
/* HTLC watches (based on what they broadcast, which *may* be out
|
||||
* of step with our current state by +/- 1 htlc. */
|
||||
if (peer_watch_their_htlc_outputs(peer, idata->tx,
|
||||
BITCOIN_HTLC_TOUS_TIMEOUT,
|
||||
BITCOIN_HTLC_TOTHEM_SPENT,
|
||||
BITCOIN_HTLC_TOTHEM_TIMEOUT))
|
||||
return next_state(peer, cstatus,
|
||||
STATE_CLOSE_WAIT_THEIRCOMMIT_WITH_HTLCS);
|
||||
|
||||
return next_state(peer, cstatus, STATE_CLOSE_WAIT_THEIRCOMMIT);
|
||||
breakdown:
|
||||
return next_state(peer, cstatus, STATE_ERR_BREAKDOWN);
|
||||
|
||||
start_clearing:
|
||||
/*
|
||||
@@ -913,14 +509,13 @@ start_clearing:
|
||||
start_closing_cleared:
|
||||
/* As soon as we send packet, they could close. */
|
||||
peer_calculate_close_fee(peer);
|
||||
peer_watch_close(peer, BITCOIN_CLOSE_DONE, INPUT_CLOSE_COMPLETE_TIMEOUT);
|
||||
queue_pkt_close_signature(peer);
|
||||
return next_state(peer, cstatus, STATE_WAIT_FOR_CLOSE_SIG);
|
||||
|
||||
accept_clearing:
|
||||
err = accept_pkt_close_clearing(peer, idata->pkt);
|
||||
if (err)
|
||||
goto err_start_unilateral_close;
|
||||
goto err_breakdown;
|
||||
|
||||
/* Notify us when there are no more htlcs in either commit tx */
|
||||
peer_watch_htlcs_cleared(peer, INPUT_HTLCS_CLEARED);
|
||||
@@ -932,36 +527,4 @@ accept_clearing:
|
||||
queue_pkt_close_clearing(peer);
|
||||
|
||||
return next_state(peer, cstatus, STATE_BOTH_CLEARING);
|
||||
|
||||
instant_close:
|
||||
/*
|
||||
* Closing, but we haven't sent anything to the blockchain so
|
||||
* there's nothing to clean up.
|
||||
*/
|
||||
/* FIXME: Should we tell other side we're going? */
|
||||
set_peer_cond(peer, PEER_CLOSED);
|
||||
|
||||
/* We can't have any HTLCs, since we haven't started. */
|
||||
if (committed_to_htlcs(peer))
|
||||
return next_state(peer, cstatus, STATE_ERR_INTERNAL);
|
||||
|
||||
return next_state(peer, cstatus, STATE_CLOSED);
|
||||
|
||||
old_commit_spotted:
|
||||
/*
|
||||
* bitcoind reported a broadcast of the not-latest commit tx.
|
||||
*/
|
||||
queue_pkt_err(peer, pkt_err(peer, "Otherspend noticed"));
|
||||
|
||||
/* No more packets, no more commands. */
|
||||
set_peer_cond(peer, PEER_CLOSED);
|
||||
|
||||
/* If we can't find it, we're lost. */
|
||||
tx = bitcoin_steal(peer, idata->ci);
|
||||
if (!tx)
|
||||
return next_state(peer, cstatus,
|
||||
STATE_ERR_INFORMATION_LEAK);
|
||||
queue_tx_broadcast(broadcast, tx);
|
||||
peer_watch_tx(peer, tx, BITCOIN_STEAL_DONE);
|
||||
return next_state(peer, cstatus, STATE_CLOSE_WAIT_STEAL);
|
||||
}
|
||||
|
||||
146
state.h
146
state.h
@@ -121,41 +121,18 @@ Pkt *accept_pkt_close_clearing(struct peer *peer, const Pkt *pkt);
|
||||
Pkt *accept_pkt_close_sig(struct peer *peer, const Pkt *pkt,
|
||||
bool *acked, bool *we_agree);
|
||||
|
||||
/**
|
||||
* committed_to_htlcs: do we have any locked-in HTLCs?
|
||||
* @peer: 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 peer *peer);
|
||||
|
||||
/**
|
||||
* peer_has_close_sig: do we have a valid close_sig from them?
|
||||
* @peer: the state data for this peer.
|
||||
*
|
||||
* We use any acceptable close tx, if we have one, in preference to a commit tx.
|
||||
*/
|
||||
bool peer_has_close_sig(const struct peer *peer);
|
||||
|
||||
/**
|
||||
* peer_watch_anchor: create a watch for the anchor transaction.
|
||||
* @peer: the state data for this peer.
|
||||
* @depthok: the input to give when anchor reaches expected depth.
|
||||
* @timeout: the input to give if anchor doesn't reach depth in time.
|
||||
* @unspent: the input to give if anchor is unspent after @depthok.
|
||||
* @theyspent: the input to give if they spend anchor with their commit tx.
|
||||
* @otherspent: the input to give if they spend anchor otherwise.
|
||||
*
|
||||
* @depthok can be INPUT_NONE if it's our anchor (we don't time
|
||||
* ourselves out).
|
||||
*/
|
||||
void peer_watch_anchor(struct peer *peer,
|
||||
enum state_input depthok,
|
||||
enum state_input timeout,
|
||||
enum state_input unspent,
|
||||
enum state_input theyspent,
|
||||
enum state_input otherspent);
|
||||
|
||||
enum state_input timeout);
|
||||
/**
|
||||
* peer_unwatch_anchor_depth: remove depth watch for the anchor.
|
||||
* @peer: the state data for this peer.
|
||||
@@ -168,127 +145,6 @@ void peer_unwatch_anchor_depth(struct peer *peer,
|
||||
enum state_input depthok,
|
||||
enum state_input timeout);
|
||||
|
||||
/**
|
||||
* peer_watch_delayed: watch this (commit) tx, tell me when I can spend it
|
||||
* @peer: the state data for this peer.
|
||||
* @tx: the tx we're watching.
|
||||
* @canspend: the input to give when commit reaches spendable depth.
|
||||
*
|
||||
* Note that this tx may be malleated, as it's dual-signed.
|
||||
*/
|
||||
void peer_watch_delayed(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
enum state_input canspend);
|
||||
|
||||
/**
|
||||
* peer_watch_tx: watch this tx until it's "irreversible"
|
||||
* @peer: the state data for this peer.
|
||||
* @tx: the tx we're watching.
|
||||
* @done: the input to give when tx is completely buried.
|
||||
*
|
||||
* Once this fires we consider the channel completely closed and stop
|
||||
* watching (eg 100 txs down).
|
||||
*
|
||||
* This is used for watching a transaction we sent (such as a steal,
|
||||
* or spend of their close, etc).
|
||||
*/
|
||||
void peer_watch_tx(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
enum state_input done);
|
||||
|
||||
/**
|
||||
* peer_watch_close: watch for close tx until it's "irreversible" (or timedout)
|
||||
* @peer: the state data for this peer.
|
||||
* @done: the input to give when tx is completely buried.
|
||||
* @timedout: the input to give if we time out (they don't provide sig).
|
||||
*
|
||||
* Once this fires we consider the channel completely closed and stop
|
||||
* watching (eg 100 txs down).
|
||||
*
|
||||
* This is used for watching a mutual close.
|
||||
*/
|
||||
void peer_watch_close(struct peer *peer,
|
||||
enum state_input done, enum state_input timedout);
|
||||
|
||||
/**
|
||||
* peer_unwatch_close_timeout: remove timeout for the close transaction
|
||||
* @peer: the state data for this peer.
|
||||
* @timeout: the input to give if anchor doesn't reach depth in time.
|
||||
*
|
||||
* This is called once we have successfully received their signature.
|
||||
*/
|
||||
void peer_unwatch_close_timeout(struct peer *peer, enum state_input timedout);
|
||||
|
||||
/**
|
||||
* peer_watch_our_htlc_outputs: HTLC outputs from our commit tx to watch.
|
||||
* @peer: 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.
|
||||
*
|
||||
* Returns true if there were any htlc outputs to watch.
|
||||
*/
|
||||
bool peer_watch_our_htlc_outputs(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
enum state_input tous_timeout,
|
||||
enum state_input tothem_spent,
|
||||
enum state_input tothem_timeout);
|
||||
|
||||
/**
|
||||
* peer_watch_their_htlc_outputs: HTLC outputs from their commit tx to watch.
|
||||
* @peer: 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.
|
||||
*
|
||||
* Returns true if there were any htlc outputs to watch.
|
||||
*/
|
||||
bool peer_watch_their_htlc_outputs(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
enum state_input tous_timeout,
|
||||
enum state_input tothem_spent,
|
||||
enum state_input tothem_timeout);
|
||||
|
||||
/**
|
||||
* peer_unwatch_htlc_output: stop watching an HTLC
|
||||
* @peer: the state data for this peer.
|
||||
* @htlc_onchain: the htlc to stop watching
|
||||
* @all_done: input to give if we're not watching any outputs anymore.
|
||||
*/
|
||||
void peer_unwatch_htlc_output(struct peer *peer,
|
||||
const struct htlc_onchain *htlc_onchain,
|
||||
enum state_input all_done);
|
||||
|
||||
/**
|
||||
* peer_unwatch_all_htlc_outputs: stop watching all HTLCs
|
||||
* @peer: the state data for this peer.
|
||||
*/
|
||||
void peer_unwatch_all_htlc_outputs(struct peer *peer);
|
||||
|
||||
/**
|
||||
* peer_watch_htlc_spend: watch our spend of an HTLC output
|
||||
* @peer: the state data for this peer.
|
||||
* @tx: the commitment tx
|
||||
* @htlc_onchain: the htlc the tx is spending an output of
|
||||
* @done: input to give when it's completely buried.
|
||||
*/
|
||||
void peer_watch_htlc_spend(struct peer *peer,
|
||||
const struct bitcoin_tx *tx,
|
||||
const struct htlc_onchain *htlc_onchain,
|
||||
enum state_input done);
|
||||
|
||||
/**
|
||||
* peer_unwatch_htlc_spend: stop watching our HTLC spend
|
||||
* @peer: the state data for this peer.
|
||||
* @htlc_onchain: the htlc to stop watching the spend for.
|
||||
* @all_done: input to give if we're not watching anything anymore.
|
||||
*/
|
||||
void peer_unwatch_htlc_spend(struct peer *peer,
|
||||
const struct htlc_onchain *htlc_onchain,
|
||||
enum state_input all_done);
|
||||
|
||||
/**
|
||||
* peer_watch_htlcs_cleared: tell us when no HTLCs are in commit txs.
|
||||
* @peer: the state data for this peer.
|
||||
|
||||
161
state_types.h
161
state_types.h
@@ -4,13 +4,6 @@
|
||||
/* FIXME: cdump is really dumb, so we put these in their own header. */
|
||||
#include "lightning.pb-c.h"
|
||||
|
||||
#define STATE_CLOSE_HTLCS_BIT 1
|
||||
#define STATE_CLOSE_STEAL_BIT 2
|
||||
#define STATE_CLOSE_THEIRCOMMIT_BIT 4
|
||||
#define STATE_CLOSE_CLOSE_BIT 8
|
||||
#define STATE_CLOSE_OURCOMMIT_BIT 16
|
||||
#define STATE_CLOSE_SPENDOURS_BIT 32
|
||||
|
||||
enum state {
|
||||
STATE_INIT,
|
||||
|
||||
@@ -44,112 +37,11 @@ enum state {
|
||||
STATE_BOTH_CLEARING,
|
||||
/* We're cleared, waiting for close signature / negotiation */
|
||||
STATE_WAIT_FOR_CLOSE_SIG,
|
||||
|
||||
/* We've broadcast the mutual close, waiting for onchain. */
|
||||
STATE_CLOSE_WAIT_CLOSE,
|
||||
|
||||
/* 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
|
||||
* their funds (steal). We also track their latest commit tx (no need
|
||||
* to spend our output, it's just a P2WPKH for us) (their_commit).
|
||||
* They can also (with our help) broadcast a mutual close tx
|
||||
* (mutual_close).
|
||||
*
|
||||
* We can also broadcast one of the following:
|
||||
* 1) Our latest commit tx (our_commit).
|
||||
* 2) After delay has passed, spend of our tx (spend_ours).
|
||||
* 3) Mutual close tx (mutual_close), already covered above.
|
||||
*
|
||||
* Thus, we could be waiting for the following combinations:
|
||||
* - steal
|
||||
* - their_commit
|
||||
* - steal + their_commit
|
||||
* - mutual_close
|
||||
* - steal + mutual_close
|
||||
* - their_commit + mutual_close
|
||||
* - steal + their_commit + mutual_close
|
||||
*
|
||||
* - our_commit
|
||||
* - steal + our_commit
|
||||
* - their_commit + our_commit
|
||||
* - steal + their_commit + our_commit
|
||||
* - mutual_close + our_commit
|
||||
* - steal + mutual_close + our_commit
|
||||
* - their_commit + mutual_close + our_commit
|
||||
* - steal + their_commit + mutual_close + our_commit
|
||||
*
|
||||
* - spend_ours
|
||||
* - steal + spend_ours
|
||||
* - their_commit + spend_ours
|
||||
* - steal + their_commit + spend_ours
|
||||
* - mutual_close + spend_ours
|
||||
* - steal + mutual_close + spend_ours
|
||||
* - their_commit + mutual_close + spend_ours
|
||||
* - steal + their_commit + 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 THEIRCOMMIT, 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_THEIRCOMMIT,
|
||||
STATE_CLOSE_WAIT_THEIRCOMMIT_WITH_HTLCS,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_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_THEIRCOMMIT_CLOSE,
|
||||
STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE_WITH_HTLCS,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_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_THEIRCOMMIT_OURCOMMIT,
|
||||
STATE_CLOSE_WAIT_THEIRCOMMIT_OURCOMMIT_WITH_HTLCS,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_OURCOMMIT,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_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_THEIRCOMMIT_CLOSE_OURCOMMIT,
|
||||
STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE_OURCOMMIT_WITH_HTLCS,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE_OURCOMMIT,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_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_THEIRCOMMIT_SPENDOURS,
|
||||
STATE_CLOSE_WAIT_THEIRCOMMIT_SPENDOURS_WITH_HTLCS,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_SPENDOURS,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_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_THEIRCOMMIT_CLOSE_SPENDOURS,
|
||||
STATE_CLOSE_WAIT_THEIRCOMMIT_CLOSE_SPENDOURS_WITH_HTLCS,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE_SPENDOURS,
|
||||
STATE_CLOSE_WAIT_STEAL_THEIRCOMMIT_CLOSE_SPENDOURS_WITH_HTLCS,
|
||||
|
||||
/* Four states to represent closing onchain (for getpeers) */
|
||||
STATE_CLOSE_ONCHAIN_CHEATED,
|
||||
@@ -160,12 +52,11 @@ enum state {
|
||||
/*
|
||||
* Where angels fear to tread.
|
||||
*/
|
||||
/* Bad packet from them / protocol breakdown. */
|
||||
STATE_ERR_BREAKDOWN,
|
||||
/* Their anchor didn't reach blockchain in reasonable time. */
|
||||
STATE_ERR_ANCHOR_TIMEOUT,
|
||||
/* Anchor was double-spent, after both considered it sufficient depth. */
|
||||
STATE_ERR_ANCHOR_LOST,
|
||||
/* A commitment tx we didn't recognise spent the anchor (impossible) */
|
||||
STATE_ERR_INFORMATION_LEAK,
|
||||
/* We ended up in an unexpected state. */
|
||||
STATE_ERR_INTERNAL,
|
||||
|
||||
@@ -213,37 +104,6 @@ enum state_input {
|
||||
BITCOIN_ANCHOR_DEPTHOK,
|
||||
/* It didn't reach the required depth in time. */
|
||||
BITCOIN_ANCHOR_TIMEOUT,
|
||||
/* It reached the required depth, then was forked off. */
|
||||
BITCOIN_ANCHOR_UNSPENT,
|
||||
/* Anchor was spent by our commit, and we can now spend it. */
|
||||
BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED,
|
||||
/* Anchor was spent by their commit tx. */
|
||||
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,
|
||||
|
||||
/* Their commit tx is completely buried. */
|
||||
BITCOIN_THEIRCOMMIT_DONE,
|
||||
/* Our spend of our own tx is completely buried. */
|
||||
BITCOIN_SPEND_OURS_DONE,
|
||||
/* Our spend of their revoked tx is completely buried. */
|
||||
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,
|
||||
|
||||
/* No more HTLCs in either commitment tx. */
|
||||
INPUT_HTLCS_CLEARED,
|
||||
|
||||
@@ -252,14 +112,6 @@ enum state_input {
|
||||
*/
|
||||
INPUT_CLOSE_COMPLETE_TIMEOUT,
|
||||
|
||||
/*
|
||||
* Inject a known R value.
|
||||
*
|
||||
* In normal operation, use CMD_SEND_HTLC_FULFILL; this is for
|
||||
* after a unilateral close.
|
||||
*/
|
||||
INPUT_RVALUE,
|
||||
|
||||
/* Commands */
|
||||
CMD_OPEN_WITH_ANCHOR,
|
||||
CMD_OPEN_WITHOUT_ANCHOR,
|
||||
@@ -269,9 +121,6 @@ enum state_input {
|
||||
CMD_SEND_COMMIT,
|
||||
CMD_CLOSE,
|
||||
|
||||
/* Connection lost/timedout with other node. */
|
||||
INPUT_CONNECTION_LOST,
|
||||
|
||||
INPUT_MAX
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user