Browse Source

utxo: keep flag to recognize to-remote option_anchor_outputs closes.

We need to remember this in the db (it's a P2WSH for option_anchor_outputs),
and we need to set nSequence to 1 to spend it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
bump-pyln-proto
Rusty Russell 5 years ago
parent
commit
754765c139
  1. 17
      common/utxo.c
  2. 1
      common/utxo.h
  3. 9
      hsmd/hsmd.c
  4. 3
      wallet/db.c
  5. 8
      wallet/test/run-wallet.c
  6. 48
      wallet/wallet.c

17
common/utxo.c

@ -29,6 +29,7 @@ void towire_utxo(u8 **pptr, const struct utxo *utxo)
towire_bool(pptr, utxo->close_info->commitment_point != NULL);
if (utxo->close_info->commitment_point)
towire_pubkey(pptr, utxo->close_info->commitment_point);
towire_bool(pptr, utxo->close_info->option_anchor_outputs);
}
}
@ -55,6 +56,8 @@ struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max)
utxo->close_info->commitment_point);
} else
utxo->close_info->commitment_point = NULL;
utxo->close_info->option_anchor_outputs
= fromwire_bool(ptr, max);
} else {
utxo->close_info = NULL;
}
@ -78,6 +81,7 @@ struct bitcoin_tx *tx_spending_utxos(const tal_t *ctx,
outcount, nlocktime);
for (size_t i = 0; i < tal_count(utxos); i++) {
u32 this_nsequence;
if (utxos[i]->is_p2sh && bip32_base) {
bip32_pubkey(bip32_base, &key, utxos[i]->keyindex);
scriptSig =
@ -90,9 +94,20 @@ struct bitcoin_tx *tx_spending_utxos(const tal_t *ctx,
redeemscript = NULL;
}
/* BOLT-a12da24dd0102c170365124782b46d9710950ac1 #3:
* #### `to_remote` Output
* ...
* The output is spent by a transaction with `nSequence` field
* set to `1` and witness:
*/
if (utxos[i]->close_info && utxos[i]->close_info->option_anchor_outputs)
this_nsequence = 1;
else
this_nsequence = nsequence;
bitcoin_tx_add_input(tx, &utxos[i]->txid,
utxos[i]->outnum,
nsequence,
this_nsequence,
scriptSig, utxos[i]->amount,
utxos[i]->scriptPubkey, NULL);

1
common/utxo.h

@ -17,6 +17,7 @@ struct ext_key;
struct unilateral_close_info {
u64 channel_id;
struct node_id peer_id;
bool option_anchor_outputs;
/* NULL if this is an option_static_remotekey commitment */
struct pubkey *commitment_point;
};

9
hsmd/hsmd.c

@ -1530,7 +1530,7 @@ static void hsm_unilateral_close_privkey(struct privkey *dst,
}
}
/* This gets the bitcoin private key needed to spend from our wallet. */
/* This gets the bitcoin private key needed to spend from our wallet */
static void hsm_key_for_utxo(struct privkey *privkey, struct pubkey *pubkey,
const struct utxo *utxo)
{
@ -1575,6 +1575,13 @@ static void sign_our_inputs(struct utxo **utxos, struct wally_psbt *psbt)
* of complexity in the calling code */
psbt_input_add_pubkey(psbt, j, &pubkey);
/* It's actually a P2WSH in this case. */
if (utxo->close_info && utxo->close_info->option_anchor_outputs) {
psbt_input_set_prev_utxo_wscript(psbt, j,
anchor_to_remote_redeem(tmpctx,
&pubkey),
utxo->amount);
}
if (wally_psbt_sign(psbt, privkey.secret.data,
sizeof(privkey.secret.data),
EC_FLAG_GRIND_R) != WALLY_OK)

3
wallet/db.c

@ -636,6 +636,9 @@ static struct migration dbmigrations[] = {
/* option_anchor_outputs is nailed at creation time. */
{SQL("ALTER TABLE channels ADD COLUMN option_anchor_outputs INTEGER"
" DEFAULT 0;"), NULL },
/* We need to know if it was option_anchor_outputs to spend to_remote */
{SQL("ALTER TABLE outputs ADD option_anchor_outputs INTEGER"
" DEFAULT 0;"), NULL},
};
/* Leak tracking. */

8
wallet/test/run-wallet.c

@ -933,6 +933,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
u.close_info->channel_id = 42;
u.close_info->peer_id = id;
u.close_info->commitment_point = &pk;
u.close_info->option_anchor_outputs = false;
/* Arbitrarily set scriptpubkey len to 20 */
u.scriptPubkey = tal_arr(w, u8, 20);
memset(u.scriptPubkey, 1, 20);
@ -948,7 +949,8 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
u = *utxos[1];
CHECK(u.close_info->channel_id == 42 &&
pubkey_eq(u.close_info->commitment_point, &pk) &&
node_id_eq(&u.close_info->peer_id, &id));
node_id_eq(&u.close_info->peer_id, &id) &&
u.close_info->option_anchor_outputs == false);
/* Now un-reserve them for the tests below */
tal_free(utxos);
@ -984,6 +986,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
u.close_info->channel_id = 42;
u.close_info->peer_id = id;
u.close_info->commitment_point = NULL;
u.close_info->option_anchor_outputs = true;
u.scriptPubkey = tal_arr(w, u8, 20);
memset(u.scriptPubkey, 1, 20);
CHECK_MSG(wallet_add_utxo(w, &u, p2sh_wpkh),
@ -998,7 +1001,8 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx)
u = *utxos[1];
CHECK(u.close_info->channel_id == 42 &&
u.close_info->commitment_point == NULL &&
node_id_eq(&u.close_info->peer_id, &id));
node_id_eq(&u.close_info->peer_id, &id) &&
u.close_info->option_anchor_outputs == true);
/* Now un-reserve them */
tal_free(utxos);

48
wallet/wallet.c

@ -113,10 +113,11 @@ static bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
", channel_id"
", peer_id"
", commitment_point"
", option_anchor_outputs"
", confirmation_height"
", spend_height"
", scriptpubkey"
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
db_bind_txid(stmt, 0, &utxo->txid);
db_bind_int(stmt, 1, utxo->outnum);
db_bind_amount_sat(stmt, 2, &utxo->amount);
@ -130,23 +131,25 @@ static bool wallet_add_utxo(struct wallet *w, struct utxo *utxo,
db_bind_pubkey(stmt, 8, utxo->close_info->commitment_point);
else
db_bind_null(stmt, 8);
db_bind_int(stmt, 9, utxo->close_info->option_anchor_outputs);
} else {
db_bind_null(stmt, 6);
db_bind_null(stmt, 7);
db_bind_null(stmt, 8);
db_bind_null(stmt, 9);
}
if (utxo->blockheight) {
db_bind_int(stmt, 9, *utxo->blockheight);
db_bind_int(stmt, 10, *utxo->blockheight);
} else
db_bind_null(stmt, 9);
db_bind_null(stmt, 10);
if (utxo->spendheight)
db_bind_int(stmt, 10, *utxo->spendheight);
db_bind_int(stmt, 11, *utxo->spendheight);
else
db_bind_null(stmt, 10);
db_bind_null(stmt, 11);
db_bind_blob(stmt, 11, utxo->scriptPubkey,
db_bind_blob(stmt, 12, utxo->scriptPubkey,
tal_bytelen(utxo->scriptPubkey));
db_exec_prepared_v2(take(stmt));
@ -177,33 +180,35 @@ static struct utxo *wallet_stmt2output(const tal_t *ctx, struct db_stmt *stmt)
utxo->close_info->commitment_point);
} else
utxo->close_info->commitment_point = NULL;
utxo->close_info->option_anchor_outputs
= db_column_int(stmt, 9);
} else {
utxo->close_info = NULL;
}
utxo->scriptPubkey =
tal_dup_arr(utxo, u8, db_column_blob(stmt, 11),
db_column_bytes(stmt, 11), 0);
tal_dup_arr(utxo, u8, db_column_blob(stmt, 12),
db_column_bytes(stmt, 12), 0);
utxo->blockheight = NULL;
utxo->spendheight = NULL;
utxo->reserved_til = NULL;
if (!db_column_is_null(stmt, 9)) {
if (!db_column_is_null(stmt, 10)) {
blockheight = tal(utxo, u32);
*blockheight = db_column_int(stmt, 9);
*blockheight = db_column_int(stmt, 10);
utxo->blockheight = blockheight;
}
if (!db_column_is_null(stmt, 10)) {
if (!db_column_is_null(stmt, 11)) {
spendheight = tal(utxo, u32);
*spendheight = db_column_int(stmt, 10);
*spendheight = db_column_int(stmt, 11);
utxo->spendheight = spendheight;
}
if (!db_column_is_null(stmt, 12)) {
if (!db_column_is_null(stmt, 13)) {
reserved_til = tal(utxo, u32);
*reserved_til = db_column_int(stmt, 12);
*reserved_til = db_column_int(stmt, 13);
utxo->reserved_til = reserved_til;
}
@ -256,6 +261,7 @@ struct utxo **wallet_get_utxos(const tal_t *ctx, struct wallet *w, const enum ou
", channel_id"
", peer_id"
", commitment_point"
", option_anchor_outputs"
", confirmation_height"
", spend_height"
", scriptpubkey "
@ -272,6 +278,7 @@ struct utxo **wallet_get_utxos(const tal_t *ctx, struct wallet *w, const enum ou
", channel_id"
", peer_id"
", commitment_point"
", option_anchor_outputs"
", confirmation_height"
", spend_height"
", scriptpubkey "
@ -309,6 +316,7 @@ struct utxo **wallet_get_unconfirmed_closeinfo_utxos(const tal_t *ctx,
", channel_id"
", peer_id"
", commitment_point"
", option_anchor_outputs"
", confirmation_height"
", spend_height"
", scriptpubkey"
@ -345,6 +353,7 @@ struct utxo *wallet_utxo_get(const tal_t *ctx, struct wallet *w,
", channel_id"
", peer_id"
", commitment_point"
", option_anchor_outputs"
", confirmation_height"
", spend_height"
", scriptpubkey"
@ -542,6 +551,7 @@ struct utxo *wallet_find_utxo(const tal_t *ctx, struct wallet *w,
", channel_id"
", peer_id"
", commitment_point"
", option_anchor_outputs"
", confirmation_height"
", spend_height"
", scriptpubkey "
@ -606,10 +616,11 @@ bool wallet_add_onchaind_utxo(struct wallet *w,
", channel_id"
", peer_id"
", commitment_point"
", option_anchor_outputs"
", confirmation_height"
", spend_height"
", scriptpubkey"
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"));
db_bind_txid(stmt, 0, txid);
db_bind_int(stmt, 1, outnum);
db_bind_amount_sat(stmt, 2, &amount);
@ -623,11 +634,12 @@ bool wallet_add_onchaind_utxo(struct wallet *w,
else
db_bind_null(stmt, 8);
db_bind_int(stmt, 9, blockheight);
db_bind_int(stmt, 9, channel->option_anchor_outputs);
db_bind_int(stmt, 10, blockheight);
/* spendheight */
db_bind_null(stmt, 10);
db_bind_blob(stmt, 11, scriptpubkey, tal_bytelen(scriptpubkey));
db_bind_null(stmt, 11);
db_bind_blob(stmt, 12, scriptpubkey, tal_bytelen(scriptpubkey));
db_exec_prepared_v2(take(stmt));
return true;

Loading…
Cancel
Save