Skip to content

Commit e58b47f

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 ba3d4ff commit e58b47f

File tree

13 files changed

+96
-87
lines changed

13 files changed

+96
-87
lines changed

fuzz/src/chanmon_consistency.rs

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

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

fuzz/src/full_stack.rs

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

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

fuzz/src/onion_message.rs

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

101101
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
102-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
103-
_secp_ctx: &Secp256k1<T>,
102+
&self, _recipient: PublicKey, _context: MessageContext, _custom_tlvs: Vec<u8>,
103+
_peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
104104
) -> Result<Vec<BlindedMessagePath>, ()> {
105105
unreachable!()
106106
}
@@ -111,7 +111,7 @@ struct TestOffersMessageHandler {}
111111
impl OffersMessageHandler for TestOffersMessageHandler {
112112
fn handle_message(
113113
&self, _message: OffersMessage, _context: Option<OffersContext>,
114-
_responder: Option<Responder>,
114+
_custom_tlvs: Option<Vec<u8>>, _responder: Option<Responder>,
115115
) -> Option<(OffersMessage, ResponseInstruction)> {
116116
None
117117
}

lightning-dns-resolver/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,11 @@ mod test {
225225
}
226226

227227
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
228-
&self, recipient: PublicKey, context: MessageContext, _peers: Vec<PublicKey>,
229-
secp_ctx: &Secp256k1<T>,
228+
&self, recipient: PublicKey, context: MessageContext, custom_tlvs: Vec<u8>,
229+
_peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
230230
) -> Result<Vec<BlindedMessagePath>, ()> {
231231
let keys = KeysManager::new(&[0; 32], 42, 43);
232-
Ok(vec![BlindedMessagePath::one_hop(recipient, context, &keys, secp_ctx).unwrap()])
232+
Ok(vec![BlindedMessagePath::one_hop(recipient, context, custom_tlvs, &keys, secp_ctx).unwrap()])
233233
}
234234
}
235235
impl Deref for DirectlyConnectedRouter {
@@ -332,7 +332,7 @@ mod test {
332332
payer.resolver.resolve_name(payment_id, name.clone(), &*payer_keys).unwrap();
333333
let query_context = MessageContext::DNSResolver(context);
334334
let reply_path =
335-
BlindedMessagePath::one_hop(payer_id, query_context, &*payer_keys, &secp_ctx).unwrap();
335+
BlindedMessagePath::one_hop(payer_id, query_context, Vec::new(), &*payer_keys, &secp_ctx).unwrap();
336336
payer.pending_messages.lock().unwrap().push((
337337
DNSResolverMessage::DNSSECQuery(msg),
338338
MessageSendInstructions::WithSpecifiedReplyPath {

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
@@ -10421,7 +10421,7 @@ where
1042110421
.collect::<Vec<_>>();
1042210422

1042310423
self.message_router
10424-
.create_blinded_paths(recipient, context, peers, secp_ctx)
10424+
.create_blinded_paths(recipient, context, Vec::new(), peers, secp_ctx)
1042510425
.and_then(|paths| (!paths.is_empty()).then(|| paths).ok_or(()))
1042610426
}
1042710427

@@ -10449,7 +10449,7 @@ where
1044910449
.collect::<Vec<_>>();
1045010450

1045110451
self.message_router
10452-
.create_compact_blinded_paths(recipient, MessageContext::Offers(context), peers, secp_ctx)
10452+
.create_compact_blinded_paths(recipient, MessageContext::Offers(context), Vec::new(), peers, secp_ctx)
1045310453
.and_then(|paths| (!paths.is_empty()).then(|| paths).ok_or(()))
1045410454
}
1045510455

@@ -11915,7 +11915,7 @@ where
1191511915
L::Target: Logger,
1191611916
{
1191711917
fn handle_message(
11918-
&self, message: OffersMessage, context: Option<OffersContext>, responder: Option<Responder>,
11918+
&self, message: OffersMessage, context: Option<OffersContext>, custom_tlvs: Option<Vec<u8>>, responder: Option<Responder>,
1191911919
) -> Option<(OffersMessage, ResponseInstruction)> {
1192011920
let secp_ctx = &self.secp_ctx;
1192111921
let expanded_key = &self.inbound_payment_key;
@@ -12058,7 +12058,7 @@ where
1205812058
let nonce = Nonce::from_entropy_source(&*self.entropy_source);
1205912059
let hmac = payment_hash.hmac_for_offer_payment(nonce, expanded_key);
1206012060
let context = MessageContext::Offers(OffersContext::InboundPayment { payment_hash, nonce, hmac });
12061-
Some((OffersMessage::Invoice(invoice), responder.respond_with_reply_path(context)))
12061+
Some((OffersMessage::Invoice(invoice), responder.respond_with_reply_path(context, custom_tlvs)))
1206212062
},
1206312063
Err(error) => Some((OffersMessage::InvoiceError(error.into()), responder.respond())),
1206412064
}

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)