Merge pull request #2370 from valentinewallace/2023-06-send-along-path-args
[rust-lightning] / lightning / src / ln / msgs.rs
index 27f8544e3b52021345f66ccd9c434beea2876bf2..0c23d4425f8663ebe6fce310692b2dc11bc89e08 100644 (file)
 //! raw socket events into your non-internet-facing system and then send routing events back to
 //! track the network on the less-secure system.
 
+use bitcoin::blockdata::constants::ChainHash;
 use bitcoin::secp256k1::PublicKey;
 use bitcoin::secp256k1::ecdsa::Signature;
-use bitcoin::{secp256k1, Witness, Transaction};
+use bitcoin::{secp256k1, Witness};
 use bitcoin::blockdata::script::Script;
 use bitcoin::hash_types::{Txid, BlockHash};
 
@@ -42,7 +43,7 @@ use crate::io_extras::read_to_end;
 
 use crate::events::{MessageSendEventsProvider, OnionMessageProvider};
 use crate::util::logger;
-use crate::util::ser::{LengthReadable, Readable, ReadableArgs, Writeable, Writer, WithoutLength, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname};
+use crate::util::ser::{LengthReadable, Readable, ReadableArgs, Writeable, Writer, WithoutLength, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname, TransactionU16LenLimited};
 
 use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
 
@@ -88,6 +89,10 @@ pub enum DecodeError {
 pub struct Init {
        /// The relevant features which the sender supports.
        pub features: InitFeatures,
+       /// Indicates chains the sender is interested in.
+       ///
+       /// If there are no common chains, the connection will be closed.
+       pub networks: Option<Vec<ChainHash>>,
        /// The receipient's network address.
        ///
        /// This adds the option to report a remote IP address back to a connecting peer using the init
@@ -425,45 +430,6 @@ pub struct ChannelReady {
        pub short_channel_id_alias: Option<u64>,
 }
 
-/// A wrapper for a `Transaction` which can only be constructed with [`TransactionU16LenLimited::new`]
-/// if the `Transaction`'s consensus-serialized length is <= u16::MAX.
-///
-/// Use [`TransactionU16LenLimited::into_transaction`] to convert into the contained `Transaction`.
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct TransactionU16LenLimited(Transaction);
-
-impl TransactionU16LenLimited {
-       /// Constructs a new `TransactionU16LenLimited` from a `Transaction` only if it's consensus-
-       /// serialized length is <= u16::MAX.
-       pub fn new(transaction: Transaction) -> Result<Self, ()> {
-               if transaction.serialized_length() > (u16::MAX as usize) {
-                       Err(())
-               } else {
-                       Ok(Self(transaction))
-               }
-       }
-
-       /// Consumes this `TransactionU16LenLimited` and returns its contained `Transaction`.
-       pub fn into_transaction(self) -> Transaction {
-               self.0
-       }
-}
-
-impl Writeable for TransactionU16LenLimited {
-       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
-               (self.0.serialized_length() as u16).write(w)?;
-               self.0.write(w)
-       }
-}
-
-impl Readable for TransactionU16LenLimited {
-       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
-               let len = <u16 as Readable>::read(r)?;
-               let mut tx_reader = FixedLengthReader::new(r, len as u64);
-               Ok(Self(Readable::read(&mut tx_reader)?))
-       }
-}
-
 /// A tx_add_input message for adding an input during interactive transaction construction
 ///
 // TODO(dual_funding): Add spec link for `tx_add_input`.
@@ -644,6 +610,11 @@ pub struct UpdateAddHTLC {
        pub payment_hash: PaymentHash,
        /// The expiry height of the HTLC
        pub cltv_expiry: u32,
+       /// The extra fee skimmed by the sender of this message. See
+       /// [`ChannelConfig::accept_underpaying_htlcs`].
+       ///
+       /// [`ChannelConfig::accept_underpaying_htlcs`]: crate::util::config::ChannelConfig::accept_underpaying_htlcs
+       pub skimmed_fee_msat: Option<u64>,
        pub(crate) onion_routing_packet: OnionPacket,
 }
 
@@ -850,7 +821,7 @@ impl NetAddress {
 }
 
 impl Writeable for NetAddress {
-fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+       fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                match self {
                        &NetAddress::IPv4 { ref addr, ref port } => {
                                1u8.write(writer)?;
@@ -1002,7 +973,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.
 ///
@@ -1176,6 +1151,11 @@ pub enum ErrorAction {
                /// An error message which we should make an effort to send before we disconnect.
                msg: Option<ErrorMessage>
        },
+       /// The peer did something incorrect. Tell them without closing any channels and disconnect them.
+       DisconnectPeerWithWarning {
+               /// A warning message which we should make an effort to send before we disconnect.
+               msg: WarningMessage,
+       },
        /// The peer did something harmless that we weren't able to process, just log and ignore
        // New code should *not* use this. New code must use IgnoreAndLog, below!
        IgnoreError,
@@ -1329,6 +1309,12 @@ pub trait ChannelMessageHandler : MessageSendEventsProvider {
        ///
        /// Note that this method is called before [`Self::peer_connected`].
        fn provided_init_features(&self, their_node_id: &PublicKey) -> InitFeatures;
+
+       /// Gets the genesis hashes for this `ChannelMessageHandler` indicating which chains it supports.
+       ///
+       /// If it's `None`, then no particular network chain hash compatibility will be enforced when
+       /// connecting to peers.
+       fn get_genesis_hashes(&self) -> Option<Vec<ChainHash>>;
 }
 
 /// A trait to describe an object which can receive routing messages.
@@ -1762,7 +1748,8 @@ impl Writeable for Init {
                self.features.write_up_to_13(w)?;
                self.features.write(w)?;
                encode_tlv_stream!(w, {
-                       (3, self.remote_network_address, option)
+                       (1, self.networks.as_ref().map(|n| WithoutLength(n)), option),
+                       (3, self.remote_network_address, option),
                });
                Ok(())
        }
@@ -1773,11 +1760,14 @@ impl Readable for Init {
                let global_features: InitFeatures = Readable::read(r)?;
                let features: InitFeatures = Readable::read(r)?;
                let mut remote_network_address: Option<NetAddress> = None;
+               let mut networks: Option<WithoutLength<Vec<ChainHash>>> = None;
                decode_tlv_stream!(r, {
+                       (1, networks, option),
                        (3, remote_network_address, option)
                });
                Ok(Init {
-                       features: features.or(global_features),
+                       features: features | global_features,
+                       networks: networks.map(|n| n.0),
                        remote_network_address,
                })
        }
@@ -1922,8 +1912,10 @@ impl_writeable_msg!(UpdateAddHTLC, {
        amount_msat,
        payment_hash,
        cltv_expiry,
-       onion_routing_packet
-}, {});
+       onion_routing_packet,
+}, {
+       (65537, skimmed_fee_msat, option)
+});
 
 impl Readable for OnionMessage {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
@@ -2450,14 +2442,14 @@ impl_writeable_msg!(GossipTimestampFilter, {
 
 #[cfg(test)]
 mod tests {
+       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::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
-       use crate::ln::msgs::{self, TransactionU16LenLimited};
-       use crate::ln::msgs::{FinalOnionHopData, OnionErrorPacket, OnionHopDataFormat};
+       use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket, OnionHopDataFormat};
        use crate::routing::gossip::{NodeAlias, NodeId};
-       use crate::util::ser::{Writeable, Readable, Hostname};
+       use crate::util::ser::{Writeable, Readable, Hostname, TransactionU16LenLimited};
 
        use bitcoin::hashes::hex::FromHex;
        use bitcoin::util::address::Address;
@@ -3349,7 +3341,8 @@ mod tests {
                        amount_msat: 3608586615801332854,
                        payment_hash: PaymentHash([1; 32]),
                        cltv_expiry: 821716,
-                       onion_routing_packet
+                       onion_routing_packet,
+                       skimmed_fee_msat: None,
                };
                let encoded_value = update_add_htlc.encode();
                let target_value = hex::decode("020202020202020202020202020202020202020202020202020202020202020200083a840000034d32144668701144760101010101010101010101010101010101010101010101010101010101010101000c89d4ff031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010202020202020202020202020202020202020202020202020202020202020202").unwrap();
@@ -3458,27 +3451,36 @@ mod tests {
 
        #[test]
        fn encoding_init() {
+               let mainnet_hash = ChainHash::from_hex("6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000").unwrap();
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![0xFF, 0xFF, 0xFF]),
+                       networks: Some(vec![mainnet_hash]),
                        remote_network_address: None,
-               }.encode(), hex::decode("00023fff0003ffffff").unwrap());
+               }.encode(), hex::decode("00023fff0003ffffff01206fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000").unwrap());
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![0xFF]),
+                       networks: None,
                        remote_network_address: None,
                }.encode(), hex::decode("0001ff0001ff").unwrap());
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![]),
+                       networks: Some(vec![mainnet_hash]),
                        remote_network_address: None,
-               }.encode(), hex::decode("00000000").unwrap());
-
+               }.encode(), hex::decode("0000000001206fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000").unwrap());
+               assert_eq!(msgs::Init {
+                       features: InitFeatures::from_le_bytes(vec![]),
+                       networks: Some(vec![ChainHash::from(&[1; 32][..]), ChainHash::from(&[2; 32][..])]),
+                       remote_network_address: None,
+               }.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 {
                                addr: [127, 0, 0, 1],
                                port: 1000,
                        }),
                };
                let encoded_value = init_msg.encode();
-               let target_value = hex::decode("000000000307017f00000103e8").unwrap();
+               let target_value = hex::decode("0000000001206fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d61900000000000307017f00000103e8").unwrap();
                assert_eq!(encoded_value, target_value);
                assert_eq!(msgs::Init::read(&mut Cursor::new(&target_value)).unwrap(), init_msg);
        }
@@ -3762,7 +3764,7 @@ mod tests {
                let test_bytes = vec![42u8; 1000];
                if let OnionHopDataFormat::NonFinalNode { short_channel_id } = payload.format {
                        _encode_varint_length_prefixed_tlv!(&mut encoded_payload, {
-                               (1, test_bytes, vec_type),
+                               (1, test_bytes, required_vec),
                                (2, HighZeroBytesDroppedBigSize(payload.amt_to_forward), required),
                                (4, HighZeroBytesDroppedBigSize(payload.outgoing_cltv_value), required),
                                (6, short_channel_id, required)