Skip to content

Commit 53996cc

Browse files
committed
Add Custom TLVs for message::ReceiveTlvs
- This update lets users add their own custom TLVs to the reply path of a sent onion message. - By including these custom TLVs, users can send custom data with the message and get it back in the response.
1 parent c35adff commit 53996cc

12 files changed

+92
-83
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ impl MessageRouter for FuzzRouter {
142142
}
143143

144144
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
145-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
146-
_secp_ctx: &Secp256k1<T>,
145+
&self, _recipient: PublicKey, _context: MessageContext, _custom_tlvs: Vec<u8>,
146+
_peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
147147
) -> Result<Vec<BlindedMessagePath>, ()> {
148148
unreachable!()
149149
}

fuzz/src/full_stack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ impl MessageRouter for FuzzRouter {
177177
}
178178

179179
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
180-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
181-
_secp_ctx: &Secp256k1<T>,
180+
&self, _recipient: PublicKey, _context: MessageContext, _custom_tlvs: Vec<u8>,
181+
_peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
182182
) -> Result<Vec<BlindedMessagePath>, ()> {
183183
unreachable!()
184184
}

fuzz/src/onion_message.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ impl MessageRouter for TestMessageRouter {
100100
}
101101

102102
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
103-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
104-
_secp_ctx: &Secp256k1<T>,
103+
&self, _recipient: PublicKey, _context: MessageContext, _custom_tlvs: Vec<u8>,
104+
_peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
105105
) -> Result<Vec<BlindedMessagePath>, ()> {
106106
unreachable!()
107107
}
@@ -112,7 +112,7 @@ struct TestOffersMessageHandler {}
112112
impl OffersMessageHandler for TestOffersMessageHandler {
113113
fn handle_message(
114114
&self, _message: OffersMessage, _context: Option<OffersContext>,
115-
_responder: Option<Responder>,
115+
_custom_tlvs: Option<Vec<u8>>, _responder: Option<Responder>,
116116
) -> Option<(OffersMessage, ResponseInstruction)> {
117117
None
118118
}

lightning/src/blinded_path/message.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ impl Readable for BlindedMessagePath {
5555
impl BlindedMessagePath {
5656
/// Create a one-hop blinded path for a message.
5757
pub fn one_hop<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
58-
recipient_node_id: PublicKey, context: MessageContext, entropy_source: ES, secp_ctx: &Secp256k1<T>
58+
recipient_node_id: PublicKey, context: MessageContext, custom_tlvs: Vec<u8>, entropy_source: ES, secp_ctx: &Secp256k1<T>
5959
) -> Result<Self, ()> where ES::Target: EntropySource {
60-
Self::new(&[], recipient_node_id, context, entropy_source, secp_ctx)
60+
Self::new(&[], recipient_node_id, context, custom_tlvs, entropy_source, secp_ctx)
6161
}
6262

6363
/// Create a path for an onion message, to be forwarded along `node_pks`. The last node
@@ -67,7 +67,7 @@ impl BlindedMessagePath {
6767
// TODO: make all payloads the same size with padding + add dummy hops
6868
pub fn new<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
6969
intermediate_nodes: &[MessageForwardNode], recipient_node_id: PublicKey,
70-
context: MessageContext, entropy_source: ES, secp_ctx: &Secp256k1<T>,
70+
context: MessageContext, custom_tlvs: Vec<u8>, entropy_source: ES, secp_ctx: &Secp256k1<T>,
7171
) -> Result<Self, ()> where ES::Target: EntropySource {
7272
let introduction_node = IntroductionNode::NodeId(
7373
intermediate_nodes.first().map_or(recipient_node_id, |n| n.node_id)
@@ -80,7 +80,7 @@ impl BlindedMessagePath {
8080
blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret),
8181
blinded_hops: blinded_hops(
8282
secp_ctx, intermediate_nodes, recipient_node_id,
83-
context, &blinding_secret,
83+
context, custom_tlvs, &blinding_secret,
8484
).map_err(|_| ())?,
8585
}))
8686
}
@@ -241,7 +241,10 @@ pub(crate) struct ReceiveTlvs {
241241
/// If `context` is `Some`, it is used to identify the blinded path that this onion message is
242242
/// sending to. This is useful for receivers to check that said blinded path is being used in
243243
/// the right context.
244-
pub context: Option<MessageContext>
244+
pub context: Option<MessageContext>,
245+
246+
/// Custom Tlvs. A user can use this to send custom tlvs information back to themself.
247+
pub custom_tlvs: Option<Vec<u8>>,
245248
}
246249

247250
impl Writeable for ForwardTlvs {
@@ -265,6 +268,7 @@ impl Writeable for ReceiveTlvs {
265268
// TODO: write padding
266269
encode_tlv_stream!(writer, {
267270
(65537, self.context, option),
271+
(65539, self.custom_tlvs, option),
268272
});
269273
Ok(())
270274
}
@@ -456,7 +460,7 @@ impl_writeable_tlv_based!(DNSResolverContext, {
456460
/// Construct blinded onion message hops for the given `intermediate_nodes` and `recipient_node_id`.
457461
pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
458462
secp_ctx: &Secp256k1<T>, intermediate_nodes: &[MessageForwardNode],
459-
recipient_node_id: PublicKey, context: MessageContext, session_priv: &SecretKey,
463+
recipient_node_id: PublicKey, context: MessageContext, custom_tlvs: Vec<u8>, session_priv: &SecretKey,
460464
) -> Result<Vec<BlindedHop>, secp256k1::Error> {
461465
let pks = intermediate_nodes.iter().map(|node| node.node_id)
462466
.chain(core::iter::once(recipient_node_id));
@@ -468,7 +472,7 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
468472
None => NextMessageHop::NodeId(pubkey),
469473
})
470474
.map(|next_hop| ControlTlvs::Forward(ForwardTlvs { next_hop, next_blinding_override: None }))
471-
.chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs{ context: Some(context) })));
475+
.chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs{ context: Some(context), custom_tlvs: Some(custom_tlvs) })));
472476

473477
let path = pks.zip(tlvs);
474478

lightning/src/ln/channelmanager.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9792,7 +9792,7 @@ where
97929792
.collect::<Vec<_>>();
97939793

97949794
self.message_router
9795-
.create_blinded_paths(recipient, context, peers, secp_ctx)
9795+
.create_blinded_paths(recipient, context, Vec::new(), peers, secp_ctx)
97969796
.and_then(|paths| (!paths.is_empty()).then(|| paths).ok_or(()))
97979797
}
97989798

@@ -9820,7 +9820,7 @@ where
98209820
.collect::<Vec<_>>();
98219821

98229822
self.message_router
9823-
.create_compact_blinded_paths(recipient, MessageContext::Offers(context), peers, secp_ctx)
9823+
.create_compact_blinded_paths(recipient, MessageContext::Offers(context), Vec::new(), peers, secp_ctx)
98249824
.and_then(|paths| (!paths.is_empty()).then(|| paths).ok_or(()))
98259825
}
98269826

@@ -11268,7 +11268,7 @@ where
1126811268
L::Target: Logger,
1126911269
{
1127011270
fn handle_message(
11271-
&self, message: OffersMessage, context: Option<OffersContext>, responder: Option<Responder>,
11271+
&self, message: OffersMessage, context: Option<OffersContext>, custom_tlvs: Option<Vec<u8>>, responder: Option<Responder>,
1127211272
) -> Option<(OffersMessage, ResponseInstruction)> {
1127311273
let secp_ctx = &self.secp_ctx;
1127411274
let expanded_key = &self.inbound_payment_key;
@@ -11411,7 +11411,7 @@ where
1141111411
let nonce = Nonce::from_entropy_source(&*self.entropy_source);
1141211412
let hmac = payment_hash.hmac_for_offer_payment(nonce, expanded_key);
1141311413
let context = MessageContext::Offers(OffersContext::InboundPayment { payment_hash, nonce, hmac });
11414-
Some((OffersMessage::Invoice(invoice), responder.respond_with_reply_path(context)))
11414+
Some((OffersMessage::Invoice(invoice), responder.respond_with_reply_path(context, custom_tlvs)))
1141511415
},
1141611416
Err(error) => Some((OffersMessage::InvoiceError(error.into()), responder.respond())),
1141711417
}

lightning/src/ln/offers_tests.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ fn claim_bolt12_payment<'a, 'b, 'c>(
193193

194194
fn extract_offer_nonce<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, message: &OnionMessage) -> Nonce {
195195
match node.onion_messenger.peel_onion_message(message) {
196-
Ok(PeeledOnion::Receive(_, Some(MessageContext::Offers(OffersContext::InvoiceRequest { nonce })), _)) => nonce,
197-
Ok(PeeledOnion::Receive(_, context, _)) => panic!("Unexpected onion message context: {:?}", context),
196+
Ok(PeeledOnion::Receive(_, Some(MessageContext::Offers(OffersContext::InvoiceRequest { nonce })), _, _)) => nonce,
197+
Ok(PeeledOnion::Receive(_, context, _, _)) => panic!("Unexpected onion message context: {:?}", context),
198198
Ok(PeeledOnion::Forward(_, _)) => panic!("Unexpected onion message forward"),
199199
Err(e) => panic!("Failed to process onion message {:?}", e),
200200
}
@@ -204,7 +204,7 @@ fn extract_invoice_request<'a, 'b, 'c>(
204204
node: &Node<'a, 'b, 'c>, message: &OnionMessage
205205
) -> (InvoiceRequest, BlindedMessagePath) {
206206
match node.onion_messenger.peel_onion_message(message) {
207-
Ok(PeeledOnion::Receive(message, _, reply_path)) => match message {
207+
Ok(PeeledOnion::Receive(message, _, _, reply_path)) => match message {
208208
ParsedOnionMessageContents::Offers(offers_message) => match offers_message {
209209
OffersMessage::InvoiceRequest(invoice_request) => (invoice_request, reply_path.unwrap()),
210210
OffersMessage::Invoice(invoice) => panic!("Unexpected invoice: {:?}", invoice),
@@ -221,7 +221,7 @@ fn extract_invoice_request<'a, 'b, 'c>(
221221

222222
fn extract_invoice<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, message: &OnionMessage) -> (Bolt12Invoice, BlindedMessagePath) {
223223
match node.onion_messenger.peel_onion_message(message) {
224-
Ok(PeeledOnion::Receive(message, _, reply_path)) => match message {
224+
Ok(PeeledOnion::Receive(message, _, _, reply_path)) => match message {
225225
ParsedOnionMessageContents::Offers(offers_message) => match offers_message {
226226
OffersMessage::InvoiceRequest(invoice_request) => panic!("Unexpected invoice_request: {:?}", invoice_request),
227227
OffersMessage::Invoice(invoice) => (invoice, reply_path.unwrap()),
@@ -240,7 +240,7 @@ fn extract_invoice_error<'a, 'b, 'c>(
240240
node: &Node<'a, 'b, 'c>, message: &OnionMessage
241241
) -> InvoiceError {
242242
match node.onion_messenger.peel_onion_message(message) {
243-
Ok(PeeledOnion::Receive(message, _, _)) => match message {
243+
Ok(PeeledOnion::Receive(message, _, _, _)) => match message {
244244
ParsedOnionMessageContents::Offers(offers_message) => match offers_message {
245245
OffersMessage::InvoiceRequest(invoice_request) => panic!("Unexpected invoice_request: {:?}", invoice_request),
246246
OffersMessage::Invoice(invoice) => panic!("Unexpected invoice: {:?}", invoice),

lightning/src/ln/peer_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl OnionMessageHandler for IgnoringMessageHandler {
143143
}
144144

145145
impl OffersMessageHandler for IgnoringMessageHandler {
146-
fn handle_message(&self, _message: OffersMessage, _context: Option<OffersContext>, _responder: Option<Responder>) -> Option<(OffersMessage, ResponseInstruction)> {
146+
fn handle_message(&self, _message: OffersMessage, _context: Option<OffersContext>, _custom_tlvs: Option<Vec<u8>>, _responder: Option<Responder>) -> Option<(OffersMessage, ResponseInstruction)> {
147147
None
148148
}
149149
}

0 commit comments

Comments
 (0)