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
+ /// 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 containing the new address.
+ pub remote_network_address: Option<NetAddress>,
}
/// An error message to be sent or received from a peer
pub channel_id: [u8; 32],
/// 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. The sender will accept payments
+ /// to be forwarded over this SCID and forward them to this messages' recipient.
+ pub short_channel_id_alias: Option<u64>,
}
/// A shutdown message to be sent or received from a peer
/// Called when a connection is established with a peer. This can be used to
/// perform routing table synchronization using a strategy defined by the
/// implementor.
- fn sync_routing_table(&self, their_node_id: &PublicKey, init: &Init);
+ fn peer_connected(&self, their_node_id: &PublicKey, init: &Init);
/// Handles the reply of a query we initiated to learn about channels
/// for a given range of blocks. We can expect to receive one or more
/// replies to a single query.
pub(crate) pad: Vec<u8>,
}
}
-#[cfg(feature = "fuzztarget")]
+#[cfg(fuzzing)]
pub use self::fuzzy_internal_msgs::*;
-#[cfg(not(feature = "fuzztarget"))]
+#[cfg(not(fuzzing))]
pub(crate) use self::fuzzy_internal_msgs::*;
#[derive(Clone)]
impl_writeable_msg!(FundingLocked, {
channel_id,
next_per_commitment_point,
-}, {});
+}, {
+ (1, short_channel_id_alias, option),
+});
impl Writeable for Init {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
// global_features gets the bottom 13 bits of our features, and local_features gets all of
// our relevant feature bits. This keeps us compatible with old nodes.
self.features.write_up_to_13(w)?;
- self.features.write(w)
+ self.features.write(w)?;
+ encode_tlv_stream!(w, {
+ (3, self.remote_network_address, option)
+ });
+ Ok(())
}
}
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;
+ decode_tlv_stream!(r, {
+ (3, remote_network_address, option)
+ });
Ok(Init {
features: features.or(global_features),
+ remote_network_address,
})
}
}
impl Writeable for OnionHopData {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
- // Note that this should never be reachable if Rust-Lightning generated the message, as we
- // check values are sane long before we get here, though its possible in the future
- // user-generated messages may hit this.
- if self.amt_to_forward > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
match self.format {
OnionHopDataFormat::Legacy { short_channel_id } => {
0u8.write(w)?;
});
},
OnionHopDataFormat::FinalNode { ref payment_data, ref keysend_preimage } => {
- if let Some(final_data) = payment_data {
- if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
- }
encode_varint_length_prefixed_tlv!(w, {
(2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required),
(4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required),
let funding_locked = msgs::FundingLocked {
channel_id: [2; 32],
next_per_commitment_point: pubkey_1,
+ short_channel_id_alias: None,
};
let encoded_value = funding_locked.encode();
let target_value = hex::decode("0202020202020202020202020202020202020202020202020202020202020202031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f").unwrap();
fn encoding_init() {
assert_eq!(msgs::Init {
features: InitFeatures::from_le_bytes(vec![0xFF, 0xFF, 0xFF]),
+ remote_network_address: None,
}.encode(), hex::decode("00023fff0003ffffff").unwrap());
assert_eq!(msgs::Init {
features: InitFeatures::from_le_bytes(vec![0xFF]),
+ remote_network_address: None,
}.encode(), hex::decode("0001ff0001ff").unwrap());
assert_eq!(msgs::Init {
features: InitFeatures::from_le_bytes(vec![]),
+ remote_network_address: None,
}.encode(), hex::decode("00000000").unwrap());
+
+ let init_msg = msgs::Init { features: InitFeatures::from_le_bytes(vec![]),
+ 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();
+ assert_eq!(encoded_value, target_value);
+ assert_eq!(msgs::Init::read(&mut Cursor::new(&target_value)).unwrap(), init_msg);
}
#[test]