Skip to content

Commit 6fa1cb2

Browse files
authored
Merge pull request #2897 from TheBlueMatt/2024-02-fix-route-ser
Fix `Route` serialization round-trip
2 parents e32020c + 24d02ff commit 6fa1cb2

File tree

3 files changed

+26
-75
lines changed

3 files changed

+26
-75
lines changed

lightning/src/ln/outbound_payment.rs

-59
Original file line numberDiff line numberDiff line change
@@ -2283,65 +2283,6 @@ mod tests {
22832283
assert!(pending_events.lock().unwrap().is_empty());
22842284
}
22852285

2286-
#[test]
2287-
fn fails_paying_for_bolt12_invoice() {
2288-
let logger = test_utils::TestLogger::new();
2289-
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
2290-
let scorer = RwLock::new(test_utils::TestScorer::new());
2291-
let router = test_utils::TestRouter::new(network_graph, &logger, &scorer);
2292-
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
2293-
2294-
let pending_events = Mutex::new(VecDeque::new());
2295-
let outbound_payments = OutboundPayments::new();
2296-
let payment_id = PaymentId([0; 32]);
2297-
let expiration = StaleExpiration::AbsoluteTimeout(Duration::from_secs(100));
2298-
2299-
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
2300-
.amount_msats(1000)
2301-
.build().unwrap()
2302-
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
2303-
.build().unwrap()
2304-
.sign(payer_sign).unwrap()
2305-
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2306-
.build().unwrap()
2307-
.sign(recipient_sign).unwrap();
2308-
2309-
assert!(
2310-
outbound_payments.add_new_awaiting_invoice(
2311-
payment_id, expiration, Retry::Attempts(0),
2312-
Some(invoice.amount_msats() / 100 + 50_000)
2313-
).is_ok()
2314-
);
2315-
assert!(outbound_payments.has_pending_payments());
2316-
2317-
let route_params = RouteParameters::from_payment_params_and_value(
2318-
PaymentParameters::from_bolt12_invoice(&invoice),
2319-
invoice.amount_msats(),
2320-
);
2321-
router.expect_find_route(
2322-
route_params.clone(), Ok(Route { paths: vec![], route_params: Some(route_params) })
2323-
);
2324-
2325-
assert_eq!(
2326-
outbound_payments.send_payment_for_bolt12_invoice(
2327-
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2328-
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2329-
),
2330-
Ok(()),
2331-
);
2332-
assert!(!outbound_payments.has_pending_payments());
2333-
2334-
let payment_hash = invoice.payment_hash();
2335-
let reason = Some(PaymentFailureReason::UnexpectedError);
2336-
2337-
assert!(!pending_events.lock().unwrap().is_empty());
2338-
assert_eq!(
2339-
pending_events.lock().unwrap().pop_front(),
2340-
Some((Event::PaymentFailed { payment_id, payment_hash, reason }, None)),
2341-
);
2342-
assert!(pending_events.lock().unwrap().is_empty());
2343-
}
2344-
23452286
#[test]
23462287
fn sends_payment_for_bolt12_invoice() {
23472288
let logger = test_utils::TestLogger::new();

lightning/src/routing/router.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -505,28 +505,28 @@ impl Writeable for Route {
505505
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
506506
(self.paths.len() as u64).write(writer)?;
507507
let mut blinded_tails = Vec::new();
508-
for path in self.paths.iter() {
508+
for (idx, path) in self.paths.iter().enumerate() {
509509
(path.hops.len() as u8).write(writer)?;
510-
for (idx, hop) in path.hops.iter().enumerate() {
510+
for hop in path.hops.iter() {
511511
hop.write(writer)?;
512-
if let Some(blinded_tail) = &path.blinded_tail {
513-
if blinded_tails.is_empty() {
514-
blinded_tails = Vec::with_capacity(path.hops.len());
515-
for _ in 0..idx {
516-
blinded_tails.push(None);
517-
}
518-
}
519-
blinded_tails.push(Some(blinded_tail));
520-
} else if !blinded_tails.is_empty() { blinded_tails.push(None); }
521512
}
513+
if let Some(blinded_tail) = &path.blinded_tail {
514+
if blinded_tails.is_empty() {
515+
blinded_tails = Vec::with_capacity(path.hops.len());
516+
for _ in 0..idx {
517+
blinded_tails.push(None);
518+
}
519+
}
520+
blinded_tails.push(Some(blinded_tail));
521+
} else if !blinded_tails.is_empty() { blinded_tails.push(None); }
522522
}
523523
write_tlv_fields!(writer, {
524524
// For compatibility with LDK versions prior to 0.0.117, we take the individual
525525
// RouteParameters' fields and reconstruct them on read.
526526
(1, self.route_params.as_ref().map(|p| &p.payment_params), option),
527527
(2, blinded_tails, optional_vec),
528528
(3, self.route_params.as_ref().map(|p| p.final_value_msat), option),
529-
(5, self.route_params.as_ref().map(|p| p.max_total_routing_fee_msat), option),
529+
(5, self.route_params.as_ref().and_then(|p| p.max_total_routing_fee_msat), option),
530530
});
531531
Ok(())
532532
}

lightning/src/util/test_utils.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ impl<'a> Router for TestRouter<'a> {
143143
&self, payer: &PublicKey, params: &RouteParameters, first_hops: Option<&[&ChannelDetails]>,
144144
inflight_htlcs: InFlightHtlcs
145145
) -> Result<Route, msgs::LightningError> {
146-
if let Some((find_route_query, find_route_res)) = self.next_routes.lock().unwrap().pop_front() {
146+
let route_res;
147+
let next_route_opt = self.next_routes.lock().unwrap().pop_front();
148+
if let Some((find_route_query, find_route_res)) = next_route_opt {
147149
assert_eq!(find_route_query, *params);
148150
if let Ok(ref route) = find_route_res {
149151
assert_eq!(route.route_params, Some(find_route_query));
@@ -201,10 +203,18 @@ impl<'a> Router for TestRouter<'a> {
201203
}
202204
}
203205
}
204-
return find_route_res;
205-
}
206+
route_res = find_route_res;
207+
} else {
208+
route_res = self.router.find_route(payer, params, first_hops, inflight_htlcs);
209+
};
206210

207-
self.router.find_route(payer, params, first_hops, inflight_htlcs)
211+
if let Ok(route) = &route_res {
212+
// Previously, `Route`s failed to round-trip through serialization due to a write/read
213+
// mismatch. Thus, here we test all test-generated routes round-trip:
214+
let ser = route.encode();
215+
assert_eq!(Route::read(&mut &ser[..]).unwrap(), *route);
216+
}
217+
route_res
208218
}
209219

210220
fn create_blinded_payment_paths<

0 commit comments

Comments
 (0)