@@ -1156,19 +1156,18 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for Probabilis
1156
1156
. or_insert_with ( ChannelLiquidity :: new)
1157
1157
. as_directed_mut ( source, & target, capacity_msat, & self . params )
1158
1158
. 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 ) ;
1160
1165
}
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 ) ;
1167
1166
} else {
1168
1167
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)." ,
1169
1168
hop. short_channel_id) ;
1170
- if hop. short_channel_id == short_channel_id { break ; }
1171
1169
}
1170
+ if hop. short_channel_id == short_channel_id { break ; }
1172
1171
}
1173
1172
}
1174
1173
@@ -1746,32 +1745,22 @@ mod tests {
1746
1745
network_graph. update_channel ( & signed_update) . unwrap ( ) ;
1747
1746
}
1748
1747
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
+
1749
1759
fn payment_path_for_amount ( amount_msat : u64 ) -> Vec < RouteHop > {
1750
1760
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) ,
1775
1764
]
1776
1765
}
1777
1766
@@ -2146,6 +2135,66 @@ mod tests {
2146
2135
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , u64 :: max_value( ) ) ;
2147
2136
}
2148
2137
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
+
2149
2198
#[ test]
2150
2199
fn reduces_liquidity_upper_bound_along_path_on_success ( ) {
2151
2200
let logger = TestLogger :: new ( ) ;
0 commit comments