Merge pull request #2568 from tnull/2023-09-housekeeping
[rust-lightning] / lightning / src / ln / msgs.rs
index 0635dafd7dbc8987d222c1be59268629fcb8cca8..c617d97fe52705c8673c6f4a68f331bb8ed644a6 100644 (file)
@@ -31,21 +31,27 @@ use bitcoin::{secp256k1, Witness};
 use bitcoin::blockdata::script::Script;
 use bitcoin::hash_types::{Txid, BlockHash};
 
+use crate::blinded_path::payment::ReceiveTlvs;
+use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
 use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
 use crate::ln::onion_utils;
 use crate::onion_message;
+use crate::sign::{NodeSigner, Recipient};
 
 use crate::prelude::*;
+use core::convert::TryFrom;
 use core::fmt;
 use core::fmt::Debug;
-use crate::io::{self, Read};
+use core::ops::Deref;
+use core::str::FromStr;
+use crate::io::{self, Cursor, Read};
 use crate::io_extras::read_to_end;
 
 use crate::events::{MessageSendEventsProvider, OnionMessageProvider};
+use crate::util::chacha20poly1305rfc::ChaChaPolyReadAdapter;
 use crate::util::logger;
-use crate::util::ser::{LengthReadable, Readable, ReadableArgs, Writeable, Writer, WithoutLength, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname, TransactionU16LenLimited};
-
-use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
+use crate::util::ser::{LengthReadable, LengthReadableArgs, Readable, ReadableArgs, Writeable, Writer, WithoutLength, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname, TransactionU16LenLimited, BigSize};
+use crate::util::base32;
 
 use crate::routing::gossip::{NodeAlias, NodeId};
 
@@ -99,7 +105,7 @@ pub struct 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 [`NodeAnnouncement`] update message containing
        /// the new address.
-       pub remote_network_address: Option<NetAddress>,
+       pub remote_network_address: Option<SocketAddress>,
 }
 
 /// An [`error`] message to be sent to or received from a peer.
@@ -111,7 +117,7 @@ pub struct ErrorMessage {
        ///
        /// All-0s indicates a general error unrelated to a specific channel, after which all channels
        /// with the sending peer should be closed.
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// A possibly human-readable error description.
        ///
        /// The string should be sanitized before it is used (e.g., emitted to logs or printed to
@@ -128,7 +134,7 @@ pub struct WarningMessage {
        /// The channel ID involved in the warning.
        ///
        /// All-0s indicates a warning unrelated to a specific channel.
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// A possibly human-readable warning description.
        ///
        /// The string should be sanitized before it is used (e.g. emitted to logs or printed to
@@ -171,7 +177,7 @@ pub struct OpenChannel {
        /// The genesis hash of the blockchain where the channel is to be opened
        pub chain_hash: BlockHash,
        /// A temporary channel ID, until the funding outpoint is announced
-       pub temporary_channel_id: [u8; 32],
+       pub temporary_channel_id: ChannelId,
        /// The channel value
        pub funding_satoshis: u64,
        /// The amount to push to the counterparty as part of the open, in milli-satoshi
@@ -225,7 +231,7 @@ pub struct OpenChannelV2 {
        /// The genesis hash of the blockchain where the channel is to be opened
        pub chain_hash: BlockHash,
        /// A temporary channel ID derived using a zeroed out value for the channel acceptor's revocation basepoint
-       pub temporary_channel_id: [u8; 32],
+       pub temporary_channel_id: ChannelId,
        /// The feerate for the funding transaction set by the channel initiator
        pub funding_feerate_sat_per_1000_weight: u32,
        /// The feerate for the commitment transaction set by the channel initiator
@@ -282,7 +288,7 @@ pub struct OpenChannelV2 {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct AcceptChannel {
        /// A temporary channel ID, until the funding outpoint is announced
-       pub temporary_channel_id: [u8; 32],
+       pub temporary_channel_id: ChannelId,
        /// The threshold below which outputs on transactions broadcast by sender will be omitted
        pub dust_limit_satoshis: u64,
        /// The maximum inbound HTLC value in flight towards sender, in milli-satoshi
@@ -330,7 +336,7 @@ pub struct AcceptChannel {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct AcceptChannelV2 {
        /// The same `temporary_channel_id` received from the initiator's `open_channel2` message.
-       pub temporary_channel_id: [u8; 32],
+       pub temporary_channel_id: ChannelId,
        /// Part of the channel value contributed by the channel acceptor
        pub funding_satoshis: u64,
        /// The threshold below which outputs on transactions broadcast by the channel acceptor will be
@@ -383,7 +389,7 @@ pub struct AcceptChannelV2 {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct FundingCreated {
        /// A temporary channel ID, until the funding is established
-       pub temporary_channel_id: [u8; 32],
+       pub temporary_channel_id: ChannelId,
        /// The funding transaction ID
        pub funding_txid: Txid,
        /// The specific output index funding this channel
@@ -406,7 +412,7 @@ pub struct FundingCreated {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct FundingSigned {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The signature of the channel acceptor (fundee) on the initial commitment transaction
        pub signature: Signature,
        #[cfg(taproot)]
@@ -420,7 +426,7 @@ pub struct FundingSigned {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelReady {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// 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.
@@ -436,7 +442,7 @@ pub struct ChannelReady {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxAddInput {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// A randomly chosen unique identifier for this input, which is even for initiators and odd for
        /// non-initiators.
        pub serial_id: u64,
@@ -455,7 +461,7 @@ pub struct TxAddInput {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxAddOutput {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// A randomly chosen unique identifier for this output, which is even for initiators and odd for
        /// non-initiators.
        pub serial_id: u64,
@@ -471,7 +477,7 @@ pub struct TxAddOutput {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxRemoveInput {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The serial ID of the input to be removed
        pub serial_id: u64,
 }
@@ -482,7 +488,7 @@ pub struct TxRemoveInput {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxRemoveOutput {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The serial ID of the output to be removed
        pub serial_id: u64,
 }
@@ -494,7 +500,7 @@ pub struct TxRemoveOutput {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxComplete {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
 }
 
 /// A tx_signatures message containing the sender's signatures for a transaction constructed with
@@ -504,7 +510,7 @@ pub struct TxComplete {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxSignatures {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The TXID
        pub tx_hash: Txid,
        /// The list of witnesses
@@ -518,7 +524,7 @@ pub struct TxSignatures {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxInitRbf {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The locktime of the transaction
        pub locktime: u32,
        /// The feerate of the transaction
@@ -535,7 +541,7 @@ pub struct TxInitRbf {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxAckRbf {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The number of satoshis the sender will contribute to or, if negative, remove from
        /// (e.g. splice-out) the funding output of the transaction
        pub funding_output_contribution: Option<i64>,
@@ -547,7 +553,7 @@ pub struct TxAckRbf {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct TxAbort {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// Message data
        pub data: Vec<u8>,
 }
@@ -558,7 +564,7 @@ pub struct TxAbort {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Shutdown {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The destination of this peer's funds on closing.
        ///
        /// Must be in one of these forms: P2PKH, P2SH, P2WPKH, P2WSH, P2TR.
@@ -585,7 +591,7 @@ pub struct ClosingSignedFeeRange {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ClosingSigned {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The proposed total fee for the closing transaction
        pub fee_satoshis: u64,
        /// A signature on the closing transaction
@@ -601,7 +607,7 @@ pub struct ClosingSigned {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateAddHTLC {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The HTLC ID
        pub htlc_id: u64,
        /// The HTLC value in milli-satoshi
@@ -634,7 +640,7 @@ pub struct OnionMessage {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFulfillHTLC {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The HTLC ID
        pub htlc_id: u64,
        /// The pre-image of the payment hash, allowing HTLC redemption
@@ -647,7 +653,7 @@ pub struct UpdateFulfillHTLC {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFailHTLC {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The HTLC ID
        pub htlc_id: u64,
        pub(crate) reason: OnionErrorPacket,
@@ -659,7 +665,7 @@ pub struct UpdateFailHTLC {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFailMalformedHTLC {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The HTLC ID
        pub htlc_id: u64,
        pub(crate) sha256_of_onion: [u8; 32],
@@ -673,7 +679,7 @@ pub struct UpdateFailMalformedHTLC {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct CommitmentSigned {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// A signature on the commitment transaction
        pub signature: Signature,
        /// Signatures on the HTLC transactions
@@ -689,7 +695,7 @@ pub struct CommitmentSigned {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct RevokeAndACK {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The secret corresponding to the per-commitment point
        pub per_commitment_secret: [u8; 32],
        /// The next sender-broadcast commitment transaction's per-commitment point
@@ -705,7 +711,7 @@ pub struct RevokeAndACK {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct UpdateFee {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// Fee rate per 1000-weight of the transaction
        pub feerate_per_kw: u32,
 }
@@ -716,7 +722,7 @@ pub struct UpdateFee {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct ChannelReestablish {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The next commitment number for the sender
        pub next_local_commitment_number: u64,
        /// The next commitment number for the recipient
@@ -736,7 +742,7 @@ pub struct ChannelReestablish {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct AnnouncementSignatures {
        /// The channel ID
-       pub channel_id: [u8; 32],
+       pub channel_id: ChannelId,
        /// The short channel ID
        pub short_channel_id: u64,
        /// A signature by the node key
@@ -747,16 +753,16 @@ pub struct AnnouncementSignatures {
 
 /// An address which can be used to connect to a remote peer.
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub enum NetAddress {
-       /// An IPv4 address/port on which the peer is listening.
-       IPv4 {
+pub enum SocketAddress {
+       /// An IPv4 address and port on which the peer is listening.
+       TcpIpV4 {
                /// The 4-byte IPv4 address
                addr: [u8; 4],
                /// The port on which the node is listening
                port: u16,
        },
-       /// An IPv6 address/port on which the peer is listening.
-       IPv6 {
+       /// An IPv6 address and port on which the peer is listening.
+       TcpIpV6 {
                /// The 16-byte IPv6 address
                addr: [u8; 16],
                /// The port on which the node is listening
@@ -789,28 +795,28 @@ pub enum NetAddress {
                port: u16,
        },
 }
-impl NetAddress {
+impl SocketAddress {
        /// Gets the ID of this address type. Addresses in [`NodeAnnouncement`] messages should be sorted
        /// by this.
        pub(crate) fn get_id(&self) -> u8 {
                match self {
-                       &NetAddress::IPv4 {..} => { 1 },
-                       &NetAddress::IPv6 {..} => { 2 },
-                       &NetAddress::OnionV2(_) => { 3 },
-                       &NetAddress::OnionV3 {..} => { 4 },
-                       &NetAddress::Hostname {..} => { 5 },
+                       &SocketAddress::TcpIpV4 {..} => { 1 },
+                       &SocketAddress::TcpIpV6 {..} => { 2 },
+                       &SocketAddress::OnionV2(_) => { 3 },
+                       &SocketAddress::OnionV3 {..} => { 4 },
+                       &SocketAddress::Hostname {..} => { 5 },
                }
        }
 
        /// Strict byte-length of address descriptor, 1-byte type not recorded
        fn len(&self) -> u16 {
                match self {
-                       &NetAddress::IPv4 { .. } => { 6 },
-                       &NetAddress::IPv6 { .. } => { 18 },
-                       &NetAddress::OnionV2(_) => { 12 },
-                       &NetAddress::OnionV3 { .. } => { 37 },
+                       &SocketAddress::TcpIpV4 { .. } => { 6 },
+                       &SocketAddress::TcpIpV6 { .. } => { 18 },
+                       &SocketAddress::OnionV2(_) => { 12 },
+                       &SocketAddress::OnionV3 { .. } => { 37 },
                        // Consists of 1-byte hostname length, hostname bytes, and 2-byte port.
-                       &NetAddress::Hostname { ref hostname, .. } => { u16::from(hostname.len()) + 3 },
+                       &SocketAddress::Hostname { ref hostname, .. } => { u16::from(hostname.len()) + 3 },
                }
        }
 
@@ -820,31 +826,31 @@ impl NetAddress {
        pub(crate) const MAX_LEN: u16 = 258;
 }
 
-impl Writeable for NetAddress {
+impl Writeable for SocketAddress {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                match self {
-                       &NetAddress::IPv4 { ref addr, ref port } => {
+                       &SocketAddress::TcpIpV4 { ref addr, ref port } => {
                                1u8.write(writer)?;
                                addr.write(writer)?;
                                port.write(writer)?;
                        },
-                       &NetAddress::IPv6 { ref addr, ref port } => {
+                       &SocketAddress::TcpIpV6 { ref addr, ref port } => {
                                2u8.write(writer)?;
                                addr.write(writer)?;
                                port.write(writer)?;
                        },
-                       &NetAddress::OnionV2(bytes) => {
+                       &SocketAddress::OnionV2(bytes) => {
                                3u8.write(writer)?;
                                bytes.write(writer)?;
                        },
-                       &NetAddress::OnionV3 { ref ed25519_pubkey, ref checksum, ref version, ref port } => {
+                       &SocketAddress::OnionV3 { ref ed25519_pubkey, ref checksum, ref version, ref port } => {
                                4u8.write(writer)?;
                                ed25519_pubkey.write(writer)?;
                                checksum.write(writer)?;
                                version.write(writer)?;
                                port.write(writer)?;
                        },
-                       &NetAddress::Hostname { ref hostname, ref port } => {
+                       &SocketAddress::Hostname { ref hostname, ref port } => {
                                5u8.write(writer)?;
                                hostname.write(writer)?;
                                port.write(writer)?;
@@ -854,25 +860,25 @@ impl Writeable for NetAddress {
        }
 }
 
-impl Readable for Result<NetAddress, u8> {
-       fn read<R: Read>(reader: &mut R) -> Result<Result<NetAddress, u8>, DecodeError> {
+impl Readable for Result<SocketAddress, u8> {
+       fn read<R: Read>(reader: &mut R) -> Result<Result<SocketAddress, u8>, DecodeError> {
                let byte = <u8 as Readable>::read(reader)?;
                match byte {
                        1 => {
-                               Ok(Ok(NetAddress::IPv4 {
+                               Ok(Ok(SocketAddress::TcpIpV4 {
                                        addr: Readable::read(reader)?,
                                        port: Readable::read(reader)?,
                                }))
                        },
                        2 => {
-                               Ok(Ok(NetAddress::IPv6 {
+                               Ok(Ok(SocketAddress::TcpIpV6 {
                                        addr: Readable::read(reader)?,
                                        port: Readable::read(reader)?,
                                }))
                        },
-                       3 => Ok(Ok(NetAddress::OnionV2(Readable::read(reader)?))),
+                       3 => Ok(Ok(SocketAddress::OnionV2(Readable::read(reader)?))),
                        4 => {
-                               Ok(Ok(NetAddress::OnionV3 {
+                               Ok(Ok(SocketAddress::OnionV3 {
                                        ed25519_pubkey: Readable::read(reader)?,
                                        checksum: Readable::read(reader)?,
                                        version: Readable::read(reader)?,
@@ -880,7 +886,7 @@ impl Readable for Result<NetAddress, u8> {
                                }))
                        },
                        5 => {
-                               Ok(Ok(NetAddress::Hostname {
+                               Ok(Ok(SocketAddress::Hostname {
                                        hostname: Readable::read(reader)?,
                                        port: Readable::read(reader)?,
                                }))
@@ -890,8 +896,8 @@ impl Readable for Result<NetAddress, u8> {
        }
 }
 
-impl Readable for NetAddress {
-       fn read<R: Read>(reader: &mut R) -> Result<NetAddress, DecodeError> {
+impl Readable for SocketAddress {
+       fn read<R: Read>(reader: &mut R) -> Result<SocketAddress, DecodeError> {
                match Readable::read(reader) {
                        Ok(Ok(res)) => Ok(res),
                        Ok(Err(_)) => Err(DecodeError::UnknownVersion),
@@ -900,6 +906,104 @@ impl Readable for NetAddress {
        }
 }
 
+/// [`SocketAddress`] error variants
+#[derive(Debug, Eq, PartialEq, Clone)]
+pub enum SocketAddressParseError {
+       /// Socket address (IPv4/IPv6) parsing error
+       SocketAddrParse,
+       /// Invalid input format
+       InvalidInput,
+       /// Invalid port
+       InvalidPort,
+       /// Invalid onion v3 address
+       InvalidOnionV3,
+}
+
+impl fmt::Display for SocketAddressParseError {
+       fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+               match self {
+                       SocketAddressParseError::SocketAddrParse => write!(f, "Socket address (IPv4/IPv6) parsing error"),
+                       SocketAddressParseError::InvalidInput => write!(f, "Invalid input format. \
+                               Expected: \"<ipv4>:<port>\", \"[<ipv6>]:<port>\", \"<onion address>.onion:<port>\" or \"<hostname>:<port>\""),
+                       SocketAddressParseError::InvalidPort => write!(f, "Invalid port"),
+                       SocketAddressParseError::InvalidOnionV3 => write!(f, "Invalid onion v3 address"),
+               }
+       }
+}
+
+#[cfg(feature = "std")]
+impl From<std::net::SocketAddrV4> for SocketAddress {
+               fn from(addr: std::net::SocketAddrV4) -> Self {
+                       SocketAddress::TcpIpV4 { addr: addr.ip().octets(), port: addr.port() }
+               }
+}
+
+#[cfg(feature = "std")]
+impl From<std::net::SocketAddrV6> for SocketAddress {
+               fn from(addr: std::net::SocketAddrV6) -> Self {
+                       SocketAddress::TcpIpV6 { addr: addr.ip().octets(), port: addr.port() }
+               }
+}
+
+#[cfg(feature = "std")]
+impl From<std::net::SocketAddr> for SocketAddress {
+               fn from(addr: std::net::SocketAddr) -> Self {
+                       match addr {
+                               std::net::SocketAddr::V4(addr) => addr.into(),
+                               std::net::SocketAddr::V6(addr) => addr.into(),
+                       }
+               }
+}
+
+fn parse_onion_address(host: &str, port: u16) -> Result<SocketAddress, SocketAddressParseError> {
+       if host.ends_with(".onion") {
+               let domain = &host[..host.len() - ".onion".len()];
+               if domain.len() != 56 {
+                       return Err(SocketAddressParseError::InvalidOnionV3);
+               }
+               let onion =  base32::Alphabet::RFC4648 { padding: false }.decode(&domain).map_err(|_| SocketAddressParseError::InvalidOnionV3)?;
+               if onion.len() != 35 {
+                       return Err(SocketAddressParseError::InvalidOnionV3);
+               }
+               let version = onion[0];
+               let first_checksum_flag = onion[1];
+               let second_checksum_flag = onion[2];
+               let mut ed25519_pubkey = [0; 32];
+               ed25519_pubkey.copy_from_slice(&onion[3..35]);
+               let checksum = u16::from_be_bytes([first_checksum_flag, second_checksum_flag]);
+               return Ok(SocketAddress::OnionV3 { ed25519_pubkey, checksum, version, port });
+
+       } else {
+               return Err(SocketAddressParseError::InvalidInput);
+       }
+}
+
+#[cfg(feature = "std")]
+impl FromStr for SocketAddress {
+       type Err = SocketAddressParseError;
+
+       fn from_str(s: &str) -> Result<Self, Self::Err> {
+               match std::net::SocketAddr::from_str(s) {
+                       Ok(addr) => Ok(addr.into()),
+                       Err(_) => {
+                               let trimmed_input = match s.rfind(":") {
+                                       Some(pos) => pos,
+                                       None => return Err(SocketAddressParseError::InvalidInput),
+                               };
+                               let host = &s[..trimmed_input];
+                               let port: u16 = s[trimmed_input + 1..].parse().map_err(|_| SocketAddressParseError::InvalidPort)?;
+                               if host.ends_with(".onion") {
+                                       return parse_onion_address(host, port);
+                               };
+                               if let Ok(hostname) = Hostname::try_from(s[..trimmed_input].to_string()) {
+                                       return Ok(SocketAddress::Hostname { hostname, port });
+                               };
+                               return Err(SocketAddressParseError::SocketAddrParse)
+                       },
+               }
+       }
+}
+
 /// Represents the set of gossip messages that require a signature from a node's identity key.
 pub enum UnsignedGossipMessage<'a> {
        /// An unsigned channel announcement.
@@ -939,7 +1043,7 @@ pub struct UnsignedNodeAnnouncement {
        /// This should be sanitized before use. There is no guarantee of uniqueness.
        pub alias: NodeAlias,
        /// List of addresses on which this node is reachable
-       pub addresses: Vec<NetAddress>,
+       pub addresses: Vec<SocketAddress>,
        pub(crate) excess_address_data: Vec<u8>,
        pub(crate) excess_data: Vec<u8>,
 }
@@ -973,7 +1077,11 @@ pub struct UnsignedChannelAnnouncement {
        pub bitcoin_key_1: NodeId,
        /// The funding key for the second node
        pub bitcoin_key_2: NodeId,
-       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 protocol.
+       pub excess_data: Vec<u8>,
 }
 /// A [`channel_announcement`] message to be sent to or received from a peer.
 ///
@@ -1140,7 +1248,7 @@ enum EncodingType {
 }
 
 /// Used to put an error message in a [`LightningError`].
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, PartialEq)]
 pub enum ErrorAction {
        /// The peer took some action which made us think they were useless. Disconnect them.
        DisconnectPeer {
@@ -1226,7 +1334,7 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider {
        /// Handle an incoming `channel_ready` message from the given peer.
        fn handle_channel_ready(&self, their_node_id: &PublicKey, msg: &ChannelReady);
 
-       // Channl close:
+       // Channel close:
        /// Handle an incoming `shutdown` message from the given peer.
        fn handle_shutdown(&self, their_node_id: &PublicKey, msg: &Shutdown);
        /// Handle an incoming `closing_signed` message from the given peer.
@@ -1413,6 +1521,8 @@ pub trait OnionMessageHandler : OnionMessageProvider {
 }
 
 mod fuzzy_internal_msgs {
+       use bitcoin::secp256k1::PublicKey;
+       use crate::blinded_path::payment::PaymentConstraints;
        use crate::prelude::*;
        use crate::ln::{PaymentPreimage, PaymentSecret};
 
@@ -1437,9 +1547,18 @@ mod fuzzy_internal_msgs {
                        payment_data: Option<FinalOnionHopData>,
                        payment_metadata: Option<Vec<u8>>,
                        keysend_preimage: Option<PaymentPreimage>,
+                       custom_tlvs: Vec<(u64, Vec<u8>)>,
                        amt_msat: u64,
                        outgoing_cltv_value: u32,
                },
+               BlindedReceive {
+                       amt_msat: u64,
+                       total_msat: u64,
+                       outgoing_cltv_value: u32,
+                       payment_secret: PaymentSecret,
+                       payment_constraints: PaymentConstraints,
+                       intro_node_blinding_point: PublicKey,
+               }
        }
 
        pub(crate) enum OutboundOnionPayload {
@@ -1453,9 +1572,21 @@ mod fuzzy_internal_msgs {
                        payment_data: Option<FinalOnionHopData>,
                        payment_metadata: Option<Vec<u8>>,
                        keysend_preimage: Option<PaymentPreimage>,
+                       custom_tlvs: Vec<(u64, Vec<u8>)>,
                        amt_msat: u64,
                        outgoing_cltv_value: u32,
                },
+               BlindedForward {
+                       encrypted_tlvs: Vec<u8>,
+                       intro_node_blinding_point: Option<PublicKey>,
+               },
+               BlindedReceive {
+                       amt_msat: u64,
+                       total_msat: u64,
+                       outgoing_cltv_value: u32,
+                       encrypted_tlvs: Vec<u8>,
+                       intro_node_blinding_point: Option<PublicKey>, // Set if the introduction node of the blinded path is the final node
+               }
        }
 
        pub struct DecodedOnionErrorPacket {
@@ -1768,7 +1899,7 @@ 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;
+               let mut remote_network_address: Option<SocketAddress> = None;
                let mut networks: Option<WithoutLength<Vec<ChainHash>>> = None;
                decode_tlv_stream!(r, {
                        (1, networks, option),
@@ -1975,14 +2106,38 @@ impl Writeable for OutboundOnionPayload {
                                });
                        },
                        Self::Receive {
-                               ref payment_data, ref payment_metadata, ref keysend_preimage, amt_msat, outgoing_cltv_value
+                               ref payment_data, ref payment_metadata, ref keysend_preimage, amt_msat,
+                               outgoing_cltv_value, ref custom_tlvs,
                        } => {
+                               // We need to update [`ln::outbound_payment::RecipientOnionFields::with_custom_tlvs`]
+                               // to reject any reserved types in the experimental range if new ones are ever
+                               // standardized.
+                               let keysend_tlv = keysend_preimage.map(|preimage| (5482373484, preimage.encode()));
+                               let mut custom_tlvs: Vec<&(u64, Vec<u8>)> = custom_tlvs.iter().chain(keysend_tlv.iter()).collect();
+                               custom_tlvs.sort_unstable_by_key(|(typ, _)| *typ);
                                _encode_varint_length_prefixed_tlv!(w, {
                                        (2, HighZeroBytesDroppedBigSize(*amt_msat), required),
                                        (4, HighZeroBytesDroppedBigSize(*outgoing_cltv_value), required),
                                        (8, payment_data, option),
-                                       (16, payment_metadata.as_ref().map(|m| WithoutLength(m)), option),
-                                       (5482373484, keysend_preimage, option)
+                                       (16, payment_metadata.as_ref().map(|m| WithoutLength(m)), option)
+                               }, custom_tlvs.iter());
+                       },
+                       Self::BlindedForward { encrypted_tlvs, intro_node_blinding_point } => {
+                               _encode_varint_length_prefixed_tlv!(w, {
+                                       (10, *encrypted_tlvs, required_vec),
+                                       (12, intro_node_blinding_point, option)
+                               });
+                       },
+                       Self::BlindedReceive {
+                               amt_msat, total_msat, outgoing_cltv_value, encrypted_tlvs,
+                               intro_node_blinding_point,
+                       } => {
+                               _encode_varint_length_prefixed_tlv!(w, {
+                                       (2, HighZeroBytesDroppedBigSize(*amt_msat), required),
+                                       (4, HighZeroBytesDroppedBigSize(*outgoing_cltv_value), required),
+                                       (10, *encrypted_tlvs, required_vec),
+                                       (12, intro_node_blinding_point, option),
+                                       (18, HighZeroBytesDroppedBigSize(*total_msat), required)
                                });
                        },
                }
@@ -1990,34 +2145,78 @@ impl Writeable for OutboundOnionPayload {
        }
 }
 
-impl Readable for InboundOnionPayload {
-       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let mut amt = HighZeroBytesDroppedBigSize(0u64);
-               let mut cltv_value = HighZeroBytesDroppedBigSize(0u32);
+impl<NS: Deref> ReadableArgs<&NS> for InboundOnionPayload where NS::Target: NodeSigner {
+       fn read<R: Read>(r: &mut R, node_signer: &NS) -> Result<Self, DecodeError> {
+               let mut amt = None;
+               let mut cltv_value = None;
                let mut short_id: Option<u64> = None;
                let mut payment_data: Option<FinalOnionHopData> = None;
+               let mut encrypted_tlvs_opt: Option<WithoutLength<Vec<u8>>> = None;
+               let mut intro_node_blinding_point = None;
                let mut payment_metadata: Option<WithoutLength<Vec<u8>>> = None;
+               let mut total_msat = None;
                let mut keysend_preimage: Option<PaymentPreimage> = None;
-               read_tlv_fields!(r, {
-                       (2, amt, required),
-                       (4, cltv_value, required),
+               let mut custom_tlvs = Vec::new();
+
+               let tlv_len = BigSize::read(r)?;
+               let rd = FixedLengthReader::new(r, tlv_len.0);
+               decode_tlv_stream_with_custom_tlv_decode!(rd, {
+                       (2, amt, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
+                       (4, cltv_value, (option, encoding: (u32, HighZeroBytesDroppedBigSize))),
                        (6, short_id, option),
                        (8, payment_data, option),
+                       (10, encrypted_tlvs_opt, option),
+                       (12, intro_node_blinding_point, option),
                        (16, payment_metadata, option),
+                       (18, total_msat, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
                        // See https://github.com/lightning/blips/blob/master/blip-0003.md
                        (5482373484, keysend_preimage, option)
+               }, |msg_type: u64, msg_reader: &mut FixedLengthReader<_>| -> Result<bool, DecodeError> {
+                       if msg_type < 1 << 16 { return Ok(false) }
+                       let mut value = Vec::new();
+                       msg_reader.read_to_end(&mut value)?;
+                       custom_tlvs.push((msg_type, value));
+                       Ok(true)
                });
 
-               if amt.0 > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
-               if let Some(short_channel_id) = short_id {
-                       if payment_data.is_some() { return Err(DecodeError::InvalidValue) }
-                       if payment_metadata.is_some() { return Err(DecodeError::InvalidValue); }
+               if amt.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
+
+               if let Some(blinding_point) = intro_node_blinding_point {
+                       if short_id.is_some() || payment_data.is_some() || payment_metadata.is_some() {
+                               return Err(DecodeError::InvalidValue)
+                       }
+                       let enc_tlvs = encrypted_tlvs_opt.ok_or(DecodeError::InvalidValue)?.0;
+                       let enc_tlvs_ss = node_signer.ecdh(Recipient::Node, &blinding_point, None)
+                               .map_err(|_| DecodeError::InvalidValue)?;
+                       let rho = onion_utils::gen_rho_from_shared_secret(&enc_tlvs_ss.secret_bytes());
+                       let mut s = Cursor::new(&enc_tlvs);
+                       let mut reader = FixedLengthReader::new(&mut s, enc_tlvs.len() as u64);
+                       match ChaChaPolyReadAdapter::read(&mut reader, rho)? {
+                               ChaChaPolyReadAdapter { readable: ReceiveTlvs { payment_secret, payment_constraints }} => {
+                                       if total_msat.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
+                                       Ok(Self::BlindedReceive {
+                                               amt_msat: amt.ok_or(DecodeError::InvalidValue)?,
+                                               total_msat: total_msat.ok_or(DecodeError::InvalidValue)?,
+                                               outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?,
+                                               payment_secret,
+                                               payment_constraints,
+                                               intro_node_blinding_point: blinding_point,
+                                       })
+                               },
+                       }
+               } else if let Some(short_channel_id) = short_id {
+                       if payment_data.is_some() || payment_metadata.is_some() || encrypted_tlvs_opt.is_some() ||
+                               total_msat.is_some()
+                       { return Err(DecodeError::InvalidValue) }
                        Ok(Self::Forward {
                                short_channel_id,
-                               amt_to_forward: amt.0,
-                               outgoing_cltv_value: cltv_value.0,
+                               amt_to_forward: amt.ok_or(DecodeError::InvalidValue)?,
+                               outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?,
                        })
                } else {
+                       if encrypted_tlvs_opt.is_some() || total_msat.is_some() {
+                               return Err(DecodeError::InvalidValue)
+                       }
                        if let Some(data) = &payment_data {
                                if data.total_msat > MAX_VALUE_MSAT {
                                        return Err(DecodeError::InvalidValue);
@@ -2027,21 +2226,14 @@ impl Readable for InboundOnionPayload {
                                payment_data,
                                payment_metadata: payment_metadata.map(|w| w.0),
                                keysend_preimage,
-                               amt_msat: amt.0,
-                               outgoing_cltv_value: cltv_value.0,
+                               amt_msat: amt.ok_or(DecodeError::InvalidValue)?,
+                               outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?,
+                               custom_tlvs,
                        })
                }
        }
 }
 
-// ReadableArgs because we need onion_utils::decode_next_hop to accommodate payment packets and
-// onion message packets.
-impl ReadableArgs<()> for InboundOnionPayload {
-       fn read<R: Read>(r: &mut R, _arg: ()) -> Result<Self, DecodeError> {
-               <Self as Readable>::read(r)
-       }
-}
-
 impl Writeable for Ping {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                self.ponglen.write(w)?;
@@ -2250,7 +2442,7 @@ impl Readable for UnsignedNodeAnnouncement {
                let alias: NodeAlias = Readable::read(r)?;
 
                let addr_len: u16 = Readable::read(r)?;
-               let mut addresses: Vec<NetAddress> = Vec::new();
+               let mut addresses: Vec<SocketAddress> = Vec::new();
                let mut addr_readpos = 0;
                let mut excess = false;
                let mut excess_byte = 0;
@@ -2449,14 +2641,18 @@ impl_writeable_msg!(GossipTimestampFilter, {
 
 #[cfg(test)]
 mod tests {
+       use std::convert::TryFrom;
        use bitcoin::blockdata::constants::ChainHash;
        use bitcoin::{Transaction, PackedLockTime, TxIn, Script, Sequence, Witness, TxOut};
        use hex;
        use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
+       use crate::ln::ChannelId;
        use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
        use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket};
+       use crate::ln::msgs::SocketAddress;
        use crate::routing::gossip::{NodeAlias, NodeId};
-       use crate::util::ser::{Writeable, Readable, Hostname, TransactionU16LenLimited};
+       use crate::util::ser::{Writeable, Readable, ReadableArgs, Hostname, TransactionU16LenLimited};
+       use crate::util::test_utils;
 
        use bitcoin::hashes::hex::FromHex;
        use bitcoin::util::address::Address;
@@ -2470,11 +2666,13 @@ mod tests {
 
        use crate::io::{self, Cursor};
        use crate::prelude::*;
-       use core::convert::TryFrom;
        use core::str::FromStr;
-
        use crate::chain::transaction::OutPoint;
 
+       #[cfg(feature = "std")]
+       use std::net::{Ipv4Addr, Ipv6Addr};
+       use crate::ln::msgs::SocketAddressParseError;
+
        #[test]
        fn encoding_channel_reestablish() {
                let public_key = {
@@ -2483,7 +2681,7 @@ mod tests {
                };
 
                let cr = msgs::ChannelReestablish {
-                       channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0],
+                       channel_id: ChannelId::from_bytes([4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0]),
                        next_local_commitment_number: 3,
                        next_remote_commitment_number: 4,
                        your_last_per_commitment_secret: [9;32],
@@ -2512,7 +2710,7 @@ mod tests {
                };
 
                let cr = msgs::ChannelReestablish {
-                       channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0],
+                       channel_id: ChannelId::from_bytes([4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0]),
                        next_local_commitment_number: 3,
                        next_remote_commitment_number: 4,
                        your_last_per_commitment_secret: [9;32],
@@ -2564,7 +2762,7 @@ mod tests {
                let sig_1 = get_sig_on!(privkey, secp_ctx, String::from("01010101010101010101010101010101"));
                let sig_2 = get_sig_on!(privkey, secp_ctx, String::from("02020202020202020202020202020202"));
                let announcement_signatures = msgs::AnnouncementSignatures {
-                       channel_id: [4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0],
+                       channel_id: ChannelId::from_bytes([4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0]),
                        short_channel_id: 2316138423780173,
                        node_signature: sig_1,
                        bitcoin_signature: sig_2,
@@ -2640,24 +2838,24 @@ mod tests {
                };
                let mut addresses = Vec::new();
                if ipv4 {
-                       addresses.push(msgs::NetAddress::IPv4 {
+                       addresses.push(SocketAddress::TcpIpV4 {
                                addr: [255, 254, 253, 252],
                                port: 9735
                        });
                }
                if ipv6 {
-                       addresses.push(msgs::NetAddress::IPv6 {
+                       addresses.push(SocketAddress::TcpIpV6 {
                                addr: [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240],
                                port: 9735
                        });
                }
                if onionv2 {
-                       addresses.push(msgs::NetAddress::OnionV2(
+                       addresses.push(msgs::SocketAddress::OnionV2(
                                [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 38, 7]
                        ));
                }
                if onionv3 {
-                       addresses.push(msgs::NetAddress::OnionV3 {
+                       addresses.push(msgs::SocketAddress::OnionV3 {
                                ed25519_pubkey: [255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224],
                                checksum: 32,
                                version: 16,
@@ -2665,7 +2863,7 @@ mod tests {
                        });
                }
                if hostname {
-                       addresses.push(msgs::NetAddress::Hostname {
+                       addresses.push(SocketAddress::Hostname {
                                hostname: Hostname::try_from(String::from("host")).unwrap(),
                                port: 9735,
                        });
@@ -2800,7 +2998,7 @@ mod tests {
                let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
                let open_channel = msgs::OpenChannel {
                        chain_hash: BlockHash::from_hex("6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000").unwrap(),
-                       temporary_channel_id: [2; 32],
+                       temporary_channel_id: ChannelId::from_bytes([2; 32]),
                        funding_satoshis: 1311768467284833366,
                        push_msat: 2536655962884945560,
                        dust_limit_satoshis: 3608586615801332854,
@@ -2861,7 +3059,7 @@ mod tests {
                let (_, pubkey_7) = get_keys_from!("0707070707070707070707070707070707070707070707070707070707070707", secp_ctx);
                let open_channelv2 = msgs::OpenChannelV2 {
                        chain_hash: BlockHash::from_hex("6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000").unwrap(),
-                       temporary_channel_id: [2; 32],
+                       temporary_channel_id: ChannelId::from_bytes([2; 32]),
                        funding_feerate_sat_per_1000_weight: 821716,
                        commitment_feerate_sat_per_1000_weight: 821716,
                        funding_satoshis: 1311768467284833366,
@@ -2951,7 +3149,7 @@ mod tests {
                let (_, pubkey_5) = get_keys_from!("0505050505050505050505050505050505050505050505050505050505050505", secp_ctx);
                let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
                let accept_channel = msgs::AcceptChannel {
-                       temporary_channel_id: [2; 32],
+                       temporary_channel_id: ChannelId::from_bytes([2; 32]),
                        dust_limit_satoshis: 1311768467284833366,
                        max_htlc_value_in_flight_msat: 2536655962884945560,
                        channel_reserve_satoshis: 3608586615801332854,
@@ -2994,7 +3192,7 @@ mod tests {
                let (_, pubkey_6) = get_keys_from!("0606060606060606060606060606060606060606060606060606060606060606", secp_ctx);
                let (_, pubkey_7) = get_keys_from!("0707070707070707070707070707070707070707070707070707070707070707", secp_ctx);
                let accept_channelv2 = msgs::AcceptChannelV2 {
-                       temporary_channel_id: [2; 32],
+                       temporary_channel_id: ChannelId::from_bytes([2; 32]),
                        funding_satoshis: 1311768467284833366,
                        dust_limit_satoshis: 1311768467284833366,
                        max_htlc_value_in_flight_msat: 2536655962884945560,
@@ -3048,7 +3246,7 @@ mod tests {
                let (privkey_1, _) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
                let sig_1 = get_sig_on!(privkey_1, secp_ctx, String::from("01010101010101010101010101010101"));
                let funding_created = msgs::FundingCreated {
-                       temporary_channel_id: [2; 32],
+                       temporary_channel_id: ChannelId::from_bytes([2; 32]),
                        funding_txid: Txid::from_hex("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap(),
                        funding_output_index: 255,
                        signature: sig_1,
@@ -3068,7 +3266,7 @@ mod tests {
                let (privkey_1, _) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
                let sig_1 = get_sig_on!(privkey_1, secp_ctx, String::from("01010101010101010101010101010101"));
                let funding_signed = msgs::FundingSigned {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        signature: sig_1,
                        #[cfg(taproot)]
                        partial_signature_with_nonce: None,
@@ -3083,7 +3281,7 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let (_, pubkey_1,) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
                let channel_ready = msgs::ChannelReady {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        next_per_commitment_point: pubkey_1,
                        short_channel_id_alias: None,
                };
@@ -3095,7 +3293,7 @@ mod tests {
        #[test]
        fn encoding_tx_add_input() {
                let tx_add_input = msgs::TxAddInput {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        serial_id: 4886718345,
                        prevtx: TransactionU16LenLimited::new(Transaction {
                                version: 2,
@@ -3130,7 +3328,7 @@ mod tests {
        #[test]
        fn encoding_tx_add_output() {
                let tx_add_output = msgs::TxAddOutput {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        serial_id: 4886718345,
                        sats: 4886718345,
                        script: Address::from_str("bc1qxmk834g5marzm227dgqvynd23y2nvt2ztwcw2z").unwrap().script_pubkey(),
@@ -3143,7 +3341,7 @@ mod tests {
        #[test]
        fn encoding_tx_remove_input() {
                let tx_remove_input = msgs::TxRemoveInput {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        serial_id: 4886718345,
                };
                let encoded_value = tx_remove_input.encode();
@@ -3154,7 +3352,7 @@ mod tests {
        #[test]
        fn encoding_tx_remove_output() {
                let tx_remove_output = msgs::TxRemoveOutput {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        serial_id: 4886718345,
                };
                let encoded_value = tx_remove_output.encode();
@@ -3165,7 +3363,7 @@ mod tests {
        #[test]
        fn encoding_tx_complete() {
                let tx_complete = msgs::TxComplete {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                };
                let encoded_value = tx_complete.encode();
                let target_value = hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap();
@@ -3175,7 +3373,7 @@ mod tests {
        #[test]
        fn encoding_tx_signatures() {
                let tx_signatures = msgs::TxSignatures {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        tx_hash: Txid::from_hex("c2d4449afa8d26140898dd54d3390b057ba2a5afcf03ba29d7dc0d8b9ffe966e").unwrap(),
                        witnesses: vec![
                                Witness::from_vec(vec![
@@ -3209,7 +3407,7 @@ mod tests {
 
        fn do_encoding_tx_init_rbf(funding_value_with_hex_target: Option<(i64, &str)>) {
                let tx_init_rbf = msgs::TxInitRbf {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        locktime: 305419896,
                        feerate_sat_per_1000_weight: 20190119,
                        funding_output_contribution: if let Some((value, _)) = funding_value_with_hex_target { Some(value) } else { None },
@@ -3235,7 +3433,7 @@ mod tests {
 
        fn do_encoding_tx_ack_rbf(funding_value_with_hex_target: Option<(i64, &str)>) {
                let tx_ack_rbf = msgs::TxAckRbf {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        funding_output_contribution: if let Some((value, _)) = funding_value_with_hex_target { Some(value) } else { None },
                };
                let encoded_value = tx_ack_rbf.encode();
@@ -3258,7 +3456,7 @@ mod tests {
        #[test]
        fn encoding_tx_abort() {
                let tx_abort = msgs::TxAbort {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        data: hex::decode("54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E").unwrap(),
                };
                let encoded_value = tx_abort.encode();
@@ -3271,12 +3469,12 @@ mod tests {
                let (_, pubkey_1) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
                let script = Builder::new().push_opcode(opcodes::OP_TRUE).into_script();
                let shutdown = msgs::Shutdown {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        scriptpubkey:
-                                    if script_type == 1 { Address::p2pkh(&::bitcoin::PublicKey{compressed: true, inner: pubkey_1}, Network::Testnet).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() },
+                               else { Address::p2wsh(&script, Network::Testnet).script_pubkey() },
                };
                let encoded_value = shutdown.encode();
                let mut target_value = hex::decode("0202020202020202020202020202020202020202020202020202020202020202").unwrap();
@@ -3306,7 +3504,7 @@ mod tests {
                let (privkey_1, _) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
                let sig_1 = get_sig_on!(privkey_1, secp_ctx, String::from("01010101010101010101010101010101"));
                let closing_signed = msgs::ClosingSigned {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        fee_satoshis: 2316138423780173,
                        signature: sig_1,
                        fee_range: None,
@@ -3317,7 +3515,7 @@ mod tests {
                assert_eq!(msgs::ClosingSigned::read(&mut Cursor::new(&target_value)).unwrap(), closing_signed);
 
                let closing_signed_with_range = msgs::ClosingSigned {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        fee_satoshis: 2316138423780173,
                        signature: sig_1,
                        fee_range: Some(msgs::ClosingSignedFeeRange {
@@ -3343,7 +3541,7 @@ mod tests {
                        hmac: [2; 32]
                };
                let update_add_htlc = msgs::UpdateAddHTLC {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        htlc_id: 2316138423780173,
                        amount_msat: 3608586615801332854,
                        payment_hash: PaymentHash([1; 32]),
@@ -3359,7 +3557,7 @@ mod tests {
        #[test]
        fn encoding_update_fulfill_htlc() {
                let update_fulfill_htlc = msgs::UpdateFulfillHTLC {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        htlc_id: 2316138423780173,
                        payment_preimage: PaymentPreimage([1; 32]),
                };
@@ -3374,7 +3572,7 @@ mod tests {
                        data: [1; 32].to_vec(),
                };
                let update_fail_htlc = msgs::UpdateFailHTLC {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        htlc_id: 2316138423780173,
                        reason
                };
@@ -3386,7 +3584,7 @@ mod tests {
        #[test]
        fn encoding_update_fail_malformed_htlc() {
                let update_fail_malformed_htlc = msgs::UpdateFailMalformedHTLC {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        htlc_id: 2316138423780173,
                        sha256_of_onion: [1; 32],
                        failure_code: 255
@@ -3407,7 +3605,7 @@ mod tests {
                let sig_3 = get_sig_on!(privkey_3, secp_ctx, String::from("01010101010101010101010101010101"));
                let sig_4 = get_sig_on!(privkey_4, secp_ctx, String::from("01010101010101010101010101010101"));
                let commitment_signed = msgs::CommitmentSigned {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        signature: sig_1,
                        htlc_signatures: if htlcs { vec![sig_2, sig_3, sig_4] } else { Vec::new() },
                        #[cfg(taproot)]
@@ -3434,7 +3632,7 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let (_, pubkey_1) = get_keys_from!("0101010101010101010101010101010101010101010101010101010101010101", secp_ctx);
                let raa = msgs::RevokeAndACK {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        per_commitment_secret: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                        next_per_commitment_point: pubkey_1,
                        #[cfg(taproot)]
@@ -3448,7 +3646,7 @@ mod tests {
        #[test]
        fn encoding_update_fee() {
                let update_fee = msgs::UpdateFee {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        feerate_per_kw: 20190119,
                };
                let encoded_value = update_fee.encode();
@@ -3481,7 +3679,7 @@ mod tests {
                }.encode(), hex::decode("00000000014001010101010101010101010101010101010101010101010101010101010101010202020202020202020202020202020202020202020202020202020202020202").unwrap());
                let init_msg = msgs::Init { features: InitFeatures::from_le_bytes(vec![]),
                        networks: Some(vec![mainnet_hash]),
-                       remote_network_address: Some(msgs::NetAddress::IPv4 {
+                       remote_network_address: Some(SocketAddress::TcpIpV4 {
                                addr: [127, 0, 0, 1],
                                port: 1000,
                        }),
@@ -3495,7 +3693,7 @@ mod tests {
        #[test]
        fn encoding_error() {
                let error = msgs::ErrorMessage {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        data: String::from("rust-lightning"),
                };
                let encoded_value = error.encode();
@@ -3506,7 +3704,7 @@ mod tests {
        #[test]
        fn encoding_warning() {
                let error = msgs::WarningMessage {
-                       channel_id: [2; 32],
+                       channel_id: ChannelId::from_bytes([2; 32]),
                        data: String::from("rust-lightning"),
                };
                let encoded_value = error.encode();
@@ -3546,8 +3744,11 @@ mod tests {
                let target_value = hex::decode("1a02080badf00d010203040404ffffffff0608deadbeef1bad1dea").unwrap();
                assert_eq!(encoded_value, target_value);
 
-               let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
-               if let msgs::InboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } = inbound_msg {
+               let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
+               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
+               if let msgs::InboundOnionPayload::Forward {
+                       short_channel_id, amt_to_forward, outgoing_cltv_value
+               } = inbound_msg {
                        assert_eq!(short_channel_id, 0xdeadbeef1bad1dea);
                        assert_eq!(amt_to_forward, 0x0badf00d01020304);
                        assert_eq!(outgoing_cltv_value, 0xffffffff);
@@ -3562,13 +3763,17 @@ mod tests {
                        keysend_preimage: None,
                        amt_msat: 0x0badf00d01020304,
                        outgoing_cltv_value: 0xffffffff,
+                       custom_tlvs: vec![],
                };
                let encoded_value = outbound_msg.encode();
                let target_value = hex::decode("1002080badf00d010203040404ffffffff").unwrap();
                assert_eq!(encoded_value, target_value);
 
-               let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
-               if let msgs::InboundOnionPayload::Receive { payment_data: None, amt_msat, outgoing_cltv_value, .. } = inbound_msg {
+               let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
+               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
+               if let msgs::InboundOnionPayload::Receive {
+                       payment_data: None, amt_msat, outgoing_cltv_value, ..
+               } = inbound_msg {
                        assert_eq!(amt_msat, 0x0badf00d01020304);
                        assert_eq!(outgoing_cltv_value, 0xffffffff);
                } else { panic!(); }
@@ -3586,12 +3791,14 @@ mod tests {
                        keysend_preimage: None,
                        amt_msat: 0x0badf00d01020304,
                        outgoing_cltv_value: 0xffffffff,
+                       custom_tlvs: vec![],
                };
                let encoded_value = outbound_msg.encode();
                let target_value = hex::decode("3602080badf00d010203040404ffffffff082442424242424242424242424242424242424242424242424242424242424242421badca1f").unwrap();
                assert_eq!(encoded_value, target_value);
 
-               let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
+               let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
+               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
                if let msgs::InboundOnionPayload::Receive {
                        payment_data: Some(FinalOnionHopData {
                                payment_secret,
@@ -3600,10 +3807,80 @@ mod tests {
                        amt_msat, outgoing_cltv_value,
                        payment_metadata: None,
                        keysend_preimage: None,
+                       custom_tlvs,
                } = inbound_msg  {
                        assert_eq!(payment_secret, expected_payment_secret);
                        assert_eq!(amt_msat, 0x0badf00d01020304);
                        assert_eq!(outgoing_cltv_value, 0xffffffff);
+                       assert_eq!(custom_tlvs, vec![]);
+               } else { panic!(); }
+       }
+
+       #[test]
+       fn encoding_final_onion_hop_data_with_bad_custom_tlvs() {
+               // If custom TLVs have type number within the range reserved for protocol, treat them as if
+               // they're unknown
+               let bad_type_range_tlvs = vec![
+                       ((1 << 16) - 4, vec![42]),
+                       ((1 << 16) - 2, vec![42; 32]),
+               ];
+               let mut msg = msgs::OutboundOnionPayload::Receive {
+                       payment_data: None,
+                       payment_metadata: None,
+                       keysend_preimage: None,
+                       custom_tlvs: bad_type_range_tlvs,
+                       amt_msat: 0x0badf00d01020304,
+                       outgoing_cltv_value: 0xffffffff,
+               };
+               let encoded_value = msg.encode();
+               let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
+               assert!(msgs::InboundOnionPayload::read(&mut Cursor::new(&encoded_value[..]), &&node_signer).is_err());
+               let good_type_range_tlvs = vec![
+                       ((1 << 16) - 3, vec![42]),
+                       ((1 << 16) - 1, vec![42; 32]),
+               ];
+               if let msgs::OutboundOnionPayload::Receive { ref mut custom_tlvs, .. } = msg {
+                       *custom_tlvs = good_type_range_tlvs.clone();
+               }
+               let encoded_value = msg.encode();
+               let inbound_msg = ReadableArgs::read(&mut Cursor::new(&encoded_value[..]), &&node_signer).unwrap();
+               match inbound_msg {
+                       msgs::InboundOnionPayload::Receive { custom_tlvs, .. } => assert!(custom_tlvs.is_empty()),
+                       _ => panic!(),
+               }
+       }
+
+       #[test]
+       fn encoding_final_onion_hop_data_with_custom_tlvs() {
+               let expected_custom_tlvs = vec![
+                       (5482373483, vec![0x12, 0x34]),
+                       (5482373487, vec![0x42u8; 8]),
+               ];
+               let msg = msgs::OutboundOnionPayload::Receive {
+                       payment_data: None,
+                       payment_metadata: None,
+                       keysend_preimage: None,
+                       custom_tlvs: expected_custom_tlvs.clone(),
+                       amt_msat: 0x0badf00d01020304,
+                       outgoing_cltv_value: 0xffffffff,
+               };
+               let encoded_value = msg.encode();
+               let target_value = hex::decode("2e02080badf00d010203040404ffffffffff0000000146c6616b021234ff0000000146c6616f084242424242424242").unwrap();
+               assert_eq!(encoded_value, target_value);
+               let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
+               let inbound_msg: msgs::InboundOnionPayload = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
+               if let msgs::InboundOnionPayload::Receive {
+                       payment_data: None,
+                       payment_metadata: None,
+                       keysend_preimage: None,
+                       custom_tlvs,
+                       amt_msat,
+                       outgoing_cltv_value,
+                       ..
+               } = inbound_msg {
+                       assert_eq!(custom_tlvs, expected_custom_tlvs);
+                       assert_eq!(amt_msat, 0x0badf00d01020304);
+                       assert_eq!(outgoing_cltv_value, 0xffffffff);
                } else { panic!(); }
        }
 
@@ -3754,7 +4031,10 @@ mod tests {
                // payload length to be encoded over multiple bytes rather than a single u8.
                let big_payload = encode_big_payload().unwrap();
                let mut rd = Cursor::new(&big_payload[..]);
-               <msgs::InboundOnionPayload as Readable>::read(&mut rd).unwrap();
+
+               let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
+               <msgs::InboundOnionPayload as ReadableArgs<&&test_utils::TestKeysInterface>>
+                       ::read(&mut rd, &&node_signer).unwrap();
        }
        // see above test, needs to be a separate method for use of the serialization macros.
        fn encode_big_payload() -> Result<Vec<u8>, io::Error> {
@@ -3776,4 +4056,47 @@ mod tests {
                }
                Ok(encoded_payload)
        }
+
+       #[test]
+       #[cfg(feature = "std")]
+       fn test_socket_address_from_str() {
+               assert_eq!(SocketAddress::TcpIpV4 {
+                       addr: Ipv4Addr::new(127, 0, 0, 1).octets(),
+                       port: 1234,
+               }, SocketAddress::from_str("127.0.0.1:1234").unwrap());
+
+               assert_eq!(SocketAddress::TcpIpV6 {
+                       addr: Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).octets(),
+                       port: 1234,
+               }, SocketAddress::from_str("[0:0:0:0:0:0:0:1]:1234").unwrap());
+               assert_eq!(
+                       SocketAddress::Hostname {
+                               hostname: Hostname::try_from("lightning-node.mydomain.com".to_string()).unwrap(),
+                               port: 1234,
+                       }, SocketAddress::from_str("lightning-node.mydomain.com:1234").unwrap());
+               assert_eq!(
+                       SocketAddress::Hostname {
+                               hostname: Hostname::try_from("example.com".to_string()).unwrap(),
+                               port: 1234,
+                       }, SocketAddress::from_str("example.com:1234").unwrap());
+               assert_eq!(SocketAddress::OnionV3 {
+                       ed25519_pubkey: [37, 24, 75, 5, 25, 73, 117, 194, 139, 102, 182, 107, 4, 105, 247, 246, 85,
+                       111, 177, 172, 49, 137, 167, 155, 64, 221, 163, 47, 31, 33, 71, 3],
+                       checksum: 48326,
+                       version: 121,
+                       port: 1234
+               }, SocketAddress::from_str("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion:1234").unwrap());
+               assert_eq!(Err(SocketAddressParseError::InvalidOnionV3), SocketAddress::from_str("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6.onion:1234"));
+               assert_eq!(Err(SocketAddressParseError::InvalidInput), SocketAddress::from_str("127.0.0.1@1234"));
+               assert_eq!(Err(SocketAddressParseError::InvalidInput), "".parse::<SocketAddress>());
+               assert!(SocketAddress::from_str("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion.onion:9735:94").is_err());
+               assert!(SocketAddress::from_str("wrong$%#.com:1234").is_err());
+               assert_eq!(Err(SocketAddressParseError::InvalidPort), SocketAddress::from_str("example.com:wrong"));
+               assert!("localhost".parse::<SocketAddress>().is_err());
+               assert!("localhost:invalid-port".parse::<SocketAddress>().is_err());
+               assert!( "invalid-onion-v3-hostname.onion:8080".parse::<SocketAddress>().is_err());
+               assert!("b32.example.onion:invalid-port".parse::<SocketAddress>().is_err());
+               assert!("invalid-address".parse::<SocketAddress>().is_err());
+               assert!(SocketAddress::from_str("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion.onion:1234").is_err());
+       }
 }