last_sent_closing_fee: Option<(u32, u64, Signature)>, // (feerate, fee, holder_sig)
- /// The hash of the block in which the funding transaction reached our CONF_TARGET. We use this
- /// to detect unconfirmation after a serialize-unserialize roundtrip where we may not see a full
- /// series of block_connected/block_disconnected calls. Obviously this is not a guarantee as we
- /// could miss the funding_tx_confirmed_in block as well, but it serves as a useful fallback.
+ /// The hash of the block in which the funding transaction was included.
funding_tx_confirmed_in: Option<BlockHash>,
+ funding_tx_confirmation_height: u64,
short_channel_id: Option<u64>,
- funding_tx_confirmations: u64,
counterparty_dust_limit_satoshis: u64,
#[cfg(test)]
}
pub const OUR_MAX_HTLCS: u16 = 50; //TODO
-/// Confirmation count threshold at which we close a channel. Ideally we'd keep the channel around
-/// on ice until the funding transaction gets more confirmations, but the LN protocol doesn't
-/// really allow for this, so instead we're stuck closing it out at that point.
-const UNCONF_THRESHOLD: u32 = 6;
const SPENDING_INPUT_FOR_A_OUTPUT_WEIGHT: u64 = 79; // prevout: 36, nSequence: 4, script len: 1, witness lengths: (3+1)/4, sig: 73/4, if-selector: 1, redeemScript: (6 ops + 2*33 pubkeys + 1*2 delay)/4
const B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT: u64 = 104; // prevout: 40, nSequence: 4, script len: 1, witness lengths: 3/4, sig: 73/4, pubkey: 33/4, output: 31 (TODO: Wrong? Useless?)
last_sent_closing_fee: None,
funding_tx_confirmed_in: None,
+ funding_tx_confirmation_height: 0,
short_channel_id: None,
- funding_tx_confirmations: 0,
feerate_per_kw: feerate,
counterparty_dust_limit_satoshis: 0,
last_sent_closing_fee: None,
funding_tx_confirmed_in: None,
+ funding_tx_confirmation_height: 0,
short_channel_id: None,
- funding_tx_confirmations: 0,
feerate_per_kw: msg.feerate_per_kw,
channel_value_satoshis: msg.funding_satoshis,
}
});
- if self.funding_tx_confirmations > 0 {
- self.funding_tx_confirmations += 1;
- }
-
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
for &(index_in_block, tx) in txdata.iter() {
}
}
}
- self.funding_tx_confirmations = 1;
+ self.funding_tx_confirmation_height = height as u64;
+ self.funding_tx_confirmed_in = Some(header.block_hash());
self.short_channel_id = match scid_from_parts(height as u64, index_in_block as u64, txo_idx as u64) {
Ok(scid) => Some(scid),
Err(_) => panic!("Block was bogus - either height was > 16 million, had > 16 million transactions, or had > 65k outputs"),
}
}
+
self.update_time_counter = cmp::max(self.update_time_counter, header.time);
- if self.funding_tx_confirmations > 0 {
- if self.funding_tx_confirmations == self.minimum_depth as u64 {
+ if self.funding_tx_confirmation_height > 0 {
+ let funding_tx_confirmations = height as i64 - self.funding_tx_confirmation_height as i64 + 1;
+ if funding_tx_confirmations == self.minimum_depth as i64 {
let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
self.channel_state |= ChannelState::OurFundingLocked as u32;
true
// funding_tx_confirmed_in and return.
false
};
- self.funding_tx_confirmed_in = Some(header.block_hash());
//TODO: Note that this must be a duplicate of the previous commitment point they sent us,
//as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
/// Called by channelmanager based on chain blocks being disconnected.
/// Returns true if we need to close the channel now due to funding transaction
/// unconfirmation/reorg.
- pub fn block_disconnected(&mut self, header: &BlockHeader) -> bool {
- if self.funding_tx_confirmations > 0 {
- self.funding_tx_confirmations -= 1;
- if self.funding_tx_confirmations == UNCONF_THRESHOLD as u64 {
+ pub fn block_disconnected(&mut self, header: &BlockHeader, height: u32) -> bool {
+ if self.funding_tx_confirmation_height > 0 {
+ let funding_tx_confirmations = height as i64 - self.funding_tx_confirmation_height as i64 + 1;
+ if funding_tx_confirmations <= 0 {
+ self.funding_tx_confirmation_height = 0;
+ }
+
+ let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
+ if (non_shutdown_state >= ChannelState::ChannelFunded as u32 ||
+ (non_shutdown_state & ChannelState::OurFundingLocked as u32) == ChannelState::OurFundingLocked as u32) &&
+ funding_tx_confirmations < self.minimum_depth as i64 / 2 {
return true;
}
}
- if Some(header.block_hash()) == self.funding_tx_confirmed_in {
- self.funding_tx_confirmations = self.minimum_depth as u64 - 1;
- }
false
}
}
self.funding_tx_confirmed_in.write(writer)?;
+ self.funding_tx_confirmation_height.write(writer)?;
self.short_channel_id.write(writer)?;
- self.funding_tx_confirmations.write(writer)?;
self.counterparty_dust_limit_satoshis.write(writer)?;
self.holder_dust_limit_satoshis.write(writer)?;
};
let funding_tx_confirmed_in = Readable::read(reader)?;
+ let funding_tx_confirmation_height = Readable::read(reader)?;
let short_channel_id = Readable::read(reader)?;
- let funding_tx_confirmations = Readable::read(reader)?;
let counterparty_dust_limit_satoshis = Readable::read(reader)?;
let holder_dust_limit_satoshis = Readable::read(reader)?;
last_sent_closing_fee,
funding_tx_confirmed_in,
+ funding_tx_confirmation_height,
short_channel_id,
- funding_tx_confirmations,
counterparty_dust_limit_satoshis,
holder_dust_limit_satoshis,