Skip to content

Commit d029c65

Browse files
committed
Deserialize payment metadata fields in the onion final hop data
1 parent 25a2066 commit d029c65

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3181,6 +3181,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31813181
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry } => {
31823182
let _legacy_hop_data = msgs::FinalOnionHopData {
31833183
payment_secret: payment_data.payment_secret,
3184+
payment_metadata: None, // Object is only for serialization backwards compat
31843185
total_msat: payment_data.total_msat
31853186
};
31863187
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, Some(payment_data))
@@ -7137,6 +7138,7 @@ mod tests {
71377138
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[0]);
71387139
let payment_data = msgs::FinalOnionHopData {
71397140
payment_secret,
7141+
payment_metadata: None,
71407142
total_msat: 100_000,
71417143
};
71427144

lightning/src/ln/msgs.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use io_extras::read_to_end;
4040

4141
use util::events::MessageSendEventsProvider;
4242
use util::logger;
43-
use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt};
43+
use util::ser::{Readable, Writeable, Writer, VecWriteWrapper, VecReadWrapper, FixedLengthReader, HighZeroBytesDroppedVarInt};
4444

4545
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
4646

@@ -904,6 +904,7 @@ mod fuzzy_internal_msgs {
904904
#[derive(Clone)]
905905
pub(crate) struct FinalOnionHopData {
906906
pub(crate) payment_secret: PaymentSecret,
907+
pub(crate) payment_metadata: Option<Vec<u8>>,
907908
/// The total value, in msat, of the payment as received by the ultimate recipient.
908909
/// Message serialization may panic if this value is more than 21 million Bitcoin.
909910
pub(crate) total_msat: u64,
@@ -1274,6 +1275,11 @@ impl_writeable_msg!(UpdateAddHTLC, {
12741275
onion_routing_packet
12751276
}, {});
12761277

1278+
// The serialization here is really funky - FinalOnionHopData somewhat serves as two different
1279+
// things. First, it is *the* object which is written with type 8 in the onion TLV. Second, it is
1280+
// the data which a node may expect to receive when we are the recipient of an invoice payment.
1281+
// Thus, its serialization doesn't match its in-memory layout - with the payment_metadata included
1282+
// in the struct, but serialized separately.
12771283
impl Writeable for FinalOnionHopData {
12781284
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
12791285
self.payment_secret.0.write(w)?;
@@ -1285,7 +1291,7 @@ impl Readable for FinalOnionHopData {
12851291
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
12861292
let secret: [u8; 32] = Readable::read(r)?;
12871293
let amt: HighZeroBytesDroppedVarInt<u64> = Readable::read(r)?;
1288-
Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0 })
1294+
Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0, payment_metadata: None, })
12891295
}
12901296
}
12911297

@@ -1314,10 +1320,15 @@ impl Writeable for OnionHopData {
13141320
if let Some(final_data) = payment_data {
13151321
if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
13161322
}
1323+
let payment_metadata = if let Some(data) = payment_data {
1324+
if let Some(ref metadata) = data.payment_metadata { Some(VecWriteWrapper(metadata))
1325+
} else { None }
1326+
} else { None };
13171327
encode_varint_length_prefixed_tlv!(w, {
13181328
(2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required),
13191329
(4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required),
13201330
(8, payment_data, option),
1331+
(16, payment_metadata, option),
13211332
(5482373484, keysend_preimage, option)
13221333
});
13231334
},
@@ -1341,26 +1352,30 @@ impl Readable for OnionHopData {
13411352
let mut cltv_value = HighZeroBytesDroppedVarInt(0u32);
13421353
let mut short_id: Option<u64> = None;
13431354
let mut payment_data: Option<FinalOnionHopData> = None;
1355+
let mut payment_metadata: Option<VecReadWrapper<u8>> = None;
13441356
let mut keysend_preimage: Option<PaymentPreimage> = None;
13451357
// The TLV type is chosen to be compatible with lnd and c-lightning.
13461358
decode_tlv_stream!(&mut rd, {
13471359
(2, amt, required),
13481360
(4, cltv_value, required),
13491361
(6, short_id, option),
13501362
(8, payment_data, option),
1363+
(16, payment_metadata, option),
13511364
(5482373484, keysend_preimage, option)
13521365
});
13531366
rd.eat_remaining().map_err(|_| DecodeError::ShortRead)?;
13541367
let format = if let Some(short_channel_id) = short_id {
13551368
if payment_data.is_some() { return Err(DecodeError::InvalidValue); }
1369+
if payment_metadata.is_some() { return Err(DecodeError::InvalidValue); }
13561370
OnionHopDataFormat::NonFinalNode {
13571371
short_channel_id,
13581372
}
13591373
} else {
1360-
if let &Some(ref data) = &payment_data {
1374+
if let Some(ref mut data) = &mut payment_data {
13611375
if data.total_msat > MAX_VALUE_MSAT {
13621376
return Err(DecodeError::InvalidValue);
13631377
}
1378+
data.payment_metadata = payment_metadata.map(|v| v.0);
13641379
}
13651380
OnionHopDataFormat::FinalNode {
13661381
payment_data,
@@ -2551,6 +2566,7 @@ mod tests {
25512566
format: OnionHopDataFormat::FinalNode {
25522567
payment_data: Some(FinalOnionHopData {
25532568
payment_secret: expected_payment_secret,
2569+
payment_metadata: None,
25542570
total_msat: 0x1badca1f
25552571
}),
25562572
keysend_preimage: None,
@@ -2565,6 +2581,7 @@ mod tests {
25652581
if let OnionHopDataFormat::FinalNode {
25662582
payment_data: Some(FinalOnionHopData {
25672583
payment_secret,
2584+
payment_metadata: None,
25682585
total_msat: 0x1badca1f
25692586
}),
25702587
keysend_preimage: None,

lightning/src/ln/onion_utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ pub(super) fn build_onion_payloads(path: &Vec<RouteHop>, total_msat: u64, paymen
139139
payment_data: if let &Some(ref payment_secret) = payment_secret_option {
140140
Some(msgs::FinalOnionHopData {
141141
payment_secret: payment_secret.clone(),
142+
payment_metadata: None,
142143
total_msat,
143144
})
144145
} else { None },

0 commit comments

Comments
 (0)