X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=3dcc74f905269a7f8a58978a529f96b6e48a5851;hb=e885d0a7747cfc3b89a3c2765a8c0dd174e3889a;hp=913bbd62d3b946f061cb7b5148539e5382e004ce;hpb=801b775a7d17eff165ea5e8a4d11a966e0ef29d0;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 913bbd62..3dcc74f9 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -16,10 +16,10 @@ //! It does not manage routing logic (see routing::router::get_route for that) nor does it manage constructing //! on-chain transactions (it only monitors the chain to watch for any force-closes that might //! imply it needs to fail HTLCs/payments/channels it manages). +//! use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::constants::genesis_block; -use bitcoin::blockdata::transaction::Transaction; use bitcoin::network::constants::Network; use bitcoin::hashes::{Hash, HashEngine}; @@ -36,10 +36,10 @@ use bitcoin::secp256k1; use chain; use chain::Watch; -use chain::chaininterface::{BroadcasterInterface,ChainListener,FeeEstimator}; -use chain::transaction::OutPoint; +use chain::chaininterface::{BroadcasterInterface, FeeEstimator}; +use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, ChannelMonitorUpdateErr, HTLC_FAIL_BACK_BUFFER, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, MonitorEvent, CLOSED_CHANNEL_UPDATE_ID}; +use chain::transaction::{OutPoint, TransactionData}; use ln::channel::{Channel, ChannelError}; -use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, 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; @@ -118,9 +118,15 @@ pub(super) enum PendingHTLCStatus { pub(super) enum HTLCForwardInfo { AddHTLC { + forward_info: PendingHTLCInfo, + + // These fields are produced in `forward_htlcs()` and consumed in + // `process_pending_htlc_forwards()` for constructing the + // `HTLCSource::PreviousHopData` for failed and forwarded + // HTLCs. prev_short_channel_id: u64, prev_htlc_id: u64, - forward_info: PendingHTLCInfo, + prev_funding_outpoint: OutPoint, }, FailHTLC { htlc_id: u64, @@ -130,10 +136,14 @@ pub(super) enum HTLCForwardInfo { /// Tracks the inbound corresponding to an outbound HTLC #[derive(Clone, PartialEq)] -pub(super) struct HTLCPreviousHopData { +pub(crate) struct HTLCPreviousHopData { short_channel_id: u64, htlc_id: u64, incoming_packet_shared_secret: [u8; 32], + + // This field is consumed by `claim_funds_from_hop()` when updating a force-closed backwards + // channel with a preimage provided by the forward channel. + outpoint: OutPoint, } struct ClaimableHTLC { @@ -149,7 +159,7 @@ struct ClaimableHTLC { /// Tracks the inbound corresponding to an outbound HTLC #[derive(Clone, PartialEq)] -pub(super) enum HTLCSource { +pub(crate) enum HTLCSource { PreviousHopData(HTLCPreviousHopData), OutboundRoute { path: Vec, @@ -405,9 +415,9 @@ pub struct ChannelManager, secp_ctx: Secp256k1, - #[cfg(test)] + #[cfg(any(test, feature = "_test_utils"))] pub(super) channel_state: Mutex>, - #[cfg(not(test))] + #[cfg(not(any(test, feature = "_test_utils")))] channel_state: Mutex>, our_network_key: SecretKey, @@ -465,6 +475,7 @@ const CHECK_CLTV_EXPIRY_SANITY: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_P const CHECK_CLTV_EXPIRY_SANITY_2: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2*CLTV_CLAIM_BUFFER; /// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels +#[derive(Clone)] pub struct ChannelDetails { /// The channel's ID (prior to funding transaction generation, this is a random 32 bytes, /// thereafter this is the txid of the funding transaction xor the funding transaction output). @@ -503,7 +514,7 @@ pub struct ChannelDetails { /// If a payment fails to send, it can be in one of several states. This enum is returned as the /// Err() type describing which state the payment is in, see the description of individual enum /// states for more. -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum PaymentSendFailure { /// A parameter which was passed to send_payment was invalid, preventing us from attempting to /// send the payment at all. No channel state has been changed or messages sent to peers, and @@ -719,10 +730,6 @@ impl /// /// Users need to notify the new ChannelManager when a new block is connected or /// disconnected using its `block_connected` and `block_disconnected` methods. - /// However, rather than calling these methods directly, the user should register - /// the ChannelManager as a listener to the BlockNotifier and call the BlockNotifier's - /// `block_(dis)connected` methods, which will notify all registered listeners in one - /// go. pub fn new(network: Network, fee_est: F, chain_monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Self { let secp_ctx = Secp256k1::new(); @@ -780,7 +787,7 @@ impl let channel = Channel::new_outbound(&self.fee_estimator, &self.keys_manager, their_network_key, channel_value_satoshis, push_msat, user_id, config)?; let res = channel.get_open_channel(self.genesis_hash.clone()); - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let mut channel_state = self.channel_state.lock().unwrap(); match channel_state.by_id.entry(channel.channel_id()) { hash_map::Entry::Occupied(_) => { @@ -852,7 +859,7 @@ impl /// /// May generate a SendShutdown message event on success, which should be relayed. pub fn close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError> { - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let (mut failed_htlcs, chan_option) = { let mut channel_state_lock = self.channel_state.lock().unwrap(); @@ -909,21 +916,24 @@ impl } } - /// Force closes a channel, immediately broadcasting the latest local commitment transaction to - /// the chain and rejecting new HTLCs on the given channel. - pub fn force_close_channel(&self, channel_id: &[u8; 32]) { - let _ = self.total_consistency_lock.read().unwrap(); - + fn force_close_channel_with_peer(&self, channel_id: &[u8; 32], peer_node_id: Option<&PublicKey>) -> Result<(), APIError> { let mut chan = { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; - if let Some(chan) = channel_state.by_id.remove(channel_id) { - if let Some(short_id) = chan.get_short_channel_id() { + if let hash_map::Entry::Occupied(chan) = channel_state.by_id.entry(channel_id.clone()) { + if let Some(node_id) = peer_node_id { + if chan.get().get_counterparty_node_id() != *node_id { + // Error or Ok here doesn't matter - the result is only exposed publicly + // when peer_node_id is None anyway. + return Ok(()); + } + } + if let Some(short_id) = chan.get().get_short_channel_id() { channel_state.short_to_id.remove(&short_id); } - chan + chan.remove_entry().1 } else { - return; + return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()}); } }; log_trace!(self.logger, "Force-closing channel {}", log_bytes!(channel_id[..])); @@ -934,13 +944,22 @@ impl msg: update }); } + + Ok(()) + } + + /// Force closes a channel, immediately broadcasting the latest local commitment transaction to + /// the chain and rejecting new HTLCs on the given channel. Fails if channel_id is unknown to the manager. + pub fn force_close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError> { + let _consistency_lock = self.total_consistency_lock.read().unwrap(); + self.force_close_channel_with_peer(channel_id, None) } /// Force close all channels, immediately broadcasting the latest local commitment transaction /// for each to the chain and rejecting new HTLCs on each. pub fn force_close_all_channels(&self) { for chan in self.list_channels() { - self.force_close_channel(&chan.channel_id); + let _ = self.force_close_channel(&chan.channel_id); } } @@ -1131,7 +1150,7 @@ impl PendingHTLCStatus::Forward(PendingHTLCInfo { routing: PendingHTLCRouting::Forward { onion_packet: outgoing_packet, - short_channel_id: short_channel_id, + short_channel_id, }, payment_hash: msg.payment_hash.clone(), incoming_shared_secret: shared_secret, @@ -1226,7 +1245,7 @@ impl let unsigned = msgs::UnsignedChannelUpdate { chain_hash: self.genesis_hash, - short_channel_id: short_channel_id, + short_channel_id, timestamp: chan.get_update_time_counter(), flags: (!were_node_one) as u8 | ((!chan.is_live() as u8) << 1), cltv_expiry_delta: CLTV_EXPIRY_DELTA, @@ -1260,7 +1279,7 @@ impl } let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, prng_seed, payment_hash); - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let err: Result<(), _> = loop { let mut channel_lock = self.channel_state.lock().unwrap(); @@ -1428,7 +1447,7 @@ impl /// May panic if the funding_txo is duplicative with some other channel (note that this should /// be trivially prevented by using unique funding transaction keys per-channel). pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) { - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let (chan, msg) = { let (res, chan) = match self.channel_state.lock().unwrap().by_id.remove(temporary_channel_id) { @@ -1452,7 +1471,7 @@ impl let mut channel_state = self.channel_state.lock().unwrap(); channel_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated { node_id: chan.get_counterparty_node_id(), - msg: msg, + msg, }); match channel_state.by_id.entry(chan.channel_id()) { hash_map::Entry::Occupied(_) => { @@ -1511,7 +1530,7 @@ impl /// /// Panics if addresses is absurdly large (more than 500). pub fn broadcast_node_announcement(&self, rgb: [u8; 3], alias: [u8; 32], addresses: Vec) { - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); if addresses.len() > 500 { panic!("More than half the message size was taken up by public addresses!"); @@ -1541,7 +1560,7 @@ impl /// Should only really ever be called in response to a PendingHTLCsForwardable event. /// Will likely generate further events. pub fn process_pending_htlc_forwards(&self) { - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let mut new_events = Vec::new(); let mut failed_forwards = Vec::new(); @@ -1558,9 +1577,11 @@ impl failed_forwards.reserve(pending_forwards.len()); for forward_info in pending_forwards.drain(..) { match forward_info { - HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info } => { + HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info, + prev_funding_outpoint } => { let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id: prev_short_channel_id, + outpoint: prev_funding_outpoint, htlc_id: prev_htlc_id, incoming_packet_shared_secret: forward_info.incoming_shared_secret, }); @@ -1587,10 +1608,12 @@ impl HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo { routing: PendingHTLCRouting::Forward { onion_packet, .. - }, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value }, } => { + }, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value }, + prev_funding_outpoint } => { log_trace!(self.logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", log_bytes!(payment_hash.0), prev_short_channel_id, short_chan_id); let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id: prev_short_channel_id, + outpoint: prev_funding_outpoint, htlc_id: prev_htlc_id, incoming_packet_shared_secret: incoming_shared_secret, }); @@ -1705,9 +1728,11 @@ impl match forward_info { HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo { routing: PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry }, - incoming_shared_secret, payment_hash, amt_to_forward, .. }, } => { + incoming_shared_secret, payment_hash, amt_to_forward, .. }, + prev_funding_outpoint } => { let prev_hop = HTLCPreviousHopData { short_channel_id: prev_short_channel_id, + outpoint: prev_funding_outpoint, htlc_id: prev_htlc_id, incoming_packet_shared_secret: incoming_shared_secret, }; @@ -1742,6 +1767,7 @@ impl ); failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id: htlc.prev_hop.short_channel_id, + outpoint: prev_funding_outpoint, htlc_id: htlc.prev_hop.htlc_id, incoming_packet_shared_secret: htlc.prev_hop.incoming_packet_shared_secret, }), payment_hash, @@ -1750,14 +1776,14 @@ impl } } else if total_value == data.total_msat { new_events.push(events::Event::PaymentReceived { - payment_hash: payment_hash, + payment_hash, payment_secret: Some(data.payment_secret), amt: total_value, }); } } else { new_events.push(events::Event::PaymentReceived { - payment_hash: payment_hash, + payment_hash, payment_secret: None, amt: amt_to_forward, }); @@ -1794,7 +1820,7 @@ impl /// /// This method handles all the details, and must be called roughly once per minute. pub fn timer_chan_freshness_every_min(&self) { - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; for (_, chan) in channel_state.by_id.iter_mut() { @@ -1819,7 +1845,7 @@ impl /// Returns false if no payment was found to fail backwards, true if the process of failing the /// HTLC backwards has been started. pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash, payment_secret: &Option) -> bool { - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let mut channel_state = Some(self.channel_state.lock().unwrap()); let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&(*payment_hash, *payment_secret)); @@ -1944,7 +1970,7 @@ impl } } }, - HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret }) => { + HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id, htlc_id, incoming_packet_shared_secret, .. }) => { let err_packet = match onion_error { HTLCFailReason::Reason { failure_code, data } => { log_trace!(self.logger, "Failing HTLC with payment_hash {} backwards from us with code {}", log_bytes!(payment_hash.0), failure_code); @@ -1998,7 +2024,7 @@ impl pub fn claim_funds(&self, payment_preimage: PaymentPreimage, payment_secret: &Option, expected_amount: u64) -> bool { let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner()); - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let mut channel_state = Some(self.channel_state.lock().unwrap()); let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&(payment_hash, *payment_secret)); @@ -2139,12 +2165,23 @@ impl }); }, HTLCSource::PreviousHopData(hop_data) => { + let prev_outpoint = hop_data.outpoint; if let Err((counterparty_node_id, err)) = match self.claim_funds_from_hop(&mut channel_state_lock, hop_data, payment_preimage) { Ok(()) => Ok(()), Err(None) => { - // TODO: There is probably a channel monitor somewhere that needs to - // learn the preimage as the channel already hit the chain and that's - // why it's missing. + let preimage_update = ChannelMonitorUpdate { + update_id: CLOSED_CHANNEL_UPDATE_ID, + updates: vec![ChannelMonitorUpdateStep::PaymentPreimage { + payment_preimage: payment_preimage.clone(), + }], + }; + // We update the ChannelMonitor on the backward link, after + // receiving an offchain preimage event from the forward link (the + // event being update_fulfill_htlc). + if let Err(e) = self.chain_monitor.update_channel(prev_outpoint, preimage_update) { + log_error!(self.logger, "Critical error: failed to update channel monitor with preimage {:?}: {:?}", + payment_preimage, e); + } Ok(()) }, Err(Some(res)) => Err(res), @@ -2183,7 +2220,7 @@ impl /// 4) once all remote copies are updated, you call this function with the update_id that /// completed, and once it is the latest the Channel will be re-enabled. pub fn channel_monitor_updated(&self, funding_txo: &OutPoint, highest_applied_update_id: u64) { - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let mut close_results = Vec::new(); let mut htlc_forwards = Vec::new(); @@ -2205,7 +2242,7 @@ impl let (raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe, funding_locked) = channel.monitor_updating_restored(&self.logger); if !pending_forwards.is_empty() { - htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), pending_forwards)); + htlc_forwards.push((channel.get_short_channel_id().expect("We can't have pending forwards before funding confirmation"), funding_txo.clone(), pending_forwards)); } htlc_failures.append(&mut pending_failures); @@ -2309,7 +2346,7 @@ impl pending_events.push(events::Event::FundingGenerationReady { temporary_channel_id: msg.temporary_channel_id, channel_value_satoshis: value, - output_script: output_script, + output_script, user_channel_id: user_id, }); Ok(()) @@ -2338,7 +2375,12 @@ impl // channel, not the temporary_channel_id. This is compatible with ourselves, but the // spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for // any messages referencing a previously-closed channel anyway. - return Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id, chan.force_shutdown(true), None)); + // We do not do a force-close here as that would generate a monitor update for + // a monitor that we didn't manage to store (and that we don't care about - we + // don't respond with the funding_signed so the channel can never go on chain). + let (_funding_txo_option, _monitor_update, failed_htlcs) = chan.force_shutdown(true); + assert!(failed_htlcs.is_empty()); + return Err(MsgHandleErrInternal::send_err_msg_no_close("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id)); }, ChannelMonitorUpdateErr::TemporaryFailure => { // There's no problem signing a counterparty's funding transaction if our monitor @@ -2389,7 +2431,7 @@ impl }; let mut pending_events = self.pending_events.lock().unwrap(); pending_events.push(events::Event::FundingBroadcastSafe { - funding_txo: funding_txo, + funding_txo, user_channel_id: user_id, }); Ok(()) @@ -2689,8 +2731,8 @@ impl } #[inline] - fn forward_htlcs(&self, per_source_pending_forwards: &mut [(u64, Vec<(PendingHTLCInfo, u64)>)]) { - for &mut (prev_short_channel_id, ref mut pending_forwards) in per_source_pending_forwards { + fn forward_htlcs(&self, per_source_pending_forwards: &mut [(u64, OutPoint, Vec<(PendingHTLCInfo, u64)>)]) { + for &mut (prev_short_channel_id, prev_funding_outpoint, ref mut pending_forwards) in per_source_pending_forwards { let mut forward_event = None; if !pending_forwards.is_empty() { let mut channel_state = self.channel_state.lock().unwrap(); @@ -2703,10 +2745,12 @@ impl PendingHTLCRouting::Receive { .. } => 0, }) { hash_map::Entry::Occupied(mut entry) => { - entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info }); + entry.get_mut().push(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_funding_outpoint, + prev_htlc_id, forward_info }); }, hash_map::Entry::Vacant(entry) => { - entry.insert(vec!(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info })); + entry.insert(vec!(HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_funding_outpoint, + prev_htlc_id, forward_info })); } } } @@ -2759,18 +2803,18 @@ impl msg, }); } - break Ok((pending_forwards, pending_failures, chan.get().get_short_channel_id().expect("RAA should only work on a short-id-available channel"))) + break Ok((pending_forwards, pending_failures, chan.get().get_short_channel_id().expect("RAA should only work on a short-id-available channel"), chan.get().get_funding_txo().unwrap())) }, hash_map::Entry::Vacant(_) => break Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id)) } }; self.fail_holding_cell_htlcs(htlcs_to_fail, msg.channel_id); match res { - Ok((pending_forwards, mut pending_failures, short_channel_id)) => { + Ok((pending_forwards, mut pending_failures, short_channel_id, channel_outpoint)) => { for failure in pending_failures.drain(..) { self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), failure.0, &failure.1, failure.2); } - self.forward_htlcs(&mut [(short_channel_id, pending_forwards)]); + self.forward_htlcs(&mut [(short_channel_id, channel_outpoint, pending_forwards)]); Ok(()) }, Err(e) => Err(e) @@ -2927,7 +2971,7 @@ impl /// (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(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let counterparty_node_id; let err: Result<(), _> = loop { let mut channel_state_lock = self.channel_state.lock().unwrap(); @@ -3056,18 +3100,18 @@ impl } } -impl - ChainListener for ChannelManager +impl ChannelManager where M::Target: chain::Watch, T::Target: BroadcasterInterface, K::Target: KeysInterface, F::Target: FeeEstimator, - L::Target: Logger, + L::Target: Logger, { - fn block_connected(&self, header: &BlockHeader, txdata: &[(usize, &Transaction)], height: u32) { + /// Updates channel state based on transactions seen in a connected block. + pub fn block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) { let header_hash = header.block_hash(); log_trace!(self.logger, "Block {} at height {} connected", header_hash, height); - let _ = self.total_consistency_lock.read().unwrap(); + let _consistency_lock = self.total_consistency_lock.read().unwrap(); let mut failed_channels = Vec::new(); let mut timed_out_htlcs = Vec::new(); { @@ -3175,9 +3219,12 @@ impl true, &events::MessageSendEvent::HandleError { ref node_id, .. } => node_id != counterparty_node_id, &events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => true, + &events::MessageSendEvent::SendChannelRangeQuery { .. } => false, + &events::MessageSendEvent::SendShortIdsQuery { .. } => false, } }); } @@ -3389,7 +3438,7 @@ impl(&self, writer: &mut W) -> Result<(), ::std::io::Error> { match self { - &HTLCForwardInfo::AddHTLC { ref prev_short_channel_id, ref prev_htlc_id, ref forward_info } => { + &HTLCForwardInfo::AddHTLC { ref prev_short_channel_id, ref prev_funding_outpoint, ref prev_htlc_id, ref forward_info } => { 0u8.write(writer)?; prev_short_channel_id.write(writer)?; + prev_funding_outpoint.write(writer)?; prev_htlc_id.write(writer)?; forward_info.write(writer)?; }, @@ -3641,6 +3694,7 @@ impl Readable for HTLCForwardInfo { match ::read(reader)? { 0 => Ok(HTLCForwardInfo::AddHTLC { prev_short_channel_id: Readable::read(reader)?, + prev_funding_outpoint: Readable::read(reader)?, prev_htlc_id: Readable::read(reader)?, forward_info: Readable::read(reader)?, }), @@ -3653,7 +3707,7 @@ impl Readable for HTLCForwardInfo { } } -impl Writeable for ChannelManager +impl Writeable for ChannelManager where M::Target: chain::Watch, T::Target: BroadcasterInterface, K::Target: KeysInterface, @@ -3661,7 +3715,7 @@ impl(&self, writer: &mut W) -> Result<(), ::std::io::Error> { - let _ = self.total_consistency_lock.write().unwrap(); + let _consistency_lock = self.total_consistency_lock.write().unwrap(); writer.write_all(&[SERIALIZATION_VERSION; 1])?; writer.write_all(&[MIN_SERIALIZATION_VERSION; 1])?; @@ -3732,7 +3786,7 @@ impl +impl<'a, ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ReadableArgs> for (BlockHash, Arc>) where M::Target: chain::Watch, T::Target: BroadcasterInterface, @@ -3820,7 +3875,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De } } -impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> +impl<'a, ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ReadableArgs> for (BlockHash, ChannelManager) where M::Target: chain::Watch, T::Target: BroadcasterInterface, @@ -3846,7 +3901,7 @@ impl<'a, ChanSigner: ChannelKeys + Readable, M: Deref, T: Deref, K: Deref, F: De let mut by_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128)); let mut short_to_id = HashMap::with_capacity(cmp::min(channel_count as usize, 128)); for _ in 0..channel_count { - let mut channel: Channel = Readable::read(reader)?; + let mut channel: Channel = Channel::read(reader, &args.keys_manager)?; if channel.last_block_connected != Default::default() && channel.last_block_connected != last_block_hash { return Err(DecodeError::InvalidValue); }