Skip to content

Commit 57d2e1f

Browse files
committed
Broadcast holder commitment immediately on alternative funding reorg
We can't rely waiting on another (or the same) renegotiated funding transaction to confirm, since it may never happen. We also don't want to rely on the counterparty to broadcast for us, or require manual intervention from the user, so we choose to broadcast the new holder commitment immediately. This ensures we're able to claim funds from an already force closed channel after an alternative funding reorg.
1 parent 6f0496b commit 57d2e1f

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4866,7 +4866,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
48664866
self.onchain_events_awaiting_threshold_conf.retain(|ref entry| entry.height <= height);
48674867
let conf_target = self.closure_conf_target();
48684868
self.onchain_tx_handler.block_disconnected(
4869-
height + 1, broadcaster, conf_target, &self.destination_script, fee_estimator, logger,
4869+
height + 1, &broadcaster, conf_target, &self.destination_script, fee_estimator, logger,
48704870
);
48714871
Vec::new()
48724872
} else { Vec::new() }
@@ -5341,26 +5341,34 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
53415341
self.onchain_events_awaiting_threshold_conf.retain(|ref entry| entry.height < height);
53425342

53435343
// TODO: Replace with `take_if` once our MSRV is >= 1.80.
5344+
let mut should_broadcast_commitment = false;
53445345
if let Some((_, conf_height)) = self.alternative_funding_confirmed.as_ref() {
53455346
if *conf_height == height {
53465347
self.alternative_funding_confirmed.take();
5347-
if self.holder_tx_signed {
5348+
if self.holder_tx_signed || self.funding_spend_seen {
53485349
// Cancel any previous claims that are no longer valid as they stemmed from a
5349-
// different funding transaction. We'll wait until we see a funding transaction
5350-
// confirm again before attempting to broadcast the new valid holder commitment.
5350+
// different funding transaction.
53515351
let new_holder_commitment_txid =
53525352
self.funding.current_holder_commitment_tx.trust().txid();
53535353
self.cancel_prev_commitment_claims(&logger, &new_holder_commitment_txid);
5354+
5355+
should_broadcast_commitment = true;
53545356
}
53555357
}
53565358
}
53575359

53585360
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(fee_estimator);
53595361
let conf_target = self.closure_conf_target();
53605362
self.onchain_tx_handler.block_disconnected(
5361-
height, broadcaster, conf_target, &self.destination_script, &bounded_fee_estimator, logger
5363+
height, &broadcaster, conf_target, &self.destination_script, &bounded_fee_estimator, logger
53625364
);
53635365

5366+
// Only attempt to broadcast the new commitment after the `block_disconnected` call above so that
5367+
// it doesn't get removed from the set of pending claims.
5368+
if should_broadcast_commitment {
5369+
self.queue_latest_holder_commitment_txn_for_broadcast(&broadcaster, &bounded_fee_estimator, logger);
5370+
}
5371+
53645372
self.best_block = BestBlock::new(header.prev_blockhash, height - 1);
53655373
}
53665374

@@ -5395,24 +5403,32 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
53955403
debug_assert!(!self.onchain_events_awaiting_threshold_conf.iter().any(|ref entry| entry.txid == *txid));
53965404

53975405
// TODO: Replace with `take_if` once our MSRV is >= 1.80.
5406+
let mut should_broadcast_commitment = false;
53985407
if let Some((alternative_funding_txid, _)) = self.alternative_funding_confirmed.as_ref() {
53995408
if alternative_funding_txid == txid {
54005409
self.alternative_funding_confirmed.take();
5401-
if self.holder_tx_signed {
5410+
if self.holder_tx_signed || self.funding_spend_seen {
54025411
// Cancel any previous claims that are no longer valid as they stemmed from a
5403-
// different funding transaction. We'll wait until we see a funding transaction
5404-
// confirm again before attempting to broadcast the new valid holder commitment.
5412+
// different funding transaction.
54055413
let new_holder_commitment_txid =
54065414
self.funding.current_holder_commitment_tx.trust().txid();
54075415
self.cancel_prev_commitment_claims(&logger, &new_holder_commitment_txid);
5416+
5417+
should_broadcast_commitment = true;
54085418
}
54095419
}
54105420
}
54115421

54125422
let conf_target = self.closure_conf_target();
54135423
self.onchain_tx_handler.transaction_unconfirmed(
5414-
txid, broadcaster, conf_target, &self.destination_script, fee_estimator, logger
5424+
txid, &broadcaster, conf_target, &self.destination_script, fee_estimator, logger
54155425
);
5426+
5427+
// Only attempt to broadcast the new commitment after the `transaction_unconfirmed` call above so
5428+
// that it doesn't get removed from the set of pending claims.
5429+
if should_broadcast_commitment {
5430+
self.queue_latest_holder_commitment_txn_for_broadcast(&broadcaster, fee_estimator, logger);
5431+
}
54165432
}
54175433

54185434
/// Filters a block's `txdata` for transactions spending watched outputs or for any child

lightning/src/chain/onchaintx.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
11201120
pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
11211121
&mut self,
11221122
txid: &Txid,
1123-
broadcaster: B,
1123+
broadcaster: &B,
11241124
conf_target: ConfirmationTarget,
11251125
destination_script: &Script,
11261126
fee_estimator: &LowerBoundedFeeEstimator<F>,
@@ -1146,7 +1146,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
11461146

11471147
#[rustfmt::skip]
11481148
pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(
1149-
&mut self, height: u32, broadcaster: B, conf_target: ConfirmationTarget,
1149+
&mut self, height: u32, broadcaster: &B, conf_target: ConfirmationTarget,
11501150
destination_script: &Script, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
11511151
)
11521152
where B::Target: BroadcasterInterface,

0 commit comments

Comments
 (0)