Skip to content

Commit cb90699

Browse files
TheBlueMattandozw
authored andcommitted
Deserialize payment metadata fields in the onion final hop data
1 parent c0f17d6 commit cb90699

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
@@ -3100,6 +3100,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31003100
PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } => {
31013101
let _legacy_hop_data = msgs::FinalOnionHopData {
31023102
payment_secret: payment_data.payment_secret,
3103+
payment_metadata: None, // Object is only for serialization backwards compat
31033104
total_msat: payment_data.total_msat
31043105
};
31053106
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, Some(payment_data), phantom_shared_secret)
@@ -7321,6 +7322,7 @@ mod tests {
73217322
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[0]);
73227323
let payment_data = msgs::FinalOnionHopData {
73237324
payment_secret,
7325+
payment_metadata: None,
73247326
total_msat: 100_000,
73257327
};
73267328

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

@@ -918,6 +918,7 @@ mod fuzzy_internal_msgs {
918918
#[derive(Clone)]
919919
pub(crate) struct FinalOnionHopData {
920920
pub(crate) payment_secret: PaymentSecret,
921+
pub(crate) payment_metadata: Option<Vec<u8>>,
921922
/// The total value, in msat, of the payment as received by the ultimate recipient.
922923
/// Message serialization may panic if this value is more than 21 million Bitcoin.
923924
pub(crate) total_msat: u64,
@@ -1301,6 +1302,11 @@ impl_writeable_msg!(UpdateAddHTLC, {
13011302
onion_routing_packet
13021303
}, {});
13031304

1305+
// The serialization here is really funky - FinalOnionHopData somewhat serves as two different
1306+
// things. First, it is *the* object which is written with type 8 in the onion TLV. Second, it is
1307+
// the data which a node may expect to receive when we are the recipient of an invoice payment.
1308+
// Thus, its serialization doesn't match its in-memory layout - with the payment_metadata included
1309+
// in the struct, but serialized separately.
13041310
impl Writeable for FinalOnionHopData {
13051311
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
13061312
self.payment_secret.0.write(w)?;
@@ -1312,7 +1318,7 @@ impl Readable for FinalOnionHopData {
13121318
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
13131319
let secret: [u8; 32] = Readable::read(r)?;
13141320
let amt: HighZeroBytesDroppedVarInt<u64> = Readable::read(r)?;
1315-
Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0 })
1321+
Ok(Self { payment_secret: PaymentSecret(secret), total_msat: amt.0, payment_metadata: None, })
13161322
}
13171323
}
13181324

@@ -1334,10 +1340,15 @@ impl Writeable for OnionHopData {
13341340
});
13351341
},
13361342
OnionHopDataFormat::FinalNode { ref payment_data, ref keysend_preimage } => {
1343+
let payment_metadata = if let Some(data) = payment_data {
1344+
if let Some(ref metadata) = data.payment_metadata { Some(VecWriteWrapper(metadata))
1345+
} else { None }
1346+
} else { None };
13371347
encode_varint_length_prefixed_tlv!(w, {
13381348
(2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required),
13391349
(4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required),
13401350
(8, payment_data, option),
1351+
(16, payment_metadata, option),
13411352
(5482373484, keysend_preimage, option)
13421353
});
13431354
},
@@ -1361,26 +1372,30 @@ impl Readable for OnionHopData {
13611372
let mut cltv_value = HighZeroBytesDroppedVarInt(0u32);
13621373
let mut short_id: Option<u64> = None;
13631374
let mut payment_data: Option<FinalOnionHopData> = None;
1375+
let mut payment_metadata: Option<VecReadWrapper<u8>> = None;
13641376
let mut keysend_preimage: Option<PaymentPreimage> = None;
13651377
// The TLV type is chosen to be compatible with lnd and c-lightning.
13661378
decode_tlv_stream!(&mut rd, {
13671379
(2, amt, required),
13681380
(4, cltv_value, required),
13691381
(6, short_id, option),
13701382
(8, payment_data, option),
1383+
(16, payment_metadata, option),
13711384
(5482373484, keysend_preimage, option)
13721385
});
13731386
rd.eat_remaining().map_err(|_| DecodeError::ShortRead)?;
13741387
let format = if let Some(short_channel_id) = short_id {
13751388
if payment_data.is_some() { return Err(DecodeError::InvalidValue); }
1389+
if payment_metadata.is_some() { return Err(DecodeError::InvalidValue); }
13761390
OnionHopDataFormat::NonFinalNode {
13771391
short_channel_id,
13781392
}
13791393
} else {
1380-
if let &Some(ref data) = &payment_data {
1394+
if let Some(ref mut data) = &mut payment_data {
13811395
if data.total_msat > MAX_VALUE_MSAT {
13821396
return Err(DecodeError::InvalidValue);
13831397
}
1398+
data.payment_metadata = payment_metadata.map(|v| v.0);
13841399
}
13851400
OnionHopDataFormat::FinalNode {
13861401
payment_data,
@@ -2587,6 +2602,7 @@ mod tests {
25872602
format: OnionHopDataFormat::FinalNode {
25882603
payment_data: Some(FinalOnionHopData {
25892604
payment_secret: expected_payment_secret,
2605+
payment_metadata: None,
25902606
total_msat: 0x1badca1f
25912607
}),
25922608
keysend_preimage: None,
@@ -2601,6 +2617,7 @@ mod tests {
26012617
if let OnionHopDataFormat::FinalNode {
26022618
payment_data: Some(FinalOnionHopData {
26032619
payment_secret,
2620+
payment_metadata: None,
26042621
total_msat: 0x1badca1f
26052622
}),
26062623
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)