Append backwards-compat TLVs to serialization of larger structs
[rust-lightning] / lightning / src / ln / channelmanager.rs
index 592ab2b6c0ef7628b593a07b76236f8a3dfe8819..402398d5f153888a957d086072e79a11f147f69d 100644 (file)
@@ -62,6 +62,7 @@ use util::logger::Logger;
 use util::errors::APIError;
 
 use core::{cmp, mem};
+use std::cell::RefCell;
 use std::collections::{HashMap, hash_map, HashSet};
 use std::io::{Cursor, Read};
 use std::sync::{Arc, Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard};
@@ -3502,11 +3503,15 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        }
 
        /// Check the holding cell in each channel and free any pending HTLCs in them if possible.
+       /// Returns whether there were any updates such as if pending HTLCs were freed or a monitor
+       /// update was applied.
+       ///
        /// This should only apply to HTLCs which were added to the holding cell because we were
        /// waiting on a monitor update to finish. In that case, we don't want to free the holding cell
        /// directly in `channel_monitor_updated` as it may introduce deadlocks calling back into user
        /// code to inform them of a channel monitor update.
-       fn check_free_holding_cells(&self) {
+       fn check_free_holding_cells(&self) -> bool {
+               let mut has_monitor_update = false;
                let mut failed_htlcs = Vec::new();
                let mut handle_errors = Vec::new();
                {
@@ -3518,11 +3523,13 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
 
                        by_id.retain(|channel_id, chan| {
                                match chan.maybe_free_holding_cell_htlcs(&self.logger) {
-                                       Ok((None, ref htlcs)) if htlcs.is_empty() => true,
                                        Ok((commitment_opt, holding_cell_failed_htlcs)) => {
-                                               failed_htlcs.push((holding_cell_failed_htlcs, *channel_id));
+                                               if !holding_cell_failed_htlcs.is_empty() {
+                                                       failed_htlcs.push((holding_cell_failed_htlcs, *channel_id));
+                                               }
                                                if let Some((commitment_update, monitor_update)) = commitment_opt {
                                                        if let Err(e) = self.chain_monitor.update_channel(chan.get_funding_txo().unwrap(), monitor_update) {
+                                                               has_monitor_update = true;
                                                                let (res, close_channel) = handle_monitor_err!(self, e, short_to_id, chan, RAACommitmentOrder::CommitmentFirst, false, true, Vec::new(), Vec::new(), channel_id);
                                                                handle_errors.push((chan.get_counterparty_node_id(), res));
                                                                if close_channel { return false; }
@@ -3543,6 +3550,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                }
                        });
                }
+
+               let has_update = has_monitor_update || !failed_htlcs.is_empty();
                for (failures, channel_id) in failed_htlcs.drain(..) {
                        self.fail_holding_cell_htlcs(failures, channel_id);
                }
@@ -3550,6 +3559,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                for (counterparty_node_id, err) in handle_errors.drain(..) {
                        let _ = handle_error!(self, err, counterparty_node_id);
                }
+
+               has_update
        }
 
        /// Handle a list of channel failures during a block_connected or block_disconnected call,
@@ -3692,16 +3703,31 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> MessageSend
                                L::Target: Logger,
 {
        fn get_and_clear_pending_msg_events(&self) -> Vec<MessageSendEvent> {
-               //TODO: This behavior should be documented. It's non-intuitive that we query
-               // ChannelMonitors when clearing other events.
-               self.process_pending_monitor_events();
+               let events = RefCell::new(Vec::new());
+               PersistenceNotifierGuard::optionally_notify(&self.total_consistency_lock, &self.persistence_notifier, || {
+                       let mut result = NotifyOption::SkipPersist;
 
-               self.check_free_holding_cells();
+                       // TODO: This behavior should be documented. It's unintuitive that we query
+                       // ChannelMonitors when clearing other events.
+                       if self.process_pending_monitor_events() {
+                               result = NotifyOption::DoPersist;
+                       }
 
-               let mut ret = Vec::new();
-               let mut channel_state = self.channel_state.lock().unwrap();
-               mem::swap(&mut ret, &mut channel_state.pending_msg_events);
-               ret
+                       if self.check_free_holding_cells() {
+                               result = NotifyOption::DoPersist;
+                       }
+
+                       let mut pending_events = Vec::new();
+                       let mut channel_state = self.channel_state.lock().unwrap();
+                       mem::swap(&mut pending_events, &mut channel_state.pending_msg_events);
+
+                       if !pending_events.is_empty() {
+                               events.replace(pending_events);
+                       }
+
+                       result
+               });
+               events.into_inner()
        }
 }
 
@@ -4542,8 +4568,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
                let _consistency_lock = self.total_consistency_lock.write().unwrap();
 
-               writer.write_all(&[SERIALIZATION_VERSION; 1])?;
-               writer.write_all(&[MIN_SERIALIZATION_VERSION; 1])?;
+               write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
 
                self.genesis_hash.write(writer)?;
                {
@@ -4626,6 +4651,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
                        session_priv.write(writer)?;
                }
 
+               write_tlv_fields!(writer, {});
+
                Ok(())
        }
 }
@@ -4749,11 +4776,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
         L::Target: Logger,
 {
        fn read<R: ::std::io::Read>(reader: &mut R, mut args: ChannelManagerReadArgs<'a, Signer, M, T, K, F, L>) -> Result<Self, DecodeError> {
-               let _ver: u8 = Readable::read(reader)?;
-               let min_ver: u8 = Readable::read(reader)?;
-               if min_ver > SERIALIZATION_VERSION {
-                       return Err(DecodeError::UnknownVersion);
-               }
+               let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let genesis_hash: BlockHash = Readable::read(reader)?;
                let best_block_height: u32 = Readable::read(reader)?;
@@ -4873,6 +4896,8 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
                        }
                }
 
+               read_tlv_fields!(reader, {}, {});
+
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&args.keys_manager.get_secure_random_bytes());