use ln::msgs::DecodeError;
use ln::onion_utils;
+use super::blinded_route::{ForwardTlvs, ReceiveTlvs};
+use util::chacha20poly1305rfc::ChaChaPolyWriteAdapter;
use util::ser::{LengthRead, LengthReadable, Readable, Writeable, Writer};
use core::cmp;
use io;
use prelude::*;
+// Per the spec, an onion message packet's `hop_data` field length should be
+// SMALL_PACKET_HOP_DATA_LEN if it fits, else BIG_PACKET_HOP_DATA_LEN if it fits.
+pub(super) const SMALL_PACKET_HOP_DATA_LEN: usize = 1300;
+pub(super) const BIG_PACKET_HOP_DATA_LEN: usize = 32768;
+
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct Packet {
version: u8,
})
}
}
+
+/// Onion message payloads contain "control" TLVs and "data" TLVs. Control TLVs are used to route
+/// the onion message from hop to hop and for path verification, whereas data TLVs contain the onion
+/// message content itself, such as an invoice request.
+pub(super) enum Payload {
+ /// This payload is for an intermediate hop.
+ Forward(ForwardControlTlvs),
+ /// This payload is for the final hop.
+ Receive {
+ control_tlvs: ReceiveControlTlvs,
+ // Coming soon:
+ // reply_path: Option<BlindedRoute>,
+ // message: Message,
+ }
+}
+
+// Coming soon:
+// enum Message {
+// InvoiceRequest(InvoiceRequest),
+// Invoice(Invoice),
+// InvoiceError(InvoiceError),
+// CustomMessage<T>,
+// }
+
+/// Forward control TLVs in their blinded and unblinded form.
+pub(super) enum ForwardControlTlvs {
+ /// If we're sending to a blinded route, the node that constructed the blinded route has provided
+ /// this hop's control TLVs, already encrypted into bytes.
+ Blinded(Vec<u8>),
+ /// If we're constructing an onion message hop through an intermediate unblinded node, we'll need
+ /// to construct the intermediate hop's control TLVs in their unblinded state to avoid encoding
+ /// them into an intermediate Vec. See [`super::blinded_route::ForwardTlvs`] for more info.
+ Unblinded(ForwardTlvs),
+}
+
+/// Receive control TLVs in their blinded and unblinded form.
+pub(super) enum ReceiveControlTlvs {
+ /// See [`ForwardControlTlvs::Blinded`].
+ Blinded(Vec<u8>),
+ /// See [`ForwardControlTlvs::Unblinded`] and [`super::blinded_route::ReceiveTlvs`].
+ Unblinded(ReceiveTlvs),
+}
+
+// Uses the provided secret to simultaneously encode and encrypt the unblinded control TLVs.
+impl Writeable for (Payload, [u8; 32]) {
+ fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+ match &self.0 {
+ Payload::Forward(ForwardControlTlvs::Blinded(encrypted_bytes)) |
+ Payload::Receive { control_tlvs: ReceiveControlTlvs::Blinded(encrypted_bytes)} => {
+ encode_varint_length_prefixed_tlv!(w, {
+ (4, encrypted_bytes, vec_type)
+ })
+ },
+ Payload::Forward(ForwardControlTlvs::Unblinded(control_tlvs)) => {
+ let write_adapter = ChaChaPolyWriteAdapter::new(self.1, &control_tlvs);
+ encode_varint_length_prefixed_tlv!(w, {
+ (4, write_adapter, required)
+ })
+ },
+ Payload::Receive { control_tlvs: ReceiveControlTlvs::Unblinded(control_tlvs)} => {
+ let write_adapter = ChaChaPolyWriteAdapter::new(self.1, &control_tlvs);
+ encode_varint_length_prefixed_tlv!(w, {
+ (4, write_adapter, required)
+ })
+ },
+ }
+ Ok(())
+ }
+}