Skip to content

Commit 828f546

Browse files
committed
Deserialize payment metadata fields in the onion final hop data
1 parent 0feb874 commit 828f546

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
@@ -3177,6 +3177,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31773177
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry } => {
31783178
let _legacy_hop_data = msgs::FinalOnionHopData {
31793179
payment_secret: payment_data.payment_secret,
3180+
payment_metadata: None, // Object is only for serialization backwards compat
31803181
total_msat: payment_data.total_msat
31813182
};
31823183
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, Some(payment_data))
@@ -7121,6 +7122,7 @@ mod tests {
71217122
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[0]);
71227123
let payment_data = msgs::FinalOnionHopData {
71237124
payment_secret,
7125+
payment_metadata: None,
71247126
total_msat: 100_000,
71257127
};
71267128

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

@@ -878,6 +878,7 @@ mod fuzzy_internal_msgs {
878878
#[derive(Clone)]
879879
pub(crate) struct FinalOnionHopData {
880880
pub(crate) payment_secret: PaymentSecret,
881+
pub(crate) payment_metadata: Option<Vec<u8>>,
881882
/// The total value, in msat, of the payment as received by the ultimate recipient.
882883
/// Message serialization may panic if this value is more than 21 million Bitcoin.
883884
pub(crate) total_msat: u64,
@@ -1248,6 +1249,11 @@ impl_writeable_msg!(UpdateAddHTLC, {
12481249
onion_routing_packet
12491250
}, {});
12501251

1252+
// The serialization here is really funky - FinalOnionHopData somewhat serves as two different
1253+
// things. First, it is *the* object which is written with type 8 in the onion TLV. Second, it is
1254+
// the data which a node may expect to receive when we are the recipient of an invoice payment.
1255+
// Thus, its serialization doesn't match its in-memory layout - with the payment_metadata included
1256+
// in the struct, but serialized separately.
12511257
impl Writeable for FinalOnionHopData {
12521258
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
12531259
self.payment_secret.0.write(w)?;
@@ -1259,7 +1265,7 @@ impl Readable for FinalOnionHopData {
12591265
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
12601266
let secret: [u8; 32] = Readable::read(r)?;
12611267
let amt: HighZeroBytesDroppedVarInt<u64> = Readable::read(r)?;
1262-
Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0 })
1268+
Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0, payment_metadata: None, })
12631269
}
12641270
}
12651271

@@ -1288,10 +1294,15 @@ impl Writeable for OnionHopData {
12881294
if let Some(final_data) = payment_data {
12891295
if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
12901296
}
1297+
let payment_metadata = if let Some(data) = payment_data {
1298+
if let Some(ref metadata) = data.payment_metadata { Some(VecWriteWrapper(metadata))
1299+
} else { None }
1300+
} else { None };
12911301
encode_varint_length_prefixed_tlv!(w, {
12921302
(2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required),
12931303
(4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required),
12941304
(8, payment_data, option),
1305+
(16, payment_metadata, option),
12951306
(5482373484, keysend_preimage, option)
12961307
});
12971308
},
@@ -1315,26 +1326,30 @@ impl Readable for OnionHopData {
13151326
let mut cltv_value = HighZeroBytesDroppedVarInt(0u32);
13161327
let mut short_id: Option<u64> = None;
13171328
let mut payment_data: Option<FinalOnionHopData> = None;
1329+
let mut payment_metadata: Option<VecReadWrapper<u8>> = None;
13181330
let mut keysend_preimage: Option<PaymentPreimage> = None;
13191331
// The TLV type is chosen to be compatible with lnd and c-lightning.
13201332
decode_tlv_stream!(&mut rd, {
13211333
(2, amt, required),
13221334
(4, cltv_value, required),
13231335
(6, short_id, option),
13241336
(8, payment_data, option),
1337+
(16, payment_metadata, option),
13251338
(5482373484, keysend_preimage, option)
13261339
});
13271340
rd.eat_remaining().map_err(|_| DecodeError::ShortRead)?;
13281341
let format = if let Some(short_channel_id) = short_id {
13291342
if payment_data.is_some() { return Err(DecodeError::InvalidValue); }
1343+
if payment_metadata.is_some() { return Err(DecodeError::InvalidValue); }
13301344
OnionHopDataFormat::NonFinalNode {
13311345
short_channel_id,
13321346
}
13331347
} else {
1334-
if let &Some(ref data) = &payment_data {
1348+
if let Some(ref mut data) = &mut payment_data {
13351349
if data.total_msat > MAX_VALUE_MSAT {
13361350
return Err(DecodeError::InvalidValue);
13371351
}
1352+
data.payment_metadata = payment_metadata.map(|v| v.0);
13381353
}
13391354
OnionHopDataFormat::FinalNode {
13401355
payment_data,
@@ -2486,6 +2501,7 @@ mod tests {
24862501
format: OnionHopDataFormat::FinalNode {
24872502
payment_data: Some(FinalOnionHopData {
24882503
payment_secret: expected_payment_secret,
2504+
payment_metadata: None,
24892505
total_msat: 0x1badca1f
24902506
}),
24912507
keysend_preimage: None,
@@ -2500,6 +2516,7 @@ mod tests {
25002516
if let OnionHopDataFormat::FinalNode {
25012517
payment_data: Some(FinalOnionHopData {
25022518
payment_secret,
2519+
payment_metadata: None,
25032520
total_msat: 0x1badca1f
25042521
}),
25052522
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)