Skip to content

Commit 3cc00dd

Browse files
committed
lightningd: use block-at-a-time replay for onchaind on restart.
And we hook in the replay watch code. Signed-off-by: Rusty Russell <[email protected]>
1 parent b904a65 commit 3cc00dd

File tree

2 files changed

+41
-36
lines changed

2 files changed

+41
-36
lines changed

lightningd/onchain_control.c

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,51 +1743,56 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
17431743
feerate_min(ld, NULL));
17441744
subd_send_msg(channel->owner, take(msg));
17451745

1746-
watch_tx_and_outputs(channel, tx);
1746+
/* If we're replaying, we just watch this */
1747+
if (channel->onchaind_replay_watches) {
1748+
replay_watch_tx(channel, blockheight, tx);
1749+
} else {
1750+
watch_tx_and_outputs(channel, tx);
1751+
}
17471752

17481753
/* We keep watching until peer finally deleted, for reorgs. */
17491754
return KEEP_WATCHING;
17501755
}
17511756

17521757
void onchaind_replay_channels(struct lightningd *ld)
17531758
{
1754-
u32 *onchaind_ids;
1755-
struct channeltx *txs;
1756-
struct channel *chan;
1759+
struct peer *peer;
1760+
struct peer_node_id_map_iter it;
17571761

1762+
/* We don't hold a db tx for all of init */
17581763
db_begin_transaction(ld->wallet->db);
1759-
onchaind_ids = wallet_onchaind_channels(tmpctx, ld->wallet);
1760-
1761-
for (size_t i = 0; i < tal_count(onchaind_ids); i++) {
1762-
log_info(ld->log, "Restarting onchaind for channel %d",
1763-
onchaind_ids[i]);
1764-
1765-
txs = wallet_channeltxs_get(onchaind_ids, ld->wallet,
1766-
onchaind_ids[i]);
1767-
chan = channel_by_dbid(ld, onchaind_ids[i]);
1768-
1769-
for (size_t j = 0; j < tal_count(txs); j++) {
1770-
if (txs[j].type == WIRE_ONCHAIND_INIT) {
1771-
onchaind_funding_spent(chan, txs[j].tx,
1772-
txs[j].blockheight);
1773-
1774-
} else if (txs[j].type == WIRE_ONCHAIND_SPENT) {
1775-
onchain_txo_spent(chan, txs[j].tx,
1776-
txs[j].input_num,
1777-
txs[j].blockheight);
1778-
1779-
} else if (txs[j].type == WIRE_ONCHAIND_DEPTH) {
1780-
onchain_tx_depth(chan, &txs[j].txid,
1781-
txs[j].depth);
1782-
1783-
} else {
1784-
fatal("unknown message of type %d during "
1785-
"onchaind replay",
1786-
txs[j].type);
1787-
}
1764+
1765+
/* For each channel, if we've recorded a spend, it's onchaind time! */
1766+
for (peer = peer_node_id_map_first(ld->peers, &it);
1767+
peer;
1768+
peer = peer_node_id_map_next(ld->peers, &it)) {
1769+
struct channel *channel;
1770+
1771+
list_for_each(&peer->channels, channel, list) {
1772+
struct bitcoin_tx *tx;
1773+
u32 blockheight;
1774+
1775+
if (channel_state_uncommitted(channel->state))
1776+
continue;
1777+
1778+
tx = wallet_get_funding_spend(tmpctx, ld->wallet, channel->dbid,
1779+
&blockheight);
1780+
if (!tx)
1781+
continue;
1782+
1783+
log_info(channel->log,
1784+
"Restarting onchaind (%s): closed in block %u",
1785+
channel_state_name(channel), blockheight);
1786+
1787+
/* We're in replay mode */
1788+
channel->onchaind_replay_watches = tal(channel, struct replay_tx_hash);
1789+
replay_tx_hash_init(channel->onchaind_replay_watches);
1790+
1791+
onchaind_funding_spent(channel, tx, blockheight);
1792+
/* Ask bitcoind to start grabbing those blocks for replay */
1793+
bitcoind_getrawblockbyheight(ld->topology->bitcoind, blockheight,
1794+
replay_block, channel);
17881795
}
1789-
tal_free(txs);
17901796
}
1791-
17921797
db_commit_transaction(ld->wallet->db);
17931798
}

tests/test_closing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1844,7 +1844,7 @@ def test_onchaind_replay(node_factory, bitcoind):
18441844
l1.restart()
18451845

18461846
# Can't wait for it, it's after the "Server started" wait in restart()
1847-
assert l1.daemon.is_in_log(r'Restarting onchaind for channel')
1847+
assert l1.daemon.is_in_log(r'Restarting onchaind \(ONCHAIN\): closed in block 109')
18481848

18491849
# l1 should still notice that the funding was spent and that we should react to it
18501850
_, txid, blocks = l1.wait_for_onchaind_tx('OUR_DELAYED_RETURN_TO_WALLET',

0 commit comments

Comments
 (0)