1 // This file is Copyright its original authors, visible in version control
4 // This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5 // or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7 // You may not use this file except in accordance with one or both of these
10 //! Structs and enums useful for constructing and reading an onion message packet.
12 use bitcoin::secp256k1::PublicKey;
14 use ln::msgs::DecodeError;
16 use util::ser::{LengthRead, LengthReadable, Readable, Writeable, Writer};
22 #[derive(Clone, Debug, PartialEq)]
23 pub(crate) struct Packet {
25 public_key: PublicKey,
26 // Unlike the onion packets used for payments, onion message packets can have payloads greater
28 // TODO: if 1300 ends up being the most common size, optimize this to be:
29 // enum { ThirteenHundred([u8; 1300]), VarLen(Vec<u8>) }
34 impl onion_utils::Packet for Packet {
36 fn new(public_key: PublicKey, hop_data: Vec<u8>, hmac: [u8; 32]) -> Packet {
46 impl Writeable for Packet {
47 fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
48 self.version.write(w)?;
49 self.public_key.write(w)?;
50 w.write_all(&self.hop_data)?;
56 impl LengthReadable for Packet {
57 fn read<R: LengthRead>(r: &mut R) -> Result<Self, DecodeError> {
58 const READ_BUFFER_SIZE: usize = 4096;
60 let version = Readable::read(r)?;
61 let public_key = Readable::read(r)?;
63 let mut hop_data = Vec::new();
64 let hop_data_len = r.total_bytes() as usize - 66; // 1 (version) + 33 (pubkey) + 32 (HMAC) = 66
66 while read_idx < hop_data_len {
67 let mut read_buffer = [0; READ_BUFFER_SIZE];
68 let read_amt = cmp::min(hop_data_len - read_idx, READ_BUFFER_SIZE);
69 r.read_exact(&mut read_buffer[..read_amt]);
70 hop_data.extend_from_slice(&read_buffer[..read_amt]);
74 let hmac = Readable::read(r)?;