Remove OnionV2 parsing support
[rust-lightning] / lightning / src / ln / msgs.rs
index 34ccc8adf7ad540ef3cdfa982159e36ae7523f30..3c6300ef8eadc5e517c3fb398c021bba8c53dd31 100644 (file)
@@ -30,7 +30,7 @@ use bitcoin::secp256k1;
 use bitcoin::blockdata::script::Script;
 use bitcoin::hash_types::{Txid, BlockHash};
 
-use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
+use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
 
 use prelude::*;
 use core::{cmp, fmt};
@@ -148,6 +148,10 @@ pub struct OpenChannel {
        pub channel_flags: u8,
        /// 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.
+       pub channel_type: Option<ChannelTypeFeatures>,
 }
 
 /// An accept_channel message to be sent or received from a peer
@@ -390,12 +394,10 @@ pub enum NetAddress {
                port: u16,
        },
        /// An old-style Tor onion address/port on which the peer is listening.
-       OnionV2 {
-               /// The bytes (usually encoded in base32 with ".onion" appended)
-               addr: [u8; 10],
-               /// The port on which the node is listening
-               port: u16,
-       },
+       ///
+       /// This field is deprecated and the Tor network generally no longer supports V2 Onion
+       /// addresses. Thus, the details are not parsed here.
+       OnionV2([u8; 12]),
        /// A new-style Tor onion address/port on which the peer is listening.
        /// To create the human-readable "hostname", concatenate ed25519_pubkey, checksum, and version,
        /// wrap as base32 and append ".onion".
@@ -417,7 +419,7 @@ impl NetAddress {
                match self {
                        &NetAddress::IPv4 {..} => { 1 },
                        &NetAddress::IPv6 {..} => { 2 },
-                       &NetAddress::OnionV2 {..} => { 3 },
+                       &NetAddress::OnionV2(_) => { 3 },
                        &NetAddress::OnionV3 {..} => { 4 },
                }
        }
@@ -427,7 +429,7 @@ impl NetAddress {
                match self {
                        &NetAddress::IPv4 { .. } => { 6 },
                        &NetAddress::IPv6 { .. } => { 18 },
-                       &NetAddress::OnionV2 { .. } => { 12 },
+                       &NetAddress::OnionV2(_) => { 12 },
                        &NetAddress::OnionV3 { .. } => { 37 },
                }
        }
@@ -449,10 +451,9 @@ impl Writeable for NetAddress {
                                addr.write(writer)?;
                                port.write(writer)?;
                        },
-                       &NetAddress::OnionV2 { ref addr, ref port } => {
+                       &NetAddress::OnionV2(bytes) => {
                                3u8.write(writer)?;
-                               addr.write(writer)?;
-                               port.write(writer)?;
+                               bytes.write(writer)?;
                        },
                        &NetAddress::OnionV3 { ref ed25519_pubkey, ref checksum, ref version, ref port } => {
                                4u8.write(writer)?;
@@ -482,12 +483,7 @@ impl Readable for Result<NetAddress, u8> {
                                        port: Readable::read(reader)?,
                                }))
                        },
-                       3 => {
-                               Ok(Ok(NetAddress::OnionV2 {
-                                       addr: Readable::read(reader)?,
-                                       port: Readable::read(reader)?,
-                               }))
-                       },
+                       3 => Ok(Ok(NetAddress::OnionV2(Readable::read(reader)?))),
                        4 => {
                                Ok(Ok(NetAddress::OnionV3 {
                                        ed25519_pubkey: Readable::read(reader)?,
@@ -745,35 +741,6 @@ pub struct CommitmentUpdate {
        pub commitment_signed: CommitmentSigned,
 }
 
-/// The information we received from a peer along the route of a payment we originated. This is
-/// returned by ChannelMessageHandler::handle_update_fail_htlc to be passed into
-/// RoutingMessageHandler::handle_htlc_fail_channel_update to update our network map.
-#[derive(Clone, Debug, PartialEq)]
-pub enum HTLCFailChannelUpdate {
-       /// We received an error which included a full ChannelUpdate message.
-       ChannelUpdateMessage {
-               /// The unwrapped message we received
-               msg: ChannelUpdate,
-       },
-       /// We received an error which indicated only that a channel has been closed
-       ChannelClosed {
-               /// The short_channel_id which has now closed.
-               short_channel_id: u64,
-               /// when this true, this channel should be permanently removed from the
-               /// consideration. Otherwise, this channel can be restored as new channel_update is received
-               is_permanent: bool,
-       },
-       /// We received an error which indicated only that a node has failed
-       NodeFailure {
-               /// The node_id that has failed.
-               node_id: PublicKey,
-               /// when this true, node should be permanently removed from the
-               /// consideration. Otherwise, the channels connected to this node can be
-               /// restored as new channel_update is received
-               is_permanent: bool,
-       }
-}
-
 /// Messages could have optional fields to use with extended features
 /// As we wish to serialize these differently from Option<T>s (Options get a tag byte, but
 /// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a
@@ -868,8 +835,6 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
        /// Handle an incoming channel_update message, returning true if it should be forwarded on,
        /// false or returning an Err otherwise.
        fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result<bool, LightningError>;
-       /// Handle some updates to the route graph that we learned due to an outbound failed payment.
-       fn handle_htlc_fail_channel_update(&self, update: &HTLCFailChannelUpdate);
        /// Gets a subset of the channel announcements and updates required to dump our routing table
        /// to a remote node, starting at the short_channel_id indicated by starting_point and
        /// including the batch_amount entries immediately higher in numerical value than starting_point.
@@ -1053,7 +1018,7 @@ impl Readable for OptionalField<u64> {
 }
 
 
-impl_writeable!(AcceptChannel, {
+impl_writeable_msg!(AcceptChannel, {
        temporary_channel_id,
        dust_limit_satoshis,
        max_htlc_value_in_flight_msat,
@@ -1069,14 +1034,14 @@ impl_writeable!(AcceptChannel, {
        htlc_basepoint,
        first_per_commitment_point,
        shutdown_scriptpubkey
-});
+}, {});
 
-impl_writeable!(AnnouncementSignatures, {
+impl_writeable_msg!(AnnouncementSignatures, {
        channel_id,
        short_channel_id,
        node_signature,
        bitcoin_signature
-});
+}, {});
 
 impl Writeable for ChannelReestablish {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
@@ -1115,41 +1080,21 @@ impl Readable for ChannelReestablish{
        }
 }
 
-impl Writeable for ClosingSigned {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               self.channel_id.write(w)?;
-               self.fee_satoshis.write(w)?;
-               self.signature.write(w)?;
-               encode_tlv_stream!(w, {
-                       (1, self.fee_range, option),
-               });
-               Ok(())
-       }
-}
-
-impl Readable for ClosingSigned {
-       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let channel_id = Readable::read(r)?;
-               let fee_satoshis = Readable::read(r)?;
-               let signature = Readable::read(r)?;
-               let mut fee_range = None;
-               decode_tlv_stream!(r, {
-                       (1, fee_range, option),
-               });
-               Ok(Self { channel_id, fee_satoshis, signature, fee_range })
-       }
-}
+impl_writeable_msg!(ClosingSigned,
+       { channel_id, fee_satoshis, signature },
+       { (1, fee_range, option) }
+);
 
 impl_writeable!(ClosingSignedFeeRange, {
        min_fee_satoshis,
        max_fee_satoshis
 });
 
-impl_writeable!(CommitmentSigned, {
+impl_writeable_msg!(CommitmentSigned, {
        channel_id,
        signature,
        htlc_signatures
-});
+}, {});
 
 impl_writeable!(DecodedOnionErrorPacket, {
        hmac,
@@ -1157,22 +1102,22 @@ impl_writeable!(DecodedOnionErrorPacket, {
        pad
 });
 
-impl_writeable!(FundingCreated, {
+impl_writeable_msg!(FundingCreated, {
        temporary_channel_id,
        funding_txid,
        funding_output_index,
        signature
-});
+}, {});
 
-impl_writeable!(FundingSigned, {
+impl_writeable_msg!(FundingSigned, {
        channel_id,
        signature
-});
+}, {});
 
-impl_writeable!(FundingLocked, {
+impl_writeable_msg!(FundingLocked, {
        channel_id,
-       next_per_commitment_point
-});
+       next_per_commitment_point,
+}, {});
 
 impl Writeable for Init {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
@@ -1193,7 +1138,7 @@ impl Readable for Init {
        }
 }
 
-impl_writeable!(OpenChannel, {
+impl_writeable_msg!(OpenChannel, {
        chain_hash,
        temporary_channel_id,
        funding_satoshis,
@@ -1213,47 +1158,55 @@ impl_writeable!(OpenChannel, {
        first_per_commitment_point,
        channel_flags,
        shutdown_scriptpubkey
+}, {
+       (1, channel_type, option),
 });
 
-impl_writeable!(RevokeAndACK, {
+impl_writeable_msg!(RevokeAndACK, {
        channel_id,
        per_commitment_secret,
        next_per_commitment_point
-});
+}, {});
 
-impl_writeable!(Shutdown, {
+impl_writeable_msg!(Shutdown, {
        channel_id,
        scriptpubkey
-});
+}, {});
 
-impl_writeable!(UpdateFailHTLC, {
+impl_writeable_msg!(UpdateFailHTLC, {
        channel_id,
        htlc_id,
        reason
-});
+}, {});
 
-impl_writeable!(UpdateFailMalformedHTLC, {
+impl_writeable_msg!(UpdateFailMalformedHTLC, {
        channel_id,
        htlc_id,
        sha256_of_onion,
        failure_code
-});
+}, {});
 
-impl_writeable!(UpdateFee, {
+impl_writeable_msg!(UpdateFee, {
        channel_id,
        feerate_per_kw
-});
+}, {});
 
-impl_writeable!(UpdateFulfillHTLC, {
+impl_writeable_msg!(UpdateFulfillHTLC, {
        channel_id,
        htlc_id,
        payment_preimage
-});
+}, {});
 
+// Note that this is written as a part of ChannelManager objects, and thus cannot change its
+// serialization format in a way which assumes we know the total serialized length/message end
+// position.
 impl_writeable!(OnionErrorPacket, {
        data
 });
 
+// Note that this is written as a part of ChannelManager objects, and thus cannot change its
+// serialization format in a way which assumes we know the total serialized length/message end
+// position.
 impl Writeable for OnionPacket {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                self.version.write(w)?;
@@ -1282,14 +1235,14 @@ impl Readable for OnionPacket {
        }
 }
 
-impl_writeable!(UpdateAddHTLC, {
+impl_writeable_msg!(UpdateAddHTLC, {
        channel_id,
        htlc_id,
        amount_msat,
        payment_hash,
        cltv_expiry,
        onion_routing_packet
-});
+}, {});
 
 impl Writeable for FinalOnionHopData {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
@@ -1700,24 +1653,10 @@ impl Writeable for QueryShortChannelIds {
        }
 }
 
-impl Readable for ReplyShortChannelIdsEnd {
-       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let chain_hash: BlockHash = Readable::read(r)?;
-               let full_information: bool = Readable::read(r)?;
-               Ok(ReplyShortChannelIdsEnd {
-                       chain_hash,
-                       full_information,
-               })
-       }
-}
-
-impl Writeable for ReplyShortChannelIdsEnd {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               self.chain_hash.write(w)?;
-               self.full_information.write(w)?;
-               Ok(())
-       }
-}
+impl_writeable_msg!(ReplyShortChannelIdsEnd, {
+       chain_hash,
+       full_information,
+}, {});
 
 impl QueryChannelRange {
        /**
@@ -1732,27 +1671,11 @@ impl QueryChannelRange {
        }
 }
 
-impl Readable for QueryChannelRange {
-       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let chain_hash: BlockHash = Readable::read(r)?;
-               let first_blocknum: u32 = Readable::read(r)?;
-               let number_of_blocks: u32 = Readable::read(r)?;
-               Ok(QueryChannelRange {
-                       chain_hash,
-                       first_blocknum,
-                       number_of_blocks
-               })
-       }
-}
-
-impl Writeable for QueryChannelRange {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               self.chain_hash.write(w)?;
-               self.first_blocknum.write(w)?;
-               self.number_of_blocks.write(w)?;
-               Ok(())
-       }
-}
+impl_writeable_msg!(QueryChannelRange, {
+       chain_hash,
+       first_blocknum,
+       number_of_blocks
+}, {});
 
 impl Readable for ReplyChannelRange {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
@@ -1812,35 +1735,19 @@ impl Writeable for ReplyChannelRange {
        }
 }
 
-impl Readable for GossipTimestampFilter {
-       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let chain_hash: BlockHash = Readable::read(r)?;
-               let first_timestamp: u32 = Readable::read(r)?;
-               let timestamp_range: u32 = Readable::read(r)?;
-               Ok(GossipTimestampFilter {
-                       chain_hash,
-                       first_timestamp,
-                       timestamp_range,
-               })
-       }
-}
-
-impl Writeable for GossipTimestampFilter {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               self.chain_hash.write(w)?;
-               self.first_timestamp.write(w)?;
-               self.timestamp_range.write(w)?;
-               Ok(())
-       }
-}
-
+impl_writeable_msg!(GossipTimestampFilter, {
+       chain_hash,
+       first_timestamp,
+       timestamp_range,
+}, {});
 
 #[cfg(test)]
 mod tests {
        use hex;
        use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
+       use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
        use ln::msgs;
-       use ln::msgs::{ChannelFeatures, FinalOnionHopData, InitFeatures, NodeFeatures, OptionalField, OnionErrorPacket, OnionHopDataFormat};
+       use ln::msgs::{FinalOnionHopData, OptionalField, OnionErrorPacket, OnionHopDataFormat};
        use util::ser::{Writeable, Readable};
 
        use bitcoin::hashes::hex::FromHex;
@@ -2007,10 +1914,9 @@ mod tests {
                        });
                }
                if onionv2 {
-                       addresses.push(msgs::NetAddress::OnionV2 {
-                               addr: [255, 254, 253, 252, 251, 250, 249, 248, 247, 246],
-                               port: 9735
-                       });
+                       addresses.push(msgs::NetAddress::OnionV2(
+                               [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 38, 7]
+                       ));
                }
                if onionv3 {
                        addresses.push(msgs::NetAddress::OnionV3 {
@@ -2144,7 +2050,7 @@ mod tests {
                do_encoding_channel_update(true, true, true, true);
        }
 
-       fn do_encoding_open_channel(random_bit: bool, shutdown: bool) {
+       fn do_encoding_open_channel(random_bit: bool, shutdown: bool, incl_chan_type: bool) {
                let secp_ctx = Secp256k1::new();
                let (_, pubkey_1) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
                let (_, pubkey_2) = get_keys_from!("0202020202020202020202020202020202020202020202020202020202020202", secp_ctx);
@@ -2171,7 +2077,8 @@ 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, key: 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();
                let mut target_value = Vec::new();
@@ -2185,15 +2092,22 @@ mod tests {
                if shutdown {
                        target_value.append(&mut hex::decode("001976a91479b000887626b294a914501a4cd226b58b23598388ac").unwrap());
                }
+               if incl_chan_type {
+                       target_value.append(&mut hex::decode("0100").unwrap());
+               }
                assert_eq!(encoded_value, target_value);
        }
 
        #[test]
        fn encoding_open_channel() {
-               do_encoding_open_channel(false, false);
-               do_encoding_open_channel(true, false);
-               do_encoding_open_channel(false, true);
-               do_encoding_open_channel(true, true);
+               do_encoding_open_channel(false, false, false);
+               do_encoding_open_channel(false, false, true);
+               do_encoding_open_channel(false, true, false);
+               do_encoding_open_channel(false, true, true);
+               do_encoding_open_channel(true, false, false);
+               do_encoding_open_channel(true, false, true);
+               do_encoding_open_channel(true, true, false);
+               do_encoding_open_channel(true, true, true);
        }
 
        fn do_encoding_accept_channel(shutdown: bool) {