X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fmsgs.rs;h=424dbafe6612f54f12a6c77c4755a0312311b169;hb=33ff2746ef3d1a36aab4f07cd1a7b512b6e411da;hp=132e6c203bb4cc360f2687cf7b3a576b7edc8ab0;hpb=20a81e5c1484dfef0cdf636438889344052cb2b1;p=rust-lightning diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 132e6c20..424dbafe 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -24,13 +24,14 @@ //! 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,10 +76,10 @@ 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 + /// 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 containg the new address. + /// that for a node_announcement update message containing the new address. pub remote_network_address: Option, } @@ -239,9 +240,9 @@ 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 @@ -442,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 @@ -452,6 +460,7 @@ impl NetAddress { &NetAddress::IPv6 {..} => { 2 }, &NetAddress::OnionV2(_) => { 3 }, &NetAddress::OnionV3 {..} => { 4 }, + &NetAddress::Hostname {..} => { 5 }, } } @@ -462,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 { @@ -492,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(()) } @@ -523,6 +541,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)), } } @@ -630,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, + /// 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, } /// A channel_update message to be sent or received from a peer #[derive(Clone, Debug, PartialEq)] @@ -812,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. @@ -967,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()) { @@ -1160,7 +1199,7 @@ impl_writeable_msg!(FundingSigned, { signature }, {}); -impl_writeable_msg!(FundingLocked, { +impl_writeable_msg!(ChannelReady, { channel_id, next_per_commitment_point, }, { @@ -1826,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; @@ -1835,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() { @@ -1892,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) } } } @@ -1968,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")); @@ -2004,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; @@ -2044,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()); } @@ -2055,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) { @@ -2155,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(); @@ -2211,7 +2261,7 @@ 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(); @@ -2259,15 +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); } @@ -2279,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(); @@ -2479,9 +2529,9 @@ mod tests { }), }; let encoded_value = init_msg.encode(); - let target_value = hex::decode("000000000307017f00000103e8").unwrap(); + 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); + assert_eq!(msgs::Init::read(&mut Cursor::new(&target_value)).unwrap(), init_msg); } #[test]