Skip to content

Commit eea3c90

Browse files
committed
lightningd: wait for onchaind to ack new spends before continuing replay.
Christian noted that if we don't do this we could flood onchaind with messages: particularly in Greenlight where the HSM (remote) may delay indefinitely, so onchaind doesn't process messages. Signed-off-by: Rusty Russell <[email protected]>
1 parent 1d6a8c9 commit eea3c90

File tree

4 files changed

+40
-10
lines changed

4 files changed

+40
-10
lines changed

lightningd/channel.c

+1
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
609609
channel->last_stable_connection = last_stable_connection;
610610
channel->stable_conn_timer = NULL;
611611
channel->onchaind_replay_watches = NULL;
612+
channel->num_onchain_spent_calls = 0;
612613
channel->stats = *stats;
613614
channel->state_changes = tal_steal(channel, state_changes);
614615

lightningd/channel.h

+4
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ struct channel {
196196

197197
/* If we're doing a replay for onchaind, here are the txids it's watching */
198198
struct replay_tx_hash *onchaind_replay_watches;
199+
/* Number of outstanding onchaind_spent calls */
200+
size_t num_onchain_spent_calls;
201+
/* Height we're replaying at (if onchaind_replay_watches set) */
202+
u32 onchaind_replay_height;
199203

200204
/* Our original funds, in funding amount */
201205
struct amount_sat our_funds;

lightningd/onchain_control.c

+33-8
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ static enum watch_result onchain_tx_watched(struct lightningd *ld,
217217

218218
static void watch_tx_and_outputs(struct channel *channel,
219219
const struct bitcoin_tx *tx);
220+
static void onchaind_replay(struct channel *channel);
220221

221222
static void replay_unwatch_txid(struct channel *channel,
222223
const struct bitcoin_txid *txid)
@@ -236,14 +237,16 @@ static void onchaind_spent_reply(struct subd *onchaind, const u8 *msg,
236237
channel_internal_error(channel, "Invalid onchaind_spent_reply %s",
237238
tal_hex(tmpctx, msg));
238239

240+
channel->num_onchain_spent_calls--;
241+
239242
/* Only delete watch if it says it doesn't care */
240243
if (interested)
241-
return;
244+
goto out;
242245

243246
/* If we're doing replay: */
244247
if (channel->onchaind_replay_watches) {
245248
replay_unwatch_txid(channel, txid);
246-
return;
249+
goto out;
247250
}
248251

249252
/* Frees the txo watches, too: see watch_tx_and_outputs() */
@@ -253,6 +256,13 @@ static void onchaind_spent_reply(struct subd *onchaind, const u8 *msg,
253256
log_unusual(channel->log, "Can't unwatch txid %s",
254257
fmt_bitcoin_txid(tmpctx, txid));
255258
tal_free(txw);
259+
260+
out:
261+
/* If that's the last request, continue asking for blocks */
262+
if (channel->onchaind_replay_watches
263+
&& channel->num_onchain_spent_calls == 0) {
264+
onchaind_replay(channel);
265+
}
256266
}
257267

258268
/**
@@ -276,7 +286,7 @@ static void onchain_txo_spent(struct channel *channel, const struct bitcoin_tx *
276286
msg = towire_onchaind_spent(channel, parts, input_num, blockheight);
277287
subd_req(channel->owner, channel->owner, take(msg), -1, 0,
278288
onchaind_spent_reply, take(txid));
279-
289+
channel->num_onchain_spent_calls++;
280290
}
281291

282292
/**
@@ -405,8 +415,24 @@ static void replay_block(struct bitcoind *bitcoind,
405415
return;
406416
}
407417

408-
/* Otherwise, loop on next block. */
409-
bitcoind_getrawblockbyheight(channel, bitcoind, height + 1, replay_block, channel);
418+
/* Ready for next block */
419+
channel->onchaind_replay_height = height + 1;
420+
421+
/* Otherwise, wait for those to be resolved (in case onchaind is slow,
422+
* e.g. waiting for HSM). */
423+
if (channel->num_onchain_spent_calls == 0)
424+
onchaind_replay(channel);
425+
}
426+
427+
static void onchaind_replay(struct channel *channel)
428+
{
429+
assert(channel->onchaind_replay_watches);
430+
assert(channel->num_onchain_spent_calls == 0);
431+
432+
bitcoind_getrawblockbyheight(channel,
433+
channel->peer->ld->topology->bitcoind,
434+
channel->onchaind_replay_height,
435+
replay_block, channel);
410436
}
411437

412438
static void handle_extracted_preimage(struct channel *channel, const u8 *msg)
@@ -1824,12 +1850,11 @@ void onchaind_replay_channels(struct lightningd *ld)
18241850

18251851
/* We're in replay mode */
18261852
channel->onchaind_replay_watches = tal(channel, struct replay_tx_hash);
1853+
channel->onchaind_replay_height = blockheight;
18271854
replay_tx_hash_init(channel->onchaind_replay_watches);
18281855

18291856
onchaind_funding_spent(channel, tx, blockheight);
1830-
/* Ask bitcoind to start grabbing those blocks for replay */
1831-
bitcoind_getrawblockbyheight(channel, ld->topology->bitcoind, blockheight,
1832-
replay_block, channel);
1857+
onchaind_replay(channel);
18331858
}
18341859
}
18351860
db_commit_transaction(ld->wallet->db);

onchaind/onchaind.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,7 @@ static bool output_spent(struct tracked_output ***outs,
11951195
u32 input_num,
11961196
u32 tx_blockheight)
11971197
{
1198-
bool interesting;
1198+
bool interesting = false;
11991199

12001200
for (size_t i = 0; i < tal_count(*outs); i++) {
12011201
struct tracked_output *out = (*outs)[i];
@@ -1220,7 +1220,7 @@ static bool output_spent(struct tracked_output ***outs,
12201220

12211221
record_coin_movements(out, tx_blockheight,
12221222
&tx_parts->txid);
1223-
return interesting;
1223+
break;
12241224
}
12251225

12261226
htlc_outpoint.txid = tx_parts->txid;

0 commit comments

Comments
 (0)