diff --git a/common/utxo.c b/common/utxo.c index 41f286a28..6b5eb7d73 100644 --- a/common/utxo.c +++ b/common/utxo.c @@ -20,7 +20,9 @@ void towire_utxo(u8 **pptr, const struct utxo *utxo) if (is_unilateral_close) { towire_u64(pptr, utxo->close_info->channel_id); towire_node_id(pptr, &utxo->close_info->peer_id); - towire_pubkey(pptr, &utxo->close_info->commitment_point); + towire_bool(pptr, utxo->close_info->commitment_point != NULL); + if (utxo->close_info->commitment_point) + towire_pubkey(pptr, utxo->close_info->commitment_point); } } @@ -42,7 +44,13 @@ struct utxo *fromwire_utxo(const tal_t *ctx, const u8 **ptr, size_t *max) utxo->close_info = tal(utxo, struct unilateral_close_info); utxo->close_info->channel_id = fromwire_u64(ptr, max); fromwire_node_id(ptr, max, &utxo->close_info->peer_id); - fromwire_pubkey(ptr, max, &utxo->close_info->commitment_point); + if (fromwire_bool(ptr, max)) { + utxo->close_info->commitment_point = tal(utxo, + struct pubkey); + fromwire_pubkey(ptr, max, + utxo->close_info->commitment_point); + } else + utxo->close_info->commitment_point = NULL; } else { utxo->close_info = NULL; } diff --git a/common/utxo.h b/common/utxo.h index 32ce97414..1eef4a082 100644 --- a/common/utxo.h +++ b/common/utxo.h @@ -17,7 +17,8 @@ struct ext_key; struct unilateral_close_info { u64 channel_id; struct node_id peer_id; - struct pubkey commitment_point; + /* NULL if this is an option_static_remotekey commitment */ + struct pubkey *commitment_point; }; struct utxo { diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index da46e0888..3b7117c09 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -1386,7 +1386,7 @@ static void hsm_unilateral_close_privkey(struct privkey *dst, derive_basepoints(&channel_seed, NULL, &basepoints, &secrets, NULL); if (!derive_simple_privkey(&secrets.payment_basepoint_secret, - &basepoints.payment, &info->commitment_point, + &basepoints.payment, info->commitment_point, dst)) { status_failed(STATUS_FAIL_INTERNAL_ERROR, "Deriving unilateral_close_privkey"); diff --git a/onchaind/onchain_wire.csv b/onchaind/onchain_wire.csv index 0af89927b..47ad2576a 100644 --- a/onchaind/onchain_wire.csv +++ b/onchaind/onchain_wire.csv @@ -91,7 +91,7 @@ msgtype,onchain_all_irrevocably_resolved,5011 msgtype,onchain_add_utxo,5012 msgdata,onchain_add_utxo,prev_out_tx,bitcoin_txid, msgdata,onchain_add_utxo,prev_out_index,u32, -msgdata,onchain_add_utxo,per_commit_point,pubkey, +msgdata,onchain_add_utxo,per_commit_point,?pubkey, msgdata,onchain_add_utxo,value,amount_sat, msgdata,onchain_add_utxo,blockheight,u32, msgdata,onchain_add_utxo,len,u16, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 5d208ffc6..e5af87224 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -784,7 +784,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx) u.close_info = tal(w, struct unilateral_close_info); u.close_info->channel_id = 42; u.close_info->peer_id = id; - u.close_info->commitment_point = pk; + u.close_info->commitment_point = &pk; CHECK_MSG(wallet_add_utxo(w, &u, p2sh_wpkh), "wallet_add_utxo with close_info"); @@ -796,7 +796,7 @@ 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) && + pubkey_eq(u.close_info->commitment_point, &pk) && node_id_eq(&u.close_info->peer_id, &id)); /* Now un-reserve them for the tests below */ tal_free(utxos); @@ -826,6 +826,29 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx) output_state_spent), "could not change output state ignoring oldstate"); + /* Attempt to save an UTXO with close_info set, no commitment_point */ + memset(&u.txid, 2, sizeof(u.txid)); + u.amount = AMOUNT_SAT(5); + u.close_info = tal(w, struct unilateral_close_info); + u.close_info->channel_id = 42; + u.close_info->peer_id = id; + u.close_info->commitment_point = NULL; + CHECK_MSG(wallet_add_utxo(w, &u, p2sh_wpkh), + "wallet_add_utxo with close_info no commitment_point"); + + /* Now select it */ + utxos = wallet_select_coins(w, w, AMOUNT_SAT(5), 0, 21, + 0 /* no confirmations required */, + &fee_estimate, &change_satoshis); + CHECK(utxos && tal_count(utxos) == 2); + + 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)); + /* Now un-reserve them */ + tal_free(utxos); + db_commit_transaction(w->db); return true; } diff --git a/wallet/wallet.c b/wallet/wallet.c index 855f121f3..508e7e2e5 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -111,7 +111,10 @@ bool wallet_add_utxo(struct wallet *w, struct utxo *utxo, if (utxo->close_info) { db_bind_u64(stmt, 6, utxo->close_info->channel_id); db_bind_node_id(stmt, 7, &utxo->close_info->peer_id); - db_bind_pubkey(stmt, 8, &utxo->close_info->commitment_point); + if (utxo->close_info->commitment_point) + db_bind_pubkey(stmt, 8, utxo->close_info->commitment_point); + else + db_bind_null(stmt, 8); } else { db_bind_null(stmt, 6); db_bind_null(stmt, 7); @@ -155,7 +158,13 @@ static struct utxo *wallet_stmt2output(const tal_t *ctx, struct db_stmt *stmt) utxo->close_info = tal(utxo, struct unilateral_close_info); utxo->close_info->channel_id = db_column_u64(stmt, 6); db_column_node_id(stmt, 7, &utxo->close_info->peer_id); - db_column_pubkey(stmt, 8, &utxo->close_info->commitment_point); + if (!db_column_is_null(stmt, 8)) { + utxo->close_info->commitment_point + = tal(utxo->close_info, struct pubkey); + db_column_pubkey(stmt, 8, + utxo->close_info->commitment_point); + } else + utxo->close_info->commitment_point = NULL; } else { utxo->close_info = NULL; }