@@ -30,7 +30,7 @@ use lightning::ln::PaymentSecret;
30
30
use lightning:: ln:: features:: InvoiceFeatures ;
31
31
#[ cfg( any( doc, test) ) ]
32
32
use lightning:: routing:: network_graph:: RoutingFees ;
33
- use lightning:: routing:: router:: RouteHintHop ;
33
+ use lightning:: routing:: router:: RouteHint ;
34
34
35
35
use secp256k1:: key:: PublicKey ;
36
36
use secp256k1:: { Message , Secp256k1 } ;
@@ -362,7 +362,7 @@ pub enum TaggedField {
362
362
ExpiryTime ( ExpiryTime ) ,
363
363
MinFinalCltvExpiry ( MinFinalCltvExpiry ) ,
364
364
Fallback ( Fallback ) ,
365
- Route ( RouteHint ) ,
365
+ PrivateRoute ( PrivateRoute ) ,
366
366
PaymentSecret ( PaymentSecret ) ,
367
367
Features ( InvoiceFeatures ) ,
368
368
}
@@ -419,7 +419,7 @@ pub struct InvoiceSignature(pub RecoverableSignature);
419
419
/// The encoded route has to be <1024 5bit characters long (<=639 bytes or <=12 hops)
420
420
///
421
421
#[ derive( Eq , PartialEq , Debug , Clone ) ]
422
- pub struct RouteHint ( Vec < RouteHintHop > ) ;
422
+ pub struct PrivateRoute ( RouteHint ) ;
423
423
424
424
/// Tag constants as specified in BOLT11
425
425
#[ allow( missing_docs) ]
@@ -431,7 +431,7 @@ pub mod constants {
431
431
pub const TAG_EXPIRY_TIME : u8 = 6 ;
432
432
pub const TAG_MIN_FINAL_CLTV_EXPIRY : u8 = 24 ;
433
433
pub const TAG_FALLBACK : u8 = 9 ;
434
- pub const TAG_ROUTE : u8 = 3 ;
434
+ pub const TAG_PRIVATE_ROUTE : u8 = 3 ;
435
435
pub const TAG_PAYMENT_SECRET : u8 = 16 ;
436
436
pub const TAG_FEATURES : u8 = 5 ;
437
437
}
@@ -509,9 +509,9 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool> InvoiceBui
509
509
}
510
510
511
511
/// 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) ) ,
515
515
Err ( e) => self . error = Some ( e) ,
516
516
}
517
517
self
@@ -747,7 +747,7 @@ impl SignedRawInvoice {
747
747
/// Finds the first element of an enum stream of a given variant and extracts one member of the
748
748
/// variant. If no element was found `None` gets returned.
749
749
///
750
- /// The following example would extract the first
750
+ /// The following example would extract the first B.
751
751
/// ```
752
752
/// use Enum::*
753
753
///
@@ -761,11 +761,35 @@ impl SignedRawInvoice {
761
761
/// assert_eq!(find_extract!(elements.iter(), Enum::B(ref x), x), Some(3u16))
762
762
/// ```
763
763
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) => {
765
789
$iter. filter_map( |tf| match * tf {
766
790
$enm => Some ( $enm_var) ,
767
791
_ => None ,
768
- } ) . next ( )
792
+ } )
769
793
} ;
770
794
}
771
795
@@ -886,17 +910,11 @@ impl RawInvoice {
886
910
887
911
/// (C-not exported) as we don't support Vec<&NonOpaqueType>
888
912
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 ( )
893
914
}
894
915
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 ( )
900
918
}
901
919
902
920
pub fn amount_pico_btc ( & self ) -> Option < u64 > {
@@ -1048,7 +1066,7 @@ impl Invoice {
1048
1066
Ok ( ( ) )
1049
1067
}
1050
1068
1051
- /// Constructs an `Invoice` from a `SignedInvoice ` by checking all its invariants.
1069
+ /// Constructs an `Invoice` from a `SignedRawInvoice ` by checking all its invariants.
1052
1070
/// ```
1053
1071
/// use lightning_invoice::*;
1054
1072
///
@@ -1145,8 +1163,15 @@ impl Invoice {
1145
1163
}
1146
1164
1147
1165
/// 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 ( )
1150
1175
}
1151
1176
1152
1177
/// Returns the currency for which the invoice was issued
@@ -1177,7 +1202,7 @@ impl TaggedField {
1177
1202
TaggedField :: ExpiryTime ( _) => constants:: TAG_EXPIRY_TIME ,
1178
1203
TaggedField :: MinFinalCltvExpiry ( _) => constants:: TAG_MIN_FINAL_CLTV_EXPIRY ,
1179
1204
TaggedField :: Fallback ( _) => constants:: TAG_FALLBACK ,
1180
- TaggedField :: Route ( _) => constants:: TAG_ROUTE ,
1205
+ TaggedField :: PrivateRoute ( _) => constants:: TAG_PRIVATE_ROUTE ,
1181
1206
TaggedField :: PaymentSecret ( _) => constants:: TAG_PAYMENT_SECRET ,
1182
1207
TaggedField :: Features ( _) => constants:: TAG_FEATURES ,
1183
1208
} ;
@@ -1268,32 +1293,32 @@ impl ExpiryTime {
1268
1293
}
1269
1294
}
1270
1295
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) )
1276
1301
} else {
1277
1302
Err ( CreationError :: RouteTooLong )
1278
1303
}
1279
1304
}
1280
1305
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 {
1283
1308
self . 0
1284
1309
}
1285
1310
}
1286
1311
1287
- impl Into < Vec < RouteHintHop > > for RouteHint {
1288
- fn into ( self ) -> Vec < RouteHintHop > {
1312
+ impl Into < RouteHint > for PrivateRoute {
1313
+ fn into ( self ) -> RouteHint {
1289
1314
self . into_inner ( )
1290
1315
}
1291
1316
}
1292
1317
1293
- impl Deref for RouteHint {
1294
- type Target = Vec < RouteHintHop > ;
1318
+ impl Deref for PrivateRoute {
1319
+ type Target = RouteHint ;
1295
1320
1296
- fn deref ( & self ) -> & Vec < RouteHintHop > {
1321
+ fn deref ( & self ) -> & RouteHint {
1297
1322
& self . 0
1298
1323
}
1299
1324
}
@@ -1652,6 +1677,7 @@ mod test {
1652
1677
#[ test]
1653
1678
fn test_builder_fail ( ) {
1654
1679
use :: * ;
1680
+ use lightning:: routing:: router:: RouteHintHop ;
1655
1681
use std:: iter:: FromIterator ;
1656
1682
use secp256k1:: key:: PublicKey ;
1657
1683
@@ -1686,10 +1712,10 @@ mod test {
1686
1712
htlc_minimum_msat : None ,
1687
1713
htlc_maximum_msat : None ,
1688
1714
} ;
1689
- let too_long_route = vec ! [ route_hop; 13 ] ;
1715
+ let too_long_route = RouteHint ( vec ! [ route_hop; 13 ] ) ;
1690
1716
let long_route_res = builder. clone ( )
1691
1717
. description ( "Test" . into ( ) )
1692
- . route ( too_long_route)
1718
+ . private_route ( too_long_route)
1693
1719
. build_raw ( ) ;
1694
1720
assert_eq ! ( long_route_res, Err ( CreationError :: RouteTooLong ) ) ;
1695
1721
@@ -1704,6 +1730,7 @@ mod test {
1704
1730
#[ test]
1705
1731
fn test_builder_ok ( ) {
1706
1732
use :: * ;
1733
+ use lightning:: routing:: router:: RouteHintHop ;
1707
1734
use secp256k1:: Secp256k1 ;
1708
1735
use secp256k1:: key:: { SecretKey , PublicKey } ;
1709
1736
use std:: time:: { UNIX_EPOCH , Duration } ;
@@ -1719,7 +1746,7 @@ mod test {
1719
1746
) . unwrap ( ) ;
1720
1747
let public_key = PublicKey :: from_secret_key ( & secp_ctx, & private_key) ;
1721
1748
1722
- let route_1 = vec ! [
1749
+ let route_1 = RouteHint ( vec ! [
1723
1750
RouteHintHop {
1724
1751
src_node_id: public_key. clone( ) ,
1725
1752
short_channel_id: de:: parse_int_be( & [ 123 ; 8 ] , 256 ) . expect( "short chan ID slice too big?" ) ,
@@ -1742,9 +1769,9 @@ mod test {
1742
1769
htlc_minimum_msat: None ,
1743
1770
htlc_maximum_msat: None ,
1744
1771
}
1745
- ] ;
1772
+ ] ) ;
1746
1773
1747
- let route_2 = vec ! [
1774
+ let route_2 = RouteHint ( vec ! [
1748
1775
RouteHintHop {
1749
1776
src_node_id: public_key. clone( ) ,
1750
1777
short_channel_id: 0 ,
@@ -1767,7 +1794,7 @@ mod test {
1767
1794
htlc_minimum_msat: None ,
1768
1795
htlc_maximum_msat: None ,
1769
1796
}
1770
- ] ;
1797
+ ] ) ;
1771
1798
1772
1799
let builder = InvoiceBuilder :: new ( Currency :: BitcoinTestnet )
1773
1800
. amount_pico_btc ( 123 )
@@ -1776,8 +1803,8 @@ mod test {
1776
1803
. expiry_time ( Duration :: from_secs ( 54321 ) )
1777
1804
. min_final_cltv_expiry ( 144 )
1778
1805
. 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 ( ) )
1781
1808
. description_hash ( sha256:: Hash :: from_slice ( & [ 3 ; 32 ] [ ..] ) . unwrap ( ) )
1782
1809
. payment_hash ( sha256:: Hash :: from_slice ( & [ 21 ; 32 ] [ ..] ) . unwrap ( ) )
1783
1810
. payment_secret ( PaymentSecret ( [ 42 ; 32 ] ) )
@@ -1800,7 +1827,7 @@ mod test {
1800
1827
assert_eq ! ( invoice. expiry_time( ) , Duration :: from_secs( 54321 ) ) ;
1801
1828
assert_eq ! ( invoice. min_final_cltv_expiry( ) , 144 ) ;
1802
1829
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) ] ) ;
1804
1831
assert_eq ! (
1805
1832
invoice. description( ) ,
1806
1833
InvoiceDescription :: Hash ( & Sha256 ( sha256:: Hash :: from_slice( & [ 3 ; 32 ] [ ..] ) . unwrap( ) ) )
0 commit comments