diff --git a/common/utxo.c b/common/utxo.c index 4d707b115..5f78cc69e 100644 --- a/common/utxo.c +++ b/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); diff --git a/common/utxo.h b/common/utxo.h index 259306da3..527ebee03 100644 --- a/common/utxo.h +++ b/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; }; diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index 2a7576bb4..1760cf971 100644 --- a/hsmd/hsmd.c +++ b/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) diff --git a/wallet/db.c b/wallet/db.c index 893ea75b9..07b3864a1 100644 --- a/wallet/db.c +++ b/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. */ diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 0c544a654..d2a4db597 100644 --- a/wallet/test/run-wallet.c +++ b/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); diff --git a/wallet/wallet.c b/wallet/wallet.c index 950818914..a07674409 100644 --- a/wallet/wallet.c +++ b/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;