@@ -1156,19 +1156,18 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for Probabilis
11561156 . or_insert_with ( ChannelLiquidity :: new)
11571157 . as_directed_mut ( source, & target, capacity_msat, & self . params )
11581158 . failed_at_channel ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , hop. short_channel_id, target) , & self . logger ) ;
1159- break ;
1159+ } else {
1160+ self . channel_liquidities
1161+ . entry ( hop. short_channel_id )
1162+ . or_insert_with ( ChannelLiquidity :: new)
1163+ . as_directed_mut ( source, & target, capacity_msat, & self . params )
1164+ . failed_downstream ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , hop. short_channel_id, target) , & self . logger ) ;
11601165 }
1161-
1162- self . channel_liquidities
1163- . entry ( hop. short_channel_id )
1164- . or_insert_with ( ChannelLiquidity :: new)
1165- . as_directed_mut ( source, & target, capacity_msat, & self . params )
1166- . failed_downstream ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , hop. short_channel_id, target) , & self . logger ) ;
11671166 } else {
11681167 log_debug ! ( self . logger, "Not able to penalize channel with SCID {} as we do not have graph info for it (likely a route-hint last-hop)." ,
11691168 hop. short_channel_id) ;
1170- if hop. short_channel_id == short_channel_id { break ; }
11711169 }
1170+ if hop. short_channel_id == short_channel_id { break ; }
11721171 }
11731172 }
11741173
@@ -1746,32 +1745,22 @@ mod tests {
17461745 network_graph. update_channel ( & signed_update) . unwrap ( ) ;
17471746 }
17481747
1748+ fn path_hop ( pubkey : PublicKey , short_channel_id : u64 , fee_msat : u64 ) -> RouteHop {
1749+ RouteHop {
1750+ pubkey,
1751+ node_features : channelmanager:: provided_node_features ( ) ,
1752+ short_channel_id,
1753+ channel_features : channelmanager:: provided_channel_features ( ) ,
1754+ fee_msat,
1755+ cltv_expiry_delta : 18 ,
1756+ }
1757+ }
1758+
17491759 fn payment_path_for_amount ( amount_msat : u64 ) -> Vec < RouteHop > {
17501760 vec ! [
1751- RouteHop {
1752- pubkey: source_pubkey( ) ,
1753- node_features: channelmanager:: provided_node_features( ) ,
1754- short_channel_id: 41 ,
1755- channel_features: channelmanager:: provided_channel_features( ) ,
1756- fee_msat: 1 ,
1757- cltv_expiry_delta: 18 ,
1758- } ,
1759- RouteHop {
1760- pubkey: target_pubkey( ) ,
1761- node_features: channelmanager:: provided_node_features( ) ,
1762- short_channel_id: 42 ,
1763- channel_features: channelmanager:: provided_channel_features( ) ,
1764- fee_msat: 2 ,
1765- cltv_expiry_delta: 18 ,
1766- } ,
1767- RouteHop {
1768- pubkey: recipient_pubkey( ) ,
1769- node_features: channelmanager:: provided_node_features( ) ,
1770- short_channel_id: 43 ,
1771- channel_features: channelmanager:: provided_channel_features( ) ,
1772- fee_msat: amount_msat,
1773- cltv_expiry_delta: 18 ,
1774- } ,
1761+ path_hop( source_pubkey( ) , 41 , 1 ) ,
1762+ path_hop( target_pubkey( ) , 42 , 2 ) ,
1763+ path_hop( recipient_pubkey( ) , 43 , amount_msat) ,
17751764 ]
17761765 }
17771766
@@ -2146,6 +2135,66 @@ mod tests {
21462135 assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , u64 :: max_value( ) ) ;
21472136 }
21482137
2138+ #[ test]
2139+ fn ignores_channels_after_removed_channels ( ) {
2140+ // Previously, if we'd tried to send over a channel which was removed from the network
2141+ // graph before we call `payment_path_failed` (which is the default if the we get a "no
2142+ // such channel" error in the `InvoicePayer`), we would call `failed_downstream` on all
2143+ // channels in the route, even ones which they payment never reached. This tests to ensure
2144+ // we do not score such channels.
2145+ let secp_ctx = Secp256k1 :: new ( ) ;
2146+ let logger = TestLogger :: new ( ) ;
2147+ let genesis_hash = genesis_block ( Network :: Testnet ) . header . block_hash ( ) ;
2148+ let mut network_graph = NetworkGraph :: new ( genesis_hash, & logger) ;
2149+ let secret_a = SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ;
2150+ let secret_b = SecretKey :: from_slice ( & [ 43 ; 32 ] ) . unwrap ( ) ;
2151+ let secret_c = SecretKey :: from_slice ( & [ 44 ; 32 ] ) . unwrap ( ) ;
2152+ let secret_d = SecretKey :: from_slice ( & [ 45 ; 32 ] ) . unwrap ( ) ;
2153+ add_channel ( & mut network_graph, 42 , secret_a, secret_b) ;
2154+ // Don't add the channel from B -> C.
2155+ add_channel ( & mut network_graph, 44 , secret_c, secret_d) ;
2156+
2157+ let pub_a = PublicKey :: from_secret_key ( & secp_ctx, & secret_a) ;
2158+ let pub_b = PublicKey :: from_secret_key ( & secp_ctx, & secret_b) ;
2159+ let pub_c = PublicKey :: from_secret_key ( & secp_ctx, & secret_c) ;
2160+ let pub_d = PublicKey :: from_secret_key ( & secp_ctx, & secret_d) ;
2161+
2162+ let path = vec ! [
2163+ path_hop( pub_b, 42 , 1 ) ,
2164+ path_hop( pub_c, 43 , 2 ) ,
2165+ path_hop( pub_d, 44 , 100 ) ,
2166+ ] ;
2167+
2168+ let node_a = NodeId :: from_pubkey ( & pub_a) ;
2169+ let node_b = NodeId :: from_pubkey ( & pub_b) ;
2170+ let node_c = NodeId :: from_pubkey ( & pub_c) ;
2171+ let node_d = NodeId :: from_pubkey ( & pub_d) ;
2172+
2173+ let params = ProbabilisticScoringParameters {
2174+ liquidity_penalty_multiplier_msat : 1_000 ,
2175+ ..ProbabilisticScoringParameters :: zero_penalty ( )
2176+ } ;
2177+ let mut scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
2178+
2179+
2180+ let usage = ChannelUsage {
2181+ amount_msat : 250 ,
2182+ inflight_htlc_msat : 0 ,
2183+ effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_000 , htlc_maximum_msat : Some ( 1_000 ) } ,
2184+ } ;
2185+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & node_a, & node_b, usage) , 128 ) ;
2186+ // Note that a default liquidity bound is used for B -> C as no channel exists
2187+ assert_eq ! ( scorer. channel_penalty_msat( 43 , & node_b, & node_c, usage) , 128 ) ;
2188+ assert_eq ! ( scorer. channel_penalty_msat( 44 , & node_c, & node_d, usage) , 128 ) ;
2189+
2190+ scorer. payment_path_failed ( & path. iter ( ) . collect :: < Vec < _ > > ( ) , 43 ) ;
2191+
2192+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & node_a, & node_b, usage) , 80 ) ;
2193+ // Note that a default liquidity bound is used for B -> C as no channel exists
2194+ assert_eq ! ( scorer. channel_penalty_msat( 43 , & node_b, & node_c, usage) , 128 ) ;
2195+ assert_eq ! ( scorer. channel_penalty_msat( 44 , & node_c, & node_d, usage) , 128 ) ;
2196+ }
2197+
21492198 #[ test]
21502199 fn reduces_liquidity_upper_bound_along_path_on_success ( ) {
21512200 let logger = TestLogger :: new ( ) ;
0 commit comments