Skip to content

Commit 4c93e5d

Browse files
committed
wallet: create htable to store scriptpubkeys for issued indexes.
For now we don't actually update it; that's next patch. Signed-off-by: Rusty Russell <[email protected]>
1 parent dc4e78a commit 4c93e5d

File tree

7 files changed

+126
-2
lines changed

7 files changed

+126
-2
lines changed

tests/test_closing.py

-1
Original file line numberDiff line numberDiff line change
@@ -4254,7 +4254,6 @@ def censoring_sendrawtx(r):
42544254

42554255

42564256
@pytest.mark.slow_test
4257-
@pytest.mark.xfail(strict=True)
42584257
def test_slow_startup_many_addresses(node_factory, bitcoind):
42594258
l1, l2 = node_factory.get_nodes(2)
42604259

wallet/test/run-db.c

+3
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ const char *rune_is_ours(struct lightningd *ld UNNEEDED, const struct rune *rune
299299
/* Generated stub for rune_unique_id */
300300
u64 rune_unique_id(const struct rune *rune UNNEEDED)
301301
{ fprintf(stderr, "rune_unique_id called!\n"); abort(); }
302+
/* Generated stub for scriptpubkey_hash */
303+
size_t scriptpubkey_hash(const u8 *out UNNEEDED)
304+
{ fprintf(stderr, "scriptpubkey_hash called!\n"); abort(); }
302305
/* Generated stub for sendpay_index_created */
303306
u64 sendpay_index_created(struct lightningd *ld UNNEEDED,
304307
const struct sha256 *payment_hash UNNEEDED,

wallet/test/run-wallet.c

+3
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,9 @@ const char *rune_is_ours(struct lightningd *ld UNNEEDED, const struct rune *rune
956956
/* Generated stub for rune_unique_id */
957957
u64 rune_unique_id(const struct rune *rune UNNEEDED)
958958
{ fprintf(stderr, "rune_unique_id called!\n"); abort(); }
959+
/* Generated stub for scriptpubkey_hash */
960+
size_t scriptpubkey_hash(const u8 *out UNNEEDED)
961+
{ fprintf(stderr, "scriptpubkey_hash called!\n"); abort(); }
959962
/* Generated stub for serialize_onionpacket */
960963
u8 *serialize_onionpacket(
961964
const tal_t *ctx UNNEEDED,

wallet/txfilter.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <wallet/txfilter.h>
88
#include <wallet/wallet.h>
99

10-
static size_t scriptpubkey_hash(const u8 *out)
10+
size_t scriptpubkey_hash(const u8 *out)
1111
{
1212
struct siphash24_ctx ctx;
1313
siphash24_init(&ctx, siphash_seed());

wallet/txfilter.h

+4
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,8 @@ void outpointfilter_remove(struct outpointfilter *of,
6666

6767
void memleak_scan_outpointfilter(struct htable *memtable,
6868
const struct outpointfilter *opf);
69+
70+
/* Useful for other callers */
71+
size_t scriptpubkey_hash(const u8 *out);
72+
6973
#endif /* LIGHTNING_WALLET_TXFILTER_H */

wallet/wallet.c

+111
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <channeld/channeld_wiregen.h>
88
#include <common/blockheight_states.h>
99
#include <common/fee_states.h>
10+
#include <common/memleak.h>
1011
#include <common/onionreply.h>
1112
#include <common/trace.h>
1213
#include <db/bindings.h>
@@ -64,6 +65,111 @@ static enum state_change state_change_in_db(enum state_change s)
6465
fatal("%s: %u is invalid", __func__, s);
6566
}
6667

68+
/* We keep a hash of these, for fast lookup */
69+
struct wallet_address {
70+
u32 index;
71+
enum addrtype addrtype;
72+
const u8 *scriptpubkey;
73+
};
74+
75+
static const u8 *wallet_address_keyof(const struct wallet_address *waddr)
76+
{
77+
return waddr->scriptpubkey;
78+
}
79+
80+
static bool wallet_address_eq_scriptpubkey(const struct wallet_address *waddr,
81+
const u8 *scriptpubkey)
82+
{
83+
return tal_arr_eq(waddr->scriptpubkey, scriptpubkey);
84+
}
85+
86+
HTABLE_DEFINE_NODUPS_TYPE(struct wallet_address,
87+
wallet_address_keyof,
88+
scriptpubkey_hash,
89+
wallet_address_eq_scriptpubkey,
90+
wallet_address_htable);
91+
92+
static void our_addresses_add(struct wallet_address_htable *our_addresses,
93+
u32 index,
94+
const u8 *scriptpubkey TAKES,
95+
enum addrtype addrtype)
96+
{
97+
struct wallet_address *waddr = tal(our_addresses, struct wallet_address);
98+
99+
waddr->index = index;
100+
waddr->addrtype = addrtype;
101+
waddr->scriptpubkey = tal_dup_talarr(waddr, u8, scriptpubkey);
102+
wallet_address_htable_add(our_addresses, waddr);
103+
}
104+
105+
static void our_addresses_add_for_index(struct wallet *w, u32 i)
106+
{
107+
struct ext_key ext;
108+
enum addrtype addrtype;
109+
const u8 *scriptpubkey;
110+
const u32 flags = BIP32_FLAG_KEY_PUBLIC | BIP32_FLAG_SKIP_HASH;
111+
112+
if (bip32_key_from_parent(w->ld->bip32_base, i,
113+
flags, &ext) != WALLY_OK) {
114+
abort();
115+
}
116+
117+
/* If we don't know (prior to 24.11), just add all
118+
* possibilities. */
119+
/* FIXME: We could deprecate P2SH once we don't see
120+
* any, since we stopped publishing them in 24.02 */
121+
if (!wallet_get_addrtype(w, i, &addrtype)) {
122+
scriptpubkey = scriptpubkey_p2wpkh_derkey(NULL, ext.pub_key);
123+
our_addresses_add(w->our_addresses,
124+
i,
125+
take(scriptpubkey_p2sh(NULL, scriptpubkey)),
126+
ADDR_P2SH_SEGWIT);
127+
our_addresses_add(w->our_addresses,
128+
i,
129+
take(scriptpubkey),
130+
ADDR_BECH32);
131+
scriptpubkey = scriptpubkey_p2tr_derkey(NULL, ext.pub_key);
132+
our_addresses_add(w->our_addresses,
133+
i,
134+
take(scriptpubkey),
135+
ADDR_P2TR);
136+
return;
137+
}
138+
139+
switch (addrtype) {
140+
/* This doesn't happen */
141+
case ADDR_P2SH_SEGWIT:
142+
abort();
143+
case ADDR_BECH32:
144+
case ADDR_ALL:
145+
scriptpubkey = scriptpubkey_p2wpkh_derkey(NULL, ext.pub_key);
146+
our_addresses_add(w->our_addresses,
147+
i,
148+
take(scriptpubkey),
149+
ADDR_BECH32);
150+
if (addrtype != ADDR_ALL)
151+
return;
152+
/* Fall thru */
153+
case ADDR_P2TR:
154+
scriptpubkey = scriptpubkey_p2tr_derkey(NULL, ext.pub_key);
155+
our_addresses_add(w->our_addresses,
156+
i,
157+
take(scriptpubkey),
158+
ADDR_P2TR);
159+
return;
160+
}
161+
abort();
162+
}
163+
164+
static void our_addresses_init(struct wallet *w)
165+
{
166+
w->our_addresses_maxindex = 0;
167+
w->our_addresses = tal(w, struct wallet_address_htable);
168+
wallet_address_htable_init(w->our_addresses);
169+
170+
our_addresses_add_for_index(w, w->our_addresses_maxindex);
171+
}
172+
67173
static void outpointfilters_init(struct wallet *w)
68174
{
69175
struct db_stmt *stmt;
@@ -114,6 +220,10 @@ struct wallet *wallet_new(struct lightningd *ld, struct timers *timers)
114220
outpointfilters_init(wallet);
115221
trace_span_end(wallet);
116222

223+
trace_span_start("our_addresses_init", wallet);
224+
our_addresses_init(wallet);
225+
trace_span_end(wallet);
226+
117227
db_commit_transaction(wallet->db);
118228
return wallet;
119229
}
@@ -6420,6 +6530,7 @@ void wallet_memleak_scan(struct htable *memtable, const struct wallet *w)
64206530
{
64216531
memleak_scan_outpointfilter(memtable, w->utxoset_outpoints);
64226532
memleak_scan_outpointfilter(memtable, w->owned_outpoints);
6533+
memleak_scan_htable(memtable, &w->our_addresses->raw);
64236534
}
64246535

64256536
struct issued_address_type *wallet_list_addresses(const tal_t *ctx, struct wallet *wallet,

wallet/wallet.h

+4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ struct wallet {
4848
* the blockchain. This is currently all P2WSH outputs */
4949
struct outpointfilter *utxoset_outpoints;
5050

51+
/* Our issued wallet addresses. We update on lookup. */
52+
u32 our_addresses_maxindex;
53+
struct wallet_address_htable *our_addresses;
54+
5155
/* How many keys should we look ahead at most? */
5256
u64 keyscan_gap;
5357
};

0 commit comments

Comments
 (0)