From eb1ef40f9669f8438aa11e1d8e8d67f8d21a5e95 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 2 Oct 2023 09:29:51 +1030 Subject: [PATCH] lightningd: make watch_txid more generic. Don't assume the arg is a channel. Signed-off-by: Rusty Russell --- lightningd/chaintopology.c | 26 +++++------ lightningd/onchain_control.c | 11 +++-- lightningd/peer_control.c | 19 ++++---- lightningd/test/run-invoice-select-inchan.c | 22 ++++----- lightningd/watch.c | 52 ++++++++++----------- lightningd/watch.h | 49 ++++++++++++++----- wallet/test/run-wallet.c | 22 ++++----- 7 files changed, 111 insertions(+), 90 deletions(-) diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 49be23683..4fb2d8abf 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -306,10 +306,10 @@ void broadcast_tx_(struct chain_topology *topo, } static enum watch_result closeinfo_txid_confirmed(struct lightningd *ld, - struct channel *channel, const struct bitcoin_txid *txid, const struct bitcoin_tx *tx, - unsigned int depth) + unsigned int depth, + void *unused) { /* Sanity check. */ if (tx != NULL) { @@ -317,14 +317,13 @@ static enum watch_result closeinfo_txid_confirmed(struct lightningd *ld, bitcoin_txid(tx, &txid2); if (!bitcoin_txid_eq(txid, &txid2)) { - channel_internal_error(channel, "Txid for %s is not %s", - type_to_string(tmpctx, - struct bitcoin_tx, - tx), - type_to_string(tmpctx, - struct bitcoin_txid, - txid)); - return DELETE_WATCH; + fatal("Txid for %s is not %s", + type_to_string(tmpctx, + struct bitcoin_tx, + tx), + type_to_string(tmpctx, + struct bitcoin_txid, + txid)); } } @@ -358,12 +357,13 @@ static void watch_for_utxo_reconfirmation(struct chain_topology *topo, assert(unconfirmed[i]->close_info != NULL); assert(unconfirmed[i]->blockheight == NULL); - if (find_txwatch(topo, &unconfirmed[i]->outpoint.txid, NULL)) + if (find_txwatch(topo, &unconfirmed[i]->outpoint.txid, + closeinfo_txid_confirmed, NULL)) continue; - watch_txid(topo, topo, NULL, + watch_txid(topo, topo, &unconfirmed[i]->outpoint.txid, - closeinfo_txid_confirmed); + closeinfo_txid_confirmed, NULL); } } diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index c55ea26fc..252c98427 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -160,10 +160,10 @@ static void onchain_tx_depth(struct channel *channel, * Entrypoint for the txwatch callback, calls onchain_tx_depth. */ static enum watch_result onchain_tx_watched(struct lightningd *ld, - struct channel *channel, const struct bitcoin_txid *txid, const struct bitcoin_tx *tx, - unsigned int depth) + unsigned int depth, + struct channel *channel) { u32 blockheight = get_block_height(ld->topology); @@ -255,9 +255,9 @@ static void watch_tx_and_outputs(struct channel *channel, bitcoin_txid(tx, &outpoint.txid); /* Make txwatch a parent of txo watches, so we can unwatch together. */ - txw = watch_txid(channel->owner, ld->topology, channel, + txw = watch_txid(channel->owner, ld->topology, &outpoint.txid, - onchain_tx_watched); + onchain_tx_watched, channel); for (outpoint.n = 0; outpoint.n < tx->wtx->num_outputs; outpoint.n++) watch_txo(txw, ld->topology, channel, &outpoint, @@ -295,7 +295,8 @@ static void handle_onchain_unwatch_tx(struct channel *channel, const u8 *msg) } /* Frees the txo watches, too: see watch_tx_and_outputs() */ - txw = find_txwatch(channel->peer->ld->topology, &txid, channel); + txw = find_txwatch(channel->peer->ld->topology, &txid, + onchain_tx_watched, channel); if (!txw) log_unusual(channel->log, "Can't unwatch txid %s", type_to_string(tmpctx, struct bitcoin_txid, &txid)); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 58e455426..c80f9c8da 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -1878,10 +1878,10 @@ static void subd_tell_depth(struct channel *channel, } static enum watch_result funding_depth_cb(struct lightningd *ld, - struct channel *channel, - const struct bitcoin_txid *txid, - const struct bitcoin_tx *tx, - unsigned int depth) + const struct bitcoin_txid *txid, + const struct bitcoin_tx *tx, + unsigned int depth, + struct channel *channel) { struct short_channel_id scid; struct txlocator *loc; @@ -2097,7 +2097,6 @@ void channel_watch_wrong_funding(struct lightningd *ld, struct channel *channel) { /* Watch the "wrong" funding too, in case we spend it. */ if (channel->shutdown_wrong_funding) { - /* FIXME: Remove arg from cb? */ watch_txo(channel, ld->topology, channel, channel->shutdown_wrong_funding, funding_spent); @@ -2106,11 +2105,10 @@ void channel_watch_wrong_funding(struct lightningd *ld, struct channel *channel) void channel_watch_funding(struct lightningd *ld, struct channel *channel) { - /* FIXME: Remove arg from cb? */ log_debug(channel->log, "Watching for funding txid: %s", type_to_string(tmpctx, struct bitcoin_txid, &channel->funding.txid)); - watch_txid(channel, ld->topology, channel, - &channel->funding.txid, funding_depth_cb); + watch_txid(channel, ld->topology, + &channel->funding.txid, funding_depth_cb, channel); watch_txo(channel, ld->topology, channel, &channel->funding, funding_spent); @@ -2121,9 +2119,8 @@ void channel_watch_inflight(struct lightningd *ld, struct channel *channel, struct channel_inflight *inflight) { - /* FIXME: Remove arg from cb? */ - watch_txid(channel, ld->topology, channel, - &inflight->funding->outpoint.txid, funding_depth_cb); + watch_txid(channel, ld->topology, + &inflight->funding->outpoint.txid, funding_depth_cb, channel); watch_txo(channel, ld->topology, channel, &inflight->funding->outpoint, funding_spent); diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index aa5a25d03..3c9fc3013 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/lightningd/test/run-invoice-select-inchan.c @@ -1009,17 +1009,17 @@ void wallet_transaction_add(struct wallet *w UNNEEDED, const struct wally_tx *tx struct txlocator *wallet_transaction_locate(const tal_t *ctx UNNEEDED, struct wallet *w UNNEEDED, const struct bitcoin_txid *txid UNNEEDED) { fprintf(stderr, "wallet_transaction_locate called!\n"); abort(); } -/* Generated stub for watch_txid */ -struct txwatch *watch_txid(const tal_t *ctx UNNEEDED, - struct chain_topology *topo UNNEEDED, - struct channel *channel UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - enum watch_result (*cb)(struct lightningd *ld UNNEEDED, - struct channel * UNNEEDED, - const struct bitcoin_txid * UNNEEDED, - const struct bitcoin_tx * UNNEEDED, - unsigned int depth)) -{ fprintf(stderr, "watch_txid called!\n"); abort(); } +/* Generated stub for watch_txid_ */ +struct txwatch *watch_txid_(const tal_t *ctx UNNEEDED, + struct chain_topology *topo UNNEEDED, + const struct bitcoin_txid *txid UNNEEDED, + enum watch_result (*cb)(struct lightningd *ld UNNEEDED, + const struct bitcoin_txid * UNNEEDED, + const struct bitcoin_tx * UNNEEDED, + unsigned int depth UNNEEDED, + void *arg) UNNEEDED, + void *arg UNNEEDED) +{ fprintf(stderr, "watch_txid_ called!\n"); abort(); } /* Generated stub for watch_txo */ struct txowatch *watch_txo(const tal_t *ctx UNNEEDED, struct chain_topology *topo UNNEEDED, diff --git a/lightningd/watch.c b/lightningd/watch.c index dacc19359..f533044b5 100644 --- a/lightningd/watch.c +++ b/lightningd/watch.c @@ -53,9 +53,6 @@ struct txowatch { struct txwatch { struct chain_topology *topo; - /* Channel who owns us (or NULL, for wallet usage). */ - struct channel *channel; - /* Transaction to watch. */ struct bitcoin_txid txid; @@ -66,10 +63,11 @@ struct txwatch { /* A new depth (0 if kicked out, otherwise 1 = tip, etc.) */ enum watch_result (*cb)(struct lightningd *ld, - struct channel *channel, const struct bitcoin_txid *txid, const struct bitcoin_tx *tx, - unsigned int depth); + unsigned int depth, + void *arg); + void *cbarg; }; const struct bitcoin_outpoint *txowatch_keyof(const struct txowatch *w) @@ -118,15 +116,15 @@ static void destroy_txwatch(struct txwatch *w) txwatch_hash_del(w->topo->txwatches, w); } -struct txwatch *watch_txid(const tal_t *ctx, - struct chain_topology *topo, - struct channel *channel, - const struct bitcoin_txid *txid, - enum watch_result (*cb)(struct lightningd *ld, - struct channel *, - const struct bitcoin_txid *, - const struct bitcoin_tx *, - unsigned int depth)) +struct txwatch *watch_txid_(const tal_t *ctx, + struct chain_topology *topo, + const struct bitcoin_txid *txid, + enum watch_result (*cb)(struct lightningd *ld, + const struct bitcoin_txid *, + const struct bitcoin_tx *, + unsigned int depth, + void *arg), + void *arg) { struct txwatch *w; @@ -135,8 +133,8 @@ struct txwatch *watch_txid(const tal_t *ctx, w->depth = 0; w->txid = *txid; w->tx = NULL; - w->channel = channel; w->cb = cb; + w->cbarg = arg; txwatch_hash_add(w->topo->txwatches, w); tal_add_destructor(w, destroy_txwatch); @@ -144,9 +142,14 @@ struct txwatch *watch_txid(const tal_t *ctx, return w; } -struct txwatch *find_txwatch(struct chain_topology *topo, - const struct bitcoin_txid *txid, - const struct channel *channel) +struct txwatch *find_txwatch_(struct chain_topology *topo, + const struct bitcoin_txid *txid, + enum watch_result (*cb)(struct lightningd *ld, + const struct bitcoin_txid *, + const struct bitcoin_tx *, + unsigned int depth, + void *arg), + void *arg) { struct txwatch_hash_iter i; struct txwatch *w; @@ -156,7 +159,7 @@ struct txwatch *find_txwatch(struct chain_topology *topo, for (w = txwatch_hash_getfirst(topo->txwatches, txid, &i); w; w = txwatch_hash_getnext(topo->txwatches, txid, &i)) { - if (w->channel == channel) + if (w->cb == cb && w->cbarg == arg) break; } return w; @@ -196,24 +199,19 @@ static bool txw_fire(struct txwatch *txw, unsigned int depth) { enum watch_result r; - struct logger *log; if (depth == txw->depth) return false; - if (txw->channel) - log = txw->channel->log; - else - log = txw->topo->log; /* We assume zero depth signals a reorganization */ - log_debug(log, + log_debug(txw->topo->log, "Got depth change %u->%u for %s%s", txw->depth, depth, type_to_string(tmpctx, struct bitcoin_txid, &txw->txid), depth ? "" : " REORG"); txw->depth = depth; - r = txw->cb(txw->topo->bitcoind->ld, txw->channel, txid, txw->tx, - txw->depth); + r = txw->cb(txw->topo->bitcoind->ld, txid, txw->tx, txw->depth, + txw->cbarg); switch (r) { case DELETE_WATCH: tal_free(txw); diff --git a/lightningd/watch.h b/lightningd/watch.h index d722eb9d7..07a7b9ad1 100644 --- a/lightningd/watch.h +++ b/lightningd/watch.h @@ -30,15 +30,25 @@ HTABLE_DEFINE_TYPE(struct txwatch, txwatch_keyof, txid_hash, txwatch_eq, txwatch_hash); -struct txwatch *watch_txid(const tal_t *ctx, - struct chain_topology *topo, - struct channel *channel, - const struct bitcoin_txid *txid, - enum watch_result (*cb)(struct lightningd *ld, - struct channel *, - const struct bitcoin_txid *, - const struct bitcoin_tx *, - unsigned int depth)); +struct txwatch *watch_txid_(const tal_t *ctx, + struct chain_topology *topo, + const struct bitcoin_txid *txid, + enum watch_result (*cb)(struct lightningd *ld, + const struct bitcoin_txid *, + const struct bitcoin_tx *, + unsigned int depth, + void *arg), + void *arg); + +#define watch_txid(ctx, topo, txid, cb, arg) \ + watch_txid_((ctx), (topo), (txid), \ + typesafe_cb_preargs(enum watch_result, void *, \ + (cb), (arg), \ + struct lightningd *, \ + const struct bitcoin_txid *, \ + const struct bitcoin_tx *, \ + unsigned int depth), \ + (arg)) struct txowatch *watch_txo(const tal_t *ctx, struct chain_topology *topo, @@ -49,9 +59,24 @@ struct txowatch *watch_txo(const tal_t *ctx, size_t input_num, const struct block *block)); -struct txwatch *find_txwatch(struct chain_topology *topo, - const struct bitcoin_txid *txid, - const struct channel *channel); +struct txwatch *find_txwatch_(struct chain_topology *topo, + const struct bitcoin_txid *txid, + enum watch_result (*cb)(struct lightningd *ld, + const struct bitcoin_txid *, + const struct bitcoin_tx *, + unsigned int depth, + void *arg), + void *arg); + +#define find_txwatch(topo, txid, cb, arg) \ + find_txwatch_((topo), (txid), \ + typesafe_cb_preargs(enum watch_result, void *, \ + (cb), (arg), \ + struct lightningd *, \ + const struct bitcoin_txid *, \ + const struct bitcoin_tx *, \ + unsigned int depth), \ + (arg)) void txwatch_fire(struct chain_topology *topo, const struct bitcoin_txid *txid, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index f1179964d..c6c58384f 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -898,17 +898,17 @@ const char *wait_index_name(enum wait_index index UNNEEDED) /* Generated stub for wait_subsystem_name */ const char *wait_subsystem_name(enum wait_subsystem subsystem UNNEEDED) { fprintf(stderr, "wait_subsystem_name called!\n"); abort(); } -/* Generated stub for watch_txid */ -struct txwatch *watch_txid(const tal_t *ctx UNNEEDED, - struct chain_topology *topo UNNEEDED, - struct channel *channel UNNEEDED, - const struct bitcoin_txid *txid UNNEEDED, - enum watch_result (*cb)(struct lightningd *ld UNNEEDED, - struct channel * UNNEEDED, - const struct bitcoin_txid * UNNEEDED, - const struct bitcoin_tx * UNNEEDED, - unsigned int depth)) -{ fprintf(stderr, "watch_txid called!\n"); abort(); } +/* Generated stub for watch_txid_ */ +struct txwatch *watch_txid_(const tal_t *ctx UNNEEDED, + struct chain_topology *topo UNNEEDED, + const struct bitcoin_txid *txid UNNEEDED, + enum watch_result (*cb)(struct lightningd *ld UNNEEDED, + const struct bitcoin_txid * UNNEEDED, + const struct bitcoin_tx * UNNEEDED, + unsigned int depth UNNEEDED, + void *arg) UNNEEDED, + void *arg UNNEEDED) +{ fprintf(stderr, "watch_txid_ called!\n"); abort(); } /* Generated stub for watch_txo */ struct txowatch *watch_txo(const tal_t *ctx UNNEEDED, struct chain_topology *topo UNNEEDED,