@@ -1234,66 +1234,74 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> Score for Probabilis
1234
1234
}
1235
1235
1236
1236
fn payment_path_failed ( & mut self , path : & Path , short_channel_id : u64 ) {
1237
- let amount_msat = path. hops . split_last ( ) . map ( | ( hop , _ ) | hop . fee_msat ) . unwrap_or ( 0 ) ;
1237
+ let amount_msat = path. final_value_msat ( ) ;
1238
1238
log_trace ! ( self . logger, "Scoring path through to SCID {} as having failed at {} msat" , short_channel_id, amount_msat) ;
1239
1239
let network_graph = self . network_graph . read_only ( ) ;
1240
- for ( hop_idx, hop) in path. hops . iter ( ) . enumerate ( ) {
1241
- let target = NodeId :: from_pubkey ( & hop. pubkey ) ;
1240
+ for ( hop_idx, ( pubkey, scid) ) in path. hops . iter ( ) . map ( |hop| ( hop. pubkey , hop. short_channel_id ) )
1241
+ . chain ( path. blinded_tail . as_ref ( ) . map ( |tail| ( tail. path . introduction_node_id , tail. intro_node_scid ) ) )
1242
+ . enumerate ( )
1243
+ {
1244
+ let target = NodeId :: from_pubkey ( & pubkey) ;
1242
1245
let channel_directed_from_source = network_graph. channels ( )
1243
- . get ( & hop . short_channel_id )
1246
+ . get ( & scid )
1244
1247
. and_then ( |channel| channel. as_directed_to ( & target) ) ;
1245
1248
1246
- let at_failed_channel = hop . short_channel_id == short_channel_id;
1249
+ let at_failed_channel = scid == short_channel_id;
1247
1250
if at_failed_channel && hop_idx == 0 {
1248
- log_warn ! ( self . logger, "Payment failed at the first hop - we do not attempt to learn channel info in such cases as we can directly observe local state.\n \t Because we know the local state, we should generally not see failures here - this may be an indication that your channel peer on channel {} is broken and you may wish to close the channel." , hop . short_channel_id ) ;
1251
+ log_warn ! ( self . logger, "Payment failed at the first hop - we do not attempt to learn channel info in such cases as we can directly observe local state.\n \t Because we know the local state, we should generally not see failures here - this may be an indication that your channel peer on channel {} is broken and you may wish to close the channel." , scid ) ;
1249
1252
}
1250
1253
1251
1254
// Only score announced channels.
1252
1255
if let Some ( ( channel, source) ) = channel_directed_from_source {
1253
1256
let capacity_msat = channel. effective_capacity ( ) . as_msat ( ) ;
1254
1257
if at_failed_channel {
1255
1258
self . channel_liquidities
1256
- . entry ( hop . short_channel_id )
1259
+ . entry ( scid )
1257
1260
. or_insert_with ( ChannelLiquidity :: new)
1258
1261
. as_directed_mut ( source, & target, 0 , capacity_msat, & self . params )
1259
- . failed_at_channel ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , hop . short_channel_id , target) , & self . logger ) ;
1262
+ . failed_at_channel ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , scid , target) , & self . logger ) ;
1260
1263
} else {
1261
1264
self . channel_liquidities
1262
- . entry ( hop . short_channel_id )
1265
+ . entry ( scid )
1263
1266
. or_insert_with ( ChannelLiquidity :: new)
1264
1267
. as_directed_mut ( source, & target, 0 , capacity_msat, & self . params )
1265
- . failed_downstream ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , hop . short_channel_id , target) , & self . logger ) ;
1268
+ . failed_downstream ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , scid , target) , & self . logger ) ;
1266
1269
}
1267
1270
} else {
1268
1271
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)." ,
1269
- hop . short_channel_id ) ;
1272
+ scid ) ;
1270
1273
}
1271
1274
if at_failed_channel { break ; }
1272
1275
}
1273
1276
}
1274
1277
1275
1278
fn payment_path_successful ( & mut self , path : & Path ) {
1276
- let amount_msat = path. hops . split_last ( ) . map ( |( hop, _) | hop. fee_msat ) . unwrap_or ( 0 ) ;
1279
+ let amount_msat = path. final_value_msat ( ) ;
1280
+ let final_scid = path. blinded_tail . as_ref ( ) . map_or_else (
1281
+ || path. hops . last ( ) . map_or ( 0 , |hop| hop. short_channel_id ) ,
1282
+ |tail| tail. intro_node_scid ) ;
1277
1283
log_trace ! ( self . logger, "Scoring path through SCID {} as having succeeded at {} msat." ,
1278
- path . hops . split_last ( ) . map ( | ( hop , _ ) | hop . short_channel_id ) . unwrap_or ( 0 ) , amount_msat) ;
1284
+ final_scid , amount_msat) ;
1279
1285
let network_graph = self . network_graph . read_only ( ) ;
1280
- for hop in & path. hops {
1281
- let target = NodeId :: from_pubkey ( & hop. pubkey ) ;
1286
+ for ( pubkey, scid) in path. hops . iter ( ) . map ( |hop| ( hop. pubkey , hop. short_channel_id ) )
1287
+ . chain ( path. blinded_tail . as_ref ( ) . map ( |tail| ( tail. path . introduction_node_id , tail. intro_node_scid ) ) )
1288
+ {
1289
+ let target = NodeId :: from_pubkey ( & pubkey) ;
1282
1290
let channel_directed_from_source = network_graph. channels ( )
1283
- . get ( & hop . short_channel_id )
1291
+ . get ( & scid )
1284
1292
. and_then ( |channel| channel. as_directed_to ( & target) ) ;
1285
1293
1286
1294
// Only score announced channels.
1287
1295
if let Some ( ( channel, source) ) = channel_directed_from_source {
1288
1296
let capacity_msat = channel. effective_capacity ( ) . as_msat ( ) ;
1289
1297
self . channel_liquidities
1290
- . entry ( hop . short_channel_id )
1298
+ . entry ( scid )
1291
1299
. or_insert_with ( ChannelLiquidity :: new)
1292
1300
. as_directed_mut ( source, & target, 0 , capacity_msat, & self . params )
1293
- . successful ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , hop . short_channel_id , target) , & self . logger ) ;
1301
+ . successful ( amount_msat, format_args ! ( "SCID {}, towards {:?}" , scid , target) , & self . logger ) ;
1294
1302
} else {
1295
1303
log_debug ! ( self . logger, "Not able to learn for channel with SCID {} as we do not have graph info for it (likely a route-hint last-hop)." ,
1296
- hop . short_channel_id ) ;
1304
+ scid ) ;
1297
1305
}
1298
1306
}
1299
1307
}
@@ -1702,17 +1710,18 @@ impl<T: Time> Readable for ChannelLiquidity<T> {
1702
1710
#[ cfg( test) ]
1703
1711
mod tests {
1704
1712
use super :: { ChannelLiquidity , HistoricalBucketRangeTracker , ProbabilisticScoringParameters , ProbabilisticScorerUsingTime } ;
1713
+ use crate :: blinded_path:: BlindedPath ;
1705
1714
use crate :: util:: config:: UserConfig ;
1706
1715
use crate :: util:: time:: Time ;
1707
1716
use crate :: util:: time:: tests:: SinceEpoch ;
1708
1717
1709
1718
use crate :: ln:: channelmanager;
1710
1719
use crate :: ln:: msgs:: { ChannelAnnouncement , ChannelUpdate , UnsignedChannelAnnouncement , UnsignedChannelUpdate } ;
1711
1720
use crate :: routing:: gossip:: { EffectiveCapacity , NetworkGraph , NodeId } ;
1712
- use crate :: routing:: router:: { Path , RouteHop } ;
1721
+ use crate :: routing:: router:: { BlindedTail , Path , RouteHop } ;
1713
1722
use crate :: routing:: scoring:: { ChannelUsage , Score } ;
1714
1723
use crate :: util:: ser:: { ReadableArgs , Writeable } ;
1715
- use crate :: util:: test_utils:: TestLogger ;
1724
+ use crate :: util:: test_utils:: { self , TestLogger } ;
1716
1725
1717
1726
use bitcoin:: blockdata:: constants:: genesis_block;
1718
1727
use bitcoin:: hashes:: Hash ;
@@ -2870,4 +2879,45 @@ mod tests {
2870
2879
} ;
2871
2880
assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 0 ) ;
2872
2881
}
2882
+
2883
+ #[ test]
2884
+ fn scores_intro_node_scid ( ) {
2885
+ // Make sure we'll score the scid contained in the blinded portion of a path
2886
+ let logger = TestLogger :: new ( ) ;
2887
+ let network_graph = network_graph ( & logger) ;
2888
+ let params = ProbabilisticScoringParameters {
2889
+ liquidity_penalty_multiplier_msat : 1_000 ,
2890
+ liquidity_offset_half_life : Duration :: from_secs ( 10 ) ,
2891
+ ..ProbabilisticScoringParameters :: zero_penalty ( )
2892
+ } ;
2893
+ let mut scorer = ProbabilisticScorer :: new ( params, & network_graph, & logger) ;
2894
+ let source = source_node_id ( ) ;
2895
+ let target = target_node_id ( ) ;
2896
+ let usage = ChannelUsage {
2897
+ amount_msat : 512 ,
2898
+ inflight_htlc_msat : 0 ,
2899
+ effective_capacity : EffectiveCapacity :: Total { capacity_msat : 1_024 , htlc_maximum_msat : 1_000 } ,
2900
+ } ;
2901
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 300 ) ;
2902
+
2903
+ let mut path = payment_path_for_amount ( 768 ) ;
2904
+ let last_hop = path. hops . pop ( ) . unwrap ( ) ;
2905
+ let _intro_node_hop = path. hops . pop ( ) . unwrap ( ) ;
2906
+ path. blinded_tail = Some ( BlindedTail {
2907
+ path : BlindedPath {
2908
+ introduction_node_id : target_pubkey ( ) ,
2909
+ blinding_point : test_utils:: pubkey ( 42 ) ,
2910
+ blinded_hops : Vec :: new ( ) ,
2911
+ } ,
2912
+ fee_msat : 2 ,
2913
+ cltv_expiry_delta : last_hop. cltv_expiry_delta ,
2914
+ final_value_msat : last_hop. fee_msat ,
2915
+ intro_node_scid : 42 ,
2916
+ } ) ;
2917
+
2918
+ scorer. payment_path_failed ( & path, 42 ) ;
2919
+ path. blinded_tail . as_mut ( ) . unwrap ( ) . final_value_msat = 256 ;
2920
+ scorer. payment_path_failed ( & path, 43 ) ;
2921
+ assert_eq ! ( scorer. channel_penalty_msat( 42 , & source, & target, usage) , 281 ) ;
2922
+ }
2873
2923
}
0 commit comments