Skip to content

Commit 478a0d5

Browse files
committed
wallet: make sure to watch all txids in transactions table.
We watch if they are to do with a channel, or have outputs going to us, but otherwise we didn't, so we never updated the blockheight in the db. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Fixed: JSON-RPC: `listtransactions` now correctly updates `blockheight` for txs created by `sendpsbt` which have no change outputs.
1 parent 2591ac4 commit 478a0d5

File tree

5 files changed

+62
-7
lines changed

5 files changed

+62
-7
lines changed

lightningd/chaintopology.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,37 @@ static void watch_for_utxo_reconfirmation(struct chain_topology *topo,
347347
}
348348
}
349349

350+
static enum watch_result tx_confirmed(struct lightningd *ld,
351+
const struct bitcoin_txid *txid,
352+
const struct bitcoin_tx *tx,
353+
unsigned int depth,
354+
void *unused)
355+
{
356+
/* We don't actually need to do anything here: the fact that we were
357+
* watching the tx made chaintopology.c update the transaction depth */
358+
if (depth != 0)
359+
return DELETE_WATCH;
360+
return KEEP_WATCHING;
361+
}
362+
363+
void watch_unconfirmed_txid(struct lightningd *ld,
364+
struct chain_topology *topo,
365+
const struct bitcoin_txid *txid)
366+
{
367+
watch_txid(ld->wallet, topo, txid, tx_confirmed, NULL);
368+
}
369+
370+
static void watch_for_unconfirmed_txs(struct lightningd *ld,
371+
struct chain_topology *topo)
372+
{
373+
struct bitcoin_txid *txids;
374+
375+
txids = wallet_transactions_by_height(tmpctx, ld->wallet, 0);
376+
log_debug(ld->log, "Got %zu unconfirmed transactions", tal_count(txids));
377+
for (size_t i = 0; i < tal_count(txids); i++)
378+
watch_unconfirmed_txid(ld, topo, &txids[i]);
379+
}
380+
350381
/* Mutual recursion via timer. */
351382
static void next_updatefee_timer(struct chain_topology *topo);
352383

@@ -1019,6 +1050,7 @@ static void remove_tip(struct chain_topology *topo)
10191050

10201051
/* This may have unconfirmed txs: reconfirm as we add blocks. */
10211052
watch_for_utxo_reconfirmation(topo, topo->ld->wallet);
1053+
10221054
block_map_del(topo->block_map, b);
10231055

10241056
/* These no longer exist, so gossipd drops any reference to them just
@@ -1469,6 +1501,11 @@ void setup_topology(struct chain_topology *topo)
14691501

14701502
/* May have unconfirmed txs: reconfirm as we add blocks. */
14711503
watch_for_utxo_reconfirmation(topo, topo->ld->wallet);
1504+
1505+
/* We usually watch txs because we have outputs coming to us, or they're
1506+
* related to a channel. But not if they're created by sendpsbt without any
1507+
* outputs to us. */
1508+
watch_for_unconfirmed_txs(topo->ld, topo);
14721509
db_commit_transaction(topo->ld->wallet->db);
14731510

14741511
tal_free(local_ctx);

lightningd/chaintopology.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct command;
99
struct lightningd;
1010
struct peer;
1111
struct txwatch;
12+
struct wallet;
1213

1314
/* We keep the last three in case there are outliers (for min/max) */
1415
#define FEE_HISTORY_NUM 3
@@ -277,4 +278,11 @@ void topology_add_sync_waiter_(const tal_t *ctx,
277278

278279
/* In channel_control.c */
279280
void notify_feerate_change(struct lightningd *ld);
281+
282+
/* We want to update db when this txid is confirmed. We always do this
283+
* if it's related to a channel or incoming funds, but sendpsbt without
284+
* change would be otherwise untracked. */
285+
void watch_unconfirmed_txid(struct lightningd *ld,
286+
struct chain_topology *topo,
287+
const struct bitcoin_txid *txid);
280288
#endif /* LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H */

tests/test_wallet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1887,8 +1887,8 @@ def test_onchain_missing_no_p2tr_migrate(node_factory, bitcoind):
18871887
l2.daemon.wait_for_log('Rescan finished! 1 outputs recovered')
18881888

18891889

1890-
@pytest.mark.xfail(strict=True)
18911890
@pytest.mark.parametrize("restart", [False, True])
1891+
@unittest.skipIf(TEST_NETWORK != 'regtest', "elementsd doesn't support psbt features we need")
18921892
def test_sendpsbt_confirm(node_factory, bitcoind, restart):
18931893
"""We should see our sendpsbt in wallet, and that it gets confirmed"""
18941894
l1, l2 = node_factory.get_nodes(2)

wallet/wallet.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5184,9 +5184,16 @@ struct bitcoin_txid *wallet_transactions_by_height(const tal_t *ctx,
51845184
struct db_stmt *stmt;
51855185
struct bitcoin_txid *txids = tal_arr(ctx, struct bitcoin_txid, 0);
51865186
int count = 0;
5187-
stmt = db_prepare_v2(
5188-
w->db, SQL("SELECT id FROM transactions WHERE blockheight=?"));
5189-
db_bind_int(stmt, blockheight);
5187+
5188+
/* Note: blockheight=NULL is not the same as is NULL! */
5189+
if (blockheight == 0) {
5190+
stmt = db_prepare_v2(
5191+
w->db, SQL("SELECT id FROM transactions WHERE blockheight IS NULL"));
5192+
} else {
5193+
stmt = db_prepare_v2(
5194+
w->db, SQL("SELECT id FROM transactions WHERE blockheight=?"));
5195+
db_bind_int(stmt, blockheight);
5196+
}
51905197
db_query_prepared(stmt);
51915198

51925199
while (db_step(stmt)) {

wallet/walletrpc.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,6 @@ static void maybe_notify_new_external_send(struct lightningd *ld,
942942
wallet_save_chain_mvt(ld, take(mvt));
943943
}
944944

945-
946945
static void sendpsbt_done(struct bitcoind *bitcoind UNUSED,
947946
bool success, const char *msg,
948947
struct sending_psbt *sending)
@@ -974,10 +973,14 @@ static void sendpsbt_done(struct bitcoind *bitcoind UNUSED,
974973
}
975974

976975
wallet_transaction_add(ld->wallet, sending->wtx, 0, 0);
976+
wally_txid(sending->wtx, &txid);
977977

978978
/* Extract the change output and add it to the DB */
979-
wallet_extract_owned_outputs(ld->wallet, sending->wtx, false, NULL);
980-
wally_txid(sending->wtx, &txid);
979+
if (wallet_extract_owned_outputs(ld->wallet, sending->wtx, false, NULL) == 0) {
980+
/* If we're not watching it for selfish reasons (i.e. pure send to
981+
* others), make sure we're watching it so we can update depth in db */
982+
watch_unconfirmed_txid(ld, ld->topology, &txid);
983+
}
981984

982985
for (size_t i = 0; i < sending->psbt->num_outputs; i++)
983986
maybe_notify_new_external_send(ld, &txid, i, sending->psbt);

0 commit comments

Comments
 (0)