Browse Source

onchaind: recognize (and ignore) anchor outputs.

Without this, onchaind fails to identify them.  So onchaind now needs
to know the funding pubkeys.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
bump-pyln-proto
Rusty Russell 4 years ago
parent
commit
a730cbdc96
  1. 2
      lightningd/onchain_control.c
  2. 4
      onchaind/onchain_types.h
  3. 2
      onchaind/onchain_wire.csv
  4. 130
      onchaind/onchaind.c
  5. 2
      onchaind/test/run-grind_feerate-bug.c
  6. 2
      onchaind/test/run-grind_feerate.c

2
lightningd/onchain_control.c

@ -624,6 +624,8 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
channel->min_possible_feerate,
channel->max_possible_feerate,
channel->future_per_commitment_point,
&channel->local_funding_pubkey,
&channel->channel_info.remote_fundingkey,
channel->option_static_remotekey,
channel->option_anchor_outputs,
is_replay);

4
onchaind/onchain_types.h

@ -73,6 +73,10 @@ enum output_type {
/* For elements we need a fee output type */
ELEMENTS_FEE,
/* Anchor outputs for option_anchor_outputs */
ANCHOR_TO_US,
ANCHOR_TO_THEM,
};

2
onchaind/onchain_wire.csv

@ -44,6 +44,8 @@ msgdata,onchain_init,num_htlcs,u64,
msgdata,onchain_init,min_possible_feerate,u32,
msgdata,onchain_init,max_possible_feerate,u32,
msgdata,onchain_init,possible_remote_per_commit_point,?pubkey,
msgdata,onchain_init,local_funding_pubkey,pubkey,
msgdata,onchain_init,remote_funding_pubkey,pubkey,
msgdata,onchain_init,option_static_remotekey,bool,
msgdata,onchain_init,option_anchor_outputs,bool,
msgdata,onchain_init,is_replay,bool,

Can't render this file because it has a wrong number of fields in line 7.

130
onchaind/onchaind.c

@ -79,6 +79,9 @@ static u8 **missing_htlc_msgs;
/* Our recorded channel balance at 'chain time' */
static struct amount_msat our_msat;
/* Needed for anchor outputs */
static struct pubkey funding_pubkey[NUM_SIDES];
/* Does option_static_remotekey apply to this commitment tx? */
static bool option_static_remotekey;
@ -1512,6 +1515,8 @@ static void output_spent(struct tracked_output ***outs,
case OUTPUT_TO_THEM:
case DELAYED_OUTPUT_TO_THEM:
case ELEMENTS_FEE:
case ANCHOR_TO_US:
case ANCHOR_TO_THEM:
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Tracked spend of %s/%s?",
tx_type_name(out->tx_type),
@ -1724,7 +1729,8 @@ static void handle_preimage(struct tracked_output **outs,
* - MUST *resolve* the output by spending it to a
* convenient address.
*/
tx = tx_to_us(outs[i], remote_htlc_to_us, outs[i], 0,
tx = tx_to_us(outs[i], remote_htlc_to_us, outs[i],
option_anchor_outputs ? 1 : 0,
0, preimage, sizeof(*preimage),
outs[i]->wscript, &tx_type,
htlc_feerate);
@ -1970,7 +1976,8 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out,
"No valid signature found for %zu htlc_timeout_txs"
" feerate %u-%u,"
" last tx %s, input %s, signature %s,"
" cltvs %s wscripts %s",
" cltvs %s wscripts %s"
" %s",
tal_count(matches),
min_possible_feerate, max_possible_feerate,
type_to_string(tmpctx, struct bitcoin_tx, tx),
@ -1978,7 +1985,9 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out,
&out->sat),
type_to_string(tmpctx, struct bitcoin_signature,
out->remote_htlc_sig),
cltvs, wscripts);
cltvs, wscripts,
option_anchor_outputs
? "option_anchor_outputs" : "");
}
hsm_sign_local_htlc_tx(tx, htlc_scripts[matches[i]], &localsig);
@ -2030,7 +2039,9 @@ static size_t resolve_our_htlc_theircommit(struct tracked_output *out,
* - MUST *resolve* the output, by spending it to a convenient
* address.
*/
tx = tx_to_us(out, remote_htlc_to_us, out, 0, cltv_expiry, NULL, 0,
tx = tx_to_us(out, remote_htlc_to_us, out,
option_anchor_outputs ? 1 : 0,
cltv_expiry, NULL, 0,
htlc_scripts[matches[0]], &tx_type, htlc_feerate);
propose_resolution_at_block(out, tx, cltv_expiry, tx_type, is_replay);
@ -2147,6 +2158,20 @@ static void note_missing_htlcs(u8 **htlc_scripts,
}
}
static void get_anchor_scriptpubkeys(const tal_t *ctx, u8 **anchor)
{
if (!option_anchor_outputs) {
anchor[LOCAL] = anchor[REMOTE] = NULL;
return;
}
for (enum side side = 0; side < NUM_SIDES; side++) {
u8 *wscript = bitcoin_wscript_anchor(tmpctx,
&funding_pubkey[side]);
anchor[side] = scriptpubkey_p2wsh(ctx, wscript);
}
}
static void handle_our_unilateral(const struct tx_parts *tx,
u32 tx_blockheight,
const struct basepoints basepoints[NUM_SIDES],
@ -2158,7 +2183,7 @@ static void handle_our_unilateral(const struct tx_parts *tx,
bool is_replay)
{
u8 **htlc_scripts;
u8 *local_wscript, *script[NUM_SIDES];
u8 *local_wscript, *script[NUM_SIDES], *anchor[NUM_SIDES];
struct pubkey local_per_commitment_point;
struct keyset *ks;
size_t i;
@ -2235,6 +2260,8 @@ static void handle_our_unilateral(const struct tx_parts *tx,
tx->outputs[i]->script_len));
}
get_anchor_scriptpubkeys(tmpctx, anchor);
for (i = 0; i < tal_count(tx->outputs); i++) {
struct tracked_output *out;
const size_t *matches;
@ -2327,6 +2354,33 @@ static void handle_our_unilateral(const struct tx_parts *tx,
add_amt(&their_outs, amt);
continue;
}
if (anchor[LOCAL]
&& wally_tx_output_scripteq(tx->outputs[i],
anchor[LOCAL])) {
/* FIXME: We should be able to spend this! */
out = new_tracked_output(&outs, &tx->txid,
tx_blockheight,
OUR_UNILATERAL, i,
amt,
ANCHOR_TO_US,
NULL, NULL, NULL);
ignore_output(out);
anchor[LOCAL] = NULL;
continue;
}
if (anchor[REMOTE]
&& wally_tx_output_scripteq(tx->outputs[i],
anchor[REMOTE])) {
out = new_tracked_output(&outs, &tx->txid,
tx_blockheight,
OUR_UNILATERAL, i,
amt,
ANCHOR_TO_THEM,
NULL, NULL, NULL);
ignore_output(out);
anchor[REMOTE] = NULL;
continue;
}
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
/* FIXME: limp along when this happens! */
@ -2479,7 +2533,7 @@ static void tell_wallet_to_remote(const struct tx_parts *tx,
*/
static void update_ledger_cheat(const struct bitcoin_txid *txid,
u32 blockheight,
struct tracked_output *out)
const struct tracked_output *out)
{
/* how much of a difference should we update the
* channel account ledger by? */
@ -2520,7 +2574,7 @@ static void handle_their_cheat(const struct tx_parts *tx,
bool is_replay)
{
u8 **htlc_scripts;
u8 *remote_wscript, *script[NUM_SIDES];
u8 *remote_wscript, *script[NUM_SIDES], *anchor[NUM_SIDES];
struct keyset *ks;
struct pubkey *k;
size_t i;
@ -2633,6 +2687,8 @@ static void handle_their_cheat(const struct tx_parts *tx,
status_debug("Script to-me: %s",
tal_hex(tmpctx, script[LOCAL]));
get_anchor_scriptpubkeys(tmpctx, anchor);
for (i = 0; i < tal_count(tx->outputs); i++) {
if (tx->outputs[i]->script_len == 0)
continue;
@ -2710,6 +2766,33 @@ static void handle_their_cheat(const struct tx_parts *tx,
add_amt(&total_outs, amt);
continue;
}
if (anchor[LOCAL]
&& wally_tx_output_scripteq(tx->outputs[i],
anchor[LOCAL])) {
/* FIXME: We should be able to spend this! */
out = new_tracked_output(&outs, &tx->txid,
tx_blockheight,
THEIR_REVOKED_UNILATERAL, i,
amt,
ANCHOR_TO_US,
NULL, NULL, NULL);
ignore_output(out);
anchor[LOCAL] = NULL;
continue;
}
if (anchor[REMOTE]
&& wally_tx_output_scripteq(tx->outputs[i],
anchor[REMOTE])) {
out = new_tracked_output(&outs, &tx->txid,
tx_blockheight,
THEIR_REVOKED_UNILATERAL, i,
amt,
ANCHOR_TO_THEM,
NULL, NULL, NULL);
ignore_output(out);
anchor[REMOTE] = NULL;
continue;
}
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
if (tal_count(matches) == 0)
@ -2786,7 +2869,7 @@ static void handle_their_unilateral(const struct tx_parts *tx,
bool is_replay)
{
u8 **htlc_scripts;
u8 *remote_wscript, *script[NUM_SIDES];
u8 *remote_wscript, *script[NUM_SIDES], *anchor[NUM_SIDES];
struct keyset *ks;
size_t i;
struct amount_sat their_outs = AMOUNT_SAT(0), our_outs = AMOUNT_SAT(0);
@ -2885,6 +2968,8 @@ static void handle_their_unilateral(const struct tx_parts *tx,
status_debug("Script to-me: %s",
tal_hex(tmpctx, script[LOCAL]));
get_anchor_scriptpubkeys(tmpctx, anchor);
for (i = 0; i < tal_count(tx->outputs); i++) {
if (tx->outputs[i]->script_len == 0)
continue;
@ -2962,6 +3047,33 @@ static void handle_their_unilateral(const struct tx_parts *tx,
add_amt(&their_outs, amt);
continue;
}
if (anchor[LOCAL]
&& wally_tx_output_scripteq(tx->outputs[i],
anchor[LOCAL])) {
/* FIXME: We should be able to spend this! */
out = new_tracked_output(&outs, &tx->txid,
tx_blockheight,
THEIR_UNILATERAL, i,
amt,
ANCHOR_TO_US,
NULL, NULL, NULL);
ignore_output(out);
anchor[LOCAL] = NULL;
continue;
}
if (anchor[REMOTE]
&& wally_tx_output_scripteq(tx->outputs[i],
anchor[REMOTE])) {
out = new_tracked_output(&outs, &tx->txid,
tx_blockheight,
THEIR_UNILATERAL, i,
amt,
ANCHOR_TO_THEM,
NULL, NULL, NULL);
ignore_output(out);
anchor[REMOTE] = NULL;
continue;
}
matches = match_htlc_output(tmpctx, tx->outputs[i], htlc_scripts);
if (tal_count(matches) == 0)
@ -3242,6 +3354,8 @@ int main(int argc, char *argv[])
&min_possible_feerate,
&max_possible_feerate,
&possible_remote_per_commitment_point,
&funding_pubkey[LOCAL],
&funding_pubkey[REMOTE],
&option_static_remotekey,
&option_anchor_outputs,
&open_is_replay)) {

2
onchaind/test/run-grind_feerate-bug.c

@ -50,7 +50,7 @@ bool fromwire_onchain_dev_memleak(const void *p UNNEEDED)
bool fromwire_onchain_htlc(const void *p UNNEEDED, struct htlc_stub *htlc UNNEEDED, bool *tell_if_missing UNNEEDED, bool *tell_immediately UNNEEDED)
{ fprintf(stderr, "fromwire_onchain_htlc called!\n"); abort(); }
/* Generated stub for fromwire_onchain_init */
bool fromwire_onchain_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u64 *num_htlcs UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, bool *option_static_remotekey UNNEEDED, bool *option_anchor_outputs UNNEEDED, bool *is_replay UNNEEDED)
bool fromwire_onchain_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u64 *num_htlcs UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, bool *option_static_remotekey UNNEEDED, bool *option_anchor_outputs UNNEEDED, bool *is_replay UNNEEDED)
{ fprintf(stderr, "fromwire_onchain_init called!\n"); abort(); }
/* Generated stub for fromwire_onchain_known_preimage */
bool fromwire_onchain_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED, bool *is_replay UNNEEDED)

2
onchaind/test/run-grind_feerate.c

@ -54,7 +54,7 @@ bool fromwire_onchain_dev_memleak(const void *p UNNEEDED)
bool fromwire_onchain_htlc(const void *p UNNEEDED, struct htlc_stub *htlc UNNEEDED, bool *tell_if_missing UNNEEDED, bool *tell_immediately UNNEEDED)
{ fprintf(stderr, "fromwire_onchain_htlc called!\n"); abort(); }
/* Generated stub for fromwire_onchain_init */
bool fromwire_onchain_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u64 *num_htlcs UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, bool *option_static_remotekey UNNEEDED, bool *option_anchor_outputs UNNEEDED, bool *is_replay UNNEEDED)
bool fromwire_onchain_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, const struct chainparams **chainparams UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct amount_msat *our_msat UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *delayed_to_us_feerate UNNEEDED, u32 *htlc_feerate UNNEEDED, u32 *penalty_feerate UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *opener UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct tx_parts **tx_parts UNNEEDED, u32 *locktime UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, struct bitcoin_signature **htlc_signature UNNEEDED, u64 *num_htlcs UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED, struct pubkey *local_funding_pubkey UNNEEDED, struct pubkey *remote_funding_pubkey UNNEEDED, bool *option_static_remotekey UNNEEDED, bool *option_anchor_outputs UNNEEDED, bool *is_replay UNNEEDED)
{ fprintf(stderr, "fromwire_onchain_init called!\n"); abort(); }
/* Generated stub for fromwire_onchain_known_preimage */
bool fromwire_onchain_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED, bool *is_replay UNNEEDED)

Loading…
Cancel
Save