use std::default::Default;
use std::{cmp,mem,fmt};
use std::sync::{Arc};
+use std::ops::Deref;
#[cfg(test)]
pub struct ChannelValueStat {
#[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,
}
// Constructors:
- pub fn new_outbound(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface<ChanKeySigner = ChanSigner>>, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, APIError> {
+ pub fn new_outbound<K: Deref>(fee_estimator: &FeeEstimator, keys_provider: &K, their_node_id: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, APIError>
+ where K::Target: KeysInterface<ChanKeySigner = ChanSigner>
+ {
let chan_keys = keys_provider.get_channel_keys(false, channel_value_satoshis);
if channel_value_satoshis >= MAX_FUNDING_SATOSHIS {
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,
/// Creates a new channel from a remote sides' request for one.
/// Assumes chain_hash has already been checked and corresponds with what we expect!
- pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface<ChanKeySigner = ChanSigner>>, their_node_id: PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, ChannelError> {
+ pub fn new_from_req<K: Deref>(fee_estimator: &FeeEstimator, keys_provider: &K, their_node_id: PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, ChannelError>
+ where K::Target: KeysInterface<ChanKeySigner = ChanSigner>
+ {
let mut chan_keys = keys_provider.get_channel_keys(true, msg.funding_satoshis);
let their_pubkeys = ChannelPublicKeys {
funding_pubkey: msg.funding_pubkey,
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));
+ 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());
- // Now that we're past error-generating stuff, update our local state:
+ 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(), local_keys.clone(), self.feerate_per_kw, Vec::new()).unwrap();
+ channel_monitor
+ } }
+ }
+
+ self.channel_monitor = Some(create_monitor!());
+ let channel_monitor = create_monitor!();
- 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_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()))
+ }, channel_monitor))
}
/// 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 temporary_channel_id = self.channel_id;
+
+ // 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));
- let temporary_channel_id = self.channel_id;
+ 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!();
- // 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());
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()))
+ }, channel_monitor))
}
/// 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,