lightningd: add p2wpkh script for bip86 base
What changed, and why it matters
This change fixes a bug where Core Lightning's wallet scanner only watched for Taproot-style transactions for BIP86-derived keys, but missed ordinary SegWit v0 (P2WPKH) transactions. Because BIP86 keys can produce both address types, funds sent to a P2WPKH address derived from the same key would not be detected or credited. This is a correctness/loss-of-funds bug rather than an active theft vulnerability.
Treat as a bug fix with possible funds-recovery implications. Users relying on BIP86-derived P2WPKH addresses should upgrade and rescan; consider release-note mention. No immediate active-exploitation response required.
Security signals we found
Funds availability / loss-of-funds bug
Incomplete address-type coverage for derived keys
Wallet transaction filter omission
No explicit security framing in commit message
Evidence from the diff
In init_txfilter(), the BIP86 keyscan loop previously added only scriptpubkey_p2tr() outputs to the transaction filter. The patch also adds scriptpubkey_p2wpkh() for the same pubkey index. Without this, the wallet’s txfilter would not match P2WPKH outputs derived from BIP86 bases, so those UTXOs would be invisible to the node and unspendable through normal wallet operations. The fix is straightforward and matches the stated intent in the commit message.
Changed components
lightningd/lightningd.cinit_txfilter()wallet txfilter / keyscanInspect captured patch +5 / −2
diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c
index e3eff22d..aff78fc8 100644
--- a/lightningd/lightningd.c
+++ b/lightningd/lightningd.c
@@ -691,8 +691,11 @@ static void init_txfilter(struct wallet *w,
for (u64 i = 0; i <= bip86_max_index + w->keyscan_gap; i++) {
struct pubkey pubkey;
bip86_pubkey(w->ld, &pubkey, i);
- u8 *script = scriptpubkey_p2tr(tmpctx, &pubkey);
- txfilter_add_scriptpubkey(filter, take(script));
+ /* Add both P2TR and P2WPKH scripts since BIP86 keys can be used for both */
+ u8 *p2tr_script = scriptpubkey_p2tr(tmpctx, &pubkey);
+ txfilter_add_scriptpubkey(filter, take(p2tr_script));
+ u8 *p2wpkh_script = scriptpubkey_p2wpkh(tmpctx, &pubkey);
+ txfilter_add_scriptpubkey(filter, take(p2wpkh_script));
}
}
}
Why this scored 46/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.