+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
use bitcoin::blockdata::block::BlockHeader;
use bitcoin::blockdata::script::{Script,Builder};
use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType};
use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
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::{CounterpartyCommitmentSecrets, LocalCommitmentTransaction, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, PreCalculatedTxCreationKeys};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
their_shutdown_scriptpubkey: Option<Script>,
- /// Used exclusively to broadcast the latest local state, mostly a historical quirk that this
- /// is here:
- channel_monitor: Option<ChannelMonitor<ChanSigner>>,
commitment_secrets: CounterpartyCommitmentSecrets,
network_sync: UpdateStatus,
their_shutdown_scriptpubkey: None,
- channel_monitor: None,
commitment_secrets: CounterpartyCommitmentSecrets::new(),
network_sync: UpdateStatus::Fresh,
their_shutdown_scriptpubkey,
- channel_monitor: None,
commitment_secrets: CounterpartyCommitmentSecrets::new(),
network_sync: UpdateStatus::Fresh,
payment_preimage: payment_preimage_arg.clone(),
}],
};
- self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone(), logger).unwrap();
if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32 | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateFailed as u32)) != 0 {
for pending_update in self.holding_cell_htlc_updates.iter() {
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, logger).0;
- let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
+ let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
+ let remote_signature = self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;
// We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
} }
}
- self.channel_monitor = Some(create_monitor!());
let channel_monitor = create_monitor!();
self.channel_state = ChannelState::FundingSent as u32;
} }
}
- 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!
/// corner case properly.
pub fn get_inbound_outbound_available_balance_msat(&self) -> (u64, u64) {
// Note that we have to handle overflow due to the above case.
- (cmp::min(self.channel_value_satoshis as i64 * 1000 - self.value_to_self_msat as i64 - self.get_inbound_pending_htlc_stats().1 as i64, 0) as u64,
- cmp::min(self.value_to_self_msat as i64 - self.get_outbound_pending_htlc_stats().1 as i64, 0) as u64)
+ (cmp::max(self.channel_value_satoshis as i64 * 1000 - self.value_to_self_msat as i64 - self.get_inbound_pending_htlc_stats().1 as i64, 0) as u64,
+ cmp::max(self.value_to_self_msat as i64 - self.get_outbound_pending_htlc_stats().1 as i64, 0) as u64)
}
// Get the fee cost of a commitment tx with a given number of HTLC outputs.
htlc_outputs: htlcs_and_sigs
}]
};
- self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone(), logger).unwrap();
for htlc in self.pending_inbound_htlcs.iter_mut() {
let new_forward = if let &InboundHTLCState::RemoteAnnounced(ref forward_info) = &htlc.state {
secret: msg.per_commitment_secret,
}],
};
- self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone(), logger).unwrap();
// Update state now that we've passed all the can-fail calls...
// (note that we may still fail to generate the new commitment_signed message, but that's
self.user_id
}
- /// 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::FundingSent as u32 {
- panic!("Can't get a channel monitor until funding has been created");
- }
- self.channel_monitor.as_mut().unwrap()
- }
-
/// Guaranteed to be Some after both FundingLocked messages have been exchanged (and, thus,
/// is_usable() returns true).
/// Allowed in any state (including after shutdown)
if header.bitcoin_hash() != self.last_block_connected {
self.last_block_connected = header.bitcoin_hash();
self.update_time_counter = cmp::max(self.update_time_counter, header.time);
- if let Some(channel_monitor) = self.channel_monitor.as_mut() {
- channel_monitor.last_block_hash = self.last_block_connected;
- }
if self.funding_tx_confirmations > 0 {
if self.funding_tx_confirmations == self.minimum_depth as u64 {
let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
self.funding_tx_confirmations = self.minimum_depth as u64 - 1;
}
self.last_block_connected = header.bitcoin_hash();
- if let Some(channel_monitor) = self.channel_monitor.as_mut() {
- channel_monitor.last_block_hash = self.last_block_connected;
- }
false
}
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
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, logger).0;
- Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &remote_keys, &Vec::new(), &self.secp_ctx)
+ let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
+ Ok(self.local_keys.sign_remote_commitment(self.feerate_per_kw, &remote_initial_commitment_tx, &pre_remote_keys, &Vec::new(), &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
}
their_revocation_point: self.their_cur_commitment_point.unwrap()
}]
};
- self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone(), logger).unwrap();
self.channel_state |= ChannelState::AwaitingRemoteRevoke as u32;
Ok((res, monitor_update))
}
htlcs.push(htlc);
}
- let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &remote_keys, &htlcs, &self.secp_ctx)
+ let pre_remote_keys = PreCalculatedTxCreationKeys::new(remote_keys);
+ let res = self.local_keys.sign_remote_commitment(feerate_per_kw, &remote_commitment_tx.0, &pre_remote_keys, &htlcs, &self.secp_ctx)
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?;
signature = res.0;
htlc_signatures = res.1;
+ let remote_keys = pre_remote_keys.trust_key_derivation();
log_trace!(logger, "Signed remote commitment tx {} with redeemscript {} -> {}",
encode::serialize_hex(&remote_commitment_tx.0),
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&remote_commitment_tx.0.txid(), feerate_per_kw, self.our_to_self_delay, htlc, &remote_keys.a_delayed_payment_key, &remote_keys.revocation_key)),
- encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &remote_keys)),
+ encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, remote_keys)),
log_bytes!(remote_keys.a_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]));
}
self.their_shutdown_scriptpubkey.write(writer)?;
self.commitment_secrets.write(writer)?;
-
- self.channel_monitor.as_ref().unwrap().write_for_disk(writer)?;
Ok(())
}
}
let their_shutdown_scriptpubkey = Readable::read(reader)?;
let commitment_secrets = Readable::read(reader)?;
- let (monitor_last_block, channel_monitor) = Readable::read(reader)?;
- // We drop the ChannelMonitor's last block connected hash cause we don't actually bother
- // doing full block connection operations on the internal ChannelMonitor copies
- if monitor_last_block != last_block_connected {
- return Err(DecodeError::InvalidValue);
- }
-
Ok(Channel {
user_id,
their_shutdown_scriptpubkey,
- channel_monitor: Some(channel_monitor),
commitment_secrets,
network_sync: UpdateStatus::Fresh,