Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 56 additions & 10 deletions lightningd/chaintopology.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,8 +888,8 @@ static void updates_complete(struct chain_topology *topo)
}

static void record_wallet_spend(struct lightningd *ld,
struct bitcoin_outpoint *outpoint,
struct bitcoin_txid *txid,
const struct bitcoin_outpoint *outpoint,
const struct bitcoin_txid *txid,
u32 tx_blockheight)
{
struct utxo *utxo;
Expand All @@ -911,31 +911,34 @@ static void record_wallet_spend(struct lightningd *ld,
/**
* topo_update_spends -- Tell the wallet about all spent outpoints
*/
static void topo_update_spends(struct chain_topology *topo, struct block *b)
static void topo_update_spends(struct chain_topology *topo,
struct bitcoin_tx **txs,
const struct bitcoin_txid *txids,
u32 blockheight)
{
const struct short_channel_id *spent_scids;
const size_t num_txs = tal_count(b->full_txs);
const size_t num_txs = tal_count(txs);
for (size_t i = 0; i < num_txs; i++) {
const struct bitcoin_tx *tx = b->full_txs[i];
const struct bitcoin_tx *tx = txs[i];

for (size_t j = 0; j < tx->wtx->num_inputs; j++) {
struct bitcoin_outpoint outpoint;

bitcoin_tx_input_get_outpoint(tx, j, &outpoint);

if (wallet_outpoint_spend(tmpctx, topo->ld->wallet,
b->height, &outpoint))
blockheight, &outpoint))
record_wallet_spend(topo->ld, &outpoint,
&b->txids[i], b->height);
&txids[i], blockheight);

}
}

/* Retrieve all potential channel closes from the UTXO set and
* tell gossipd about them. */
spent_scids =
wallet_utxoset_get_spent(tmpctx, topo->ld->wallet, b->height);
gossipd_notify_spends(topo->bitcoind->ld, b->height, spent_scids);
wallet_utxoset_get_spent(tmpctx, topo->ld->wallet, blockheight);
gossipd_notify_spends(topo->bitcoind->ld, blockheight, spent_scids);
}

static void topo_add_utxos(struct chain_topology *topo, struct block *b)
Expand Down Expand Up @@ -982,7 +985,7 @@ static void add_tip(struct chain_topology *topo, struct block *b)
trace_span_end(b);

trace_span_start("topo_update_spends", b);
topo_update_spends(topo, b);
topo_update_spends(topo, b->full_txs, b->txids, b->height);
trace_span_end(b);

/* Only keep the transactions we care about. */
Expand Down Expand Up @@ -1388,6 +1391,7 @@ void setup_topology(struct chain_topology *topo)
struct bitcoin_block *blk;
bool blockscan_start_set;
u32 blockscan_start;
s64 fixup;

/* This waits for bitcoind. */
bitcoind_check_commands(topo->bitcoind);
Expand All @@ -1413,6 +1417,15 @@ void setup_topology(struct chain_topology *topo)
blockscan_start = blocknum_reduce(blockscan_start, topo->ld->config.rescan);
}

fixup = db_get_intvar(topo->ld->wallet->db, "fixup_block_scan", -1);
if (fixup == -1) {
/* Never done fixup: this is set to non-zero if we have blocks. */
topo->old_block_scan = wallet_blocks_minheight(topo->ld->wallet);
db_set_intvar(topo->ld->wallet->db, "fixup_block_scan",
topo->old_block_scan);
} else {
topo->old_block_scan = fixup;
}
db_commit_transaction(topo->ld->wallet->db);

/* Sanity checks, then topology initialization. */
Expand Down Expand Up @@ -1509,6 +1522,36 @@ void setup_topology(struct chain_topology *topo)
tal_add_destructor(topo, destroy_chain_topology);
}

static void fixup_scan_block(struct bitcoind *bitcoind,
u32 height,
struct bitcoin_blkid *blkid,
struct bitcoin_block *blk,
struct chain_topology *topo)
{
log_debug(topo->ld->log, "fixup_scan: block %u with %zu txs", height, tal_count(blk->tx));
topo_update_spends(topo, blk->tx, blk->txids, height);

/* Caught up. */
if (height == get_block_height(topo)) {
log_info(topo->ld->log, "Scanning for missed UTXOs finished");
db_set_intvar(topo->ld->wallet->db, "fixup_block_scan", 0);
return;
}

db_set_intvar(topo->ld->wallet->db, "fixup_block_scan", ++topo->old_block_scan);
bitcoind_getrawblockbyheight(topo, topo->bitcoind,
topo->old_block_scan,
fixup_scan_block, topo);
}

static void fixup_scan(struct chain_topology *topo)
{
log_info(topo->ld->log, "Scanning for missed UTXOs from block %u", topo->old_block_scan);
bitcoind_getrawblockbyheight(topo, topo->bitcoind,
topo->old_block_scan,
fixup_scan_block, topo);
}

void begin_topology(struct chain_topology *topo)
{
/* If we were not synced, start looping to check */
Expand All @@ -1518,6 +1561,9 @@ void begin_topology(struct chain_topology *topo)
start_fee_estimate(topo);
/* Regular block updates */
try_extend_tip(topo);

if (topo->old_block_scan)
fixup_scan(topo);
}

void stop_topology(struct chain_topology *topo)
Expand Down
3 changes: 3 additions & 0 deletions lightningd/chaintopology.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ struct chain_topology {
/* The number of headers known to the bitcoin backend at startup. Not
* updated after the initial check. */
u32 headercount;

/* Progress on routine to look for old missed transactions. 0 = not interested. */
u32 old_block_scan;
};

/* Information relevant to locating a TX in a blockchain. */
Expand Down
Binary file added tests/data/l3-missing-utxo.sqlite3.xz
Binary file not shown.
Loading
Loading