X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-c-bindings%2Fsrc%2Flightning%2Frouting%2Fscoring.rs;h=9a77d6f02ee9ae3ae9ab10ad33ed911ed05b36b1;hb=f10bdbea94cd8c638a42ab637a52e86a7cfd8157;hp=a45f706391b500a39ad8e9ae21854167e1feb004;hpb=45ad3320df3768514d968c70fc4b6a9d50028050;p=ldk-c-bindings diff --git a/lightning-c-bindings/src/lightning/routing/scoring.rs b/lightning-c-bindings/src/lightning/routing/scoring.rs index a45f706..9a77d6f 100644 --- a/lightning-c-bindings/src/lightning/routing/scoring.rs +++ b/lightning-c-bindings/src/lightning/routing/scoring.rs @@ -42,7 +42,7 @@ //! let scorer = ProbabilisticScorer::new(params, &network_graph, &logger); //! # let random_seed_bytes = [42u8; 32]; //! -//! let route = find_route(&payer, &route_params, &network_graph.read_only(), None, &logger, &scorer, &random_seed_bytes); +//! let route = find_route(&payer, &route_params, &network_graph, None, &logger, &scorer, &random_seed_bytes); //! # } //! ``` //! @@ -83,6 +83,10 @@ pub struct Score { pub payment_path_failed: extern "C" fn (this_arg: *mut c_void, path: crate::c_types::derived::CVec_RouteHopZ, short_channel_id: u64), /// Handles updating channel penalties after successfully routing along a path. pub payment_path_successful: extern "C" fn (this_arg: *mut c_void, path: crate::c_types::derived::CVec_RouteHopZ), + /// Handles updating channel penalties after a probe over the given path failed. + pub probe_failed: extern "C" fn (this_arg: *mut c_void, path: crate::c_types::derived::CVec_RouteHopZ, short_channel_id: u64), + /// Handles updating channel penalties after a probe over the given path succeeded. + pub probe_successful: extern "C" fn (this_arg: *mut c_void, path: crate::c_types::derived::CVec_RouteHopZ), /// Serialize the object into a byte array pub write: extern "C" fn (this_arg: *const c_void) -> crate::c_types::derived::CVec_u8Z, /// Frees any resources associated with this object given its this_arg pointer. @@ -98,6 +102,8 @@ pub(crate) extern "C" fn Score_clone_fields(orig: &Score) -> Score { channel_penalty_msat: Clone::clone(&orig.channel_penalty_msat), payment_path_failed: Clone::clone(&orig.payment_path_failed), payment_path_successful: Clone::clone(&orig.payment_path_successful), + probe_failed: Clone::clone(&orig.probe_failed), + probe_successful: Clone::clone(&orig.probe_successful), write: Clone::clone(&orig.write), free: Clone::clone(&orig.free), } @@ -123,6 +129,14 @@ impl rustScore for Score { let mut local_path = Vec::new(); for item in path.iter() { local_path.push( { crate::lightning::routing::router::RouteHop { inner: unsafe { ObjOps::nonnull_ptr_to_inner(((*item) as *const lightning::routing::router::RouteHop<>) as *mut _) }, is_owned: false } }); }; (self.payment_path_successful)(self.this_arg, local_path.into()) } + fn probe_failed(&mut self, mut path: &[&lightning::routing::router::RouteHop], mut short_channel_id: u64) { + let mut local_path = Vec::new(); for item in path.iter() { local_path.push( { crate::lightning::routing::router::RouteHop { inner: unsafe { ObjOps::nonnull_ptr_to_inner(((*item) as *const lightning::routing::router::RouteHop<>) as *mut _) }, is_owned: false } }); }; + (self.probe_failed)(self.this_arg, local_path.into(), short_channel_id) + } + fn probe_successful(&mut self, mut path: &[&lightning::routing::router::RouteHop]) { + let mut local_path = Vec::new(); for item in path.iter() { local_path.push( { crate::lightning::routing::router::RouteHop { inner: unsafe { ObjOps::nonnull_ptr_to_inner(((*item) as *const lightning::routing::router::RouteHop<>) as *mut _) }, is_owned: false } }); }; + (self.probe_successful)(self.this_arg, local_path.into()) + } } // We're essentially a pointer already, or at least a set of pointers, so allow us to be used @@ -482,6 +496,8 @@ pub extern "C" fn FixedPenaltyScorer_as_Score(this_arg: &FixedPenaltyScorer) -> channel_penalty_msat: FixedPenaltyScorer_Score_channel_penalty_msat, payment_path_failed: FixedPenaltyScorer_Score_payment_path_failed, payment_path_successful: FixedPenaltyScorer_Score_payment_path_successful, + probe_failed: FixedPenaltyScorer_Score_probe_failed, + probe_successful: FixedPenaltyScorer_Score_probe_successful, write: FixedPenaltyScorer_write_void, } } @@ -499,6 +515,14 @@ extern "C" fn FixedPenaltyScorer_Score_payment_path_successful(this_arg: *mut c_ let mut local__path = Vec::new(); for mut item in _path.as_slice().iter() { local__path.push( { item.get_native_ref() }); }; >::payment_path_successful(unsafe { &mut *(this_arg as *mut nativeFixedPenaltyScorer) }, &local__path[..]) } +extern "C" fn FixedPenaltyScorer_Score_probe_failed(this_arg: *mut c_void, mut _path: crate::c_types::derived::CVec_RouteHopZ, mut _short_channel_id: u64) { + let mut local__path = Vec::new(); for mut item in _path.as_slice().iter() { local__path.push( { item.get_native_ref() }); }; + >::probe_failed(unsafe { &mut *(this_arg as *mut nativeFixedPenaltyScorer) }, &local__path[..], _short_channel_id) +} +extern "C" fn FixedPenaltyScorer_Score_probe_successful(this_arg: *mut c_void, mut _path: crate::c_types::derived::CVec_RouteHopZ) { + let mut local__path = Vec::new(); for mut item in _path.as_slice().iter() { local__path.push( { item.get_native_ref() }); }; + >::probe_successful(unsafe { &mut *(this_arg as *mut nativeFixedPenaltyScorer) }, &local__path[..]) +} #[no_mangle] /// Serialize the FixedPenaltyScorer object into a byte array which can be read by FixedPenaltyScorer_read @@ -597,6 +621,9 @@ pub(crate) type nativeProbabilisticScoringParameters = nativeProbabilisticScorin /// /// Used to configure base, liquidity, and amount penalties, the sum of which comprises the channel /// penalty (i.e., the amount in msats willing to be paid to avoid routing through the channel). +/// +/// The penalty applied to any channel by the [`ProbabilisticScorer`] is the sum of each of the +/// parameters here. #[must_use] #[repr(C)] pub struct ProbabilisticScoringParameters { @@ -658,6 +685,39 @@ pub extern "C" fn ProbabilisticScoringParameters_get_base_penalty_msat(this_ptr: pub extern "C" fn ProbabilisticScoringParameters_set_base_penalty_msat(this_ptr: &mut ProbabilisticScoringParameters, mut val: u64) { unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.base_penalty_msat = val; } +/// A multiplier used with the payment amount to calculate a fixed penalty applied to each +/// channel, in excess of the [`base_penalty_msat`]. +/// +/// The purpose of the amount penalty is to avoid having fees dominate the channel cost (i.e., +/// fees plus penalty) for large payments. The penalty is computed as the product of this +/// multiplier and `2^30`ths of the payment amount. +/// +/// ie `base_penalty_amount_multiplier_msat * amount_msat / 2^30` +/// +/// Default value: 8,192 msat +/// +/// [`base_penalty_msat`]: Self::base_penalty_msat +#[no_mangle] +pub extern "C" fn ProbabilisticScoringParameters_get_base_penalty_amount_multiplier_msat(this_ptr: &ProbabilisticScoringParameters) -> u64 { + let mut inner_val = &mut this_ptr.get_native_mut_ref().base_penalty_amount_multiplier_msat; + *inner_val +} +/// A multiplier used with the payment amount to calculate a fixed penalty applied to each +/// channel, in excess of the [`base_penalty_msat`]. +/// +/// The purpose of the amount penalty is to avoid having fees dominate the channel cost (i.e., +/// fees plus penalty) for large payments. The penalty is computed as the product of this +/// multiplier and `2^30`ths of the payment amount. +/// +/// ie `base_penalty_amount_multiplier_msat * amount_msat / 2^30` +/// +/// Default value: 8,192 msat +/// +/// [`base_penalty_msat`]: Self::base_penalty_msat +#[no_mangle] +pub extern "C" fn ProbabilisticScoringParameters_set_base_penalty_amount_multiplier_msat(this_ptr: &mut ProbabilisticScoringParameters, mut val: u64) { + unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.base_penalty_amount_multiplier_msat = val; +} /// A multiplier used in conjunction with the negative `log10` of the channel's success /// probability for a payment to determine the liquidity penalty. /// @@ -736,7 +796,7 @@ pub extern "C" fn ProbabilisticScoringParameters_set_liquidity_offset_half_life( /// multiplier and `2^20`ths of the payment amount, weighted by the negative `log10` of the /// success probability. /// -/// `-log10(success_probability) * amount_penalty_multiplier_msat * amount_msat / 2^20` +/// `-log10(success_probability) * liquidity_penalty_amount_multiplier_msat * amount_msat / 2^20` /// /// In practice, this means for 0.1 success probability (`-log10(0.1) == 1`) each `2^20`th of /// the amount will result in a penalty of the multiplier. And, as the success probability @@ -746,8 +806,8 @@ pub extern "C" fn ProbabilisticScoringParameters_set_liquidity_offset_half_life( /// /// Default value: 256 msat #[no_mangle] -pub extern "C" fn ProbabilisticScoringParameters_get_amount_penalty_multiplier_msat(this_ptr: &ProbabilisticScoringParameters) -> u64 { - let mut inner_val = &mut this_ptr.get_native_mut_ref().amount_penalty_multiplier_msat; +pub extern "C" fn ProbabilisticScoringParameters_get_liquidity_penalty_amount_multiplier_msat(this_ptr: &ProbabilisticScoringParameters) -> u64 { + let mut inner_val = &mut this_ptr.get_native_mut_ref().liquidity_penalty_amount_multiplier_msat; *inner_val } /// A multiplier used in conjunction with a payment amount and the negative `log10` of the @@ -758,7 +818,7 @@ pub extern "C" fn ProbabilisticScoringParameters_get_amount_penalty_multiplier_m /// multiplier and `2^20`ths of the payment amount, weighted by the negative `log10` of the /// success probability. /// -/// `-log10(success_probability) * amount_penalty_multiplier_msat * amount_msat / 2^20` +/// `-log10(success_probability) * liquidity_penalty_amount_multiplier_msat * amount_msat / 2^20` /// /// In practice, this means for 0.1 success probability (`-log10(0.1) == 1`) each `2^20`th of /// the amount will result in a penalty of the multiplier. And, as the success probability @@ -768,19 +828,72 @@ pub extern "C" fn ProbabilisticScoringParameters_get_amount_penalty_multiplier_m /// /// Default value: 256 msat #[no_mangle] -pub extern "C" fn ProbabilisticScoringParameters_set_amount_penalty_multiplier_msat(this_ptr: &mut ProbabilisticScoringParameters, mut val: u64) { - unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.amount_penalty_multiplier_msat = val; +pub extern "C" fn ProbabilisticScoringParameters_set_liquidity_penalty_amount_multiplier_msat(this_ptr: &mut ProbabilisticScoringParameters, mut val: u64) { + unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.liquidity_penalty_amount_multiplier_msat = val; } -/// Constructs a new ProbabilisticScoringParameters given each field -#[must_use] +/// This penalty is applied when `htlc_maximum_msat` is equal to or larger than half of the +/// channel's capacity, which makes us prefer nodes with a smaller `htlc_maximum_msat`. We +/// treat such nodes preferentially as this makes balance discovery attacks harder to execute, +/// thereby creating an incentive to restrict `htlc_maximum_msat` and improve privacy. +/// +/// Default value: 250 msat #[no_mangle] -pub extern "C" fn ProbabilisticScoringParameters_new(mut base_penalty_msat_arg: u64, mut liquidity_penalty_multiplier_msat_arg: u64, mut liquidity_offset_half_life_arg: u64, mut amount_penalty_multiplier_msat_arg: u64) -> ProbabilisticScoringParameters { - ProbabilisticScoringParameters { inner: ObjOps::heap_alloc(nativeProbabilisticScoringParameters { - base_penalty_msat: base_penalty_msat_arg, - liquidity_penalty_multiplier_msat: liquidity_penalty_multiplier_msat_arg, - liquidity_offset_half_life: core::time::Duration::from_secs(liquidity_offset_half_life_arg), - amount_penalty_multiplier_msat: amount_penalty_multiplier_msat_arg, - }), is_owned: true } +pub extern "C" fn ProbabilisticScoringParameters_get_anti_probing_penalty_msat(this_ptr: &ProbabilisticScoringParameters) -> u64 { + let mut inner_val = &mut this_ptr.get_native_mut_ref().anti_probing_penalty_msat; + *inner_val +} +/// This penalty is applied when `htlc_maximum_msat` is equal to or larger than half of the +/// channel's capacity, which makes us prefer nodes with a smaller `htlc_maximum_msat`. We +/// treat such nodes preferentially as this makes balance discovery attacks harder to execute, +/// thereby creating an incentive to restrict `htlc_maximum_msat` and improve privacy. +/// +/// Default value: 250 msat +#[no_mangle] +pub extern "C" fn ProbabilisticScoringParameters_set_anti_probing_penalty_msat(this_ptr: &mut ProbabilisticScoringParameters, mut val: u64) { + unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.anti_probing_penalty_msat = val; +} +/// This penalty is applied when the amount we're attempting to send over a channel exceeds our +/// current estimate of the channel's available liquidity. +/// +/// Note that in this case all other penalties, including the +/// [`liquidity_penalty_multiplier_msat`] and [`liquidity_penalty_amount_multiplier_msat`]-based +/// penalties, as well as the [`base_penalty_msat`] and the [`anti_probing_penalty_msat`], if +/// applicable, are still included in the overall penalty. +/// +/// If you wish to avoid creating paths with such channels entirely, setting this to a value of +/// `u64::max_value()` will guarantee that. +/// +/// Default value: 1_0000_0000_000 msat (1 Bitcoin) +/// +/// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat +/// [`liquidity_penalty_amount_multiplier_msat`]: Self::liquidity_penalty_amount_multiplier_msat +/// [`base_penalty_msat`]: Self::base_penalty_msat +/// [`anti_probing_penalty_msat`]: Self::anti_probing_penalty_msat +#[no_mangle] +pub extern "C" fn ProbabilisticScoringParameters_get_considered_impossible_penalty_msat(this_ptr: &ProbabilisticScoringParameters) -> u64 { + let mut inner_val = &mut this_ptr.get_native_mut_ref().considered_impossible_penalty_msat; + *inner_val +} +/// This penalty is applied when the amount we're attempting to send over a channel exceeds our +/// current estimate of the channel's available liquidity. +/// +/// Note that in this case all other penalties, including the +/// [`liquidity_penalty_multiplier_msat`] and [`liquidity_penalty_amount_multiplier_msat`]-based +/// penalties, as well as the [`base_penalty_msat`] and the [`anti_probing_penalty_msat`], if +/// applicable, are still included in the overall penalty. +/// +/// If you wish to avoid creating paths with such channels entirely, setting this to a value of +/// `u64::max_value()` will guarantee that. +/// +/// Default value: 1_0000_0000_000 msat (1 Bitcoin) +/// +/// [`liquidity_penalty_multiplier_msat`]: Self::liquidity_penalty_multiplier_msat +/// [`liquidity_penalty_amount_multiplier_msat`]: Self::liquidity_penalty_amount_multiplier_msat +/// [`base_penalty_msat`]: Self::base_penalty_msat +/// [`anti_probing_penalty_msat`]: Self::anti_probing_penalty_msat +#[no_mangle] +pub extern "C" fn ProbabilisticScoringParameters_set_considered_impossible_penalty_msat(this_ptr: &mut ProbabilisticScoringParameters, mut val: u64) { + unsafe { &mut *ObjOps::untweak_ptr(this_ptr.inner) }.considered_impossible_penalty_msat = val; } impl Clone for ProbabilisticScoringParameters { fn clone(&self) -> Self { @@ -819,6 +932,55 @@ pub extern "C" fn ProbabilisticScorer_debug_log_liquidity_stats(this_arg: &crate unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.debug_log_liquidity_stats() } +/// Query the estimated minimum and maximum liquidity available for sending a payment over the +/// channel with `scid` towards the given `target` node. +#[must_use] +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_estimated_channel_liquidity_range(this_arg: &crate::lightning::routing::scoring::ProbabilisticScorer, mut scid: u64, target: &crate::lightning::routing::gossip::NodeId) -> crate::c_types::derived::COption_C2Tuple_u64u64ZZ { + let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.estimated_channel_liquidity_range(scid, target.get_native_ref()); + let mut local_ret = if ret.is_none() { crate::c_types::derived::COption_C2Tuple_u64u64ZZ::None } else { crate::c_types::derived::COption_C2Tuple_u64u64ZZ::Some( { let (mut orig_ret_0_0, mut orig_ret_0_1) = (ret.unwrap()); let mut local_ret_0 = (orig_ret_0_0, orig_ret_0_1).into(); local_ret_0 }) }; + local_ret +} + +/// Marks the node with the given `node_id` as banned, i.e., +/// it will be avoided during path finding. +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_add_banned(this_arg: &mut crate::lightning::routing::scoring::ProbabilisticScorer, node_id: &crate::lightning::routing::gossip::NodeId) { + unsafe { &mut (*ObjOps::untweak_ptr(this_arg.inner as *mut crate::lightning::routing::scoring::nativeProbabilisticScorer)) }.add_banned(node_id.get_native_ref()) +} + +/// Removes the node with the given `node_id` from the list of nodes to avoid. +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_remove_banned(this_arg: &mut crate::lightning::routing::scoring::ProbabilisticScorer, node_id: &crate::lightning::routing::gossip::NodeId) { + unsafe { &mut (*ObjOps::untweak_ptr(this_arg.inner as *mut crate::lightning::routing::scoring::nativeProbabilisticScorer)) }.remove_banned(node_id.get_native_ref()) +} + +/// Sets a manual penalty for the given node. +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_set_manual_penalty(this_arg: &mut crate::lightning::routing::scoring::ProbabilisticScorer, node_id: &crate::lightning::routing::gossip::NodeId, mut penalty: u64) { + unsafe { &mut (*ObjOps::untweak_ptr(this_arg.inner as *mut crate::lightning::routing::scoring::nativeProbabilisticScorer)) }.set_manual_penalty(node_id.get_native_ref(), penalty) +} + +/// Removes the node with the given `node_id` from the list of manual penalties. +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_remove_manual_penalty(this_arg: &mut crate::lightning::routing::scoring::ProbabilisticScorer, node_id: &crate::lightning::routing::gossip::NodeId) { + unsafe { &mut (*ObjOps::untweak_ptr(this_arg.inner as *mut crate::lightning::routing::scoring::nativeProbabilisticScorer)) }.remove_manual_penalty(node_id.get_native_ref()) +} + +/// Clears the list of manual penalties that are applied during path finding. +#[no_mangle] +pub extern "C" fn ProbabilisticScorer_clear_manual_penalties(this_arg: &mut crate::lightning::routing::scoring::ProbabilisticScorer) { + unsafe { &mut (*ObjOps::untweak_ptr(this_arg.inner as *mut crate::lightning::routing::scoring::nativeProbabilisticScorer)) }.clear_manual_penalties() +} + +/// Marks all nodes in the given list as banned, i.e., +/// they will be avoided during path finding. +#[no_mangle] +pub extern "C" fn ProbabilisticScoringParameters_add_banned_from_list(this_arg: &mut crate::lightning::routing::scoring::ProbabilisticScoringParameters, mut node_ids: crate::c_types::derived::CVec_NodeIdZ) { + let mut local_node_ids = Vec::new(); for mut item in node_ids.into_rust().drain(..) { local_node_ids.push( { *unsafe { Box::from_raw(item.take_inner()) } }); }; + unsafe { &mut (*ObjOps::untweak_ptr(this_arg.inner as *mut crate::lightning::routing::scoring::nativeProbabilisticScoringParameters)) }.add_banned_from_list(local_node_ids) +} + /// Creates a "default" ProbabilisticScoringParameters. See struct and individual field documentaiton for details on which values are used. #[must_use] #[no_mangle] @@ -845,6 +1007,8 @@ pub extern "C" fn ProbabilisticScorer_as_Score(this_arg: &ProbabilisticScorer) - channel_penalty_msat: ProbabilisticScorer_Score_channel_penalty_msat, payment_path_failed: ProbabilisticScorer_Score_payment_path_failed, payment_path_successful: ProbabilisticScorer_Score_payment_path_successful, + probe_failed: ProbabilisticScorer_Score_probe_failed, + probe_successful: ProbabilisticScorer_Score_probe_successful, write: ProbabilisticScorer_write_void, } } @@ -862,6 +1026,14 @@ extern "C" fn ProbabilisticScorer_Score_payment_path_successful(this_arg: *mut c let mut local_path = Vec::new(); for mut item in path.as_slice().iter() { local_path.push( { item.get_native_ref() }); }; >::payment_path_successful(unsafe { &mut *(this_arg as *mut nativeProbabilisticScorer) }, &local_path[..]) } +extern "C" fn ProbabilisticScorer_Score_probe_failed(this_arg: *mut c_void, mut path: crate::c_types::derived::CVec_RouteHopZ, mut short_channel_id: u64) { + let mut local_path = Vec::new(); for mut item in path.as_slice().iter() { local_path.push( { item.get_native_ref() }); }; + >::probe_failed(unsafe { &mut *(this_arg as *mut nativeProbabilisticScorer) }, &local_path[..], short_channel_id) +} +extern "C" fn ProbabilisticScorer_Score_probe_successful(this_arg: *mut c_void, mut path: crate::c_types::derived::CVec_RouteHopZ) { + let mut local_path = Vec::new(); for mut item in path.as_slice().iter() { local_path.push( { item.get_native_ref() }); }; + >::probe_successful(unsafe { &mut *(this_arg as *mut nativeProbabilisticScorer) }, &local_path[..]) +} mod approx {