lightningd: dispatch bwatch wallet scriptpubkey watches
What changed, and why it matters
This commit wires up the Core Lightning wallet to a new internal watcher service (bwatch) so that incoming payments to wallet addresses are detected and processed. It is a follow-up plumbing change that registers a dispatch handler for wallet scriptpubkey watches. There is no direct evidence in the commit that it fixes a security bug, but it is part of a larger change that could affect how funds are tracked and credited.
Review the preceding commit that introduced wallet_watch_spk and wallet_scriptpubkey_watch_revert to assess whether this dispatch registration is completing a security-relevant fix. In isolation, this commit does not require emergency action.
Security signals we found
Change is infrastructure/plumbing for wallet address watching
No input validation, parsing, or cryptographic logic is modified
No memory safety, authorization, or network-facing changes visible
References handler functions introduced in a previous commit not shown in diff
Evidence from the diff
The patch updates lightningd/watchman.c/h to register the wallet/spk owner prefix with the watchman dispatcher. It adds a watch_handlers entry mapping ‘wallet/spk/’ to wallet_watch_spk and wallet_scriptpubkey_watch_revert, updates documentation comments to reflect the new owner suffix format (e.g., wallet/spk/
Changed components
lightningd/watchman.clightningd/watchman.hCore Lightning wallet/bwatch scriptpubkey watch dispatchInspect captured patch +14 / −10
diff --git a/lightningd/watchman.c b/lightningd/watchman.c
index e5ebaf46..a9671404 100644
--- a/lightningd/watchman.c
+++ b/lightningd/watchman.c
@@ -4,7 +4,6 @@
#include <bitcoin/short_channel_id.h>
#include <ccan/array_size/array_size.h>
#include <ccan/str/str.h>
-#include <ccan/tal/str/str.h>
#include <common/autodata.h>
#include <common/json_command.h>
#include <common/json_param.h>
@@ -38,7 +37,7 @@
/* A pending operation - method and params to send to bwatch */
struct pending_op {
- /* "{method}:{owner}", e.g. "addscriptpubkeywatch:wallet/p2wpkh/42".
+ /* "{method}:{owner}", e.g. "addscriptpubkeywatch:wallet/spk/42/p2tr".
* Method and owner are recoverable from this without a separate field. */
const char *op_id;
const char *json_params; /* JSON params to send to bwatch */
@@ -181,7 +180,7 @@ struct watchman *watchman_new(const tal_t *ctx, struct lightningd *ld)
* callback never needs to parse the JSON-RPC response id. */
struct bwatch_ack_arg {
struct watchman *wm;
- const char *op_id; /* "{method}:{owner}", e.g. "addscriptpubkeywatch:wallet/p2wpkh/42" */
+ const char *op_id; /* "{method}:{owner}", e.g. "addscriptpubkeywatch:wallet/spk/42/p2tr" */
};
/* Response callback for bwatch RPC requests; handles both success and error. */
@@ -218,7 +217,7 @@ static const char *method_from_op_id(const tal_t *ctx, const char *op_id)
}
/* Send an RPC request to the bwatch plugin.
- * op_id must be "{method}:{owner}", e.g. "addscriptpubkeywatch:wallet/p2wpkh/42". */
+ * op_id must be "{method}:{owner}", e.g. "addscriptpubkeywatch:wallet/spk/42/p2tr". */
static void send_to_bwatch(struct watchman *wm, const char *method,
const char *op_id, const char *json_params)
{
@@ -320,8 +319,8 @@ static void watchman_del(struct lightningd *ld, const char *method,
*
* Called when bwatch confirms it has processed an add/del operation.
* Removes the operation from the pending queue and datastore.
- * op_id must be the bare stored id (e.g. "add:wallet/p2wpkh/0"), not the
- * full JSON-RPC response id.
+ * op_id must be the bare stored id (e.g. "addscriptpubkeywatch:wallet/spk/0/p2wpkh"),
+ * not the full JSON-RPC response id.
*/
void watchman_ack(struct lightningd *ld, const char *op_id)
{
@@ -466,7 +465,11 @@ static const struct watch_dispatch {
watch_found_fn handler;
watch_revert_fn revert;
} watch_handlers[] = {
- /* Entries added in subsequent commits alongside their handler functions. */
+ /* wallet/spk/<keyidx>/<form>: WATCH_SCRIPTPUBKEY, fires when an
+ * address form (p2wpkh/p2tr/p2sh_p2wpkh) of this HD key receives
+ * funds. One dispatch entry serves all forms: the handler parses the
+ * keyindex and recovers the form from the matched output script. */
+ { "wallet/spk/", wallet_watch_spk, wallet_scriptpubkey_watch_revert },
{ NULL, NULL, NULL },
};
diff --git a/lightningd/watchman.h b/lightningd/watchman.h
index f7c0893d..b60a9680 100644
--- a/lightningd/watchman.h
+++ b/lightningd/watchman.h
@@ -27,9 +27,10 @@ struct watchman {
/**
* watch_found_fn - Handler for watch_found notifications (tx-based watches)
* @ld: lightningd instance
- * @suffix: the owner string after the prefix (e.g. "42" for wallet/p2wpkh/42,
- * or "100x1x0" for gossip/100x1x0); the handler is responsible for
- * parsing whatever identifier it stored in that suffix
+ * @suffix: the owner string after the prefix (e.g. "42/p2tr" for
+ * wallet/spk/42/p2tr, or "100x1x0" for gossip/100x1x0); the handler
+ * is responsible for parsing whatever identifier it stored in that
+ * suffix
* @tx: the transaction that matched
* @outnum: which output matched (for scriptpubkey watches) or input for outpoint watches
* @blockheight: the block height where tx was found
Why this scored 27/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.