lightningd: make watch_txid more generic.

Don't assume the arg is a channel.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-10-02 09:29:51 +10:30
parent 4eb2f95e16
commit eb1ef40f96
7 changed files with 111 additions and 90 deletions

View file

@ -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);
}
}

View file

@ -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));

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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,

View file

@ -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,