Browse Source

state: don't spend the "to-us" output from their commit tx.

There's no reason to, it's a simple p2wpkh to our key.

We still spend the "to-us" from our commit tx, since it could be
theoretically be stolen by the revocation value, and it's a complex
p2wsh which a normal wallet won't have the information to spend.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
eb5d832963
  1. 9
      daemon/peer.c
  2. 85
      state.c
  3. 7
      state.h
  4. 87
      state_types.h

9
daemon/peer.c

@ -1086,7 +1086,7 @@ bool peer_watch_our_htlc_outputs(struct peer *peer,
return false;
}
bool peer_watch_their_htlc_outputs(struct peer *peer,
const struct bitcoin_event *tx,
const struct bitcoin_tx *tx,
enum state_input tous_timeout,
enum state_input tothem_spent,
enum state_input tothem_timeout)
@ -1222,13 +1222,6 @@ const struct bitcoin_tx *bitcoin_spend_ours(struct peer *peer)
return tx;
}
/* Create a bitcoin spend tx (to spend their commit's outputs) */
const struct bitcoin_tx *bitcoin_spend_theirs(const struct peer *peer,
const struct bitcoin_event *btc)
{
FIXME_STUB(peer);
}
/* Create a bitcoin steal tx (to steal all their commit's outputs) */
const struct bitcoin_tx *bitcoin_steal(const struct peer *peer,
struct bitcoin_event *btc)

85
state.c

@ -559,40 +559,40 @@ enum command_status state(struct peer *peer,
/* 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_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_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_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_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_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_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_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_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_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_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_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:
@ -609,6 +609,7 @@ enum command_status state(struct peer *peer,
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
@ -618,13 +619,15 @@ enum command_status state(struct peer *peer,
return next_state(peer, cstatus, STATE_CLOSED);
}
if ((bits & STATE_CLOSE_SPENDTHEM_BIT)
&& input_is(input, BITCOIN_SPEND_THEIRS_DONE)) {
/* 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_SPENDTHEM_BIT));
& 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)
@ -632,10 +635,13 @@ enum command_status state(struct peer *peer,
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);
@ -645,6 +651,7 @@ enum command_status state(struct peer *peer,
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)
@ -732,21 +739,21 @@ enum command_status state(struct peer *peer,
break;
/*
* Now, other side can always spring a commit transaction on us
* (even if they already have, due to tx malleability).
* 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)) {
tx = bitcoin_spend_theirs(peer, idata->btc);
queue_tx_broadcast(broadcast, tx);
peer_watch_tx(peer, tx, BITCOIN_SPEND_THEIRS_DONE);
peer_watch_tx(peer, idata->tx, BITCOIN_THEIRCOMMIT_DONE);
/* HTLC watches: if any, set HTLCs bit. */
if (peer_watch_their_htlc_outputs(peer, idata->btc,
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_SPENDTHEM_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)) {
@ -875,20 +882,18 @@ them_unilateral:
/* No more inputs, no more commands. */
set_peer_cond(peer, PEER_CLOSED);
tx = bitcoin_spend_theirs(peer, idata->btc);
queue_tx_broadcast(broadcast, tx);
peer_watch_tx(peer, tx, BITCOIN_SPEND_THEIRS_DONE);
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->btc,
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_SPENDTHEM_WITH_HTLCS);
STATE_CLOSE_WAIT_THEIRCOMMIT_WITH_HTLCS);
return next_state(peer, cstatus, STATE_CLOSE_WAIT_SPENDTHEM);
return next_state(peer, cstatus, STATE_CLOSE_WAIT_THEIRCOMMIT);
start_clearing:
/*

7
state.h

@ -31,6 +31,7 @@ union input {
Pkt *pkt;
struct command *cmd;
struct bitcoin_event *btc;
struct bitcoin_tx *tx;
struct htlc_progress *htlc_prog;
struct htlc_onchain {
/* Which commitment we using. */
@ -245,7 +246,7 @@ bool peer_watch_our_htlc_outputs(struct peer *peer,
* Returns true if there were any htlc outputs to watch.
*/
bool peer_watch_their_htlc_outputs(struct peer *peer,
const struct bitcoin_event *tx,
const struct bitcoin_tx *tx,
enum state_input tous_timeout,
enum state_input tothem_spent,
enum state_input tothem_timeout);
@ -318,10 +319,6 @@ const struct bitcoin_tx *bitcoin_close(struct peer *peer);
/* Create a bitcoin spend tx (to spend our commit's outputs) */
const struct bitcoin_tx *bitcoin_spend_ours(struct peer *peer);
/* Create a bitcoin spend tx (to spend their commit's outputs) */
const struct bitcoin_tx *bitcoin_spend_theirs(const struct peer *peer,
const struct bitcoin_event *btc);
/* Create a bitcoin steal tx (to steal all their commit's outputs) */
const struct bitcoin_tx *bitcoin_steal(const struct peer *peer,
struct bitcoin_event *btc);

87
state_types.h

@ -6,7 +6,7 @@
#define STATE_CLOSE_HTLCS_BIT 1
#define STATE_CLOSE_STEAL_BIT 2
#define STATE_CLOSE_SPENDTHEM_BIT 4
#define STATE_CLOSE_THEIRCOMMIT_BIT 4
#define STATE_CLOSE_CLOSE_BIT 8
#define STATE_CLOSE_OURCOMMIT_BIT 16
#define STATE_CLOSE_SPENDOURS_BIT 32
@ -53,9 +53,10 @@ enum state {
/*
* 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 respond to their latest commit tx by
* spending (spend_them). They can also (with our help) broadcast
* a mutual close tx (mutual_close).
* 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).
@ -64,30 +65,30 @@ enum state {
*
* Thus, we could be waiting for the following combinations:
* - steal
* - spend_them
* - steal + spend_them
* - their_commit
* - steal + their_commit
* - mutual_close
* - steal + mutual_close
* - spend_them + mutual_close
* - steal + spend_them + mutual_close
* - their_commit + mutual_close
* - steal + their_commit + mutual_close
*
* - our_commit
* - steal + our_commit
* - spend_them + our_commit
* - steal + spend_them + our_commit
* - their_commit + our_commit
* - steal + their_commit + our_commit
* - mutual_close + our_commit
* - steal + mutual_close + our_commit
* - spend_them + mutual_close + our_commit
* - steal + spend_them + mutual_close + our_commit
* - their_commit + mutual_close + our_commit
* - steal + their_commit + mutual_close + our_commit
*
* - spend_ours
* - steal + spend_ours
* - spend_them + spend_ours
* - steal + spend_them + spend_ours
* - their_commit + spend_ours
* - steal + their_commit + spend_ours
* - mutual_close + spend_ours
* - steal + mutual_close + spend_ours
* - spend_them + mutual_close + spend_ours
* - steal + spend_them + 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:
*
@ -98,57 +99,57 @@ enum state {
* 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
* 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_SPENDTHEM,
STATE_CLOSE_WAIT_SPENDTHEM_WITH_HTLCS,
STATE_CLOSE_WAIT_STEAL_SPENDTHEM,
STATE_CLOSE_WAIT_STEAL_SPENDTHEM_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_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_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_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_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_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_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_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_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_SPENDTHEM_CLOSE_SPENDOURS,
STATE_CLOSE_WAIT_SPENDTHEM_CLOSE_SPENDOURS_WITH_HTLCS,
STATE_CLOSE_WAIT_STEAL_SPENDTHEM_CLOSE_SPENDOURS,
STATE_CLOSE_WAIT_STEAL_SPENDTHEM_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,
/*
* Where angels fear to tread.
@ -221,8 +222,8 @@ enum state_input {
/* HTLC to us timed out. */
BITCOIN_HTLC_TOUS_TIMEOUT,
/* Our spend of their commit tx is completely buried. */
BITCOIN_SPEND_THEIRS_DONE,
/* 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. */

Loading…
Cancel
Save