X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=148fdfa4854e0f906e6c45ad4299a15b26d2d36a;hb=1d7c4f663c41b13ed4a8b67d69c23136442a9b6b;hp=a17eb1a610bc132f736dcf42438b3689d20bb3f0;hpb=4395b92cc8bfe0cc803e70bba11f4db58d5d0dbf;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index a17eb1a6..148fdfa4 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -21,7 +21,6 @@ use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::transaction::Transaction; use bitcoin::blockdata::constants::genesis_block; use bitcoin::network::constants::Network; -use bitcoin::util::hash::BitcoinHash; use bitcoin::hashes::{Hash, HashEngine}; use bitcoin::hashes::hmac::{Hmac, HmacEngine}; @@ -38,14 +37,16 @@ use bitcoin::secp256k1; use chain::chaininterface::{BroadcasterInterface,ChainListener,FeeEstimator}; use chain::transaction::OutPoint; use ln::channel::{Channel, ChannelError}; -use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, ManyChannelMonitor, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY}; +use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, ManyChannelMonitor, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, MonitorEvent}; use ln::features::{InitFeatures, NodeFeatures}; use routing::router::{Route, RouteHop}; use ln::msgs; +use ln::msgs::NetAddress; use ln::onion_utils; use ln::msgs::{ChannelMessageHandler, DecodeError, LightningError, OptionalField}; use chain::keysinterface::{ChannelKeys, KeysInterface, KeysManager, InMemoryChannelKeys}; use util::config::UserConfig; +use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsProvider}; use util::{byte_utils, events}; use util::ser::{Readable, ReadableArgs, MaybeReadable, Writeable, Writer}; use util::chacha20::{ChaCha20, ChaChaReader}; @@ -179,12 +180,15 @@ pub(super) enum HTLCFailReason { } /// payment_hash type, use to cross-lock hop +/// (C-not exported) as we just use [u8; 32] directly #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] pub struct PaymentHash(pub [u8;32]); /// payment_preimage type, use to route payment between hop +/// (C-not exported) as we just use [u8; 32] directly #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] pub struct PaymentPreimage(pub [u8;32]); /// payment_secret type, use to authenticate sender to the receiver and tie MPP HTLCs together +/// (C-not exported) as we just use [u8; 32] directly #[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] pub struct PaymentSecret(pub [u8;32]); @@ -312,7 +316,7 @@ pub(super) struct ChannelHolder { claimable_htlcs: HashMap<(PaymentHash, Option), Vec>, /// Messages to send to peers - pushed to in the same lock that they are generated in (except /// for broadcast messages, where ordering isn't as strict). - pub(super) pending_msg_events: Vec, + pub(super) pending_msg_events: Vec, } /// State we hold per-peer. In the future we should put channels in here, but for now we only hold @@ -722,7 +726,7 @@ impl ChannelManager { default_configuration: config.clone(), - genesis_hash: genesis_block(network).header.bitcoin_hash(), + genesis_hash: genesis_block(network).header.block_hash(), fee_estimator: fee_est, monitor, tx_broadcaster, @@ -1243,7 +1247,8 @@ impl // Only public for testing, this should otherwise never be called direcly pub(crate) fn send_payment_along_path(&self, path: &Vec, payment_hash: &PaymentHash, payment_secret: &Option, total_value: u64, cur_height: u32) -> Result<(), APIError> { log_trace!(self.logger, "Attempting to send payment for path with next hop {}", path.first().unwrap().short_channel_id); - let (session_priv, prng_seed) = self.keys_manager.get_onion_rand(); + let prng_seed = self.keys_manager.get_secure_random_bytes(); + let session_priv = SecretKey::from_slice(&self.keys_manager.get_secure_random_bytes()[..]).expect("RNG is busted"); let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &session_priv) .map_err(|_| APIError::RouteError{err: "Pubkey along hop was maliciously selected"})?; @@ -1483,7 +1488,7 @@ impl // be absurd. We ensure this by checking that at least 500 (our stated public contract on when // broadcast_node_announcement panics) of the maximum-length addresses would fit in a 64KB // message... - const HALF_MESSAGE_IS_ADDRS: u32 = ::std::u16::MAX as u32 / (msgs::NetAddress::MAX_LEN as u32 + 1) / 2; + const HALF_MESSAGE_IS_ADDRS: u32 = ::std::u16::MAX as u32 / (NetAddress::MAX_LEN as u32 + 1) / 2; #[deny(const_err)] #[allow(dead_code)] // ...by failing to compile if the number of addresses that would be half of a message is @@ -1503,7 +1508,7 @@ impl /// only Tor Onion addresses. /// /// Panics if addresses is absurdly large (more than 500). - pub fn broadcast_node_announcement(&self, rgb: [u8; 3], alias: [u8; 32], addresses: Vec) { + pub fn broadcast_node_announcement(&self, rgb: [u8; 3], alias: [u8; 32], addresses: Vec) { let _ = self.total_consistency_lock.read().unwrap(); if addresses.len() > 500 { @@ -2917,6 +2922,7 @@ impl /// If successful, will generate a UpdateHTLCs event, so you should probably poll /// PeerManager::process_events afterwards. /// Note: This API is likely to change! + /// (C-not exported) Cause its doc(hidden) anyway #[doc(hidden)] pub fn update_fee(&self, channel_id: [u8;32], feerate_per_kw: u32) -> Result<(), APIError> { let _ = self.total_consistency_lock.read().unwrap(); @@ -2966,31 +2972,61 @@ impl Err(e) => { Err(APIError::APIMisuseError { err: e.err })} } } + + /// Process pending events from the ManyChannelMonitor. + fn process_pending_monitor_events(&self) { + let mut failed_channels = Vec::new(); + { + for monitor_event in self.monitor.get_and_clear_pending_monitor_events() { + match monitor_event { + MonitorEvent::HTLCEvent(htlc_update) => { + if let Some(preimage) = htlc_update.payment_preimage { + log_trace!(self.logger, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0)); + self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage); + } else { + log_trace!(self.logger, "Failing HTLC with hash {} from our monitor", log_bytes!(htlc_update.payment_hash.0)); + self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); + } + }, + MonitorEvent::CommitmentTxBroadcasted(funding_outpoint) => { + let mut channel_lock = self.channel_state.lock().unwrap(); + let channel_state = &mut *channel_lock; + let by_id = &mut channel_state.by_id; + let short_to_id = &mut channel_state.short_to_id; + let pending_msg_events = &mut channel_state.pending_msg_events; + if let Some(mut chan) = by_id.remove(&funding_outpoint.to_channel_id()) { + if let Some(short_id) = chan.get_short_channel_id() { + short_to_id.remove(&short_id); + } + failed_channels.push(chan.force_shutdown(false)); + if let Ok(update) = self.get_channel_update(&chan) { + pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate { + msg: update + }); + } + } + }, + } + } + } + + for failure in failed_channels.drain(..) { + self.finish_force_close_channel(failure); + } + } } -impl events::MessageSendEventsProvider for ChannelManager +impl MessageSendEventsProvider for ChannelManager where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, L::Target: Logger, { - fn get_and_clear_pending_msg_events(&self) -> Vec { - // TODO: Event release to users and serialization is currently race-y: it's very easy for a - // user to serialize a ChannelManager with pending events in it and lose those events on - // restart. This is doubly true for the fail/fulfill-backs from monitor events! - { - //TODO: This behavior should be documented. - for htlc_update in self.monitor.get_and_clear_pending_htlcs_updated() { - if let Some(preimage) = htlc_update.payment_preimage { - log_trace!(self.logger, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0)); - self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage); - } else { - log_trace!(self.logger, "Failing HTLC with hash {} from our monitor", log_bytes!(htlc_update.payment_hash.0)); - self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); - } - } - } + fn get_and_clear_pending_msg_events(&self) -> Vec { + //TODO: This behavior should be documented. It's non-intuitive that we query + // ChannelMonitors when clearing other events. + self.process_pending_monitor_events(); let mut ret = Vec::new(); let mut channel_state = self.channel_state.lock().unwrap(); @@ -2999,29 +3035,17 @@ impl } } -impl events::EventsProvider for ChannelManager +impl EventsProvider for ChannelManager where M::Target: ManyChannelMonitor, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, L::Target: Logger, { - fn get_and_clear_pending_events(&self) -> Vec { - // TODO: Event release to users and serialization is currently race-y: it's very easy for a - // user to serialize a ChannelManager with pending events in it and lose those events on - // restart. This is doubly true for the fail/fulfill-backs from monitor events! - { - //TODO: This behavior should be documented. - for htlc_update in self.monitor.get_and_clear_pending_htlcs_updated() { - if let Some(preimage) = htlc_update.payment_preimage { - log_trace!(self.logger, "Claiming HTLC with preimage {} from our monitor", log_bytes!(preimage.0)); - self.claim_funds_internal(self.channel_state.lock().unwrap(), htlc_update.source, preimage); - } else { - log_trace!(self.logger, "Failing HTLC with hash {} from our monitor", log_bytes!(htlc_update.payment_hash.0)); - self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_update.source, &htlc_update.payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); - } - } - } + fn get_and_clear_pending_events(&self) -> Vec { + //TODO: This behavior should be documented. It's non-intuitive that we query + // ChannelMonitors when clearing other events. + self.process_pending_monitor_events(); let mut ret = Vec::new(); let mut pending_events = self.pending_events.lock().unwrap(); @@ -3039,7 +3063,7 @@ impl>, + /// + /// (C-not exported) because we have no HashMap bindings + pub channel_monitors: HashMap>, +} + +impl<'a, ChanSigner: 'a + ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> + ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L> + where M::Target: ManyChannelMonitor, + T::Target: BroadcasterInterface, + K::Target: KeysInterface, + F::Target: FeeEstimator, + L::Target: Logger, + { + /// Simple utility function to create a ChannelManagerReadArgs which creates the monitor + /// HashMap for you. This is primarily useful for C bindings where it is not practical to + /// populate a HashMap directly from C. + pub fn new(keys_manager: K, fee_estimator: F, monitor: M, tx_broadcaster: T, logger: L, default_config: UserConfig, + mut channel_monitors: Vec<&'a mut ChannelMonitor>) -> Self { + Self { + keys_manager, fee_estimator, monitor, tx_broadcaster, logger, default_config, + channel_monitors: channel_monitors.drain(..).map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect() + } + } } // Implement ReadableArgs for an Arc'd ChannelManager to make it a bit easier to work with the @@ -3797,7 +3827,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De F::Target: FeeEstimator, L::Target: Logger, { - fn read(reader: &mut R, args: ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L>) -> Result { + fn read(reader: &mut R, mut args: ChannelManagerReadArgs<'a, ChanSigner, M, T, K, F, L>) -> Result { let _ver: u8 = Readable::read(reader)?; let min_ver: u8 = Readable::read(reader)?; if min_ver > SERIALIZATION_VERSION {