diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index ad5dbabbe..ef76b702c 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -348,6 +348,22 @@ static void updates_complete(struct chain_topology *topo) next_topology_timer(topo); } +/** + * topo_update_spends -- Tell the wallet about all spent outpoints + */ +static void topo_update_spends(struct chain_topology *topo, struct block *b) +{ + for (size_t i = 0; i < tal_count(b->full_txs); i++) { + const struct bitcoin_tx *tx = b->full_txs[i]; + for (size_t j = 0; j < tal_count(tx->input); j++) { + const struct bitcoin_tx_input *input = &tx->input[j]; + wallet_outpoint_spend(topo->wallet, b->height, + &input->txid, + input->index); + } + } +} + static void add_tip(struct chain_topology *topo, struct block *b) { /* Attach to tip; b is now the tip. */ @@ -357,6 +373,8 @@ static void add_tip(struct chain_topology *topo, struct block *b) topo->tip = b; wallet_block_add(topo->wallet, b); + topo_update_spends(topo, b); + /* Only keep the transactions we care about. */ filter_block_txs(topo, b); diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index d037d35cc..55d8d2bae 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -258,6 +258,10 @@ struct json_result *null_response(const tal_t *ctx UNNEEDED) void outpointfilter_add(struct outpointfilter *of UNNEEDED, const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED) { fprintf(stderr, "outpointfilter_add called!\n"); abort(); } +/* Generated stub for outpointfilter_matches */ +bool outpointfilter_matches(struct outpointfilter *of UNNEEDED, + const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED) +{ fprintf(stderr, "outpointfilter_matches called!\n"); abort(); } /* Generated stub for outpointfilter_new */ struct outpointfilter *outpointfilter_new(tal_t *ctx UNNEEDED) { fprintf(stderr, "outpointfilter_new called!\n"); abort(); } diff --git a/wallet/wallet.c b/wallet/wallet.c index cbab537d2..4ef77c6c2 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1783,3 +1783,22 @@ void wallet_blocks_rollback(struct wallet *w, u32 height) sqlite3_bind_int(stmt, 1, height); db_exec_prepared(w->db, stmt); } + +void wallet_outpoint_spend(struct wallet *w, const u32 blockheight, + const struct bitcoin_txid *txid, const u32 outnum) +{ + sqlite3_stmt *stmt; + if (outpointfilter_matches(w->owned_outpoints, txid, outnum)) { + stmt = db_prepare(w->db, + "UPDATE outputs " + "SET spend_height = ? " + "WHERE prev_out_tx = ?" + " AND prev_out_index = ?"); + + sqlite3_bind_int(stmt, 1, blockheight); + sqlite3_bind_sha256_double(stmt, 2, &txid->shad); + sqlite3_bind_int(stmt, 3, outnum); + + db_exec_prepared(w->db, stmt); + } +} diff --git a/wallet/wallet.h b/wallet/wallet.h index eda20ca88..27662f01e 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -704,4 +704,7 @@ void wallet_block_remove(struct wallet *w, struct block *b); */ void wallet_blocks_rollback(struct wallet *w, u32 height); +void wallet_outpoint_spend(struct wallet *w, const u32 blockheight, + const struct bitcoin_txid *txid, const u32 outnum); + #endif /* WALLET_WALLET_H */