#[cfg(test)]
pub(super) local_keys: ChanSigner,
shutdown_pubkey: PublicKey,
+ destination_script: Script,
// Our commitment numbers start at 2^48-1 and count down, whereas the ones used in transaction
// generation start at 0 and count up...this simplifies some parts of implementation at the
their_shutdown_scriptpubkey: Option<Script>,
- channel_monitor: ChannelMonitor<ChanSigner>,
+ /// 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,
let feerate = fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
- let secp_ctx = Secp256k1::new();
- let channel_monitor = ChannelMonitor::new(chan_keys.clone(),
- chan_keys.funding_key(), chan_keys.revocation_base_key(), chan_keys.delayed_payment_base_key(),
- chan_keys.htlc_base_key(), chan_keys.payment_base_key(), &keys_provider.get_shutdown_pubkey(), config.own_channel_config.our_to_self_delay,
- keys_provider.get_destination_script(), logger.clone());
-
Ok(Channel {
user_id: user_id,
config: config.channel_options.clone(),
channel_id: keys_provider.get_channel_id(),
channel_state: ChannelState::OurInitSent as u32,
channel_outbound: true,
- secp_ctx: secp_ctx,
+ secp_ctx: Secp256k1::new(),
channel_value_satoshis: channel_value_satoshis,
latest_monitor_update_id: 0,
local_keys: chan_keys,
shutdown_pubkey: keys_provider.get_shutdown_pubkey(),
+ destination_script: keys_provider.get_destination_script(),
+
cur_local_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
cur_remote_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
value_to_self_msat: channel_value_satoshis * 1000 - push_msat,
their_shutdown_scriptpubkey: None,
- channel_monitor: channel_monitor,
+ channel_monitor: None,
commitment_secrets: CounterpartyCommitmentSecrets::new(),
network_sync: UpdateStatus::Fresh,
return Err(ChannelError::Close("Insufficient funding amount for initial commitment"));
}
- let secp_ctx = Secp256k1::new();
- let channel_monitor = ChannelMonitor::new(chan_keys.clone(),
- chan_keys.funding_key(), chan_keys.revocation_base_key(), chan_keys.delayed_payment_base_key(),
- chan_keys.htlc_base_key(), chan_keys.payment_base_key(), &keys_provider.get_shutdown_pubkey(), config.own_channel_config.our_to_self_delay,
- keys_provider.get_destination_script(), logger.clone());
-
let their_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
match &msg.shutdown_scriptpubkey {
&OptionalField::Present(ref script) => {
channel_id: msg.temporary_channel_id,
channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
channel_outbound: false,
- secp_ctx: secp_ctx,
+ secp_ctx: Secp256k1::new(),
latest_monitor_update_id: 0,
local_keys: chan_keys,
shutdown_pubkey: keys_provider.get_shutdown_pubkey(),
+ destination_script: keys_provider.get_destination_script(),
+
cur_local_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
cur_remote_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
value_to_self_msat: msg.push_msat,
their_shutdown_scriptpubkey,
- channel_monitor: channel_monitor,
+ channel_monitor: None,
commitment_secrets: CounterpartyCommitmentSecrets::new(),
network_sync: UpdateStatus::Fresh,
payment_preimage: payment_preimage_arg.clone(),
}],
};
- self.channel_monitor.update_monitor_ooo(monitor_update.clone()).unwrap();
+ self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).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() {
}
};
+ // 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();
- self.channel_monitor.set_basic_channel_info(&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());
-
let funding_txo_script = 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());
- self.channel_monitor.provide_latest_local_commitment_tx_info(local_initial_commitment_tx, local_keys, self.feerate_per_kw, Vec::new()).unwrap();
+ self.channel_monitor = Some(ChannelMonitor::new(self.local_keys.clone(),
+ &self.shutdown_pubkey, self.our_to_self_delay,
+ &self.destination_script, (funding_txo, funding_txo_script),
+ &their_pubkeys.htlc_basepoint, &their_pubkeys.delayed_payment_basepoint,
+ self.their_to_self_delay, funding_redeemscript, self.channel_value_satoshis,
+ self.get_commitment_transaction_number_obscure_factor(),
+ self.logger.clone()));
+
+ self.channel_monitor.as_mut().unwrap().provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap());
+ self.channel_monitor.as_mut().unwrap().provide_latest_local_commitment_tx_info(local_initial_commitment_tx, local_keys, self.feerate_per_kw, Vec::new()).unwrap();
self.channel_state = ChannelState::FundingSent as u32;
self.channel_id = funding_txo.to_channel_id();
self.cur_remote_commitment_transaction_number -= 1;
Ok((msgs::FundingSigned {
channel_id: self.channel_id,
signature: our_signature
- }, self.channel_monitor.clone()))
+ }, self.channel_monitor.as_ref().unwrap().clone()))
}
/// Handles a funding_signed message from the remote end.
local_keys, feerate_per_kw: self.feerate_per_kw, htlc_outputs: Vec::new(),
}]
};
- self.channel_monitor.update_monitor_ooo(monitor_update.clone()).unwrap();
+ 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;
local_keys, feerate_per_kw: self.feerate_per_kw, htlc_outputs: htlcs_and_sigs
}]
};
- self.channel_monitor.update_monitor_ooo(monitor_update.clone()).unwrap();
+ self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).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.update_monitor_ooo(monitor_update.clone()).unwrap();
+ self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).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
their_current_per_commitment_point: data_loss.my_current_per_commitment_point
}]
};
- self.channel_monitor.update_monitor_ooo(monitor_update.clone()).unwrap();
+ self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).unwrap();
return Err(ChannelError::CloseDelayBroadcast {
msg: "We have fallen behind - we have received proof that if we broadcast remote is going to claim our funds - we can't do any automated broadcasting",
update: monitor_update
if self.channel_state < ChannelState::FundingCreated as u32 {
panic!("Can't get a channel monitor until funding has been created");
}
- &mut self.channel_monitor
+ self.channel_monitor.as_mut().unwrap()
}
/// Guaranteed to be Some after both FundingLocked messages have been exchanged (and, thus,
}
if header.bitcoin_hash() != self.last_block_connected {
self.last_block_connected = header.bitcoin_hash();
- self.channel_monitor.last_block_hash = self.last_block_connected;
+ 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();
- self.channel_monitor.last_block_hash = self.last_block_connected;
+ if let Some(channel_monitor) = self.channel_monitor.as_mut() {
+ channel_monitor.last_block_hash = self.last_block_connected;
+ }
false
}
}
};
- let their_pubkeys = self.their_pubkeys.as_ref().unwrap();
- let funding_redeemscript = self.get_funding_redeemscript();
- self.channel_monitor.set_basic_channel_info(&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());
-
- let funding_txo_script = 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:
- self.channel_monitor.provide_latest_remote_commitment_tx_info(&commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap());
+
+ 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();
+ self.channel_monitor = Some(ChannelMonitor::new(self.local_keys.clone(),
+ &self.shutdown_pubkey, self.our_to_self_delay,
+ &self.destination_script, (funding_txo, funding_txo_script),
+ &their_pubkeys.htlc_basepoint, &their_pubkeys.delayed_payment_basepoint,
+ self.their_to_self_delay, funding_redeemscript, self.channel_value_satoshis,
+ self.get_commitment_transaction_number_obscure_factor(),
+ self.logger.clone()));
+
+ self.channel_monitor.as_mut().unwrap().provide_latest_remote_commitment_tx_info(&commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number, self.their_cur_commitment_point.unwrap());
self.channel_state = ChannelState::FundingCreated as u32;
self.channel_id = funding_txo.to_channel_id();
self.cur_remote_commitment_transaction_number -= 1;
funding_txid: funding_txo.txid,
funding_output_index: funding_txo.index,
signature: our_signature
- }, self.channel_monitor.clone()))
+ }, self.channel_monitor.as_ref().unwrap().clone()))
}
/// Gets an UnsignedChannelAnnouncement, as well as a signature covering it using our
their_revocation_point: self.their_cur_commitment_point.unwrap()
}]
};
- self.channel_monitor.update_monitor_ooo(monitor_update.clone()).unwrap();
+ self.channel_monitor.as_mut().unwrap().update_monitor_ooo(monitor_update.clone()).unwrap();
self.channel_state |= ChannelState::AwaitingRemoteRevoke as u32;
Ok((res, monitor_update))
}
self.channel_state = ChannelState::ShutdownComplete as u32;
self.channel_update_count += 1;
- (self.channel_monitor.get_latest_local_commitment_txn(), dropped_outbound_htlcs)
+ if self.channel_monitor.is_some() {
+ (self.channel_monitor.as_mut().unwrap().get_latest_local_commitment_txn(), dropped_outbound_htlcs)
+ } else {
+ // We aren't even signed funding yet, so can't broadcast anything
+ (Vec::new(), dropped_outbound_htlcs)
+ }
}
}
self.local_keys.write(writer)?;
self.shutdown_pubkey.write(writer)?;
+ self.destination_script.write(writer)?;
self.cur_local_commitment_transaction_number.write(writer)?;
self.cur_remote_commitment_transaction_number.write(writer)?;
self.commitment_secrets.write(writer)?;
- self.channel_monitor.write_for_disk(writer)?;
+ self.channel_monitor.as_ref().unwrap().write_for_disk(writer)?;
Ok(())
}
}
let local_keys = Readable::read(reader)?;
let shutdown_pubkey = Readable::read(reader)?;
+ let destination_script = Readable::read(reader)?;
let cur_local_commitment_transaction_number = Readable::read(reader)?;
let cur_remote_commitment_transaction_number = Readable::read(reader)?;
local_keys,
shutdown_pubkey,
+ destination_script,
cur_local_commitment_transaction_number,
cur_remote_commitment_transaction_number,
their_shutdown_scriptpubkey,
- channel_monitor,
+ channel_monitor: Some(channel_monitor),
commitment_secrets,
network_sync: UpdateStatus::Fresh,
}
impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
- pub(super) fn new(keys: ChanSigner, funding_key: &SecretKey, revocation_base_key: &SecretKey, delayed_payment_base_key: &SecretKey, htlc_base_key: &SecretKey, payment_base_key: &SecretKey, shutdown_pubkey: &PublicKey, our_to_self_delay: u16, destination_script: Script, logger: Arc<Logger>) -> ChannelMonitor<ChanSigner> {
+ pub(super) fn new(keys: ChanSigner, shutdown_pubkey: &PublicKey,
+ our_to_self_delay: u16, destination_script: &Script, funding_info: (OutPoint, Script),
+ their_htlc_base_key: &PublicKey, their_delayed_payment_base_key: &PublicKey,
+ their_to_self_delay: u16, funding_redeemscript: Script, channel_value_satoshis: u64,
+ commitment_transaction_number_obscure_factor: u64,
+ logger: Arc<Logger>) -> ChannelMonitor<ChanSigner> {
+
+ assert!(commitment_transaction_number_obscure_factor <= (1 << 48));
+ let funding_key = keys.funding_key().clone();
+ let revocation_base_key = keys.revocation_base_key().clone();
+ let htlc_base_key = keys.htlc_base_key().clone();
+ let delayed_payment_base_key = keys.delayed_payment_base_key().clone();
+ let payment_base_key = keys.payment_base_key().clone();
ChannelMonitor {
latest_update_id: 0,
- commitment_transaction_number_obscure_factor: 0,
+ commitment_transaction_number_obscure_factor,
key_storage: Storage::Local {
keys,
- funding_key: funding_key.clone(),
- revocation_base_key: revocation_base_key.clone(),
- htlc_base_key: htlc_base_key.clone(),
- delayed_payment_base_key: delayed_payment_base_key.clone(),
- payment_base_key: payment_base_key.clone(),
+ funding_key,
+ revocation_base_key,
+ htlc_base_key,
+ delayed_payment_base_key,
+ payment_base_key,
shutdown_pubkey: shutdown_pubkey.clone(),
- funding_info: None,
+ funding_info: Some(funding_info),
current_remote_commitment_txid: None,
prev_remote_commitment_txid: None,
},
- their_htlc_base_key: None,
- their_delayed_payment_base_key: None,
- funding_redeemscript: None,
- channel_value_satoshis: None,
+ their_htlc_base_key: Some(their_htlc_base_key.clone()),
+ their_delayed_payment_base_key: Some(their_delayed_payment_base_key.clone()),
+ funding_redeemscript: Some(funding_redeemscript),
+ channel_value_satoshis: Some(channel_value_satoshis),
their_cur_revocation_points: None,
our_to_self_delay: our_to_self_delay,
- their_to_self_delay: None,
+ their_to_self_delay: Some(their_to_self_delay),
commitment_secrets: CounterpartyCommitmentSecrets::new(),
remote_claimable_outpoints: HashMap::new(),
payment_preimages: HashMap::new(),
pending_htlcs_updated: Vec::new(),
- destination_script: destination_script,
+ destination_script: destination_script.clone(),
to_remote_rescue: None,
pending_claim_requests: HashMap::new(),
Ok(())
}
- /// Allows this monitor to scan only for transactions which are applicable. Note that this is
- /// optional, without it this monitor cannot be used in an SPV client, but you may wish to
- /// avoid this on a monitor you wish to send to a watchtower as it provides slightly better
- /// privacy.
- /// It's the responsibility of the caller to register outpoint and script with passing the former
- /// value as key to add_update_monitor.
- pub(super) fn set_funding_info(&mut self, new_funding_info: (OutPoint, Script)) {
- match self.key_storage {
- Storage::Local { ref mut funding_info, .. } => {
- *funding_info = Some(new_funding_info);
- },
- Storage::Watchtower { .. } => {
- panic!("Channel somehow ended up with its internal ChannelMonitor being in Watchtower mode?");
- }
- }
- }
-
- /// We log these base keys at channel opening to being able to rebuild redeemscript in case of leaked revoked commit tx
- /// Panics if commitment_transaction_number_obscure_factor doesn't fit in 48 bits
- pub(super) fn set_basic_channel_info(&mut self, their_htlc_base_key: &PublicKey, their_delayed_payment_base_key: &PublicKey, their_to_self_delay: u16, funding_redeemscript: Script, channel_value_satoshis: u64, commitment_transaction_number_obscure_factor: u64) {
- self.their_htlc_base_key = Some(their_htlc_base_key.clone());
- self.their_delayed_payment_base_key = Some(their_delayed_payment_base_key.clone());
- self.their_to_self_delay = Some(their_to_self_delay);
- self.funding_redeemscript = Some(funding_redeemscript);
- self.channel_value_satoshis = Some(channel_value_satoshis);
- assert!(commitment_transaction_number_obscure_factor < (1 << 48));
- self.commitment_transaction_number_obscure_factor = commitment_transaction_number_obscure_factor;
- }
-
/// Gets the update_id from the latest ChannelMonitorUpdate which was applied to this
/// ChannelMonitor.
pub fn get_latest_update_id(&self) -> u64 {
use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use bitcoin_hashes::hex::FromHex;
use hex;
+ use chain::transaction::OutPoint;
use ln::channelmanager::{PaymentPreimage, PaymentHash};
use ln::channelmonitor::{ChannelMonitor, InputDescriptors};
use ln::chan_utils;
// Prune with one old state and a local commitment tx holding a few overlaps with the
// old state.
- let mut monitor = ChannelMonitor::new(keys, &SecretKey::from_slice(&[41; 32]).unwrap(), &SecretKey::from_slice(&[42; 32]).unwrap(), &SecretKey::from_slice(&[43; 32]).unwrap(), &SecretKey::from_slice(&[44; 32]).unwrap(), &SecretKey::from_slice(&[44; 32]).unwrap(), &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[45; 32]).unwrap()), 0, Script::new(), logger.clone());
+ let mut monitor = ChannelMonitor::new(keys,
+ &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0, &Script::new(),
+ (OutPoint { txid: Sha256dHash::from_slice(&[43; 32]).unwrap(), index: 0 }, Script::new()),
+ &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[44; 32]).unwrap()),
+ &PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[45; 32]).unwrap()),
+ 0, Script::new(), 46, 0, logger.clone());
+
monitor.their_to_self_delay = Some(10);
monitor.provide_latest_local_commitment_tx_info(LocalCommitmentTransaction::dummy(), dummy_keys!(), 0, preimages_to_local_htlcs!(preimages[0..10])).unwrap();