@@ -17,7 +17,7 @@ use bitcoin::secp256k1::PublicKey;
17
17
use ln:: channelmanager:: ChannelDetails ;
18
18
use ln:: features:: { ChannelFeatures , InvoiceFeatures , NodeFeatures } ;
19
19
use ln:: msgs:: { DecodeError , ErrorAction , LightningError , MAX_VALUE_MSAT } ;
20
- use routing:: scoring:: Score ;
20
+ use routing:: scoring:: { Score , DynamicPenaltyScorer } ;
21
21
use routing:: network_graph:: { DirectedChannelInfoWithUpdate , EffectiveCapacity , NetworkGraph , ReadOnlyNetworkGraph , NodeId , RoutingFees } ;
22
22
use util:: ser:: { Writeable , Readable } ;
23
23
use util:: logger:: { Level , Logger } ;
@@ -151,7 +151,7 @@ impl Readable for Route {
151
151
152
152
/// Parameters needed to find a [`Route`].
153
153
///
154
- /// Passed to [`find_route`] and also provided in [`Event::PaymentPathFailed`] for retrying a failed
154
+ /// Passed to [`find_route`] and [`build_route_from_hops`], but also provided in [`Event::PaymentPathFailed`] for retrying a failed
155
155
/// payment path.
156
156
///
157
157
/// [`Event::PaymentPathFailed`]: crate::util::events::Event::PaymentPathFailed
@@ -1747,10 +1747,54 @@ fn add_random_cltv_offset(route: &mut Route, payment_params: &PaymentParameters,
1747
1747
}
1748
1748
}
1749
1749
1750
+ /// Build a route from us (payer) with the given hops ending at the target node (payee).
1751
+ ///
1752
+ /// Re-uses logic from `find_route`, so the restrictions described there also apply here.
1753
+ pub fn build_route_from_hops < L : Deref > (
1754
+ our_node_pubkey : & PublicKey , hops : & [ PublicKey ] , route_params : & RouteParameters , network : & NetworkGraph ,
1755
+ logger : L , random_seed_bytes : & [ u8 ; 32 ] ) -> Result < Route , LightningError >
1756
+ where L :: Target : Logger {
1757
+ let network_graph = network. read_only ( ) ;
1758
+ match build_route_from_hops_internal (
1759
+ our_node_pubkey, hops, & route_params. payment_params , & network_graph,
1760
+ route_params. final_value_msat , route_params. final_cltv_expiry_delta , logger, random_seed_bytes
1761
+ ) {
1762
+ Ok ( mut route) => {
1763
+ add_random_cltv_offset ( & mut route, & route_params. payment_params , & network_graph, random_seed_bytes) ;
1764
+ Ok ( route)
1765
+ } ,
1766
+ Err ( err) => Err ( err) ,
1767
+ }
1768
+ }
1769
+
1770
+ fn build_route_from_hops_internal < L : Deref > (
1771
+ our_node_pubkey : & PublicKey , hops : & [ PublicKey ] , payment_params : & PaymentParameters ,
1772
+ network_graph : & ReadOnlyNetworkGraph , final_value_msat : u64 , final_cltv_expiry_delta : u32 ,
1773
+ logger : L , random_seed_bytes : & [ u8 ; 32 ] ) -> Result < Route , LightningError > where L :: Target : Logger {
1774
+
1775
+ let hop_ids: Vec < NodeId > = core:: iter:: once ( NodeId :: from_pubkey ( & our_node_pubkey) )
1776
+ . chain ( hops. iter ( ) . map ( |hop_pubkey| NodeId :: from_pubkey ( & hop_pubkey) ) ) . collect ( ) ;
1777
+
1778
+ let filter_by_nodeids = |_short_channel_id : u64 , _send_amt_msat : u64 , _capacity_msat : u64 ,
1779
+ source : & NodeId , target : & NodeId | {
1780
+ if hop_ids. iter ( ) . find ( |x| * * x == * source) . is_some ( )
1781
+ && hop_ids. iter ( ) . find ( |x| * * x == * target) . is_some ( ) {
1782
+ 0
1783
+ } else {
1784
+ u64:: max_value ( )
1785
+ }
1786
+ } ;
1787
+
1788
+ let scorer = DynamicPenaltyScorer :: with_penalty_func ( filter_by_nodeids) ;
1789
+
1790
+ get_route ( our_node_pubkey, payment_params, network_graph, None , final_value_msat,
1791
+ final_cltv_expiry_delta, logger, & scorer, random_seed_bytes)
1792
+ }
1793
+
1750
1794
#[ cfg( test) ]
1751
1795
mod tests {
1752
1796
use routing:: network_graph:: { NetworkGraph , NetGraphMsgHandler , NodeId } ;
1753
- use routing:: router:: { get_route, add_random_cltv_offset, default_node_features,
1797
+ use routing:: router:: { get_route, build_route_from_hops_internal , add_random_cltv_offset, default_node_features,
1754
1798
PaymentParameters , Route , RouteHint , RouteHintHop , RouteHop , RoutingFees ,
1755
1799
DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA , MAX_PATH_LENGTH_ESTIMATE } ;
1756
1800
use routing:: scoring:: Score ;
0 commit comments