@@ -176,6 +176,12 @@ impl_writeable_tlv_based!(RouteParameters, {
176
176
/// Maximum total CTLV difference we allow for a full payment path.
177
177
pub const DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA : u32 = 1008 ;
178
178
179
+ /// Maximum number of paths we allow an MPP payment to have.
180
+ // The default limit is currently set rather arbitrary - there aren't any real fundamental path-count
181
+ // limits. After we support retrying individual paths we should likely bump this, but
182
+ // for now more than 10 paths likely carries too much one-path failure.
183
+ pub const DEFAULT_MAX_MPP_PATH_COUNT : u8 = 10 ;
184
+
179
185
// The median hop CLTV expiry delta currently seen in the network.
180
186
const MEDIAN_HOP_CLTV_EXPIRY_DELTA : u32 = 40 ;
181
187
@@ -215,12 +221,16 @@ pub struct PaymentParameters {
215
221
216
222
/// The maximum total CLTV delta we accept for the route.
217
223
pub max_total_cltv_expiry_delta : u32 ,
224
+
225
+ /// The maximum number of paths that may be used by MPP payments.
226
+ pub max_mpp_path_count : u8 ,
218
227
}
219
228
220
229
impl_writeable_tlv_based ! ( PaymentParameters , {
221
230
( 0 , payee_pubkey, required) ,
222
231
( 1 , max_total_cltv_expiry_delta, ( default_value, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA ) ) ,
223
232
( 2 , features, option) ,
233
+ ( 3 , max_mpp_path_count, ( default_value, DEFAULT_MAX_MPP_PATH_COUNT ) ) ,
224
234
( 4 , route_hints, vec_type) ,
225
235
( 6 , expiry_time, option) ,
226
236
} ) ;
@@ -234,6 +244,7 @@ impl PaymentParameters {
234
244
route_hints : vec ! [ ] ,
235
245
expiry_time : None ,
236
246
max_total_cltv_expiry_delta : DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA ,
247
+ max_mpp_path_count : DEFAULT_MAX_MPP_PATH_COUNT ,
237
248
}
238
249
}
239
250
@@ -269,6 +280,13 @@ impl PaymentParameters {
269
280
pub fn with_max_total_cltv_expiry_delta ( self , max_total_cltv_expiry_delta : u32 ) -> Self {
270
281
Self { max_total_cltv_expiry_delta, ..self }
271
282
}
283
+
284
+ /// Includes a limit for the maximum number of payment paths that may be used by MPP.
285
+ ///
286
+ /// (C-not exported) since bindings don't support move semantics
287
+ pub fn with_max_mpp_path_count ( self , max_mpp_path_count : u8 ) -> Self {
288
+ Self { max_mpp_path_count, ..self }
289
+ }
272
290
}
273
291
274
292
/// A list of hops along a payment path terminating with a channel to the recipient.
@@ -790,6 +808,11 @@ where L::Target: Logger {
790
808
node_info. features . supports_basic_mpp ( )
791
809
} else { false }
792
810
} else { false } ;
811
+
812
+ if allow_mpp && payment_params. max_mpp_path_count == 0 {
813
+ return Err ( LightningError { err : "Can't find an MPP route with no paths allowed." . to_owned ( ) , action : ErrorAction :: IgnoreError } ) ;
814
+ }
815
+
793
816
log_trace ! ( logger, "Searching for a route from payer {} to payee {} {} MPP and {} first hops {}overriding the network graph" , our_node_pubkey,
794
817
payment_params. payee_pubkey, if allow_mpp { "with" } else { "without" } ,
795
818
first_hops. map( |hops| hops. len( ) ) . unwrap_or( 0 ) , if first_hops. is_some( ) { "" } else { "not " } ) ;
@@ -917,12 +940,10 @@ where L::Target: Logger {
917
940
// Taking too many smaller paths also increases the chance of payment failure.
918
941
// Thus to avoid this effect, we require from our collected links to provide
919
942
// at least a minimal contribution to the recommended value yet-to-be-fulfilled.
920
- // This requirement is currently 10% of the value.
921
-
922
- // Derive the minimal liquidity contribution with a ratio of 10 (10%, rounded up)
923
- // or 100% if we're not allowed to do multipath payments.
943
+ // This requirement is currently set to be 1/max_mpp_path_count of the payment
944
+ // value to ensure we only ever return routes that do not violate this limit.
924
945
let minimal_value_contribution_msat: u64 = if allow_mpp {
925
- ( final_value_msat + 9 ) / 10
946
+ ( final_value_msat + ( payment_params . max_mpp_path_count as u64 - 1 ) ) / payment_params . max_mpp_path_count as u64
926
947
} else {
927
948
final_value_msat
928
949
} ;
@@ -1669,6 +1690,8 @@ where L::Target: Logger {
1669
1690
} ) ;
1670
1691
selected_paths. push ( path) ;
1671
1692
}
1693
+ // Make sure we would never create a route with more paths than we allow.
1694
+ assert ! ( selected_paths. len( ) <= payment_params. max_mpp_path_count. into( ) ) ;
1672
1695
1673
1696
if let Some ( features) = & payment_params. features {
1674
1697
for path in selected_paths. iter_mut ( ) {
0 commit comments