Skip to content

Commit 7b4b753

Browse files
authored
Merge pull request #946 from jkczyz/2021-06-get-route-interface
Align get_route's interface with ChannelManager and Invoice
2 parents a8038a8 + d0355b7 commit 7b4b753

File tree

6 files changed

+123
-97
lines changed

6 files changed

+123
-97
lines changed

fuzz/src/router.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use lightning::chain::transaction::OutPoint;
1616
use lightning::ln::channelmanager::ChannelDetails;
1717
use lightning::ln::features::InitFeatures;
1818
use lightning::ln::msgs;
19-
use lightning::routing::router::{get_route, RouteHintHop};
19+
use lightning::routing::router::{get_route, RouteHint, RouteHintHop};
2020
use lightning::util::logger::Logger;
2121
use lightning::util::ser::Readable;
2222
use lightning::routing::network_graph::{NetworkGraph, RoutingFees};
@@ -225,13 +225,13 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
225225
Some(&first_hops_vec[..])
226226
},
227227
};
228-
let mut last_hops_vec = Vec::new();
228+
let mut last_hops = Vec::new();
229229
{
230230
let count = get_slice!(1)[0];
231231
for _ in 0..count {
232232
scid += 1;
233233
let rnid = node_pks.iter().skip(slice_to_be16(get_slice!(2))as usize % node_pks.len()).next().unwrap();
234-
last_hops_vec.push(RouteHintHop {
234+
last_hops.push(RouteHint(vec![RouteHintHop {
235235
src_node_id: *rnid,
236236
short_channel_id: scid,
237237
fees: RoutingFees {
@@ -241,10 +241,9 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
241241
cltv_expiry_delta: slice_to_be16(get_slice!(2)),
242242
htlc_minimum_msat: Some(slice_to_be64(get_slice!(8))),
243243
htlc_maximum_msat: None,
244-
});
244+
}]));
245245
}
246246
}
247-
let last_hops = &last_hops_vec[..];
248247
for target in node_pks.iter() {
249248
let _ = get_route(&our_pubkey, &net_graph, target, None,
250249
first_hops.map(|c| c.iter().collect::<Vec<_>>()).as_ref().map(|a| a.as_slice()),

lightning-invoice/src/de.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use bitcoin_hashes::Hash;
1212
use bitcoin_hashes::sha256;
1313
use lightning::ln::PaymentSecret;
1414
use lightning::routing::network_graph::RoutingFees;
15-
use lightning::routing::router::RouteHintHop;
15+
use lightning::routing::router::{RouteHint, RouteHintHop};
1616

1717
use num_traits::{CheckedAdd, CheckedMul};
1818

@@ -21,7 +21,7 @@ use secp256k1::recovery::{RecoveryId, RecoverableSignature};
2121
use secp256k1::key::PublicKey;
2222

2323
use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiry, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp,
24-
SemanticError, RouteHint, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice, constants, SignedRawInvoice,
24+
SemanticError, PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice, constants, SignedRawInvoice,
2525
RawDataPart, CreationError, InvoiceFeatures};
2626

2727
use self::hrp_sm::parse_hrp;
@@ -433,8 +433,8 @@ impl FromBase32 for TaggedField {
433433
Ok(TaggedField::MinFinalCltvExpiry(MinFinalCltvExpiry::from_base32(field_data)?)),
434434
constants::TAG_FALLBACK =>
435435
Ok(TaggedField::Fallback(Fallback::from_base32(field_data)?)),
436-
constants::TAG_ROUTE =>
437-
Ok(TaggedField::Route(RouteHint::from_base32(field_data)?)),
436+
constants::TAG_PRIVATE_ROUTE =>
437+
Ok(TaggedField::PrivateRoute(PrivateRoute::from_base32(field_data)?)),
438438
constants::TAG_PAYMENT_SECRET =>
439439
Ok(TaggedField::PaymentSecret(PaymentSecret::from_base32(field_data)?)),
440440
constants::TAG_FEATURES =>
@@ -558,10 +558,10 @@ impl FromBase32 for Fallback {
558558
}
559559
}
560560

561-
impl FromBase32 for RouteHint {
561+
impl FromBase32 for PrivateRoute {
562562
type Err = ParseError;
563563

564-
fn from_base32(field_data: &[u5]) -> Result<RouteHint, ParseError> {
564+
fn from_base32(field_data: &[u5]) -> Result<PrivateRoute, ParseError> {
565565
let bytes = Vec::<u8>::from_base32(field_data)?;
566566

567567
if bytes.len() % 51 != 0 {
@@ -593,7 +593,7 @@ impl FromBase32 for RouteHint {
593593
route_hops.push(hop);
594594
}
595595

596-
Ok(RouteHint(route_hops))
596+
Ok(PrivateRoute(RouteHint(route_hops)))
597597
}
598598
}
599599

@@ -930,8 +930,8 @@ mod test {
930930
#[test]
931931
fn test_parse_route() {
932932
use lightning::routing::network_graph::RoutingFees;
933-
use lightning::routing::router::RouteHintHop;
934-
use ::RouteHint;
933+
use lightning::routing::router::{RouteHint, RouteHintHop};
934+
use ::PrivateRoute;
935935
use bech32::FromBase32;
936936
use de::parse_int_be;
937937

@@ -976,10 +976,10 @@ mod test {
976976
htlc_maximum_msat: None
977977
});
978978

979-
assert_eq!(RouteHint::from_base32(&input), Ok(RouteHint(expected)));
979+
assert_eq!(PrivateRoute::from_base32(&input), Ok(PrivateRoute(RouteHint(expected))));
980980

981981
assert_eq!(
982-
RouteHint::from_base32(&[u5::try_from_u8(0).unwrap(); 40][..]),
982+
PrivateRoute::from_base32(&[u5::try_from_u8(0).unwrap(); 40][..]),
983983
Err(ParseError::UnexpectedEndOfTaggedFields)
984984
);
985985
}

lightning-invoice/src/lib.rs

+71-44
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use lightning::ln::PaymentSecret;
3030
use lightning::ln::features::InvoiceFeatures;
3131
#[cfg(any(doc, test))]
3232
use lightning::routing::network_graph::RoutingFees;
33-
use lightning::routing::router::RouteHintHop;
33+
use lightning::routing::router::RouteHint;
3434

3535
use secp256k1::key::PublicKey;
3636
use secp256k1::{Message, Secp256k1};
@@ -362,7 +362,7 @@ pub enum TaggedField {
362362
ExpiryTime(ExpiryTime),
363363
MinFinalCltvExpiry(MinFinalCltvExpiry),
364364
Fallback(Fallback),
365-
Route(RouteHint),
365+
PrivateRoute(PrivateRoute),
366366
PaymentSecret(PaymentSecret),
367367
Features(InvoiceFeatures),
368368
}
@@ -419,7 +419,7 @@ pub struct InvoiceSignature(pub RecoverableSignature);
419419
/// The encoded route has to be <1024 5bit characters long (<=639 bytes or <=12 hops)
420420
///
421421
#[derive(Eq, PartialEq, Debug, Clone)]
422-
pub struct RouteHint(Vec<RouteHintHop>);
422+
pub struct PrivateRoute(RouteHint);
423423

424424
/// Tag constants as specified in BOLT11
425425
#[allow(missing_docs)]
@@ -431,7 +431,7 @@ pub mod constants {
431431
pub const TAG_EXPIRY_TIME: u8 = 6;
432432
pub const TAG_MIN_FINAL_CLTV_EXPIRY: u8 = 24;
433433
pub const TAG_FALLBACK: u8 = 9;
434-
pub const TAG_ROUTE: u8 = 3;
434+
pub const TAG_PRIVATE_ROUTE: u8 = 3;
435435
pub const TAG_PAYMENT_SECRET: u8 = 16;
436436
pub const TAG_FEATURES: u8 = 5;
437437
}
@@ -509,9 +509,9 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
509509
}
510510

511511
/// Adds a private route.
512-
pub fn route(mut self, route: Vec<RouteHintHop>) -> Self {
513-
match RouteHint::new(route) {
514-
Ok(r) => self.tagged_fields.push(TaggedField::Route(r)),
512+
pub fn private_route(mut self, hint: RouteHint) -> Self {
513+
match PrivateRoute::new(hint) {
514+
Ok(r) => self.tagged_fields.push(TaggedField::PrivateRoute(r)),
515515
Err(e) => self.error = Some(e),
516516
}
517517
self
@@ -747,7 +747,7 @@ impl SignedRawInvoice {
747747
/// Finds the first element of an enum stream of a given variant and extracts one member of the
748748
/// variant. If no element was found `None` gets returned.
749749
///
750-
/// The following example would extract the first
750+
/// The following example would extract the first B.
751751
/// ```
752752
/// use Enum::*
753753
///
@@ -761,11 +761,35 @@ impl SignedRawInvoice {
761761
/// assert_eq!(find_extract!(elements.iter(), Enum::B(ref x), x), Some(3u16))
762762
/// ```
763763
macro_rules! find_extract {
764-
($iter:expr, $enm:pat, $enm_var:ident) => {
764+
($iter:expr, $enm:pat, $enm_var:ident) => {
765+
find_all_extract!($iter, $enm, $enm_var).next()
766+
};
767+
}
768+
769+
/// Finds the all elements of an enum stream of a given variant and extracts one member of the
770+
/// variant through an iterator.
771+
///
772+
/// The following example would extract all A.
773+
/// ```
774+
/// use Enum::*
775+
///
776+
/// enum Enum {
777+
/// A(u8),
778+
/// B(u16)
779+
/// }
780+
///
781+
/// let elements = vec![A(1), A(2), B(3), A(4)]
782+
///
783+
/// assert_eq!(
784+
/// find_all_extract!(elements.iter(), Enum::A(ref x), x).collect::<Vec<u8>>(),
785+
/// vec![1u8, 2u8, 4u8])
786+
/// ```
787+
macro_rules! find_all_extract {
788+
($iter:expr, $enm:pat, $enm_var:ident) => {
765789
$iter.filter_map(|tf| match *tf {
766790
$enm => Some($enm_var),
767791
_ => None,
768-
}).next()
792+
})
769793
};
770794
}
771795

@@ -886,17 +910,11 @@ impl RawInvoice {
886910

887911
/// (C-not exported) as we don't support Vec<&NonOpaqueType>
888912
pub fn fallbacks(&self) -> Vec<&Fallback> {
889-
self.known_tagged_fields().filter_map(|tf| match tf {
890-
&TaggedField::Fallback(ref f) => Some(f),
891-
_ => None,
892-
}).collect::<Vec<&Fallback>>()
913+
find_all_extract!(self.known_tagged_fields(), TaggedField::Fallback(ref x), x).collect()
893914
}
894915

895-
pub fn routes(&self) -> Vec<&RouteHint> {
896-
self.known_tagged_fields().filter_map(|tf| match tf {
897-
&TaggedField::Route(ref r) => Some(r),
898-
_ => None,
899-
}).collect::<Vec<&RouteHint>>()
916+
pub fn private_routes(&self) -> Vec<&PrivateRoute> {
917+
find_all_extract!(self.known_tagged_fields(), TaggedField::PrivateRoute(ref x), x).collect()
900918
}
901919

902920
pub fn amount_pico_btc(&self) -> Option<u64> {
@@ -1048,7 +1066,7 @@ impl Invoice {
10481066
Ok(())
10491067
}
10501068

1051-
/// Constructs an `Invoice` from a `SignedInvoice` by checking all its invariants.
1069+
/// Constructs an `Invoice` from a `SignedRawInvoice` by checking all its invariants.
10521070
/// ```
10531071
/// use lightning_invoice::*;
10541072
///
@@ -1145,8 +1163,15 @@ impl Invoice {
11451163
}
11461164

11471165
/// Returns a list of all routes included in the invoice
1148-
pub fn routes(&self) -> Vec<&RouteHint> {
1149-
self.signed_invoice.routes()
1166+
pub fn private_routes(&self) -> Vec<&PrivateRoute> {
1167+
self.signed_invoice.private_routes()
1168+
}
1169+
1170+
/// Returns a list of all routes included in the invoice as the underlying hints
1171+
pub fn route_hints(&self) -> Vec<&RouteHint> {
1172+
find_all_extract!(
1173+
self.signed_invoice.known_tagged_fields(), TaggedField::PrivateRoute(ref x), x
1174+
).map(|route| &**route).collect()
11501175
}
11511176

11521177
/// Returns the currency for which the invoice was issued
@@ -1177,7 +1202,7 @@ impl TaggedField {
11771202
TaggedField::ExpiryTime(_) => constants::TAG_EXPIRY_TIME,
11781203
TaggedField::MinFinalCltvExpiry(_) => constants::TAG_MIN_FINAL_CLTV_EXPIRY,
11791204
TaggedField::Fallback(_) => constants::TAG_FALLBACK,
1180-
TaggedField::Route(_) => constants::TAG_ROUTE,
1205+
TaggedField::PrivateRoute(_) => constants::TAG_PRIVATE_ROUTE,
11811206
TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET,
11821207
TaggedField::Features(_) => constants::TAG_FEATURES,
11831208
};
@@ -1268,32 +1293,32 @@ impl ExpiryTime {
12681293
}
12691294
}
12701295

1271-
impl RouteHint {
1272-
/// Create a new (partial) route from a list of hops
1273-
pub fn new(hops: Vec<RouteHintHop>) -> Result<RouteHint, CreationError> {
1274-
if hops.len() <= 12 {
1275-
Ok(RouteHint(hops))
1296+
impl PrivateRoute {
1297+
/// Creates a new (partial) route from a list of hops
1298+
pub fn new(hops: RouteHint) -> Result<PrivateRoute, CreationError> {
1299+
if hops.0.len() <= 12 {
1300+
Ok(PrivateRoute(hops))
12761301
} else {
12771302
Err(CreationError::RouteTooLong)
12781303
}
12791304
}
12801305

1281-
/// Returrn the underlying vector of hops
1282-
pub fn into_inner(self) -> Vec<RouteHintHop> {
1306+
/// Returns the underlying list of hops
1307+
pub fn into_inner(self) -> RouteHint {
12831308
self.0
12841309
}
12851310
}
12861311

1287-
impl Into<Vec<RouteHintHop>> for RouteHint {
1288-
fn into(self) -> Vec<RouteHintHop> {
1312+
impl Into<RouteHint> for PrivateRoute {
1313+
fn into(self) -> RouteHint {
12891314
self.into_inner()
12901315
}
12911316
}
12921317

1293-
impl Deref for RouteHint {
1294-
type Target = Vec<RouteHintHop>;
1318+
impl Deref for PrivateRoute {
1319+
type Target = RouteHint;
12951320

1296-
fn deref(&self) -> &Vec<RouteHintHop> {
1321+
fn deref(&self) -> &RouteHint {
12971322
&self.0
12981323
}
12991324
}
@@ -1652,6 +1677,7 @@ mod test {
16521677
#[test]
16531678
fn test_builder_fail() {
16541679
use ::*;
1680+
use lightning::routing::router::RouteHintHop;
16551681
use std::iter::FromIterator;
16561682
use secp256k1::key::PublicKey;
16571683

@@ -1686,10 +1712,10 @@ mod test {
16861712
htlc_minimum_msat: None,
16871713
htlc_maximum_msat: None,
16881714
};
1689-
let too_long_route = vec![route_hop; 13];
1715+
let too_long_route = RouteHint(vec![route_hop; 13]);
16901716
let long_route_res = builder.clone()
16911717
.description("Test".into())
1692-
.route(too_long_route)
1718+
.private_route(too_long_route)
16931719
.build_raw();
16941720
assert_eq!(long_route_res, Err(CreationError::RouteTooLong));
16951721

@@ -1704,6 +1730,7 @@ mod test {
17041730
#[test]
17051731
fn test_builder_ok() {
17061732
use ::*;
1733+
use lightning::routing::router::RouteHintHop;
17071734
use secp256k1::Secp256k1;
17081735
use secp256k1::key::{SecretKey, PublicKey};
17091736
use std::time::{UNIX_EPOCH, Duration};
@@ -1719,7 +1746,7 @@ mod test {
17191746
).unwrap();
17201747
let public_key = PublicKey::from_secret_key(&secp_ctx, &private_key);
17211748

1722-
let route_1 = vec![
1749+
let route_1 = RouteHint(vec![
17231750
RouteHintHop {
17241751
src_node_id: public_key.clone(),
17251752
short_channel_id: de::parse_int_be(&[123; 8], 256).expect("short chan ID slice too big?"),
@@ -1742,9 +1769,9 @@ mod test {
17421769
htlc_minimum_msat: None,
17431770
htlc_maximum_msat: None,
17441771
}
1745-
];
1772+
]);
17461773

1747-
let route_2 = vec![
1774+
let route_2 = RouteHint(vec![
17481775
RouteHintHop {
17491776
src_node_id: public_key.clone(),
17501777
short_channel_id: 0,
@@ -1767,7 +1794,7 @@ mod test {
17671794
htlc_minimum_msat: None,
17681795
htlc_maximum_msat: None,
17691796
}
1770-
];
1797+
]);
17711798

17721799
let builder = InvoiceBuilder::new(Currency::BitcoinTestnet)
17731800
.amount_pico_btc(123)
@@ -1776,8 +1803,8 @@ mod test {
17761803
.expiry_time(Duration::from_secs(54321))
17771804
.min_final_cltv_expiry(144)
17781805
.fallback(Fallback::PubKeyHash([0;20]))
1779-
.route(route_1.clone())
1780-
.route(route_2.clone())
1806+
.private_route(route_1.clone())
1807+
.private_route(route_2.clone())
17811808
.description_hash(sha256::Hash::from_slice(&[3;32][..]).unwrap())
17821809
.payment_hash(sha256::Hash::from_slice(&[21;32][..]).unwrap())
17831810
.payment_secret(PaymentSecret([42; 32]))
@@ -1800,7 +1827,7 @@ mod test {
18001827
assert_eq!(invoice.expiry_time(), Duration::from_secs(54321));
18011828
assert_eq!(invoice.min_final_cltv_expiry(), 144);
18021829
assert_eq!(invoice.fallbacks(), vec![&Fallback::PubKeyHash([0;20])]);
1803-
assert_eq!(invoice.routes(), vec![&RouteHint(route_1), &RouteHint(route_2)]);
1830+
assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]);
18041831
assert_eq!(
18051832
invoice.description(),
18061833
InvoiceDescription::Hash(&Sha256(sha256::Hash::from_slice(&[3;32][..]).unwrap()))

0 commit comments

Comments
 (0)