X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fmsgs.rs;h=05a336c18eff5634e0fee7f2cec8b86a66e02a89;hb=28c9b56113ff1ebb1b505a2c979c55c1626aa06b;hp=0e5b2e07e7a4cea649bc44939a67f2c940f71779;hpb=e98f68aee626becf056f443a87207ff6c81003a3;p=rust-lightning diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 0e5b2e07..05a336c1 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -31,6 +31,8 @@ use bitcoin::blockdata::script::Script; use bitcoin::hash_types::{Txid, BlockHash}; use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; +use ln::onion_utils; +use onion_message; use prelude::*; use core::fmt; @@ -40,7 +42,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::{LengthReadable, Readable, ReadableArgs, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt, Hostname}; use ln::{PaymentPreimage, PaymentHash, PaymentSecret}; @@ -304,6 +306,14 @@ pub struct UpdateAddHTLC { pub(crate) onion_routing_packet: OnionPacket, } + /// An onion message to be sent or received from a peer +#[derive(Clone, Debug, PartialEq)] +pub struct OnionMessage { + /// Used in decrypting the onion packet's payload. + pub blinding_point: PublicKey, + pub(crate) onion_routing_packet: onion_message::Packet, +} + /// An update_fulfill_htlc message to be sent or received from a peer #[derive(Clone, Debug, PartialEq)] pub struct UpdateFulfillHTLC { @@ -442,6 +452,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 @@ -452,6 +469,7 @@ impl NetAddress { &NetAddress::IPv6 {..} => { 2 }, &NetAddress::OnionV2(_) => { 3 }, &NetAddress::OnionV3 {..} => { 4 }, + &NetAddress::Hostname {..} => { 5 }, } } @@ -462,11 +480,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 { @@ -492,7 +514,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(()) } @@ -523,6 +550,12 @@ impl Readable for Result { port: Readable::read(reader)?, })) }, + 5 => { + Ok(Ok(NetAddress::Hostname { + hostname: Readable::read(reader)?, + port: Readable::read(reader)?, + })) + }, _ => return Ok(Err(byte)), } } @@ -624,8 +657,8 @@ pub struct UnsignedChannelUpdate { pub cltv_expiry_delta: u16, /// The minimum HTLC size incoming to sender, in milli-satoshi pub htlc_minimum_msat: u64, - /// Optionally, the maximum HTLC value incoming to sender, in milli-satoshi - pub htlc_maximum_msat: OptionalField, + /// The maximum HTLC value incoming to sender, in milli-satoshi. Used to be optional. + pub htlc_maximum_msat: u64, /// The base HTLC fee charged by sender, in milli-satoshi pub fee_base_msat: u32, /// The amount to fee multiplier, in micro-satoshi @@ -970,6 +1003,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()) { @@ -1304,6 +1349,29 @@ impl_writeable_msg!(UpdateAddHTLC, { onion_routing_packet }, {}); +impl Readable for OnionMessage { + fn read(r: &mut R) -> Result { + let blinding_point: PublicKey = Readable::read(r)?; + let len: u16 = Readable::read(r)?; + let mut packet_reader = FixedLengthReader::new(r, len as u64); + let onion_routing_packet: onion_message::Packet = ::read(&mut packet_reader)?; + Ok(Self { + blinding_point, + onion_routing_packet, + }) + } +} + +impl Writeable for OnionMessage { + fn write(&self, w: &mut W) -> Result<(), io::Error> { + self.blinding_point.write(w)?; + let onion_packet_len = self.onion_routing_packet.serialized_length(); + (onion_packet_len as u16).write(w)?; + self.onion_routing_packet.write(w)?; + Ok(()) + } +} + impl Writeable for FinalOnionHopData { fn write(&self, w: &mut W) -> Result<(), io::Error> { self.payment_secret.0.write(w)?; @@ -1349,6 +1417,14 @@ impl Writeable for OnionHopData { } } +// ReadableArgs because we need onion_utils::decode_next_hop to accommodate payment packets and +// onion message packets. +impl ReadableArgs<()> for OnionHopData { + fn read(r: &mut R, _arg: ()) -> Result { + ::read(r) + } +} + impl Readable for OnionHopData { fn read(mut r: &mut R) -> Result { use bitcoin::consensus::encode::{Decodable, Error, VarInt}; @@ -1491,14 +1567,12 @@ impl_writeable!(ChannelAnnouncement, { impl Writeable for UnsignedChannelUpdate { fn write(&self, w: &mut W) -> Result<(), io::Error> { - let mut message_flags: u8 = 0; - if let OptionalField::Present(_) = self.htlc_maximum_msat { - message_flags = 1; - } + // `message_flags` used to indicate presence of `htlc_maximum_msat`, but was deprecated in the spec. + const MESSAGE_FLAGS: u8 = 1; self.chain_hash.write(w)?; self.short_channel_id.write(w)?; self.timestamp.write(w)?; - let all_flags = self.flags as u16 | ((message_flags as u16) << 8); + let all_flags = self.flags as u16 | ((MESSAGE_FLAGS as u16) << 8); all_flags.write(w)?; self.cltv_expiry_delta.write(w)?; self.htlc_minimum_msat.write(w)?; @@ -1512,22 +1586,20 @@ impl Writeable for UnsignedChannelUpdate { impl Readable for UnsignedChannelUpdate { fn read(r: &mut R) -> Result { - let has_htlc_maximum_msat; Ok(Self { chain_hash: Readable::read(r)?, short_channel_id: Readable::read(r)?, timestamp: Readable::read(r)?, flags: { let flags: u16 = Readable::read(r)?; - let message_flags = flags >> 8; - has_htlc_maximum_msat = (message_flags as i32 & 1) == 1; + // Note: we ignore the `message_flags` for now, since it was deprecated by the spec. flags as u8 }, cltv_expiry_delta: Readable::read(r)?, htlc_minimum_msat: Readable::read(r)?, fee_base_msat: Readable::read(r)?, fee_proportional_millionths: Readable::read(r)?, - htlc_maximum_msat: if has_htlc_maximum_msat { Readable::read(r)? } else { OptionalField::Absent }, + htlc_maximum_msat: Readable::read(r)?, excess_data: read_to_end(r)?, }) } @@ -1829,7 +1901,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; @@ -1843,6 +1915,7 @@ mod tests { use io::Cursor; use prelude::*; + use core::convert::TryFrom; #[test] fn encoding_channel_reestablish_no_secret() { @@ -1971,7 +2044,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")); @@ -2007,6 +2080,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; @@ -2047,6 +2126,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()); } @@ -2058,18 +2140,19 @@ 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); - } - - fn do_encoding_channel_update(direction: bool, disable: bool, htlc_maximum_msat: bool, excess_data: bool) { + 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, excess_data: bool) { let secp_ctx = Secp256k1::new(); let (privkey_1, _) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx); let sig_1 = get_sig_on!(privkey_1, secp_ctx, String::from("01010101010101010101010101010101")); @@ -2080,7 +2163,7 @@ mod tests { flags: if direction { 1 } else { 0 } | if disable { 1 << 1 } else { 0 }, cltv_expiry_delta: 144, htlc_minimum_msat: 1000000, - htlc_maximum_msat: if htlc_maximum_msat { OptionalField::Present(131355275467161) } else { OptionalField::Absent }, + htlc_maximum_msat: 131355275467161, fee_base_msat: 10000, fee_proportional_millionths: 20, excess_data: if excess_data { vec![0, 0, 0, 0, 59, 154, 202, 0] } else { Vec::new() } @@ -2093,11 +2176,7 @@ mod tests { let mut target_value = hex::decode("d977cb9b53d93a6ff64bb5f1e158b4094b66e798fb12911168a3ccdf80a83096340a6a95da0ae8d9f776528eecdbb747eb6b545495a4319ed5378e35b21e073a").unwrap(); target_value.append(&mut hex::decode("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f").unwrap()); target_value.append(&mut hex::decode("00083a840000034d013413a7").unwrap()); - if htlc_maximum_msat { - target_value.append(&mut hex::decode("01").unwrap()); - } else { - target_value.append(&mut hex::decode("00").unwrap()); - } + target_value.append(&mut hex::decode("01").unwrap()); target_value.append(&mut hex::decode("00").unwrap()); if direction { let flag = target_value.last_mut().unwrap(); @@ -2108,9 +2187,7 @@ mod tests { *flag = *flag | 1 << 1; } target_value.append(&mut hex::decode("009000000000000f42400000271000000014").unwrap()); - if htlc_maximum_msat { - target_value.append(&mut hex::decode("0000777788889999").unwrap()); - } + target_value.append(&mut hex::decode("0000777788889999").unwrap()); if excess_data { target_value.append(&mut hex::decode("000000003b9aca00").unwrap()); } @@ -2119,16 +2196,14 @@ mod tests { #[test] fn encoding_channel_update() { - do_encoding_channel_update(false, false, false, false); - do_encoding_channel_update(false, false, false, true); - do_encoding_channel_update(true, false, false, false); - do_encoding_channel_update(true, false, false, true); - do_encoding_channel_update(false, true, false, false); - do_encoding_channel_update(false, true, false, true); - do_encoding_channel_update(false, false, true, false); - do_encoding_channel_update(false, false, true, true); - do_encoding_channel_update(true, true, true, false); - do_encoding_channel_update(true, true, true, true); + do_encoding_channel_update(false, false, false); + do_encoding_channel_update(false, false, true); + do_encoding_channel_update(true, false, false); + do_encoding_channel_update(true, false, true); + do_encoding_channel_update(false, true, false); + do_encoding_channel_update(false, true, true); + do_encoding_channel_update(true, true, false); + do_encoding_channel_update(true, true, true); } fn do_encoding_open_channel(random_bit: bool, shutdown: bool, incl_chan_type: bool) {