+// 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 bitcoin::blockdata::opcodes;
-use bitcoin::util::hash::BitcoinHash;
use bitcoin::util::bip143;
use bitcoin::consensus::encode;
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,
user_id: user_id,
config: config.channel_options.clone(),
- channel_id: keys_provider.get_channel_id(),
+ channel_id: keys_provider.get_secure_random_bytes(),
channel_state: ChannelState::OurInitSent as u32,
channel_outbound: true,
secp_ctx: Secp256k1::new(),
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,
let htlc_basepoint = &self.local_keys.pubkeys().htlc_basepoint;
let their_pubkeys = self.their_pubkeys.as_ref().unwrap();
- Ok(secp_check!(TxCreationKeys::new(&self.secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &their_pubkeys.revocation_basepoint, &their_pubkeys.htlc_basepoint), "Local tx keys generation got bogus keys".to_owned()))
+ Ok(secp_check!(TxCreationKeys::derive_new(&self.secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &their_pubkeys.revocation_basepoint, &their_pubkeys.htlc_basepoint), "Local tx keys generation got bogus keys".to_owned()))
}
#[inline]
let htlc_basepoint = &self.local_keys.pubkeys().htlc_basepoint;
let their_pubkeys = self.their_pubkeys.as_ref().unwrap();
- Ok(secp_check!(TxCreationKeys::new(&self.secp_ctx, &self.their_cur_commitment_point.unwrap(), &their_pubkeys.delayed_payment_basepoint, &their_pubkeys.htlc_basepoint, revocation_basepoint, htlc_basepoint), "Remote tx keys generation got bogus keys".to_owned()))
+ Ok(secp_check!(TxCreationKeys::derive_new(&self.secp_ctx, &self.their_cur_commitment_point.unwrap(), &their_pubkeys.delayed_payment_basepoint, &their_pubkeys.htlc_basepoint, revocation_basepoint, htlc_basepoint), "Remote tx keys generation got bogus keys".to_owned()))
}
/// Gets the redeemscript for the funding transaction output (ie the funding transaction output
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() {
} }
}
- 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)
}
});
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
- if header.bitcoin_hash() != self.last_block_connected {
+ if header.block_hash() != self.last_block_connected {
if self.funding_tx_confirmations > 0 {
self.funding_tx_confirmations += 1;
}
}
}
}
- if header.bitcoin_hash() != self.last_block_connected {
- self.last_block_connected = header.bitcoin_hash();
+ if header.block_hash() != self.last_block_connected {
+ self.last_block_connected = header.block_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 {
// funding_tx_confirmed_in and return.
false
};
- self.funding_tx_confirmed_in = Some(header.bitcoin_hash());
+ self.funding_tx_confirmed_in = Some(self.last_block_connected);
//TODO: Note that this must be a duplicate of the previous commitment point they sent us,
//as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
return true;
}
}
- if Some(header.bitcoin_hash()) == self.funding_tx_confirmed_in {
+ self.last_block_connected = header.block_hash();
+ if Some(self.last_block_connected) == self.funding_tx_confirmed_in {
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
}
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))
}
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,
#[cfg(test)]
mod tests {
- use bitcoin::BitcoinHash;
use bitcoin::util::bip143;
use bitcoin::consensus::encode::serialize;
use bitcoin::blockdata::script::{Script, Builder};
fn get_channel_keys(&self, _inbound: bool, _channel_value_satoshis: u64) -> InMemoryChannelKeys {
self.chan_keys.clone()
}
- fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) { panic!(); }
- fn get_channel_id(&self) -> [u8; 32] { [0; 32] }
+ fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
}
fn public_from_secret_hex(secp_ctx: &Secp256k1<All>, hex: &str) -> PublicKey {
// Now change the fee so we can check that the fee in the open_channel message is the
// same as the old fee.
fee_est.fee_est = 500;
- let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.bitcoin_hash());
+ let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
assert_eq!(open_channel_msg.feerate_per_kw, original_fee);
}
let mut node_a_chan = Channel::<EnforcingChannelKeys>::new_outbound(&&feeest, &&keys_provider, node_a_node_id, 10000000, 100000, 42, &config).unwrap();
// Create Node B's channel by receiving Node A's open_channel message
- let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.bitcoin_hash());
+ let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
let mut node_b_chan = Channel::<EnforcingChannelKeys>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, InitFeatures::known(), &open_channel_msg, 7, &config).unwrap();
let per_commitment_secret = SecretKey::from_slice(&hex::decode("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..]).unwrap();
let per_commitment_point = PublicKey::from_secret_key(&secp_ctx, &per_commitment_secret);
let htlc_basepoint = &chan.local_keys.pubkeys().htlc_basepoint;
- let keys = TxCreationKeys::new(&secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &their_pubkeys.revocation_basepoint, &their_pubkeys.htlc_basepoint).unwrap();
+ let keys = TxCreationKeys::derive_new(&secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &their_pubkeys.revocation_basepoint, &their_pubkeys.htlc_basepoint).unwrap();
chan.their_pubkeys = Some(their_pubkeys);