Add onion_message::Packet and adapt construct_onion_packet_with_init_noise for it
[rust-lightning] / lightning / src / ln / msgs.rs
index 9007f3f2ea7d59aaa820c0999e5c069be3718935..424dbafe6612f54f12a6c77c4755a0312311b169 100644 (file)
 //! raw socket events into your non-internet-facing system and then send routing events back to
 //! track the network on the less-secure system.
 
-use bitcoin::secp256k1::key::PublicKey;
-use bitcoin::secp256k1::Signature;
+use bitcoin::secp256k1::PublicKey;
+use bitcoin::secp256k1::ecdsa::Signature;
 use bitcoin::secp256k1;
 use bitcoin::blockdata::script::Script;
 use bitcoin::hash_types::{Txid, BlockHash};
 
 use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
+use ln::onion_utils;
 
 use prelude::*;
 use core::fmt;
@@ -40,7 +41,7 @@ use io_extras::read_to_end;
 
 use util::events::MessageSendEventsProvider;
 use util::logger;
-use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt};
+use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt, Hostname};
 
 use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 
@@ -75,6 +76,11 @@ pub enum DecodeError {
 pub struct Init {
        /// The relevant features which the sender supports
        pub features: InitFeatures,
+       /// The receipient's network address. This adds the option to report a remote IP address
+       /// back to a connecting peer using the init message. A node can decide to use that information
+       /// to discover a potential update to its public IPv4 address (NAT) and use
+       /// that for a node_announcement update message containing the new address.
+       pub remote_network_address: Option<NetAddress>,
 }
 
 /// An error message to be sent or received from a peer
@@ -204,6 +210,12 @@ pub struct AcceptChannel {
        pub first_per_commitment_point: PublicKey,
        /// Optionally, a request to pre-set the to-sender output's scriptPubkey for when we collaboratively close
        pub shutdown_scriptpubkey: OptionalField<Script>,
+       /// The channel type that this channel will represent. If none is set, we derive the channel
+       /// type from the intersection of our feature bits with our counterparty's feature bits from
+       /// the Init message.
+       ///
+       /// This is required to match the equivalent field in [`OpenChannel::channel_type`].
+       pub channel_type: Option<ChannelTypeFeatures>,
 }
 
 /// A funding_created message to be sent or received from a peer
@@ -228,13 +240,16 @@ pub struct FundingSigned {
        pub signature: Signature,
 }
 
-/// A funding_locked message to be sent or received from a peer
+/// A channel_ready message to be sent or received from a peer
 #[derive(Clone, Debug, PartialEq)]
-pub struct FundingLocked {
+pub struct ChannelReady {
        /// The channel ID
        pub channel_id: [u8; 32],
        /// The per-commitment point of the second commitment transaction
        pub next_per_commitment_point: PublicKey,
+       /// If set, provides a short_channel_id alias for this channel. The sender will accept payments
+       /// to be forwarded over this SCID and forward them to this messages' recipient.
+       pub short_channel_id_alias: Option<u64>,
 }
 
 /// A shutdown message to be sent or received from a peer
@@ -428,6 +443,13 @@ pub enum NetAddress {
                /// The port on which the node is listening
                port: u16,
        },
+       /// A hostname/port on which the peer is listening.
+       Hostname {
+               /// The hostname on which the node is listening.
+               hostname: Hostname,
+               /// The port on which the node is listening.
+               port: u16,
+       },
 }
 impl NetAddress {
        /// Gets the ID of this address type. Addresses in node_announcement messages should be sorted
@@ -438,6 +460,7 @@ impl NetAddress {
                        &NetAddress::IPv6 {..} => { 2 },
                        &NetAddress::OnionV2(_) => { 3 },
                        &NetAddress::OnionV3 {..} => { 4 },
+                       &NetAddress::Hostname {..} => { 5 },
                }
        }
 
@@ -448,11 +471,15 @@ impl NetAddress {
                        &NetAddress::IPv6 { .. } => { 18 },
                        &NetAddress::OnionV2(_) => { 12 },
                        &NetAddress::OnionV3 { .. } => { 37 },
+                       // Consists of 1-byte hostname length, hostname bytes, and 2-byte port.
+                       &NetAddress::Hostname { ref hostname, .. } => { u16::from(hostname.len()) + 3 },
                }
        }
 
-       /// The maximum length of any address descriptor, not including the 1-byte type
-       pub(crate) const MAX_LEN: u16 = 37;
+       /// The maximum length of any address descriptor, not including the 1-byte type.
+       /// This maximum length is reached by a hostname address descriptor:
+       /// a hostname with a maximum length of 255, its 1-byte length and a 2-byte port.
+       pub(crate) const MAX_LEN: u16 = 258;
 }
 
 impl Writeable for NetAddress {
@@ -478,7 +505,12 @@ impl Writeable for NetAddress {
                                checksum.write(writer)?;
                                version.write(writer)?;
                                port.write(writer)?;
-                       }
+                       },
+                       &NetAddress::Hostname { ref hostname, ref port } => {
+                               5u8.write(writer)?;
+                               hostname.write(writer)?;
+                               port.write(writer)?;
+                       },
                }
                Ok(())
        }
@@ -509,6 +541,12 @@ impl Readable for Result<NetAddress, u8> {
                                        port: Readable::read(reader)?,
                                }))
                        },
+                       5 => {
+                               Ok(Ok(NetAddress::Hostname {
+                                       hostname: Readable::read(reader)?,
+                                       port: Readable::read(reader)?,
+                               }))
+                       },
                        _ => return Ok(Err(byte)),
                }
        }
@@ -616,7 +654,10 @@ pub struct UnsignedChannelUpdate {
        pub fee_base_msat: u32,
        /// The amount to fee multiplier, in micro-satoshi
        pub fee_proportional_millionths: u32,
-       pub(crate) excess_data: Vec<u8>,
+       /// Excess data which was signed as a part of the message which we do not (yet) understand how
+       /// to decode. This is stored to ensure forward-compatibility as new fields are added to the
+       /// lightning gossip
+       pub excess_data: Vec<u8>,
 }
 /// A channel_update message to be sent or received from a peer
 #[derive(Clone, Debug, PartialEq)]
@@ -798,8 +839,8 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider {
        fn handle_funding_created(&self, their_node_id: &PublicKey, msg: &FundingCreated);
        /// Handle an incoming funding_signed message from the given peer.
        fn handle_funding_signed(&self, their_node_id: &PublicKey, msg: &FundingSigned);
-       /// Handle an incoming funding_locked message from the given peer.
-       fn handle_funding_locked(&self, their_node_id: &PublicKey, msg: &FundingLocked);
+       /// Handle an incoming channel_ready message from the given peer.
+       fn handle_channel_ready(&self, their_node_id: &PublicKey, msg: &ChannelReady);
 
        // Channl close:
        /// Handle an incoming shutdown message from the given peer.
@@ -877,7 +918,7 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
        /// Called when a connection is established with a peer. This can be used to
        /// perform routing table synchronization using a strategy defined by the
        /// implementor.
-       fn sync_routing_table(&self, their_node_id: &PublicKey, init: &Init);
+       fn peer_connected(&self, their_node_id: &PublicKey, init: &Init);
        /// Handles the reply of a query we initiated to learn about channels
        /// for a given range of blocks. We can expect to receive one or more
        /// replies to a single query.
@@ -937,9 +978,9 @@ mod fuzzy_internal_msgs {
                pub(crate) pad: Vec<u8>,
        }
 }
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
 pub use self::fuzzy_internal_msgs::*;
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
 pub(crate) use self::fuzzy_internal_msgs::*;
 
 #[derive(Clone)]
@@ -953,6 +994,18 @@ pub(crate) struct OnionPacket {
        pub(crate) hmac: [u8; 32],
 }
 
+impl onion_utils::Packet for OnionPacket {
+       type Data = onion_utils::FixedSizeOnionPacket;
+       fn new(pubkey: PublicKey, hop_data: onion_utils::FixedSizeOnionPacket, hmac: [u8; 32]) -> Self {
+               Self {
+                       version: 0,
+                       public_key: Ok(pubkey),
+                       hop_data: hop_data.0,
+                       hmac,
+               }
+       }
+}
+
 impl PartialEq for OnionPacket {
        fn eq(&self, other: &OnionPacket) -> bool {
                for (i, j) in self.hop_data.iter().zip(other.hop_data.iter()) {
@@ -985,7 +1038,7 @@ impl fmt::Display for DecodeError {
                        DecodeError::InvalidValue => f.write_str("Nonsense bytes didn't map to the type they were interpreted as"),
                        DecodeError::ShortRead => f.write_str("Packet extended beyond the provided bytes"),
                        DecodeError::BadLengthDescriptor => f.write_str("A length descriptor in the packet didn't describe the later data correctly"),
-                       DecodeError::Io(ref e) => e.fmt(f),
+                       DecodeError::Io(ref e) => fmt::Debug::fmt(e, f),
                        DecodeError::UnsupportedCompression => f.write_str("We don't support receiving messages with zlib-compressed fields"),
                }
        }
@@ -1064,7 +1117,9 @@ impl_writeable_msg!(AcceptChannel, {
        htlc_basepoint,
        first_per_commitment_point,
        shutdown_scriptpubkey
-}, {});
+}, {
+       (1, channel_type, option),
+});
 
 impl_writeable_msg!(AnnouncementSignatures, {
        channel_id,
@@ -1144,17 +1199,23 @@ impl_writeable_msg!(FundingSigned, {
        signature
 }, {});
 
-impl_writeable_msg!(FundingLocked, {
+impl_writeable_msg!(ChannelReady, {
        channel_id,
        next_per_commitment_point,
-}, {});
+}, {
+       (1, short_channel_id_alias, option),
+});
 
 impl Writeable for Init {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                // global_features gets the bottom 13 bits of our features, and local_features gets all of
                // our relevant feature bits. This keeps us compatible with old nodes.
                self.features.write_up_to_13(w)?;
-               self.features.write(w)
+               self.features.write(w)?;
+               encode_tlv_stream!(w, {
+                       (3, self.remote_network_address, option)
+               });
+               Ok(())
        }
 }
 
@@ -1162,8 +1223,13 @@ impl Readable for Init {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let global_features: InitFeatures = Readable::read(r)?;
                let features: InitFeatures = Readable::read(r)?;
+               let mut remote_network_address: Option<NetAddress> = None;
+               decode_tlv_stream!(r, {
+                       (3, remote_network_address, option)
+               });
                Ok(Init {
                        features: features.or(global_features),
+                       remote_network_address,
                })
        }
 }
@@ -1291,10 +1357,6 @@ impl Readable for FinalOnionHopData {
 
 impl Writeable for OnionHopData {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               // Note that this should never be reachable if Rust-Lightning generated the message, as we
-               // check values are sane long before we get here, though its possible in the future
-               // user-generated messages may hit this.
-               if self.amt_to_forward > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
                match self.format {
                        OnionHopDataFormat::Legacy { short_channel_id } => {
                                0u8.write(w)?;
@@ -1311,9 +1373,6 @@ impl Writeable for OnionHopData {
                                });
                        },
                        OnionHopDataFormat::FinalNode { ref payment_data, ref keysend_preimage } => {
-                               if let Some(final_data) = payment_data {
-                                       if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
-                               }
                                encode_varint_length_prefixed_tlv!(w, {
                                        (2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required),
                                        (4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required),
@@ -1806,7 +1865,7 @@ mod tests {
        use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
        use ln::msgs;
        use ln::msgs::{FinalOnionHopData, OptionalField, OnionErrorPacket, OnionHopDataFormat};
-       use util::ser::{Writeable, Readable};
+       use util::ser::{Writeable, Readable, Hostname};
 
        use bitcoin::hashes::hex::FromHex;
        use bitcoin::util::address::Address;
@@ -1815,11 +1874,12 @@ mod tests {
        use bitcoin::blockdata::opcodes;
        use bitcoin::hash_types::{Txid, BlockHash};
 
-       use bitcoin::secp256k1::key::{PublicKey,SecretKey};
+       use bitcoin::secp256k1::{PublicKey,SecretKey};
        use bitcoin::secp256k1::{Secp256k1, Message};
 
        use io::Cursor;
        use prelude::*;
+       use core::convert::TryFrom;
 
        #[test]
        fn encoding_channel_reestablish_no_secret() {
@@ -1872,7 +1932,7 @@ mod tests {
                ($privkey: expr, $ctx: expr, $string: expr) => {
                        {
                                let sighash = Message::from_slice(&$string.into_bytes()[..]).unwrap();
-                               $ctx.sign(&sighash, &$privkey)
+                               $ctx.sign_ecdsa(&sighash, &$privkey)
                        }
                }
        }
@@ -1948,7 +2008,7 @@ mod tests {
                do_encoding_channel_announcement(true, true);
        }
 
-       fn do_encoding_node_announcement(unknown_features_bits: bool, ipv4: bool, ipv6: bool, onionv2: bool, onionv3: bool, excess_address_data: bool, excess_data: bool) {
+       fn do_encoding_node_announcement(unknown_features_bits: bool, ipv4: bool, ipv6: bool, onionv2: bool, onionv3: bool, hostname: bool, excess_address_data: bool, excess_data: bool) {
                let secp_ctx = Secp256k1::new();
                let (privkey_1, pubkey_1) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
                let sig_1 = get_sig_on!(privkey_1, secp_ctx, String::from("01010101010101010101010101010101"));
@@ -1984,6 +2044,12 @@ mod tests {
                                port: 9735
                        });
                }
+               if hostname {
+                       addresses.push(msgs::NetAddress::Hostname {
+                               hostname: Hostname::try_from(String::from("host")).unwrap(),
+                               port: 9735,
+                       });
+               }
                let mut addr_len = 0;
                for addr in &addresses {
                        addr_len += addr.len() + 1;
@@ -2024,6 +2090,9 @@ mod tests {
                if onionv3 {
                        target_value.append(&mut hex::decode("04fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e00020102607").unwrap());
                }
+               if hostname {
+                       target_value.append(&mut hex::decode("0504686f73742607").unwrap());
+               }
                if excess_address_data {
                        target_value.append(&mut hex::decode("216c280b5395a2546e7e4b2663e04f811622f15a4f92e83aa2e92ba2a573c139142c54ae63072a1ec1ee7dc0c04bde5c847806172aa05c92c22ae8e308d1d269").unwrap());
                }
@@ -2035,15 +2104,16 @@ mod tests {
 
        #[test]
        fn encoding_node_announcement() {
-               do_encoding_node_announcement(true, true, true, true, true, true, true);
-               do_encoding_node_announcement(false, false, false, false, false, false, false);
-               do_encoding_node_announcement(false, true, false, false, false, false, false);
-               do_encoding_node_announcement(false, false, true, false, false, false, false);
-               do_encoding_node_announcement(false, false, false, true, false, false, false);
-               do_encoding_node_announcement(false, false, false, false, true, false, false);
-               do_encoding_node_announcement(false, false, false, false, false, true, false);
-               do_encoding_node_announcement(false, true, false, true, false, true, false);
-               do_encoding_node_announcement(false, false, true, false, true, false, false);
+               do_encoding_node_announcement(true, true, true, true, true, true, true, true);
+               do_encoding_node_announcement(false, false, false, false, false, false, false, false);
+               do_encoding_node_announcement(false, true, false, false, false, false, false, false);
+               do_encoding_node_announcement(false, false, true, false, false, false, false, false);
+               do_encoding_node_announcement(false, false, false, true, false, false, false, false);
+               do_encoding_node_announcement(false, false, false, false, true, false, false, false);
+               do_encoding_node_announcement(false, false, false, false, false, true, false, false);
+               do_encoding_node_announcement(false, false, false, false, false, false, true, false);
+               do_encoding_node_announcement(false, true, false, true, false, false, true, false);
+               do_encoding_node_announcement(false, false, true, false, true, false, false, false);
        }
 
        fn do_encoding_channel_update(direction: bool, disable: bool, htlc_maximum_msat: bool, excess_data: bool) {
@@ -2135,7 +2205,7 @@ mod tests {
                        htlc_basepoint: pubkey_5,
                        first_per_commitment_point: pubkey_6,
                        channel_flags: if random_bit { 1 << 5 } else { 0 },
-                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent },
+                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent },
                        channel_type: if incl_chan_type { Some(ChannelTypeFeatures::empty()) } else { None },
                };
                let encoded_value = open_channel.encode();
@@ -2191,7 +2261,8 @@ mod tests {
                        delayed_payment_basepoint: pubkey_4,
                        htlc_basepoint: pubkey_5,
                        first_per_commitment_point: pubkey_6,
-                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent }
+                       shutdown_scriptpubkey: if shutdown { OptionalField::Present(Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey()) } else { OptionalField::Absent },
+                       channel_type: None,
                };
                let encoded_value = accept_channel.encode();
                let mut target_value = hex::decode("020202020202020202020202020202020202020202020202020202020202020212345678901234562334032891223698321446687011447600083a840000034d000c89d4c0bcc0bc031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d076602531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe33703462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f703f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a").unwrap();
@@ -2238,14 +2309,15 @@ mod tests {
        }
 
        #[test]
-       fn encoding_funding_locked() {
+       fn encoding_channel_ready() {
                let secp_ctx = Secp256k1::new();
                let (_, pubkey_1,) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
-               let funding_locked = msgs::FundingLocked {
+               let channel_ready = msgs::ChannelReady {
                        channel_id: [2; 32],
                        next_per_commitment_point: pubkey_1,
+                       short_channel_id_alias: None,
                };
-               let encoded_value = funding_locked.encode();
+               let encoded_value = channel_ready.encode();
                let target_value = hex::decode("0202020202020202020202020202020202020202020202020202020202020202031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f").unwrap();
                assert_eq!(encoded_value, target_value);
        }
@@ -2257,9 +2329,9 @@ mod tests {
                let shutdown = msgs::Shutdown {
                        channel_id: [2; 32],
                        scriptpubkey:
-                                    if script_type == 1 { Address::p2pkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).script_pubkey() }
-                               else if script_type == 2 { Address::p2sh(&script, Network::Testnet).script_pubkey() }
-                               else if script_type == 3 { Address::p2wpkh(&::bitcoin::PublicKey{compressed: true, key: pubkey_1}, Network::Testnet).unwrap().script_pubkey() }
+                                    if script_type == 1 { Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).script_pubkey() }
+                               else if script_type == 2 { Address::p2sh(&script, Network::Testnet).unwrap().script_pubkey() }
+                               else if script_type == 3 { Address::p2wpkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).unwrap().script_pubkey() }
                                else                     { Address::p2wsh(&script, Network::Testnet).script_pubkey() },
                };
                let encoded_value = shutdown.encode();
@@ -2439,13 +2511,27 @@ mod tests {
        fn encoding_init() {
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![0xFF, 0xFF, 0xFF]),
+                       remote_network_address: None,
                }.encode(), hex::decode("00023fff0003ffffff").unwrap());
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![0xFF]),
+                       remote_network_address: None,
                }.encode(), hex::decode("0001ff0001ff").unwrap());
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![]),
+                       remote_network_address: None,
                }.encode(), hex::decode("00000000").unwrap());
+
+               let init_msg = msgs::Init { features: InitFeatures::from_le_bytes(vec![]),
+                       remote_network_address: Some(msgs::NetAddress::IPv4 {
+                               addr: [127, 0, 0, 1],
+                               port: 1000,
+                       }),
+               };
+               let encoded_value = init_msg.encode();
+               let target_value = hex::decode("000000000307017f00000103e8").unwrap();
+               assert_eq!(encoded_value, target_value);
+               assert_eq!(msgs::Init::read(&mut Cursor::new(&target_value)).unwrap(), init_msg);
        }
 
        #[test]