use ln::features::{ChannelFeatures, InitFeatures};
use ln::msgs;
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
-use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep};
+use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys};
use ln::chan_utils;
&their_pubkeys.htlc_basepoint, &their_pubkeys.delayed_payment_basepoint,
self.their_to_self_delay, funding_redeemscript.clone(), self.channel_value_satoshis,
self.get_commitment_transaction_number_obscure_factor(),
+ local_initial_commitment_tx.clone(),
self.logger.clone());
channel_monitor.provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap());
- channel_monitor.provide_latest_local_commitment_tx_info(local_initial_commitment_tx.clone(), Vec::new()).unwrap();
channel_monitor
} }
}
let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
macro_rules! create_monitor {
() => { {
+ let local_commitment_tx = LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx.clone(), &msg.signature, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), their_funding_pubkey, local_keys.clone(), self.feerate_per_kw, Vec::new());
let mut channel_monitor = ChannelMonitor::new(self.local_keys.clone(),
&self.shutdown_pubkey, self.our_to_self_delay,
&self.destination_script, (funding_txo.clone(), funding_txo_script.clone()),
&their_pubkeys.htlc_basepoint, &their_pubkeys.delayed_payment_basepoint,
self.their_to_self_delay, funding_redeemscript.clone(), self.channel_value_satoshis,
self.get_commitment_transaction_number_obscure_factor(),
+ local_commitment_tx,
self.logger.clone());
channel_monitor.provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap());
- channel_monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx.clone(), &msg.signature, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), their_funding_pubkey, local_keys.clone(), self.feerate_per_kw, Vec::new()), Vec::new()).unwrap();
channel_monitor
} }
return Err(ChannelError::Close("Remote provided CLTV expiry in seconds instead of block height"));
}
- //TODO: Check msg.cltv_expiry further? Do this in channel manager?
-
if self.channel_state & ChannelState::LocalShutdownSent as u32 != 0 {
if let PendingHTLCStatus::Forward(_) = pending_forward_state {
panic!("ChannelManager shouldn't be trying to add a forwardable HTLC after we've started closing");
self.network_sync == UpdateStatus::DisabledMarked
}
- /// Called by channelmanager based on chain blocks being connected.
- /// Note that we only need to use this to detect funding_signed, anything else is handled by
- /// the channel_monitor.
- /// In case of Err, the channel may have been closed, at which point the standard requirements
- /// apply - no calls may be made except those explicitly stated to be allowed post-shutdown.
+ /// When we receive a new block, we (a) check whether the block contains the funding
+ /// transaction (which would start us counting blocks until we send the funding_signed), and
+ /// (b) check the height of the block against outbound holding cell HTLCs in case we need to
+ /// give up on them prematurely and time them out. Everything else (e.g. commitment
+ /// transaction broadcasts, channel closure detection, HTLC transaction broadcasting, etc) is
+ /// handled by the ChannelMonitor.
+ ///
+ /// If we return Err, the channel may have been closed, at which point the standard
+ /// requirements apply - no calls may be made except those explicitly stated to be allowed
+ /// post-shutdown.
/// Only returns an ErrorAction of DisconnectPeer, if Err.
- pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Result<Option<msgs::FundingLocked>, msgs::ErrorMessage> {
+ ///
+ /// May return some HTLCs (and their payment_hash) which have timed out and should be failed
+ /// back.
+ pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> {
+ let mut timed_out_htlcs = Vec::new();
+ self.holding_cell_htlc_updates.retain(|htlc_update| {
+ match htlc_update {
+ &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, ref cltv_expiry, .. } => {
+ if *cltv_expiry <= height + HTLC_FAIL_BACK_BUFFER {
+ timed_out_htlcs.push((source.clone(), payment_hash.clone()));
+ false
+ } else { true }
+ },
+ _ => true
+ }
+ });
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
if header.bitcoin_hash() != self.last_block_connected {
if self.funding_tx_confirmations > 0 {
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret);
- return Ok(Some(msgs::FundingLocked {
+ return Ok((Some(msgs::FundingLocked {
channel_id: self.channel_id,
next_per_commitment_point: next_per_commitment_point,
- }));
+ }), timed_out_htlcs));
} else {
self.monitor_pending_funding_locked = true;
- return Ok(None);
+ return Ok((None, timed_out_htlcs));
}
}
}
}
}
- Ok(None)
+ Ok((None, timed_out_htlcs))
}
/// Called by channelmanager based on chain blocks being disconnected.
return Err(ChannelError::Ignore("Cannot send value that would put us over their reserve value"));
}
- //TODO: Check cltv_expiry? Do this in channel manager?
-
// Now update local state:
if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) {
self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::AddHTLC {