Skip to content

Commit 6da97e6

Browse files
committed
wallet: save keytype when issuing new address.
Signed-off-by: Rusty Russell <[email protected]>
1 parent 13af9bc commit 6da97e6

File tree

9 files changed

+107
-18
lines changed

9 files changed

+107
-18
lines changed

lightningd/channel_control.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,9 +1212,9 @@ static void peer_got_shutdown(struct channel *channel, const u8 *msg)
12121212
u8 *scriptpubkey;
12131213
struct lightningd *ld = channel->peer->ld;
12141214
struct bitcoin_outpoint *wrong_funding;
1215-
bool anysegwit = feature_negotiated(ld->our_features,
1216-
channel->peer->their_features,
1217-
OPT_SHUTDOWN_ANYSEGWIT);
1215+
bool anysegwit = !chainparams->is_elements && feature_negotiated(ld->our_features,
1216+
channel->peer->their_features,
1217+
OPT_SHUTDOWN_ANYSEGWIT);
12181218
bool anchors = feature_negotiated(ld->our_features,
12191219
channel->peer->their_features,
12201220
OPT_ANCHOR_OUTPUTS_DEPRECATED)

lightningd/dual_open_control.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,9 @@ wallet_commit_channel(struct lightningd *ld,
13831383
{
13841384
struct amount_msat our_msat, lease_fee_msat;
13851385
struct channel_inflight *inflight;
1386+
bool anysegwit = !chainparams->is_elements && feature_negotiated(channel->peer->ld->our_features,
1387+
channel->peer->their_features,
1388+
OPT_SHUTDOWN_ANYSEGWIT);
13861389
bool any_active = peer_any_channel(channel->peer, channel_state_wants_peercomms, NULL);
13871390

13881391
if (!amount_sat_to_msat(&our_msat, our_funding)) {
@@ -1395,8 +1398,11 @@ wallet_commit_channel(struct lightningd *ld,
13951398
return NULL;
13961399
}
13971400

1398-
/* Get a key to use for closing outputs from this tx */
1399-
channel->final_key_idx = wallet_get_newindex(ld);
1401+
/* Get a key to use for closing outputs from this tx. Prefer
1402+
* P2TR, but we'll use BECH32 for older peers (but always P2TR
1403+
* for our own onchian spends, if any). */
1404+
1405+
channel->final_key_idx = wallet_get_newindex(ld, anysegwit ? ADDR_P2TR : (ADDR_BECH32|ADDR_P2TR));
14001406
if (channel->final_key_idx == -1) {
14011407
log_broken(channel->log, "Can't get final key index");
14021408
return NULL;

lightningd/opening_control.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ wallet_commit_channel(struct lightningd *ld,
110110
struct timeabs timestamp;
111111
bool any_active = peer_any_channel(uc->peer, channel_state_wants_peercomms, NULL);
112112
struct channel_stats zero_channel_stats;
113+
enum addrtype addrtype;
113114

114115
/* We can't have any payments yet */
115116
memset(&zero_channel_stats, 0, sizeof(zero_channel_stats));
@@ -119,8 +120,14 @@ wallet_commit_channel(struct lightningd *ld,
119120
*/
120121
assert(!(uc->got_offer && uc->fc));
121122

123+
/* FIXME: P2TR for elements! */
124+
if (chainparams->is_elements)
125+
addrtype = ADDR_BECH32;
126+
else
127+
addrtype = ADDR_P2TR;
128+
122129
/* Get a key to use for closing outputs from this tx */
123-
final_key_idx = wallet_get_newindex(ld);
130+
final_key_idx = wallet_get_newindex(ld, addrtype);
124131
if (final_key_idx == -1) {
125132
log_broken(uc->log, "Can't get final key index");
126133
return NULL;

wallet/db.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,9 @@ static struct migration dbmigrations[] = {
10211021
{SQL("ALTER TABLE channels ADD remote_htlc_minimum_msat BIGINT DEFAULT NULL;"), NULL},
10221022
{SQL("ALTER TABLE channels ADD last_stable_connection BIGINT DEFAULT 0;"), NULL},
10231023
{NULL, migrate_initialize_alias_local},
1024-
/* FIXME: Remove now-unused type column from channeltxs */
1024+
{SQL("CREATE TABLE addresses ("
1025+
" keyidx BIGINT,"
1026+
" addrtype INTEGER)"), NULL},
10251027
};
10261028

10271029
/**

wallet/reservation.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,16 @@ static struct command_result *finish_psbt(struct command *cmd,
366366
struct pubkey pubkey;
367367
s64 keyidx;
368368
u8 *b32script;
369+
enum addrtype type;
370+
371+
/* FIXME: P2TR for elements! */
372+
if (chainparams->is_elements)
373+
type = ADDR_BECH32;
374+
else
375+
type = ADDR_P2TR;
369376

370377
/* Get a change adddress */
371-
keyidx = wallet_get_newindex(cmd->ld);
378+
keyidx = wallet_get_newindex(cmd->ld, type);
372379
if (keyidx < 0)
373380
return command_fail(cmd, LIGHTNINGD,
374381
"Failed to generate change address."
@@ -700,7 +707,15 @@ static struct command_result *json_addpsbtoutput(struct command *cmd,
700707

701708
/* Get a change adddress */
702709
if (!b32script) {
703-
keyidx = wallet_get_newindex(cmd->ld);
710+
enum addrtype type;
711+
712+
/* FIXME: P2TR for elements! */
713+
if (chainparams->is_elements)
714+
type = ADDR_BECH32;
715+
else
716+
type = ADDR_P2TR;
717+
718+
keyidx = wallet_get_newindex(cmd->ld, type);
704719
if (keyidx < 0)
705720
return command_fail(cmd, LIGHTNINGD,
706721
"Failed to generate change address."

wallet/wallet.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,17 +836,50 @@ bool wallet_can_spend(struct wallet *w, const u8 *script,
836836
return false;
837837
}
838838

839-
s64 wallet_get_newindex(struct lightningd *ld)
839+
s64 wallet_get_newindex(struct lightningd *ld, enum addrtype addrtype)
840840
{
841+
struct db_stmt *stmt;
841842
u64 newidx = db_get_intvar(ld->wallet->db, "bip32_max_index", 0) + 1;
842843

843844
if (newidx == BIP32_INITIAL_HARDENED_CHILD)
844845
return -1;
845846

846847
db_set_intvar(ld->wallet->db, "bip32_max_index", newidx);
848+
stmt = db_prepare_v2(ld->wallet->db,
849+
SQL("INSERT INTO addresses ("
850+
" keyidx"
851+
", addrtype"
852+
") VALUES (?, ?);"));
853+
db_bind_u64(stmt, newidx);
854+
db_bind_int(stmt, wallet_addrtype_in_db(addrtype));
855+
db_exec_prepared_v2(take(stmt));
856+
847857
return newidx;
848858
}
849859

860+
enum addrtype wallet_get_addrtype(struct wallet *wallet, u64 idx)
861+
{
862+
struct db_stmt *stmt;
863+
enum addrtype type;
864+
865+
stmt = db_prepare_v2(wallet->db,
866+
SQL("SELECT addrtype"
867+
" FROM addresses"
868+
" WHERE keyidx=?"));
869+
db_bind_u64(stmt, idx);
870+
db_query_prepared(stmt);
871+
872+
/* Unknown means prior to v24.11 */
873+
if (!db_step(stmt)) {
874+
tal_free(stmt);
875+
return ADDR_P2TR|ADDR_BECH32;
876+
}
877+
878+
type = wallet_addrtype_in_db(db_col_int(stmt, "addrtype"));
879+
tal_free(stmt);
880+
return type;
881+
}
882+
850883
static void wallet_shachain_init(struct wallet *wallet,
851884
struct wallet_shachain *chain)
852885
{

wallet/wallet.h

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,30 @@ static inline enum channel_state channel_state_in_db(enum channel_state s)
271271
fatal("%s: %u is invalid", __func__, s);
272272
}
273273

274+
/* /!\ This is a DB ENUM, please do not change the numbering of any
275+
* already defined elements (adding is ok) /!\ */
276+
enum addrtype {
277+
ADDR_BECH32 = 2,
278+
ADDR_P2TR = 4,
279+
ADDR_ALL = (ADDR_BECH32 + ADDR_P2TR)
280+
};
281+
282+
static inline enum addrtype wallet_addrtype_in_db(enum addrtype t)
283+
{
284+
switch (t) {
285+
case ADDR_BECH32:
286+
BUILD_ASSERT(ADDR_BECH32 == 2);
287+
return t;
288+
case ADDR_P2TR:
289+
BUILD_ASSERT(ADDR_P2TR == 4);
290+
return t;
291+
case ADDR_ALL:
292+
BUILD_ASSERT(ADDR_ALL == 6);
293+
return t;
294+
}
295+
fatal("%s: %u is invalid", __func__, t);
296+
}
297+
274298
/* A database backed shachain struct. The datastructure is
275299
* writethrough, reads are performed from an in-memory version, all
276300
* writes are passed through to the DB. */
@@ -567,10 +591,18 @@ bool wallet_can_spend(struct wallet *w,
567591
/**
568592
* wallet_get_newindex - get a new index from the wallet.
569593
* @ld: (in) lightning daemon
594+
* @addrtype: (in) addess types we will publish for this
570595
*
571596
* Returns -1 on error (key exhaustion).
572597
*/
573-
s64 wallet_get_newindex(struct lightningd *ld);
598+
s64 wallet_get_newindex(struct lightningd *ld, enum addrtype addrtype);
599+
600+
/**
601+
* wallet_get_addrtype - get the address types for this key.
602+
* @wallet: (in) wallet
603+
* @keyidx: what address types we've published.
604+
*/
605+
enum addrtype wallet_get_addrtype(struct wallet *w, u64 keyidx);
574606

575607
/**
576608
* wallet_shachain_add_hash -- wallet wrapper around shachain_add_hash

wallet/walletrpc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ bool WARN_UNUSED_RESULT newaddr_inner(struct command *cmd, struct pubkey *pubkey
119119
u8 *b32script;
120120
u8 *p2tr_script;
121121

122-
keyidx = wallet_get_newindex(cmd->ld);
122+
keyidx = wallet_get_newindex(cmd->ld, addrtype);
123123
if (keyidx < 0) {
124124
// return command_fail(cmd, LIGHTNINGD, "Keys exhausted ");
125125
return false;

wallet/walletrpc.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
#define LIGHTNING_WALLET_WALLETRPC_H
33
#include "config.h"
44

5-
enum addrtype {
6-
ADDR_BECH32 = 2,
7-
ADDR_P2TR = 4,
8-
ADDR_ALL = (ADDR_BECH32 + ADDR_P2TR)
9-
};
10-
115
struct utxo;
126

137
/* We evaluate reserved timeouts lazily, so use this. */

0 commit comments

Comments
 (0)