Merge pull request #928 from TheBlueMatt/2021-05-really-tlv-ser
[rust-lightning] / lightning / src / ln / channelmanager.rs
index e39a778bc65722dc3e3fc176546552464922f54a..fb9f467c5ba3e6c7a5063390e7f9581e272b8625 100644 (file)
@@ -61,8 +61,9 @@ use util::chacha20::{ChaCha20, ChaChaReader};
 use util::logger::Logger;
 use util::errors::APIError;
 
+use prelude::*;
 use core::{cmp, mem};
-use std::cell::RefCell;
+use core::cell::RefCell;
 use std::collections::{HashMap, hash_map, HashSet};
 use std::io::{Cursor, Read};
 use std::sync::{Arc, Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard};
@@ -1933,19 +1934,24 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        // smaller than 500:
        const STATIC_ASSERT: u32 = Self::HALF_MESSAGE_IS_ADDRS - 500;
 
-       /// Generates a signed node_announcement from the given arguments and creates a
-       /// BroadcastNodeAnnouncement event. Note that such messages will be ignored unless peers have
-       /// seen a channel_announcement from us (ie unless we have public channels open).
+       /// Regenerates channel_announcements and generates a signed node_announcement from the given
+       /// arguments, providing them in corresponding events via
+       /// [`get_and_clear_pending_msg_events`], if at least one public channel has been confirmed
+       /// on-chain. This effectively re-broadcasts all channel announcements and sends our node
+       /// announcement to ensure that the lightning P2P network is aware of the channels we have and
+       /// our network addresses.
        ///
-       /// RGB is a node "color" and alias is a printable human-readable string to describe this node
-       /// to humans. They carry no in-protocol meaning.
+       /// `rgb` is a node "color" and `alias` is a printable human-readable string to describe this
+       /// node to humans. They carry no in-protocol meaning.
        ///
-       /// addresses represent the set (possibly empty) of socket addresses on which this node accepts
-       /// incoming connections. These will be broadcast to the network, publicly tying these
-       /// addresses together. If you wish to preserve user privacy, addresses should likely contain
-       /// only Tor Onion addresses.
+       /// `addresses` represent the set (possibly empty) of socket addresses on which this node
+       /// accepts incoming connections. These will be included in the node_announcement, publicly
+       /// tying these addresses together and to this node. If you wish to preserve user privacy,
+       /// addresses should likely contain only Tor Onion addresses.
        ///
-       /// Panics if addresses is absurdly large (more than 500).
+       /// Panics if `addresses` is absurdly large (more than 500).
+       ///
+       /// [`get_and_clear_pending_msg_events`]: MessageSendEventsProvider::get_and_clear_pending_msg_events
        pub fn broadcast_node_announcement(&self, rgb: [u8; 3], alias: [u8; 32], mut addresses: Vec<NetAddress>) {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
@@ -1966,14 +1972,37 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        excess_data: Vec::new(),
                };
                let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]);
+               let node_announce_sig = self.secp_ctx.sign(&msghash, &self.our_network_key);
 
-               let mut channel_state = self.channel_state.lock().unwrap();
-               channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastNodeAnnouncement {
-                       msg: msgs::NodeAnnouncement {
-                               signature: self.secp_ctx.sign(&msghash, &self.our_network_key),
-                               contents: announcement
-                       },
-               });
+               let mut channel_state_lock = self.channel_state.lock().unwrap();
+               let channel_state = &mut *channel_state_lock;
+
+               let mut announced_chans = false;
+               for (_, chan) in channel_state.by_id.iter() {
+                       if let Some(msg) = chan.get_signed_channel_announcement(&self.our_network_key, self.get_our_node_id(), self.genesis_hash.clone()) {
+                               channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
+                                       msg,
+                                       update_msg: match self.get_channel_update(chan) {
+                                               Ok(msg) => msg,
+                                               Err(_) => continue,
+                                       },
+                               });
+                               announced_chans = true;
+                       } else {
+                               // If the channel is not public or has not yet reached funding_locked, check the
+                               // next channel. If we don't yet have any public channels, we'll skip the broadcast
+                               // below as peers may not accept it without channels on chain first.
+                       }
+               }
+
+               if announced_chans {
+                       channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastNodeAnnouncement {
+                               msg: msgs::NodeAnnouncement {
+                                       signature: node_announce_sig,
+                                       contents: announcement
+                               },
+                       });
+               }
        }
 
        /// Processes HTLCs which are pending waiting on random forward delay.
@@ -3301,39 +3330,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        return Err(MsgHandleErrInternal::from_no_close(LightningError{err: "Got an announcement_signatures before we were ready for it".to_owned(), action: msgs::ErrorAction::IgnoreError}));
                                }
 
-                               let our_node_id = self.get_our_node_id();
-                               let (announcement, our_bitcoin_sig) =
-                                       try_chan_entry!(self, chan.get_mut().get_channel_announcement(our_node_id.clone(), self.genesis_hash.clone()), channel_state, chan);
-
-                               let were_node_one = announcement.node_id_1 == our_node_id;
-                               let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]);
-                               {
-                                       let their_node_key = if were_node_one { &announcement.node_id_2 } else { &announcement.node_id_1 };
-                                       let their_bitcoin_key = if were_node_one { &announcement.bitcoin_key_2 } else { &announcement.bitcoin_key_1 };
-                                       match (self.secp_ctx.verify(&msghash, &msg.node_signature, their_node_key),
-                                                  self.secp_ctx.verify(&msghash, &msg.bitcoin_signature, their_bitcoin_key)) {
-                                               (Err(e), _) => {
-                                                       let chan_err: ChannelError = ChannelError::Close(format!("Bad announcement_signatures. Failed to verify node_signature: {:?}. Maybe using different node_secret for transport and routing msg? UnsignedChannelAnnouncement used for verification is {:?}. their_node_key is {:?}", e, &announcement, their_node_key));
-                                                       try_chan_entry!(self, Err(chan_err), channel_state, chan);
-                                               },
-                                               (_, Err(e)) => {
-                                                       let chan_err: ChannelError = ChannelError::Close(format!("Bad announcement_signatures. Failed to verify bitcoin_signature: {:?}. UnsignedChannelAnnouncement used for verification is {:?}. their_bitcoin_key is ({:?})", e, &announcement, their_bitcoin_key));
-                                                       try_chan_entry!(self, Err(chan_err), channel_state, chan);
-                                               },
-                                               _ => {}
-                                       }
-                               }
-
-                               let our_node_sig = self.secp_ctx.sign(&msghash, &self.our_network_key);
-
                                channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelAnnouncement {
-                                       msg: msgs::ChannelAnnouncement {
-                                               node_signature_1: if were_node_one { our_node_sig } else { msg.node_signature },
-                                               node_signature_2: if were_node_one { msg.node_signature } else { our_node_sig },
-                                               bitcoin_signature_1: if were_node_one { our_bitcoin_sig } else { msg.bitcoin_signature },
-                                               bitcoin_signature_2: if were_node_one { msg.bitcoin_signature } else { our_bitcoin_sig },
-                                               contents: announcement,
-                                       },
+                                       msg: try_chan_entry!(self, chan.get_mut().announcement_signatures(&self.our_network_key, self.get_our_node_id(), self.genesis_hash.clone(), msg), channel_state, chan),
                                        update_msg: self.get_channel_update(chan.get()).unwrap(), // can only fail if we're not in a ready state
                                });
                        },
@@ -3503,11 +3501,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();
                {
@@ -3519,11 +3521,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; }
@@ -3544,6 +3548,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);
                }
@@ -3551,6 +3557,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,
@@ -3678,7 +3686,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
 
        #[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
        pub fn get_and_clear_pending_events(&self) -> Vec<events::Event> {
-               let events = std::cell::RefCell::new(Vec::new());
+               let events = core::cell::RefCell::new(Vec::new());
                let event_handler = |event| events.borrow_mut().push(event);
                self.process_pending_events(&event_handler);
                events.into_inner()
@@ -3703,7 +3711,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> MessageSend
                                result = NotifyOption::DoPersist;
                        }
 
-                       self.check_free_holding_cells();
+                       if self.check_free_holding_cells() {
+                               result = NotifyOption::DoPersist;
+                       }
 
                        let mut pending_events = Vec::new();
                        let mut channel_state = self.channel_state.lock().unwrap();
@@ -4307,9 +4317,9 @@ impl PersistenceNotifier {
 const SERIALIZATION_VERSION: u8 = 1;
 const MIN_SERIALIZATION_VERSION: u8 = 1;
 
-impl Writeable for PendingHTLCInfo {
+impl Writeable for PendingHTLCRouting {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
-               match &self.routing {
+               match &self {
                        &PendingHTLCRouting::Forward { ref onion_packet, ref short_channel_id } => {
                                0u8.write(writer)?;
                                onion_packet.write(writer)?;
@@ -4322,39 +4332,37 @@ impl Writeable for PendingHTLCInfo {
                                incoming_cltv_expiry.write(writer)?;
                        },
                }
-               self.incoming_shared_secret.write(writer)?;
-               self.payment_hash.write(writer)?;
-               self.amt_to_forward.write(writer)?;
-               self.outgoing_cltv_value.write(writer)?;
                Ok(())
        }
 }
 
-impl Readable for PendingHTLCInfo {
-       fn read<R: ::std::io::Read>(reader: &mut R) -> Result<PendingHTLCInfo, DecodeError> {
-               Ok(PendingHTLCInfo {
-                       routing: match Readable::read(reader)? {
-                               0u8 => PendingHTLCRouting::Forward {
-                                       onion_packet: Readable::read(reader)?,
-                                       short_channel_id: Readable::read(reader)?,
-                               },
-                               1u8 => PendingHTLCRouting::Receive {
-                                       payment_data: msgs::FinalOnionHopData {
-                                               payment_secret: Readable::read(reader)?,
-                                               total_msat: Readable::read(reader)?,
-                                       },
-                                       incoming_cltv_expiry: Readable::read(reader)?,
+impl Readable for PendingHTLCRouting {
+       fn read<R: ::std::io::Read>(reader: &mut R) -> Result<PendingHTLCRouting, DecodeError> {
+               match Readable::read(reader)? {
+                       0u8 => Ok(PendingHTLCRouting::Forward {
+                               onion_packet: Readable::read(reader)?,
+                               short_channel_id: Readable::read(reader)?,
+                       }),
+                       1u8 => Ok(PendingHTLCRouting::Receive {
+                               payment_data: msgs::FinalOnionHopData {
+                                       payment_secret: Readable::read(reader)?,
+                                       total_msat: Readable::read(reader)?,
                                },
-                               _ => return Err(DecodeError::InvalidValue),
-                       },
-                       incoming_shared_secret: Readable::read(reader)?,
-                       payment_hash: Readable::read(reader)?,
-                       amt_to_forward: Readable::read(reader)?,
-                       outgoing_cltv_value: Readable::read(reader)?,
-               })
+                               incoming_cltv_expiry: Readable::read(reader)?,
+                       }),
+                       _ => Err(DecodeError::InvalidValue),
+               }
        }
 }
 
+impl_writeable_tlv_based!(PendingHTLCInfo, {
+       (0, routing),
+       (2, incoming_shared_secret),
+       (4, payment_hash),
+       (6, amt_to_forward),
+       (8, outgoing_cltv_value)
+}, {}, {});
+
 impl Writeable for HTLCFailureMsg {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
                match self {
@@ -4407,33 +4415,52 @@ impl Readable for PendingHTLCStatus {
        }
 }
 
-impl_writeable!(HTLCPreviousHopData, 0, {
-       short_channel_id,
-       outpoint,
-       htlc_id,
-       incoming_packet_shared_secret
-});
+impl_writeable_tlv_based!(HTLCPreviousHopData, {
+       (0, short_channel_id),
+       (2, outpoint),
+       (4, htlc_id),
+       (6, incoming_packet_shared_secret)
+}, {}, {});
 
 impl Writeable for ClaimableHTLC {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
-               self.prev_hop.write(writer)?;
-               self.value.write(writer)?;
-               self.payment_data.payment_secret.write(writer)?;
-               self.payment_data.total_msat.write(writer)?;
-               self.cltv_expiry.write(writer)
+               write_tlv_fields!(writer, {
+                       (0, self.prev_hop),
+                       (2, self.value),
+                       (4, self.payment_data.payment_secret),
+                       (6, self.payment_data.total_msat),
+                       (8, self.cltv_expiry)
+               }, {});
+               Ok(())
        }
 }
 
 impl Readable for ClaimableHTLC {
        fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+               let mut prev_hop = HTLCPreviousHopData {
+                       short_channel_id: 0, htlc_id: 0,
+                       incoming_packet_shared_secret: [0; 32],
+                       outpoint: OutPoint::null(),
+               };
+               let mut value = 0;
+               let mut payment_secret = PaymentSecret([0; 32]);
+               let mut total_msat = 0;
+               let mut cltv_expiry = 0;
+               read_tlv_fields!(reader, {
+                       (0, prev_hop),
+                       (2, value),
+                       (4, payment_secret),
+                       (6, total_msat),
+                       (8, cltv_expiry)
+               }, {});
                Ok(ClaimableHTLC {
-                       prev_hop: Readable::read(reader)?,
-                       value: Readable::read(reader)?,
+                       prev_hop,
+                       value,
                        payment_data: msgs::FinalOnionHopData {
-                               payment_secret: Readable::read(reader)?,
-                               total_msat: Readable::read(reader)?,
+                               payment_secret,
+                               total_msat,
                        },
-                       cltv_expiry: Readable::read(reader)?,
+                       cltv_expiry,
                })
        }
 }
@@ -4538,13 +4565,13 @@ impl Readable for HTLCForwardInfo {
        }
 }
 
-impl_writeable!(PendingInboundPayment, 0, {
-       payment_secret,
-       expiry_time,
-       user_payment_id,
-       payment_preimage,
-       min_value_msat
-});
+impl_writeable_tlv_based!(PendingInboundPayment, {
+       (0, payment_secret),
+       (2, expiry_time),
+       (4, user_payment_id),
+       (6, payment_preimage),
+       (8, min_value_msat),
+}, {}, {});
 
 impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelManager<Signer, M, T, K, F, L>
        where M::Target: chain::Watch<Signer>,
@@ -4556,8 +4583,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)?;
                {
@@ -4640,6 +4666,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(())
        }
 }
@@ -4763,11 +4791,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)?;
@@ -4887,6 +4911,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());