Skip to content

Commit 6a81f07

Browse files
committed
wallet: don't assume wally_tx outputs tal_bytelen(script) is the same as script_len.
It seems to be here, but it wouldn't have to be, so use the explicit length. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent e82f0c4 commit 6a81f07

File tree

6 files changed

+43
-17
lines changed

6 files changed

+43
-17
lines changed

lightningd/closing_control.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd)
484484
if (wallet_can_spend(
485485
ld->wallet,
486486
channel->shutdown_scriptpubkey[LOCAL],
487+
tal_bytelen(channel->shutdown_scriptpubkey[LOCAL]),
487488
&index_val)) {
488489
if (bip32_key_from_parent(
489490
ld->bip32_base,
@@ -742,7 +743,7 @@ static struct command_result *json_close(struct command *cmd,
742743
}
743744

744745
/* If they give a local address, adjust final_key_idx. */
745-
if (!wallet_can_spend(cmd->ld->wallet, close_to_script,
746+
if (!wallet_can_spend(cmd->ld->wallet, close_to_script, tal_bytelen(close_to_script),
746747
&final_key_idx)) {
747748
final_key_idx = channel->final_key_idx;
748749
}

lightningd/dual_open_control.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ openchannel2_hook_cb(struct openchannel2_payload *payload STEALS)
695695
u32 found_wallet_index;
696696
if (wallet_can_spend(dualopend->ld->wallet,
697697
payload->our_shutdown_scriptpubkey,
698+
tal_bytelen(payload->our_shutdown_scriptpubkey),
698699
&found_wallet_index)) {
699700
our_shutdown_script_wallet_index = tal(tmpctx, u32);
700701
*our_shutdown_script_wallet_index = found_wallet_index;
@@ -3092,6 +3093,7 @@ static struct command_result *openchannel_init(struct command *cmd,
30923093
* NULL if not found. */
30933094
if (wallet_can_spend(cmd->ld->wallet,
30943095
oa->our_upfront_shutdown_script,
3096+
tal_bytelen(oa->our_upfront_shutdown_script),
30953097
&found_wallet_index)) {
30963098
our_upfront_shutdown_script_wallet_index = &found_wallet_index;
30973099
} else
@@ -3860,6 +3862,7 @@ static struct command_result *json_queryrates(struct command *cmd,
38603862
u32 found_wallet_index;
38613863
if (wallet_can_spend(cmd->ld->wallet,
38623864
oa->our_upfront_shutdown_script,
3865+
tal_bytelen(oa->our_upfront_shutdown_script),
38633866
&found_wallet_index)) {
38643867
our_upfront_shutdown_script_wallet_index = tal(tmpctx, u32);
38653868
*our_upfront_shutdown_script_wallet_index = found_wallet_index;
@@ -4207,6 +4210,7 @@ bool peer_restart_dualopend(struct peer *peer,
42074210
u32 found_wallet_index;
42084211
if (wallet_can_spend(peer->ld->wallet,
42094212
channel->shutdown_scriptpubkey[LOCAL],
4213+
tal_bytelen(channel->shutdown_scriptpubkey[LOCAL]),
42104214
&found_wallet_index)) {
42114215
local_shutdown_script_wallet_index = tal(tmpctx, u32);
42124216
*local_shutdown_script_wallet_index = found_wallet_index;

lightningd/opening_control.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ openchannel_hook_final(struct openchannel_hook_payload *payload STEALS)
710710
u32 found_wallet_index;
711711
if (wallet_can_spend(payload->openingd->ld->wallet,
712712
our_upfront_shutdown_script,
713+
tal_bytelen(our_upfront_shutdown_script),
713714
&found_wallet_index)) {
714715
upfront_shutdown_script_wallet_index = tal(tmpctx, u32);
715716
*upfront_shutdown_script_wallet_index = found_wallet_index;
@@ -1400,6 +1401,7 @@ static struct command_result *json_fundchannel_start(struct command *cmd,
14001401
u32 found_wallet_index;
14011402
if (wallet_can_spend(fc->cmd->ld->wallet,
14021403
fc->our_upfront_shutdown_script,
1404+
tal_bytelen(fc->our_upfront_shutdown_script),
14031405
&found_wallet_index)) {
14041406
upfront_shutdown_script_wallet_index = tal(tmpctx, u32);
14051407
*upfront_shutdown_script_wallet_index = found_wallet_index;

wallet/wallet.c

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,40 +65,53 @@ static enum state_change state_change_in_db(enum state_change s)
6565
fatal("%s: %u is invalid", __func__, s);
6666
}
6767

68+
/* libwally uses pointer/size pairs */
69+
struct script_with_len {
70+
const u8 *script;
71+
size_t len;
72+
};
73+
6874
/* We keep a hash of these, for fast lookup */
6975
struct wallet_address {
7076
u32 index;
7177
enum addrtype addrtype;
72-
const u8 *scriptpubkey;
78+
struct script_with_len swl;
7379
};
7480

75-
static const u8 *wallet_address_keyof(const struct wallet_address *waddr)
81+
static size_t script_with_len_hash(const struct script_with_len *swl)
82+
{
83+
return siphash24(siphash_seed(), swl->script, swl->len);
84+
}
85+
86+
static const struct script_with_len *wallet_address_keyof(const struct wallet_address *waddr)
7687
{
77-
return waddr->scriptpubkey;
88+
return &waddr->swl;
7889
}
7990

8091
static bool wallet_address_eq_scriptpubkey(const struct wallet_address *waddr,
81-
const u8 *scriptpubkey)
92+
const struct script_with_len *script)
8293
{
83-
return tal_arr_eq(waddr->scriptpubkey, scriptpubkey);
94+
return memeq(waddr->swl.script, waddr->swl.len, script->script, script->len);
8495
}
8596

8697
HTABLE_DEFINE_NODUPS_TYPE(struct wallet_address,
8798
wallet_address_keyof,
88-
scriptpubkey_hash,
99+
script_with_len_hash,
89100
wallet_address_eq_scriptpubkey,
90101
wallet_address_htable);
91102

92103
static void our_addresses_add(struct wallet_address_htable *our_addresses,
93104
u32 index,
94105
const u8 *scriptpubkey TAKES,
106+
size_t scriptpubkey_len,
95107
enum addrtype addrtype)
96108
{
97109
struct wallet_address *waddr = tal(our_addresses, struct wallet_address);
98110

99111
waddr->index = index;
100112
waddr->addrtype = addrtype;
101-
waddr->scriptpubkey = tal_dup_talarr(waddr, u8, scriptpubkey);
113+
waddr->swl.script = tal_dup_arr(waddr, u8, scriptpubkey, scriptpubkey_len, 0);
114+
waddr->swl.len = scriptpubkey_len;
102115
wallet_address_htable_add(our_addresses, waddr);
103116
}
104117

@@ -119,19 +132,20 @@ static void our_addresses_add_for_index(struct wallet *w, u32 i)
119132
/* FIXME: We could deprecate P2SH once we don't see
120133
* any, since we stopped publishing them in 24.02 */
121134
if (!wallet_get_addrtype(w, i, &addrtype)) {
135+
const u8 *addr;
122136
scriptpubkey = scriptpubkey_p2wpkh_derkey(NULL, ext.pub_key);
137+
addr = scriptpubkey_p2sh(NULL, scriptpubkey);
123138
our_addresses_add(w->our_addresses,
124-
i,
125-
take(scriptpubkey_p2sh(NULL, scriptpubkey)),
139+
i, take(addr), tal_bytelen(addr),
126140
ADDR_P2SH_SEGWIT);
127141
our_addresses_add(w->our_addresses,
128142
i,
129-
take(scriptpubkey),
143+
take(scriptpubkey), tal_bytelen(scriptpubkey),
130144
ADDR_BECH32);
131145
scriptpubkey = scriptpubkey_p2tr_derkey(NULL, ext.pub_key);
132146
our_addresses_add(w->our_addresses,
133147
i,
134-
take(scriptpubkey),
148+
take(scriptpubkey), tal_bytelen(scriptpubkey),
135149
ADDR_P2TR);
136150
return;
137151
}
@@ -146,6 +160,7 @@ static void our_addresses_add_for_index(struct wallet *w, u32 i)
146160
our_addresses_add(w->our_addresses,
147161
i,
148162
take(scriptpubkey),
163+
tal_bytelen(scriptpubkey),
149164
ADDR_BECH32);
150165
if (addrtype != ADDR_ALL)
151166
return;
@@ -155,6 +170,7 @@ static void our_addresses_add_for_index(struct wallet *w, u32 i)
155170
our_addresses_add(w->our_addresses,
156171
i,
157172
take(scriptpubkey),
173+
tal_bytelen(scriptpubkey),
158174
ADDR_P2TR);
159175
return;
160176
}
@@ -892,18 +908,19 @@ bool wallet_add_onchaind_utxo(struct wallet *w,
892908
return true;
893909
}
894910

895-
bool wallet_can_spend(struct wallet *w, const u8 *script,
911+
bool wallet_can_spend(struct wallet *w, const u8 *script, size_t script_len,
896912
u32 *index)
897913
{
898914
u64 bip32_max_index;
899915
const struct wallet_address *waddr;
916+
struct script_with_len scriptwl = {script, script_len};
900917

901918
/* Update hash table if we need to */
902919
bip32_max_index = db_get_intvar(w->db, "bip32_max_index", 0);
903920
while (w->our_addresses_maxindex < bip32_max_index + w->keyscan_gap)
904921
our_addresses_add_for_index(w, ++w->our_addresses_maxindex);
905922

906-
waddr = wallet_address_htable_get(w->our_addresses, script);
923+
waddr = wallet_address_htable_get(w->our_addresses, &scriptwl);
907924
if (!waddr)
908925
return false;
909926

@@ -2914,7 +2931,7 @@ int wallet_extract_owned_outputs(struct wallet *w, const struct wally_tx *wtx,
29142931
if (!amount_asset_is_main(&asset))
29152932
continue;
29162933

2917-
if (!wallet_can_spend(w, txout->script, &index))
2934+
if (!wallet_can_spend(w, txout->script, txout->script_len, &index))
29182935
continue;
29192936

29202937
utxo = tal(w, struct utxo);

wallet/wallet.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,10 +591,12 @@ struct utxo **wallet_utxo_boost(const tal_t *ctx,
591591
*
592592
* @w: (in) wallet holding the pubkeys to check against (privkeys are on HSM)
593593
* @script: (in) the script to check
594+
* @script_len: (in) the length of @script
594595
* @index: (out) the bip32 derivation index that matched the script
595596
*/
596597
bool wallet_can_spend(struct wallet *w,
597598
const u8 *script,
599+
size_t script_len,
598600
u32 *index);
599601

600602
/**

wallet/walletrpc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ static void match_psbt_outputs_to_wallet(struct wally_psbt *psbt,
729729
const size_t script_len = psbt->outputs[outndx].script_len;
730730
u32 index;
731731

732-
if (!wallet_can_spend(w, script, &index))
732+
if (!wallet_can_spend(w, script, script_len, &index))
733733
continue;
734734

735735
if (bip32_key_from_parent(
@@ -936,7 +936,7 @@ static void maybe_notify_new_external_send(struct lightningd *ld,
936936
/* If it's going to our wallet, ignore */
937937
script = wally_psbt_output_get_script(tmpctx,
938938
&psbt->outputs[outnum]);
939-
if (wallet_can_spend(ld->wallet, script, &index))
939+
if (wallet_can_spend(ld->wallet, script, tal_bytelen(script), &index))
940940
return;
941941

942942
outpoint.txid = *txid;

0 commit comments

Comments
 (0)