Browse Source

onchaind: add a new state for where we're not producing an output.

DONATING_TO_MINERS is pretty clear, I think.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
eb52dde5b5
  1. 53
      onchaind/onchain.c
  2. 3
      onchaind/onchain_types.h
  3. 6
      tests/test_lightningd.py

53
onchaind/onchain.c

@ -213,6 +213,8 @@ static const char *output_type_name(enum output_type output_type)
* 3. the their-commitment, our HTLC redeem case (`<remotehtlcsig> <payment_preimage>`) * 3. the their-commitment, our HTLC redeem case (`<remotehtlcsig> <payment_preimage>`)
* 4. the their-revoked-commitment, to-local (`<revocation_sig> 1`) * 4. the their-revoked-commitment, to-local (`<revocation_sig> 1`)
* 5. the their-revoked-commitment, htlc (`<revocation_sig> <revocationkey>`) * 5. the their-revoked-commitment, htlc (`<revocation_sig> <revocationkey>`)
*
* Overrides *tx_type if it all turns to dust.
*/ */
static struct bitcoin_tx *tx_to_us(const tal_t *ctx, static struct bitcoin_tx *tx_to_us(const tal_t *ctx,
struct tracked_output *out, struct tracked_output *out,
@ -221,7 +223,8 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx,
const void *elem, size_t elemsize, const void *elem, size_t elemsize,
const u8 *wscript, const u8 *wscript,
const struct privkey *privkey, const struct privkey *privkey,
const struct pubkey *pubkey) const struct pubkey *pubkey,
enum tx_type *tx_type)
{ {
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
u64 fee; u64 fee;
@ -247,6 +250,7 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx,
if (tx->output[0].amount < dust_limit_satoshis + fee) { if (tx->output[0].amount < dust_limit_satoshis + fee) {
tx->output[0].amount = 0; tx->output[0].amount = 0;
tx->output[0].script = scriptpubkey_opreturn(tx->output); tx->output[0].script = scriptpubkey_opreturn(tx->output);
*tx_type = DONATING_TO_MINERS;
} else } else
tx->output[0].amount -= fee; tx->output[0].amount -= fee;
@ -723,6 +727,7 @@ static void resolve_htlc_tx(struct tracked_output ***outs,
{ {
struct tracked_output *out; struct tracked_output *out;
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
enum tx_type tx_type = OUR_DELAYED_RETURN_TO_WALLET;
u8 *wscript = bitcoin_wscript_htlc_tx(htlc_tx, to_self_delay[LOCAL], u8 *wscript = bitcoin_wscript_htlc_tx(htlc_tx, to_self_delay[LOCAL],
&keyset->self_revocation_key, &keyset->self_revocation_key,
&keyset->self_delayed_payment_key); &keyset->self_delayed_payment_key);
@ -756,10 +761,10 @@ static void resolve_htlc_tx(struct tracked_output ***outs,
tx = tx_to_us(*outs, out, to_self_delay[LOCAL], 0, NULL, 0, tx = tx_to_us(*outs, out, to_self_delay[LOCAL], 0, NULL, 0,
wscript, wscript,
&delayed_payment_privkey, &delayed_payment_privkey,
&keyset->self_delayed_payment_key); &keyset->self_delayed_payment_key,
&tx_type);
propose_resolution(out, tx, to_self_delay[LOCAL], propose_resolution(out, tx, to_self_delay[LOCAL], tx_type);
OUR_DELAYED_RETURN_TO_WALLET);
} }
/* BOLT #5: /* BOLT #5:
@ -777,6 +782,7 @@ static void resolve_htlc_tx(struct tracked_output ***outs,
static void steal_htlc_tx(struct tracked_output *out) static void steal_htlc_tx(struct tracked_output *out)
{ {
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
enum tx_type tx_type = OUR_PENALTY_TX;
/* BOLT #3: /* BOLT #3:
* *
@ -787,8 +793,9 @@ static void steal_htlc_tx(struct tracked_output *out)
&ONE, sizeof(ONE), &ONE, sizeof(ONE),
out->wscript, out->wscript,
revocation_privkey, revocation_privkey,
&keyset->self_revocation_key); &keyset->self_revocation_key,
propose_resolution(out, tx, 0, OUR_PENALTY_TX); &tx_type);
propose_resolution(out, tx, 0, tx_type);
} }
/* An output has been spent: see if it resolves something we care about. */ /* An output has been spent: see if it resolves something we care about. */
@ -1046,6 +1053,8 @@ static void handle_preimage(struct tracked_output **outs,
outs[i]->wscript); outs[i]->wscript);
propose_resolution(outs[i], tx, 0, OUR_HTLC_SUCCESS_TX); propose_resolution(outs[i], tx, 0, OUR_HTLC_SUCCESS_TX);
} else { } else {
enum tx_type tx_type = THEIR_HTLC_FULFILL_TO_US;
/* BOLT #5: /* BOLT #5:
* *
* otherwise, it MUST spend the output to a convenient * otherwise, it MUST spend the output to a convenient
@ -1055,9 +1064,9 @@ static void handle_preimage(struct tracked_output **outs,
preimage, sizeof(*preimage), preimage, sizeof(*preimage),
outs[i]->wscript, outs[i]->wscript,
&htlc_privkey, &htlc_privkey,
&keyset->other_htlc_key); &keyset->other_htlc_key,
propose_resolution(outs[i], tx, 0, &tx_type);
THEIR_HTLC_FULFILL_TO_US); propose_resolution(outs[i], tx, 0, tx_type);
} }
} }
} }
@ -1206,6 +1215,7 @@ static void resolve_our_htlc_ourcommit(struct tracked_output *out)
static void resolve_our_htlc_theircommit(struct tracked_output *out) static void resolve_our_htlc_theircommit(struct tracked_output *out)
{ {
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
enum tx_type tx_type = OUR_HTLC_TIMEOUT_TO_US;
/* BOLT #5: /* BOLT #5:
* *
@ -1222,10 +1232,10 @@ static void resolve_our_htlc_theircommit(struct tracked_output *out)
tx = tx_to_us(out, out, 0, out->htlc->cltv_expiry, NULL, 0, tx = tx_to_us(out, out, 0, out->htlc->cltv_expiry, NULL, 0,
out->wscript, out->wscript,
&htlc_privkey, &htlc_privkey,
&keyset->other_htlc_key); &keyset->other_htlc_key,
&tx_type);
propose_resolution_at_block(out, tx, out->htlc->cltv_expiry, propose_resolution_at_block(out, tx, out->htlc->cltv_expiry, tx_type);
OUR_HTLC_TIMEOUT_TO_US);
} }
static void resolve_their_htlc(struct tracked_output *out) static void resolve_their_htlc(struct tracked_output *out)
@ -1439,6 +1449,8 @@ static void handle_our_unilateral(const struct bitcoin_tx *tx,
if (script[LOCAL] if (script[LOCAL]
&& scripteq(tx->output[i].script, script[LOCAL])) { && scripteq(tx->output[i].script, script[LOCAL])) {
struct bitcoin_tx *to_us; struct bitcoin_tx *to_us;
enum tx_type tx_type = OUR_DELAYED_RETURN_TO_WALLET;
/* BOLT #5: /* BOLT #5:
* *
* 1. _A's main output_: A node SHOULD spend this * 1. _A's main output_: A node SHOULD spend this
@ -1461,14 +1473,15 @@ static void handle_our_unilateral(const struct bitcoin_tx *tx,
NULL, 0, NULL, 0,
local_wscript, local_wscript,
&delayed_payment_privkey, &delayed_payment_privkey,
&keyset->self_delayed_payment_key); &keyset->self_delayed_payment_key,
&tx_type);
/* BOLT #5: /* BOLT #5:
* *
* If the output is spent (as recommended), the output * If the output is spent (as recommended), the output
* is *resolved* by the spending transaction */ * is *resolved* by the spending transaction */
propose_resolution(out, to_us, to_self_delay[LOCAL], propose_resolution(out, to_us, to_self_delay[LOCAL],
OUR_DELAYED_RETURN_TO_WALLET); tx_type);
script[LOCAL] = NULL; script[LOCAL] = NULL;
continue; continue;
@ -1547,6 +1560,7 @@ static void steal_to_them_output(struct tracked_output *out)
const tal_t *tmpctx = tal_tmpctx(NULL); const tal_t *tmpctx = tal_tmpctx(NULL);
u8 *wscript; u8 *wscript;
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
enum tx_type tx_type = OUR_PENALTY_TX;
/* BOLT #3: /* BOLT #3:
* *
@ -1563,15 +1577,17 @@ static void steal_to_them_output(struct tracked_output *out)
&ONE, sizeof(ONE), &ONE, sizeof(ONE),
wscript, wscript,
revocation_privkey, revocation_privkey,
&keyset->self_revocation_key); &keyset->self_revocation_key,
&tx_type);
propose_resolution(out, tx, 0, OUR_PENALTY_TX); propose_resolution(out, tx, 0, tx_type);
tal_free(tmpctx); tal_free(tmpctx);
} }
static void steal_htlc(struct tracked_output *out) static void steal_htlc(struct tracked_output *out)
{ {
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
enum tx_type tx_type = OUR_PENALTY_TX;
u8 der[PUBKEY_DER_LEN]; u8 der[PUBKEY_DER_LEN];
/* BOLT #3: /* BOLT #3:
@ -1586,9 +1602,10 @@ static void steal_htlc(struct tracked_output *out)
der, sizeof(der), der, sizeof(der),
out->wscript, out->wscript,
revocation_privkey, revocation_privkey,
&keyset->self_revocation_key); &keyset->self_revocation_key,
&tx_type);
propose_resolution(out, tx, 0, OUR_PENALTY_TX); propose_resolution(out, tx, 0, tx_type);
} }
/* BOLT #5: /* BOLT #5:

3
onchaind/onchain_types.h

@ -35,6 +35,9 @@ enum tx_type {
/* When we use revocation key to take output. */ /* When we use revocation key to take output. */
OUR_PENALTY_TX, OUR_PENALTY_TX,
/* Amount too small, we're just spending it to close UTXO */
DONATING_TO_MINERS,
/* Special type for marking outputs as resolved by self. */ /* Special type for marking outputs as resolved by self. */
SELF, SELF,

6
tests/test_lightningd.py

@ -1773,13 +1773,13 @@ class LightningDTests(BaseLightningDTests):
l2.daemon.wait_for_log(' to ONCHAIN') l2.daemon.wait_for_log(' to ONCHAIN')
# Wait for timeout. # Wait for timeout.
l1.daemon.wait_for_log('Propose handling THEIR_UNILATERAL/OUR_HTLC by OUR_HTLC_TIMEOUT_TO_US .* in 5 blocks') l1.daemon.wait_for_log('Propose handling THEIR_UNILATERAL/OUR_HTLC by DONATING_TO_MINERS .* in 5 blocks')
bitcoind.generate_block(5) bitcoind.generate_block(5)
l1.daemon.wait_for_log('sendrawtx exit 0') l1.daemon.wait_for_log('sendrawtx exit 0')
bitcoind.generate_block(1) bitcoind.generate_block(1)
l1.daemon.wait_for_log('Resolved THEIR_UNILATERAL/OUR_HTLC by our proposal OUR_HTLC_TIMEOUT_TO_US') l1.daemon.wait_for_log('Resolved THEIR_UNILATERAL/OUR_HTLC by our proposal DONATING_TO_MINERS')
# 100 deep and l2 forgets. # 100 deep and l2 forgets.
bitcoind.generate_block(92) bitcoind.generate_block(92)
@ -1788,7 +1788,7 @@ class LightningDTests(BaseLightningDTests):
bitcoind.generate_block(1) bitcoind.generate_block(1)
l2.daemon.wait_for_log('onchaind complete, forgetting peer') l2.daemon.wait_for_log('onchaind complete, forgetting peer')
# l1 forgets 100 blocks after OUR_HTLC_TIMEOUT_TO_US. # l1 forgets 100 blocks after DONATING_TO_MINERS.
bitcoind.generate_block(6) bitcoind.generate_block(6)
sync_blockheight([l1]) sync_blockheight([l1])
assert not l1.daemon.is_in_log('onchaind complete, forgetting peer') assert not l1.daemon.is_in_log('onchaind complete, forgetting peer')

Loading…
Cancel
Save