use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::ChannelMonitor;
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
-use ln::chan_utils::{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};
use ln::chan_utils;
use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
use chain::transaction::OutPoint;
last_sent_closing_fee: Option<(u64, u64, Signature)>, // (feerate, fee, our_sig)
+ funding_txo: Option<OutPoint>,
+
/// 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
their_shutdown_scriptpubkey: Option<Script>,
channel_monitor: ChannelMonitor<ChanSigner>,
+ commitment_secrets: CounterpartyCommitmentSecrets,
network_sync: UpdateStatus,
last_sent_closing_fee: None,
+ funding_txo: None,
funding_tx_confirmed_in: None,
short_channel_id: None,
last_block_connected: Default::default(),
their_shutdown_scriptpubkey: None,
channel_monitor: channel_monitor,
+ commitment_secrets: CounterpartyCommitmentSecrets::new(),
network_sync: UpdateStatus::Fresh,
last_sent_closing_fee: None,
+ funding_txo: None,
funding_tx_confirmed_in: None,
short_channel_id: None,
last_block_connected: Default::default(),
their_shutdown_scriptpubkey,
channel_monitor: channel_monitor,
+ commitment_secrets: CounterpartyCommitmentSecrets::new(),
network_sync: UpdateStatus::Fresh,
let txins = {
let mut ins: Vec<TxIn> = Vec::new();
ins.push(TxIn {
- previous_output: self.channel_monitor.get_funding_txo().unwrap().into_bitcoin_outpoint(),
+ previous_output: self.funding_txo.unwrap().into_bitcoin_outpoint(),
script_sig: Script::new(),
sequence: ((0x80 as u32) << 8*3) | ((obscured_commitment_transaction_number >> 3*8) as u32),
witness: Vec::new(),
let txins = {
let mut ins: Vec<TxIn> = Vec::new();
ins.push(TxIn {
- previous_output: self.channel_monitor.get_funding_txo().unwrap().into_bitcoin_outpoint(),
+ previous_output: self.funding_txo.unwrap().into_bitcoin_outpoint(),
script_sig: Script::new(),
sequence: 0xffffffff,
witness: Vec::new(),
// channel.
return Err(ChannelError::Close("Received funding_created after we got the channel!"));
}
- if self.channel_monitor.get_min_seen_secret() != (1 << 48) ||
+ if self.commitment_secrets.get_min_seen_secret() != (1 << 48) ||
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_txo = OutPoint::new(msg.funding_txid, msg.funding_output_index);
- let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh();
- self.channel_monitor.set_funding_info((funding_txo, funding_txo_script));
+ self.funding_txo = Some(funding_txo.clone());
let (remote_initial_commitment_tx, local_initial_commitment_tx, our_signature, local_keys) = match self.funding_created_signature(&msg.signature) {
Ok(res) => res,
Err(e) => {
- self.channel_monitor.unset_funding_info();
+ self.funding_txo = None;
return Err(e);
}
};
+ let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh();
+ self.channel_monitor.set_funding_info((funding_txo, funding_txo_script));
+
// Now that we're past error-generating stuff, update our local state:
self.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());
if self.channel_state & !(ChannelState::MonitorUpdateFailed as u32) != ChannelState::FundingCreated as u32 {
return Err(ChannelError::Close("Received funding_signed in strange state!"));
}
- if self.channel_monitor.get_min_seen_secret() != (1 << 48) ||
+ if self.commitment_secrets.get_min_seen_secret() != (1 << 48) ||
self.cur_remote_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER - 1 ||
self.cur_local_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER {
panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
return Err(ChannelError::Close("Got a revoke commitment secret which didn't correspond to their current pubkey"));
}
}
+ self.commitment_secrets.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret)
+ .map_err(|_| ChannelError::Close("Previous secrets did not match new one"))?;
self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret)
- .map_err(|e| ChannelError::Close(e.0))?;
+ .unwrap();
if self.channel_state & ChannelState::AwaitingRemoteRevoke as u32 == 0 {
// Our counterparty seems to have burned their coins to us (by revoking a state when we
/// Returns the funding_txo we either got from our peer, or were given by
/// get_outbound_funding_created.
pub fn get_funding_txo(&self) -> Option<OutPoint> {
- self.channel_monitor.get_funding_txo()
+ self.funding_txo
}
/// Allowed in any state (including after shutdown)
}
if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
for (ref tx, index_in_block) in txn_matched.iter().zip(indexes_of_txn_matched) {
- if tx.txid() == self.channel_monitor.get_funding_txo().unwrap().txid {
- let txo_idx = self.channel_monitor.get_funding_txo().unwrap().index as usize;
+ if tx.txid() == self.funding_txo.unwrap().txid {
+ let txo_idx = self.funding_txo.unwrap().index as usize;
if txo_idx >= tx.output.len() || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() ||
tx.output[txo_idx].value != self.channel_value_satoshis {
if self.channel_outbound {
if self.channel_state != (ChannelState::OurInitSent as u32 | ChannelState::TheirInitSent as u32) {
panic!("Tried to get a funding_created messsage at a time other than immediately after initial handshake completion (or tried to get funding_created twice)");
}
- if self.channel_monitor.get_min_seen_secret() != (1 << 48) ||
+ if self.commitment_secrets.get_min_seen_secret() != (1 << 48) ||
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_txo_script = self.get_funding_redeemscript().to_v0_p2wsh();
- self.channel_monitor.set_funding_info((funding_txo, funding_txo_script));
-
+ self.funding_txo = Some(funding_txo.clone());
let (our_signature, commitment_tx) = match self.get_outbound_funding_created_signature() {
Ok(res) => res,
Err(e) => {
log_error!(self, "Got bad signatures: {:?}!", e);
- self.channel_monitor.unset_funding_info();
+ self.funding_txo = None;
return Err(e);
}
};
+ let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh();
+ self.channel_monitor.set_funding_info((funding_txo, funding_txo_script));
let temporary_channel_id = self.channel_id;
// Now that we're past error-generating stuff, update our local state:
assert_eq!(self.channel_state & ChannelState::PeerDisconnected as u32, ChannelState::PeerDisconnected as u32);
assert_ne!(self.cur_remote_commitment_transaction_number, INITIAL_COMMITMENT_NUMBER);
let data_loss_protect = if self.cur_remote_commitment_transaction_number + 1 < INITIAL_COMMITMENT_NUMBER {
- let remote_last_secret = self.channel_monitor.get_secret(self.cur_remote_commitment_transaction_number + 2).unwrap();
+ let remote_last_secret = self.commitment_secrets.get_secret(self.cur_remote_commitment_transaction_number + 2).unwrap();
log_trace!(self, "Enough info to generate a Data Loss Protect with per_commitment_secret {}", log_bytes!(remote_last_secret));
OptionalField::Present(DataLossProtect {
your_last_per_commitment_secret: remote_last_secret,
None => 0u8.write(writer)?,
}
+ write_option!(self.funding_txo);
write_option!(self.funding_tx_confirmed_in);
write_option!(self.short_channel_id);
write_option!(self.their_shutdown_scriptpubkey);
+ self.commitment_secrets.write(writer)?;
+
self.channel_monitor.write_for_disk(writer)?;
Ok(())
}
_ => return Err(DecodeError::InvalidValue),
};
+ let funding_txo = Readable::read(reader)?;
let funding_tx_confirmed_in = Readable::read(reader)?;
let short_channel_id = Readable::read(reader)?;
let their_node_id = Readable::read(reader)?;
let their_shutdown_scriptpubkey = Readable::read(reader)?;
+ let commitment_secrets = Readable::read(reader)?;
+
let (monitor_last_block, channel_monitor) = ReadableArgs::read(reader, logger.clone())?;
// 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
last_sent_closing_fee,
+ funding_txo,
funding_tx_confirmed_in,
short_channel_id,
last_block_connected,
their_shutdown_scriptpubkey,
channel_monitor,
+ commitment_secrets,
network_sync: UpdateStatus::Fresh,
chan.our_dust_limit_satoshis = 546;
let funding_info = OutPoint::new(Sha256dHash::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), 0);
- chan.channel_monitor.set_funding_info((funding_info, Script::new()));
+ chan.funding_txo = Some(funding_info);
let their_pubkeys = ChannelPublicKeys {
funding_pubkey: public_from_secret_hex(&secp_ctx, "1552dfba4f6cf29a62a0af13c8d6981d36d0ef8d61ba10fb0fe90da7634d7e13"),