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;
/// to drop us, but we store this anyway.
ShutdownComplete = 4096,
}
-const BOTH_SIDES_SHUTDOWN_MASK: u32 = (ChannelState::LocalShutdownSent as u32 | ChannelState::RemoteShutdownSent as u32);
-const MULTI_STATE_FLAGS: u32 = (BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32);
+const BOTH_SIDES_SHUTDOWN_MASK: u32 = ChannelState::LocalShutdownSent as u32 | ChannelState::RemoteShutdownSent as u32;
+const MULTI_STATE_FLAGS: u32 = BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32;
const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
/// Maximmum `funding_satoshis` value, according to the BOLT #2 specification
/// it's 2^24.
-pub const MAX_FUNDING_SATOSHIS: u64 = (1 << 24);
+pub const MAX_FUNDING_SATOSHIS: u64 = 1 << 24;
/// Used to return a simple Error back to ChannelManager. Will get converted to a
/// msgs::ErrorAction::SendErrorMessage or msgs::ErrorAction::IgnoreError as appropriate with our
// They sign the "local" commitment transaction...
secp_check!(self.secp_ctx.verify(&local_sighash, &sig, self.their_funding_pubkey()), "Invalid funding_created signature from peer");
- let localtx = LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx, sig, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), self.their_funding_pubkey(), local_keys, self.feerate_per_kw, Vec::new());
+ let localtx = LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx, sig.clone(), &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), self.their_funding_pubkey(), local_keys, self.feerate_per_kw, Vec::new());
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0;
&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
} }
}
/// Handles a funding_signed message from the remote end.
/// If this call is successful, broadcast the funding transaction (and not before!)
- pub fn funding_signed(&mut self, msg: &msgs::FundingSigned) -> Result<ChannelMonitorUpdate, (Option<ChannelMonitorUpdate>, ChannelError)> {
+ pub fn funding_signed(&mut self, msg: &msgs::FundingSigned) -> Result<ChannelMonitor<ChanSigner>, ChannelError> {
if !self.channel_outbound {
- return Err((None, ChannelError::Close("Received funding_signed for an inbound channel?")));
+ return Err(ChannelError::Close("Received funding_signed for an inbound channel?"));
}
if self.channel_state & !(ChannelState::MonitorUpdateFailed as u32) != ChannelState::FundingCreated as u32 {
- return Err((None, ChannelError::Close("Received funding_signed in strange state!")));
+ return Err(ChannelError::Close("Received funding_signed in strange state!"));
}
if self.commitment_secrets.get_min_seen_secret() != (1 << 48) ||
- self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER - 1 ||
+ self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER ||
self.cur_local_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER {
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
}
let funding_script = self.get_funding_redeemscript();
- let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number).map_err(|e| (None, e))?;
+ let remote_keys = self.build_remote_transaction_keys()?;
+ let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0;
+
+ let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0;
let local_sighash = hash_to_message!(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]);
// They sign the "local" commitment transaction, allowing us to broadcast the tx if we wish.
if let Err(_) = self.secp_ctx.verify(&local_sighash, &msg.signature, their_funding_pubkey) {
- return Err((None, ChannelError::Close("Invalid funding_signed signature from peer")));
+ return Err(ChannelError::Close("Invalid funding_signed signature from peer"));
}
- self.latest_monitor_update_id += 1;
- let monitor_update = ChannelMonitorUpdate {
- update_id: self.latest_monitor_update_id,
- updates: vec![ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo {
- commitment_tx: LocalCommitmentTransaction::new_missing_local_sig(local_initial_commitment_tx, &msg.signature, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), their_funding_pubkey, local_keys, self.feerate_per_kw, Vec::new()),
- htlc_outputs: Vec::new(),
- }]
- };
- self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).unwrap();
- self.channel_state = ChannelState::FundingSent as u32 | (self.channel_state & (ChannelState::MonitorUpdateFailed as u32));
- self.cur_local_commitment_transaction_number -= 1;
+ let their_pubkeys = self.their_pubkeys.as_ref().unwrap();
+ let funding_redeemscript = self.get_funding_redeemscript();
+ let funding_txo = self.funding_txo.as_ref().unwrap();
+ 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.clone(), &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());
- if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
- Ok(monitor_update)
- } else {
- Err((Some(monitor_update),
- ChannelError::Ignore("Previous monitor update failure prevented funding_signed from allowing funding broadcast")))
+ 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
+ } }
}
+
+ self.channel_monitor = Some(create_monitor!());
+ let channel_monitor = create_monitor!();
+
+ assert_eq!(self.channel_state & (ChannelState::MonitorUpdateFailed as u32), 0); // We have no had any monitor(s) yet to fail update!
+ self.channel_state = ChannelState::FundingSent as u32;
+ self.cur_local_commitment_transaction_number -= 1;
+ self.cur_remote_commitment_transaction_number -= 1;
+
+ Ok(channel_monitor)
}
pub fn funding_locked(&mut self, msg: &msgs::FundingLocked) -> Result<(), ChannelError> {
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");
let mut monitor_update = ChannelMonitorUpdate {
update_id: self.latest_monitor_update_id,
updates: vec![ChannelMonitorUpdateStep::LatestLocalCommitmentTXInfo {
- commitment_tx: LocalCommitmentTransaction::new_missing_local_sig(local_commitment_tx.0, &msg.signature, &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), &their_funding_pubkey, local_keys, self.feerate_per_kw, htlcs_without_source),
+ commitment_tx: LocalCommitmentTransaction::new_missing_local_sig(local_commitment_tx.0, msg.signature.clone(), &PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key()), &their_funding_pubkey, local_keys, self.feerate_per_kw, htlcs_without_source),
htlc_outputs: htlcs_and_sigs
}]
};
/// May only be called after funding has been initiated (ie is_funding_initiated() is true)
pub fn channel_monitor(&mut self) -> &mut ChannelMonitor<ChanSigner> {
- if self.channel_state < ChannelState::FundingCreated as u32 {
+ if self.channel_state < ChannelState::FundingSent as u32 {
panic!("Can't get a channel monitor until funding has been created");
}
self.channel_monitor.as_mut().unwrap()
/// Returns true if funding_created was sent/received.
pub fn is_funding_initiated(&self) -> bool {
- self.channel_state >= ChannelState::FundingCreated as u32
+ self.channel_state >= ChannelState::FundingSent as u32
}
/// Returns true if this channel is fully shut down. True here implies that no further actions
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.
}
/// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created)
- fn get_outbound_funding_created_signature(&mut self) -> Result<(Signature, Transaction), ChannelError> {
+ fn get_outbound_funding_created_signature(&mut self) -> Result<Signature, ChannelError> {
let remote_keys = self.build_remote_transaction_keys()?;
let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false, self.feerate_per_kw).0;
- Ok((self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx)
- .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?.0, remote_initial_commitment_tx))
+ Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), self.our_to_self_delay, &self.secp_ctx)
+ .map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed"))?.0)
}
/// Updates channel state with knowledge of the funding transaction's txid/index, and generates
/// Note that channel_id changes during this call!
/// Do NOT broadcast the funding transaction until after a successful funding_signed call!
/// If an Err is returned, it is a ChannelError::Close.
- pub fn get_outbound_funding_created(&mut self, funding_txo: OutPoint) -> Result<(msgs::FundingCreated, ChannelMonitor<ChanSigner>), ChannelError> {
+ pub fn get_outbound_funding_created(&mut self, funding_txo: OutPoint) -> Result<msgs::FundingCreated, ChannelError> {
if !self.channel_outbound {
panic!("Tried to create outbound funding_created message on an inbound channel!");
}
}
self.funding_txo = Some(funding_txo.clone());
- let (our_signature, commitment_tx) = match self.get_outbound_funding_created_signature() {
+ let our_signature = match self.get_outbound_funding_created_signature() {
Ok(res) => res,
Err(e) => {
log_error!(self, "Got bad signatures: {:?}!", e);
// Now that we're past error-generating stuff, update our local state:
- let their_pubkeys = self.their_pubkeys.as_ref().unwrap();
- let funding_redeemscript = self.get_funding_redeemscript();
- let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
- macro_rules! create_monitor {
- () => { {
- let mut channel_monitor = ChannelMonitor::new(self.local_keys.clone(),
- &self.shutdown_pubkey, self.our_to_self_delay,
- &self.destination_script, (funding_txo, 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(),
- self.logger.clone());
-
- channel_monitor.provide_latest_remote_commitment_tx_info(&commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap());
- channel_monitor
- } }
- }
-
- self.channel_monitor = Some(create_monitor!());
- let channel_monitor = create_monitor!();
-
self.channel_state = ChannelState::FundingCreated as u32;
self.channel_id = funding_txo.to_channel_id();
- self.cur_remote_commitment_transaction_number -= 1;
- Ok((msgs::FundingCreated {
- temporary_channel_id: temporary_channel_id,
+ Ok(msgs::FundingCreated {
+ temporary_channel_id,
funding_txid: funding_txo.txid,
funding_output_index: funding_txo.index,
signature: our_signature
- }, channel_monitor))
+ })
}
/// Gets an UnsignedChannelAnnouncement, as well as a signature covering it using our
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 {
value: 10000000, script_pubkey: output_script.clone(),
}]};
let funding_outpoint = OutPoint::new(tx.txid(), 0);
- let (funding_created_msg, _) = node_a_chan.get_outbound_funding_created(funding_outpoint).unwrap();
+ let funding_created_msg = node_a_chan.get_outbound_funding_created(funding_outpoint).unwrap();
let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg).unwrap();
// Node B --> Node A: funding signed
macro_rules! test_commitment {
( $their_sig_hex: expr, $our_sig_hex: expr, $tx_hex: expr, {
$( { $htlc_idx: expr, $their_htlc_sig_hex: expr, $our_htlc_sig_hex: expr, $htlc_tx_hex: expr } ), *
- } ) => {
+ } ) => { {
unsigned_tx = {
let mut res = chan.build_commitment_transaction(0xffffffffffff - 42, &keys, true, false, chan.feerate_per_kw);
let htlcs = res.2.drain(..)
})*
assert_eq!(unsigned_tx.1.len(), per_htlc.len());
- localtx = LocalCommitmentTransaction::new_missing_local_sig(unsigned_tx.0.clone(), &their_signature, &PublicKey::from_secret_key(&secp_ctx, chan.local_keys.funding_key()), chan.their_funding_pubkey(), keys.clone(), chan.feerate_per_kw, per_htlc);
- chan_keys.sign_local_commitment(&mut localtx, &chan.secp_ctx);
+ localtx = LocalCommitmentTransaction::new_missing_local_sig(unsigned_tx.0.clone(), their_signature.clone(), &PublicKey::from_secret_key(&secp_ctx, chan.local_keys.funding_key()), chan.their_funding_pubkey(), keys.clone(), chan.feerate_per_kw, per_htlc);
+ let local_sig = chan_keys.sign_local_commitment(&localtx, &chan.secp_ctx).unwrap();
- assert_eq!(serialize(localtx.with_valid_witness())[..],
+ assert_eq!(serialize(&localtx.add_local_sig(&redeemscript, local_sig))[..],
hex::decode($tx_hex).unwrap()[..]);
+ let htlc_sigs = chan_keys.sign_local_commitment_htlc_transactions(&localtx, chan.their_to_self_delay, &chan.secp_ctx).unwrap();
+ let mut htlc_sig_iter = localtx.per_htlc.iter().zip(htlc_sigs.iter().enumerate());
+
$({
let remote_signature = Signature::from_der(&hex::decode($their_htlc_sig_hex).unwrap()[..]).unwrap();
assert!(preimage.is_some());
}
- chan_keys.sign_htlc_transaction(&mut localtx, $htlc_idx, preimage, chan.their_to_self_delay, &chan.secp_ctx);
+ let mut htlc_sig = htlc_sig_iter.next().unwrap();
+ while (htlc_sig.1).1.is_none() { htlc_sig = htlc_sig_iter.next().unwrap(); }
+ assert_eq!((htlc_sig.0).0.transaction_output_index, Some($htlc_idx));
- assert_eq!(serialize(localtx.htlc_with_valid_witness($htlc_idx).as_ref().unwrap())[..],
+ assert_eq!(serialize(&localtx.get_signed_htlc_tx((htlc_sig.1).0, &(htlc_sig.1).1.unwrap(), &preimage, chan.their_to_self_delay))[..],
hex::decode($htlc_tx_hex).unwrap()[..]);
})*
- }
+ loop {
+ let htlc_sig = htlc_sig_iter.next();
+ if htlc_sig.is_none() { break; }
+ assert!((htlc_sig.unwrap().1).1.is_none());
+ }
+ } }
}
{