Skip to content

Commit cd93a41

Browse files
committed
Remove message type bound on ResponseInstruction
Our onion message handlers generally have one or more methods which return a `ResponseInstruction` parameterized with the expected message type (enum) of the message handler. Sadly, that restriction is impossible to represent in our bindings - our bindings concretize all LDK structs, enums, and traits into a single concrete instance with generics set to our concrete trait instances (which hold a jump table). This prevents us from having multiple instances of `ResponseInstruction` structs for different message types. Our bindings do, however, support different parameterizations of standard enums, including `Option`s and tuples. In order to support bindings for the onion message handlers, we are thus forced into std types bound by expected message types, which we do here by making `ResponseInstruction` contain only the instructions and generally using it as a two-tuple of `(message, ResponseInstruction)`.
1 parent bbfa15e commit cd93a41

File tree

7 files changed

+97
-86
lines changed

7 files changed

+97
-86
lines changed

fuzz/src/onion_message.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ impl OffersMessageHandler for TestOffersMessageHandler {
109109
fn handle_message(
110110
&self, _message: OffersMessage, _context: Option<OffersContext>,
111111
_responder: Option<Responder>,
112-
) -> ResponseInstruction<OffersMessage> {
113-
ResponseInstruction::NoResponse
112+
) -> Option<(OffersMessage, ResponseInstruction)> {
113+
None
114114
}
115115
}
116116

@@ -119,13 +119,15 @@ struct TestAsyncPaymentsMessageHandler {}
119119
impl AsyncPaymentsMessageHandler for TestAsyncPaymentsMessageHandler {
120120
fn held_htlc_available(
121121
&self, message: HeldHtlcAvailable, responder: Option<Responder>,
122-
) -> ResponseInstruction<ReleaseHeldHtlc> {
122+
) -> Option<(ReleaseHeldHtlc, ResponseInstruction)> {
123123
let responder = match responder {
124124
Some(resp) => resp,
125-
None => return ResponseInstruction::NoResponse,
125+
None => return None,
126126
};
127-
responder
128-
.respond(ReleaseHeldHtlc { payment_release_secret: message.payment_release_secret })
127+
Some((
128+
ReleaseHeldHtlc { payment_release_secret: message.payment_release_secret },
129+
responder.respond(),
130+
))
129131
}
130132
fn release_held_htlc(&self, _message: ReleaseHeldHtlc) {}
131133
}
@@ -158,10 +160,10 @@ impl CustomOnionMessageHandler for TestCustomMessageHandler {
158160
fn handle_custom_message(
159161
&self, message: Self::CustomMessage, _context: Option<Vec<u8>>,
160162
responder: Option<Responder>,
161-
) -> ResponseInstruction<Self::CustomMessage> {
163+
) -> Option<(Self::CustomMessage, ResponseInstruction)> {
162164
match responder {
163-
Some(responder) => responder.respond(message),
164-
None => ResponseInstruction::NoResponse,
165+
Some(responder) => Some((message, responder.respond())),
166+
None => None,
165167
}
166168
}
167169
fn read_custom_message<R: io::Read>(

lightning/src/ln/channelmanager.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10749,41 +10749,41 @@ where
1074910749
{
1075010750
fn handle_message(
1075110751
&self, message: OffersMessage, context: Option<OffersContext>, responder: Option<Responder>,
10752-
) -> ResponseInstruction<OffersMessage> {
10752+
) -> Option<(OffersMessage, ResponseInstruction)> {
1075310753
let secp_ctx = &self.secp_ctx;
1075410754
let expanded_key = &self.inbound_payment_key;
1075510755

1075610756
match message {
1075710757
OffersMessage::InvoiceRequest(invoice_request) => {
1075810758
let responder = match responder {
1075910759
Some(responder) => responder,
10760-
None => return ResponseInstruction::NoResponse,
10760+
None => return None,
1076110761
};
1076210762

1076310763
let nonce = match context {
1076410764
None if invoice_request.metadata().is_some() => None,
1076510765
Some(OffersContext::InvoiceRequest { nonce }) => Some(nonce),
10766-
_ => return ResponseInstruction::NoResponse,
10766+
_ => return None,
1076710767
};
1076810768

1076910769
let invoice_request = match nonce {
1077010770
Some(nonce) => match invoice_request.verify_using_recipient_data(
1077110771
nonce, expanded_key, secp_ctx,
1077210772
) {
1077310773
Ok(invoice_request) => invoice_request,
10774-
Err(()) => return ResponseInstruction::NoResponse,
10774+
Err(()) => return None,
1077510775
},
1077610776
None => match invoice_request.verify_using_metadata(expanded_key, secp_ctx) {
1077710777
Ok(invoice_request) => invoice_request,
10778-
Err(()) => return ResponseInstruction::NoResponse,
10778+
Err(()) => return None,
1077910779
},
1078010780
};
1078110781

1078210782
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
1078310783
&invoice_request.inner
1078410784
) {
1078510785
Ok(amount_msats) => amount_msats,
10786-
Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())),
10786+
Err(error) => return Some((OffersMessage::InvoiceError(error.into()), responder.respond())),
1078710787
};
1078810788

1078910789
let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
@@ -10793,7 +10793,7 @@ where
1079310793
Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret),
1079410794
Err(()) => {
1079510795
let error = Bolt12SemanticError::InvalidAmount;
10796-
return responder.respond(OffersMessage::InvoiceError(error.into()));
10796+
return Some((OffersMessage::InvoiceError(error.into()), responder.respond()));
1079710797
},
1079810798
};
1079910799

@@ -10807,7 +10807,7 @@ where
1080710807
Ok(payment_paths) => payment_paths,
1080810808
Err(()) => {
1080910809
let error = Bolt12SemanticError::MissingPaths;
10810-
return responder.respond(OffersMessage::InvoiceError(error.into()));
10810+
return Some((OffersMessage::InvoiceError(error.into()), responder.respond()));
1081110811
},
1081210812
};
1081310813

@@ -10852,14 +10852,14 @@ where
1085210852
};
1085310853

1085410854
match response {
10855-
Ok(invoice) => responder.respond(OffersMessage::Invoice(invoice)),
10856-
Err(error) => responder.respond(OffersMessage::InvoiceError(error.into())),
10855+
Ok(invoice) => Some((OffersMessage::Invoice(invoice), responder.respond())),
10856+
Err(error) => Some((OffersMessage::InvoiceError(error.into()), responder.respond())),
1085710857
}
1085810858
},
1085910859
OffersMessage::Invoice(invoice) => {
1086010860
let payment_id = match self.verify_bolt12_invoice(&invoice, context.as_ref()) {
1086110861
Ok(payment_id) => payment_id,
10862-
Err(()) => return ResponseInstruction::NoResponse,
10862+
Err(()) => return None,
1086310863
};
1086410864

1086510865
let logger = WithContext::from(
@@ -10871,7 +10871,7 @@ where
1087110871
payment_id, invoice, context, responder,
1087210872
};
1087310873
self.pending_events.lock().unwrap().push_back((event, None));
10874-
return ResponseInstruction::NoResponse;
10874+
return None;
1087510875
}
1087610876

1087710877
let error = match self.send_payment_for_verified_bolt12_invoice(
@@ -10890,26 +10890,26 @@ where
1089010890
},
1089110891
Err(Bolt12PaymentError::UnexpectedInvoice)
1089210892
| Err(Bolt12PaymentError::DuplicateInvoice)
10893-
| Ok(()) => return ResponseInstruction::NoResponse,
10893+
| Ok(()) => return None,
1089410894
};
1089510895

1089610896
match responder {
10897-
Some(responder) => responder.respond(OffersMessage::InvoiceError(error)),
10897+
Some(responder) => Some((OffersMessage::InvoiceError(error), responder.respond())),
1089810898
None => {
1089910899
log_trace!(logger, "No reply path to send error: {:?}", error);
10900-
ResponseInstruction::NoResponse
10900+
None
1090110901
},
1090210902
}
1090310903
},
1090410904
#[cfg(async_payments)]
1090510905
OffersMessage::StaticInvoice(_invoice) => {
1090610906
match responder {
1090710907
Some(responder) => {
10908-
responder.respond(OffersMessage::InvoiceError(
10909-
InvoiceError::from_string("Static invoices not yet supported".to_string())
10910-
))
10908+
return Some((OffersMessage::InvoiceError(
10909+
InvoiceError::from_string("Static invoices not yet supported".to_string())
10910+
), responder.respond()));
1091110911
},
10912-
None => return ResponseInstruction::NoResponse,
10912+
None => return None,
1091310913
}
1091410914
},
1091510915
OffersMessage::InvoiceError(invoice_error) => {
@@ -10932,7 +10932,7 @@ where
1093210932
_ => {},
1093310933
}
1093410934

10935-
ResponseInstruction::NoResponse
10935+
None
1093610936
},
1093710937
}
1093810938
}
@@ -10956,8 +10956,8 @@ where
1095610956
{
1095710957
fn held_htlc_available(
1095810958
&self, _message: HeldHtlcAvailable, _responder: Option<Responder>
10959-
) -> ResponseInstruction<ReleaseHeldHtlc> {
10960-
ResponseInstruction::NoResponse
10959+
) -> Option<(ReleaseHeldHtlc, ResponseInstruction)> {
10960+
None
1096110961
}
1096210962

1096310963
fn release_held_htlc(&self, _message: ReleaseHeldHtlc) {}

lightning/src/ln/peer_handler.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,21 +144,21 @@ impl OnionMessageHandler for IgnoringMessageHandler {
144144
}
145145

146146
impl OffersMessageHandler for IgnoringMessageHandler {
147-
fn handle_message(&self, _message: OffersMessage, _context: Option<OffersContext>, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
148-
ResponseInstruction::NoResponse
147+
fn handle_message(&self, _message: OffersMessage, _context: Option<OffersContext>, _responder: Option<Responder>) -> Option<(OffersMessage, ResponseInstruction)> {
148+
None
149149
}
150150
}
151151
impl AsyncPaymentsMessageHandler for IgnoringMessageHandler {
152152
fn held_htlc_available(
153153
&self, _message: HeldHtlcAvailable, _responder: Option<Responder>,
154-
) -> ResponseInstruction<ReleaseHeldHtlc> {
155-
ResponseInstruction::NoResponse
154+
) -> Option<(ReleaseHeldHtlc, ResponseInstruction)> {
155+
None
156156
}
157157
fn release_held_htlc(&self, _message: ReleaseHeldHtlc) {}
158158
}
159159
impl CustomOnionMessageHandler for IgnoringMessageHandler {
160160
type CustomMessage = Infallible;
161-
fn handle_custom_message(&self, _message: Self::CustomMessage, _context: Option<Vec<u8>>, _responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
161+
fn handle_custom_message(&self, _message: Self::CustomMessage, _context: Option<Vec<u8>>, _responder: Option<Responder>) -> Option<(Infallible, ResponseInstruction)> {
162162
// Since we always return `None` in the read the handle method should never be called.
163163
unreachable!();
164164
}

lightning/src/onion_message/async_payments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub trait AsyncPaymentsMessageHandler {
3030
/// the held funds.
3131
fn held_htlc_available(
3232
&self, message: HeldHtlcAvailable, responder: Option<Responder>,
33-
) -> ResponseInstruction<ReleaseHeldHtlc>;
33+
) -> Option<(ReleaseHeldHtlc, ResponseInstruction)>;
3434

3535
/// Handle a [`ReleaseHeldHtlc`] message. If authentication of the message succeeds, an HTLC
3636
/// should be released to the corresponding payee.

lightning/src/onion_message/functional_tests.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ impl Drop for MessengerNode {
7676
struct TestOffersMessageHandler {}
7777

7878
impl OffersMessageHandler for TestOffersMessageHandler {
79-
fn handle_message(&self, _message: OffersMessage, _context: Option<OffersContext>, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
80-
ResponseInstruction::NoResponse
79+
fn handle_message(&self, _message: OffersMessage, _context: Option<OffersContext>, _responder: Option<Responder>) -> Option<(OffersMessage, ResponseInstruction)> {
80+
None
8181
}
8282
}
8383

@@ -86,8 +86,8 @@ struct TestAsyncPaymentsMessageHandler {}
8686
impl AsyncPaymentsMessageHandler for TestAsyncPaymentsMessageHandler {
8787
fn held_htlc_available(
8888
&self, _message: HeldHtlcAvailable, _responder: Option<Responder>,
89-
) -> ResponseInstruction<ReleaseHeldHtlc> {
90-
ResponseInstruction::NoResponse
89+
) -> Option<(ReleaseHeldHtlc, ResponseInstruction)> {
90+
None
9191
}
9292
fn release_held_htlc(&self, _message: ReleaseHeldHtlc) {}
9393
}
@@ -174,7 +174,7 @@ impl Drop for TestCustomMessageHandler {
174174

175175
impl CustomOnionMessageHandler for TestCustomMessageHandler {
176176
type CustomMessage = TestCustomMessage;
177-
fn handle_custom_message(&self, msg: Self::CustomMessage, context: Option<Vec<u8>>, responder: Option<Responder>) -> ResponseInstruction<Self::CustomMessage> {
177+
fn handle_custom_message(&self, msg: Self::CustomMessage, context: Option<Vec<u8>>, responder: Option<Responder>) -> Option<(Self::CustomMessage, ResponseInstruction)> {
178178
let expectation = self.get_next_expectation();
179179
assert_eq!(msg, expectation.expect);
180180

@@ -190,10 +190,10 @@ impl CustomOnionMessageHandler for TestCustomMessageHandler {
190190

191191
match responder {
192192
Some(responder) if expectation.include_reply_path => {
193-
responder.respond_with_reply_path(response, MessageContext::Custom(context.unwrap_or_else(Vec::new)))
193+
Some((response, responder.respond_with_reply_path(MessageContext::Custom(context.unwrap_or_else(Vec::new)))))
194194
},
195-
Some(responder) => responder.respond(response),
196-
None => ResponseInstruction::NoResponse,
195+
Some(responder) => Some((response, responder.respond())),
196+
None => None
197197
}
198198
}
199199
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, DecodeError> where Self: Sized {
@@ -444,8 +444,9 @@ fn async_response_over_one_blinded_hop() {
444444
let response_instruction = nodes[0].custom_message_handler.handle_custom_message(message, None, responder);
445445

446446
// 6. Simulate Alice asynchronously responding back to Bob with a response.
447+
let (msg, instructions) = response_instruction.unwrap();
447448
assert_eq!(
448-
nodes[0].messenger.handle_onion_message_response(response_instruction),
449+
nodes[0].messenger.handle_onion_message_response(msg, instructions),
449450
Ok(Some(SendSuccess::Buffered)),
450451
);
451452

@@ -477,8 +478,9 @@ fn async_response_with_reply_path_succeeds() {
477478
alice.custom_message_handler.expect_message_and_response(message.clone());
478479
let response_instruction = alice.custom_message_handler.handle_custom_message(message, None, Some(responder));
479480

481+
let (msg, instructions) = response_instruction.unwrap();
480482
assert_eq!(
481-
alice.messenger.handle_onion_message_response(response_instruction),
483+
alice.messenger.handle_onion_message_response(msg, instructions),
482484
Ok(Some(SendSuccess::Buffered)),
483485
);
484486

@@ -516,8 +518,9 @@ fn async_response_with_reply_path_fails() {
516518
alice.custom_message_handler.expect_message_and_response(message.clone());
517519
let response_instruction = alice.custom_message_handler.handle_custom_message(message, None, Some(responder));
518520

521+
let (msg, instructions) = response_instruction.unwrap();
519522
assert_eq!(
520-
alice.messenger.handle_onion_message_response(response_instruction),
523+
alice.messenger.handle_onion_message_response(msg, instructions),
521524
Err(SendError::PathNotFound),
522525
);
523526
}

0 commit comments

Comments
 (0)