Skip to content

Commit d83b355

Browse files
committed
Handle 1-conf funding_locked in channel no matter the event order
See comment in the diff for more details
1 parent 655cbe3 commit d83b355

File tree

1 file changed

+60
-38
lines changed

1 file changed

+60
-38
lines changed

lightning/src/ln/channel.rs

Lines changed: 60 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3476,11 +3476,59 @@ impl<Signer: Sign> Channel<Signer> {
34763476
self.network_sync == UpdateStatus::DisabledMarked
34773477
}
34783478

3479+
fn check_get_funding_locked(&mut self, height: u32) -> Option<msgs::FundingLocked> {
3480+
if self.funding_tx_confirmation_height > 0 {
3481+
let funding_tx_confirmations = height as i64 - self.funding_tx_confirmation_height as i64 + 1;
3482+
if funding_tx_confirmations <= 0 {
3483+
self.funding_tx_confirmation_height = 0;
3484+
}
3485+
3486+
if funding_tx_confirmations >= self.minimum_depth as i64 {
3487+
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
3488+
let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
3489+
self.channel_state |= ChannelState::OurFundingLocked as u32;
3490+
true
3491+
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
3492+
self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
3493+
self.update_time_counter += 1;
3494+
true
3495+
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
3496+
// We got a reorg but not enough to trigger a force close, just update
3497+
// funding_tx_confirmed_in and return.
3498+
false
3499+
} else if self.channel_state < ChannelState::ChannelFunded as u32 {
3500+
panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
3501+
} else {
3502+
// We got a reorg but not enough to trigger a force close, just update
3503+
// funding_tx_confirmed_in and return.
3504+
false
3505+
};
3506+
3507+
//TODO: Note that this must be a duplicate of the previous commitment point they sent us,
3508+
//as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
3509+
//they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
3510+
//a protocol oversight, but I assume I'm just missing something.
3511+
if need_commitment_update {
3512+
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
3513+
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
3514+
return Some(msgs::FundingLocked {
3515+
channel_id: self.channel_id,
3516+
next_per_commitment_point,
3517+
});
3518+
} else {
3519+
self.monitor_pending_funding_locked = true;
3520+
}
3521+
}
3522+
}
3523+
}
3524+
None
3525+
}
3526+
34793527
/// When a transaction is confirmed, we check whether it is or spends the funding transaction
34803528
/// In the first case, we store the confirmation height and calculating the short channel id.
34813529
/// In the second, we simply return an Err indicating we need to be force-closed now.
34823530
pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData, logger: &L)
3483-
-> Result<(), msgs::ErrorMessage> where L::Target: Logger {
3531+
-> Result<Option<msgs::FundingLocked>, msgs::ErrorMessage> where L::Target: Logger {
34843532
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
34853533
if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
34863534
for &(index_in_block, tx) in txdata.iter() {
@@ -3525,6 +3573,13 @@ impl<Signer: Sign> Channel<Signer> {
35253573
((index_in_block as u64) << (2*8)) |
35263574
((txo_idx as u64) << (0*8)));
35273575
}
3576+
// If we allow 1-conf funding, we may need to check for funding_locked here and
3577+
// send it immediately instead of waiting for an update_best_block call (which
3578+
// may have already happened for this block).
3579+
// XXX: Test this case!
3580+
if let Some(funding_locked) = self.check_get_funding_locked(height) {
3581+
return Ok(Some(funding_locked));
3582+
}
35283583
}
35293584
for inp in tx.input.iter() {
35303585
if inp.previous_output == funding_txo.into_bitcoin_outpoint() {
@@ -3537,7 +3592,7 @@ impl<Signer: Sign> Channel<Signer> {
35373592
}
35383593
}
35393594
}
3540-
Ok(())
3595+
Ok(None)
35413596
}
35423597

35433598
/// When a new block is connected, we check the height of the block against outbound holding
@@ -3566,6 +3621,7 @@ impl<Signer: Sign> Channel<Signer> {
35663621
});
35673622

35683623
self.update_time_counter = cmp::max(self.update_time_counter, highest_header_time);
3624+
35693625
if self.funding_tx_confirmation_height > 0 {
35703626
let funding_tx_confirmations = height as i64 - self.funding_tx_confirmation_height as i64 + 1;
35713627
if funding_tx_confirmations <= 0 {
@@ -3582,42 +3638,8 @@ impl<Signer: Sign> Channel<Signer> {
35823638
});
35833639
}
35843640

3585-
if funding_tx_confirmations == self.minimum_depth as i64 {
3586-
let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
3587-
self.channel_state |= ChannelState::OurFundingLocked as u32;
3588-
true
3589-
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
3590-
self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
3591-
self.update_time_counter += 1;
3592-
true
3593-
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
3594-
// We got a reorg but not enough to trigger a force close, just update
3595-
// funding_tx_confirmed_in and return.
3596-
false
3597-
} else if self.channel_state < ChannelState::ChannelFunded as u32 {
3598-
panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
3599-
} else {
3600-
// We got a reorg but not enough to trigger a force close, just update
3601-
// funding_tx_confirmed_in and return.
3602-
false
3603-
};
3604-
3605-
//TODO: Note that this must be a duplicate of the previous commitment point they sent us,
3606-
//as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
3607-
//they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
3608-
//a protocol oversight, but I assume I'm just missing something.
3609-
if need_commitment_update {
3610-
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
3611-
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
3612-
return Ok((Some(msgs::FundingLocked {
3613-
channel_id: self.channel_id,
3614-
next_per_commitment_point,
3615-
}), timed_out_htlcs));
3616-
} else {
3617-
self.monitor_pending_funding_locked = true;
3618-
return Ok((None, timed_out_htlcs));
3619-
}
3620-
}
3641+
if let Some(funding_locked) = self.check_get_funding_locked(height) {
3642+
return Ok((Some(funding_locked), timed_out_htlcs));
36213643
}
36223644
}
36233645

0 commit comments

Comments
 (0)