X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fonion_message%2Fpacket.rs;h=fca7dd6a91ac6a1eda39e5519822c1c9101df78c;hb=5c7af8c6d32dd4bb2b307ba29c68667a15cb8509;hp=5ce02c54d08800b777a0c2c3a25f27ba1ffae462;hpb=f352d03ee98aed3d940e697fcb09371cfdc3ab15;p=rust-lightning diff --git a/lightning/src/onion_message/packet.rs b/lightning/src/onion_message/packet.rs index 5ce02c54..fca7dd6a 100644 --- a/lightning/src/onion_message/packet.rs +++ b/lightning/src/onion_message/packet.rs @@ -12,18 +12,21 @@ use bitcoin::secp256k1::PublicKey; use bitcoin::secp256k1::ecdh::SharedSecret; -use crate::blinded_path::BlindedPath; +use crate::blinded_path::{BlindedPath, NextMessageHop}; use crate::blinded_path::message::{ForwardTlvs, ReceiveTlvs}; use crate::blinded_path::utils::Padding; use crate::ln::msgs::DecodeError; use crate::ln::onion_utils; +#[cfg(async_payments)] +use super::async_payments::AsyncPaymentsMessage; use super::messenger::CustomOnionMessageHandler; use super::offers::OffersMessage; -use crate::util::chacha20poly1305rfc::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter}; +use crate::crypto::streams::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter}; use crate::util::logger::Logger; use crate::util::ser::{BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, Readable, ReadableArgs, Writeable, Writer}; use core::cmp; +use core::fmt; use crate::io::{self, Read}; use crate::prelude::*; @@ -33,7 +36,7 @@ pub(super) const SMALL_PACKET_HOP_DATA_LEN: usize = 1300; pub(super) const BIG_PACKET_HOP_DATA_LEN: usize = 32768; /// Packet of hop data for next peer -#[derive(Clone, Debug, Hash, PartialEq, Eq)] +#[derive(Clone, Hash, PartialEq, Eq)] pub struct Packet { /// Bolt 04 version number pub version: u8, @@ -62,6 +65,12 @@ impl onion_utils::Packet for Packet { } } +impl fmt::Debug for Packet { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_fmt(format_args!("Onion message packet version {} with hmac {:?}", self.version, &self.hmac[..])) + } +} + impl Writeable for Packet { fn write(&self, w: &mut W) -> Result<(), io::Error> { self.version.write(w)?; @@ -117,10 +126,13 @@ pub(super) enum Payload { /// The contents of an [`OnionMessage`] as read from the wire. /// /// [`OnionMessage`]: crate::ln::msgs::OnionMessage -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum ParsedOnionMessageContents { /// A message related to BOLT 12 Offers. Offers(OffersMessage), + /// A message related to async payments. + #[cfg(async_payments)] + AsyncPayments(AsyncPaymentsMessage), /// A custom onion message specified by the user. Custom(T), } @@ -132,15 +144,27 @@ impl OnionMessageContents for ParsedOnionMessageContent fn tlv_type(&self) -> u64 { match self { &ParsedOnionMessageContents::Offers(ref msg) => msg.tlv_type(), + #[cfg(async_payments)] + &ParsedOnionMessageContents::AsyncPayments(ref msg) => msg.tlv_type(), &ParsedOnionMessageContents::Custom(ref msg) => msg.tlv_type(), } } + fn msg_type(&self) -> &'static str { + match self { + ParsedOnionMessageContents::Offers(ref msg) => msg.msg_type(), + #[cfg(async_payments)] + ParsedOnionMessageContents::AsyncPayments(ref msg) => msg.msg_type(), + ParsedOnionMessageContents::Custom(ref msg) => msg.msg_type(), + } + } } impl Writeable for ParsedOnionMessageContents { fn write(&self, w: &mut W) -> Result<(), io::Error> { match self { ParsedOnionMessageContents::Offers(msg) => Ok(msg.write(w)?), + #[cfg(async_payments)] + ParsedOnionMessageContents::AsyncPayments(msg) => Ok(msg.write(w)?), ParsedOnionMessageContents::Custom(msg) => Ok(msg.write(w)?), } } @@ -150,6 +174,9 @@ impl Writeable for ParsedOnionMessageContents { pub trait OnionMessageContents: Writeable + core::fmt::Debug { /// Returns the TLV type identifying the message contents. MUST be >= 64. fn tlv_type(&self) -> u64; + + /// Returns the message type + fn msg_type(&self) -> &'static str; } /// Forward control TLVs in their blinded and unblinded form. @@ -239,6 +266,12 @@ for Payload::CustomM message = Some(ParsedOnionMessageContents::Offers(msg)); Ok(true) }, + #[cfg(async_payments)] + tlv_type if AsyncPaymentsMessage::is_known_type(tlv_type) => { + let msg = AsyncPaymentsMessage::read(msg_reader, tlv_type)?; + message = Some(ParsedOnionMessageContents::AsyncPayments(msg)); + Ok(true) + }, _ => match handler.read_custom_message(msg_type, msg_reader)? { Some(msg) => { message = Some(ParsedOnionMessageContents::Custom(msg)); @@ -284,20 +317,26 @@ impl Readable for ControlTlvs { fn read(r: &mut R) -> Result { _init_and_read_tlv_stream!(r, { (1, _padding, option), - (2, _short_channel_id, option), + (2, short_channel_id, option), (4, next_node_id, option), (6, path_id, option), (8, next_blinding_override, option), }); let _padding: Option = _padding; - let _short_channel_id: Option = _short_channel_id; - let valid_fwd_fmt = next_node_id.is_some() && path_id.is_none(); - let valid_recv_fmt = next_node_id.is_none() && next_blinding_override.is_none(); + let next_hop = match (short_channel_id, next_node_id) { + (Some(_), Some(_)) => return Err(DecodeError::InvalidValue), + (Some(scid), None) => Some(NextMessageHop::ShortChannelId(scid)), + (None, Some(pubkey)) => Some(NextMessageHop::NodeId(pubkey)), + (None, None) => None, + }; + + let valid_fwd_fmt = next_hop.is_some() && path_id.is_none(); + let valid_recv_fmt = next_hop.is_none() && next_blinding_override.is_none(); let payload_fmt = if valid_fwd_fmt { ControlTlvs::Forward(ForwardTlvs { - next_node_id: next_node_id.unwrap(), + next_hop: next_hop.unwrap(), next_blinding_override, }) } else if valid_recv_fmt {