///
/// [`find_route`]: crate::routing::router::find_route
pub trait LockableScore<'a> {
+ /// The [`Score`] type.
+ type Score: 'a + Score;
+
/// The locked [`Score`] type.
- type Locked: 'a + Score;
+ type Locked: DerefMut<Target = Self::Score> + Sized;
/// Returns the locked scorer.
fn lock(&'a self) -> Self::Locked;
impl<'a, T> WriteableScore<'a> for T where T: LockableScore<'a> + Writeable {}
/// This is not exported to bindings users
impl<'a, T: 'a + Score> LockableScore<'a> for Mutex<T> {
+ type Score = T;
type Locked = MutexGuard<'a, T>;
- fn lock(&'a self) -> MutexGuard<'a, T> {
+ fn lock(&'a self) -> Self::Locked {
Mutex::lock(self).unwrap()
}
}
impl<'a, T: 'a + Score> LockableScore<'a> for RefCell<T> {
+ type Score = T;
type Locked = RefMut<'a, T>;
- fn lock(&'a self) -> RefMut<'a, T> {
+ fn lock(&'a self) -> Self::Locked {
self.borrow_mut()
}
}
#[cfg(c_bindings)]
/// A concrete implementation of [`LockableScore`] which supports multi-threading.
-pub struct MultiThreadedLockableScore<S: Score> {
- score: Mutex<S>,
-}
-#[cfg(c_bindings)]
-/// A locked `MultiThreadedLockableScore`.
-pub struct MultiThreadedScoreLock<'a, S: Score>(MutexGuard<'a, S>);
-#[cfg(c_bindings)]
-impl<'a, T: Score + 'a> Score for MultiThreadedScoreLock<'a, T> {
- type ScoreParams = <T as Score>::ScoreParams;
- fn channel_penalty_msat(&self, scid: u64, source: &NodeId, target: &NodeId, usage: ChannelUsage, score_params: &Self::ScoreParams) -> u64 {
- self.0.channel_penalty_msat(scid, source, target, usage, score_params)
- }
- fn payment_path_failed(&mut self, path: &Path, short_channel_id: u64) {
- self.0.payment_path_failed(path, short_channel_id)
- }
- fn payment_path_successful(&mut self, path: &Path) {
- self.0.payment_path_successful(path)
- }
- fn probe_failed(&mut self, path: &Path, short_channel_id: u64) {
- self.0.probe_failed(path, short_channel_id)
- }
- fn probe_successful(&mut self, path: &Path) {
- self.0.probe_successful(path)
- }
-}
-#[cfg(c_bindings)]
-impl<'a, T: Score + 'a> Writeable for MultiThreadedScoreLock<'a, T> {
- fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
- self.0.write(writer)
- }
+pub struct MultiThreadedLockableScore<T: Score> {
+ score: Mutex<T>,
}
#[cfg(c_bindings)]
-impl<'a, T: Score + 'a> LockableScore<'a> for MultiThreadedLockableScore<T> {
+impl<'a, T: 'a + Score> LockableScore<'a> for MultiThreadedLockableScore<T> {
+ type Score = T;
type Locked = MultiThreadedScoreLock<'a, T>;
- fn lock(&'a self) -> MultiThreadedScoreLock<'a, T> {
+ fn lock(&'a self) -> Self::Locked {
MultiThreadedScoreLock(Mutex::lock(&self.score).unwrap())
}
}
}
#[cfg(c_bindings)]
-impl<'a, T: Score + 'a> WriteableScore<'a> for MultiThreadedLockableScore<T> {}
+impl<'a, T: 'a + Score> WriteableScore<'a> for MultiThreadedLockableScore<T> {}
#[cfg(c_bindings)]
impl<T: Score> MultiThreadedLockableScore<T> {
}
}
+#[cfg(c_bindings)]
+/// A locked `MultiThreadedLockableScore`.
+pub struct MultiThreadedScoreLock<'a, T: Score>(MutexGuard<'a, T>);
+
+#[cfg(c_bindings)]
+impl<'a, T: 'a + Score> Writeable for MultiThreadedScoreLock<'a, T> {
+ fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
+ self.0.write(writer)
+ }
+}
+
+#[cfg(c_bindings)]
+impl<'a, T: 'a + Score> DerefMut for MultiThreadedScoreLock<'a, T> {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ self.0.deref_mut()
+ }
+}
+
+#[cfg(c_bindings)]
+impl<'a, T: 'a + Score> Deref for MultiThreadedScoreLock<'a, T> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ self.0.deref()
+ }
+}
+
#[cfg(c_bindings)]
/// This is not exported to bindings users
impl<'a, T: Writeable> Writeable for RefMut<'a, T> {
}
#[cfg(not(feature = "no-std"))]
-type ConfiguredTime = std::time::Instant;
+type ConfiguredTime = crate::util::time::MonotonicTime;
#[cfg(feature = "no-std")]
use crate::util::time::Eternity;
#[cfg(feature = "no-std")]
pub considered_impossible_penalty_msat: u64,
}
+impl Default for ProbabilisticScoringFeeParameters {
+ fn default() -> Self {
+ Self {
+ base_penalty_msat: 500,
+ base_penalty_amount_multiplier_msat: 8192,
+ liquidity_penalty_multiplier_msat: 30_000,
+ liquidity_penalty_amount_multiplier_msat: 192,
+ manual_node_penalties: HashMap::new(),
+ anti_probing_penalty_msat: 250,
+ considered_impossible_penalty_msat: 1_0000_0000_000,
+ historical_liquidity_penalty_multiplier_msat: 10_000,
+ historical_liquidity_penalty_amount_multiplier_msat: 64,
+ }
+ }
+}
+
+impl ProbabilisticScoringFeeParameters {
+ /// Marks the node with the given `node_id` as banned,
+ /// i.e it will be avoided during path finding.
+ pub fn add_banned(&mut self, node_id: &NodeId) {
+ self.manual_node_penalties.insert(*node_id, u64::max_value());
+ }
+
+ /// Marks all nodes in the given list as banned, i.e.,
+ /// they will be avoided during path finding.
+ pub fn add_banned_from_list(&mut self, node_ids: Vec<NodeId>) {
+ for id in node_ids {
+ self.manual_node_penalties.insert(id, u64::max_value());
+ }
+ }
+
+ /// Removes the node with the given `node_id` from the list of nodes to avoid.
+ pub fn remove_banned(&mut self, node_id: &NodeId) {
+ self.manual_node_penalties.remove(node_id);
+ }
+
+ /// Sets a manual penalty for the given node.
+ pub fn set_manual_penalty(&mut self, node_id: &NodeId, penalty: u64) {
+ self.manual_node_penalties.insert(*node_id, penalty);
+ }
+
+ /// Removes the node with the given `node_id` from the list of manual penalties.
+ pub fn remove_manual_penalty(&mut self, node_id: &NodeId) {
+ self.manual_node_penalties.remove(node_id);
+ }
+
+ /// Clears the list of manual penalties that are applied during path finding.
+ pub fn clear_manual_penalties(&mut self) {
+ self.manual_node_penalties = HashMap::new();
+ }
+}
+
+#[cfg(test)]
+impl ProbabilisticScoringFeeParameters {
+ fn zero_penalty() -> Self {
+ Self {
+ base_penalty_msat: 0,
+ base_penalty_amount_multiplier_msat: 0,
+ liquidity_penalty_multiplier_msat: 0,
+ liquidity_penalty_amount_multiplier_msat: 0,
+ historical_liquidity_penalty_multiplier_msat: 0,
+ historical_liquidity_penalty_amount_multiplier_msat: 0,
+ manual_node_penalties: HashMap::new(),
+ anti_probing_penalty_msat: 0,
+ considered_impossible_penalty_msat: 0,
+ }
+ }
+}
+
/// Parameters for configuring [`ProbabilisticScorer`].
///
/// Used to configure decay parameters that are static throughout the lifetime of the scorer.
pub liquidity_offset_half_life: Duration,
}
-#[cfg(test)]
-impl ProbabilisticScoringDecayParameters {
- fn zero_penalty() -> Self {
+impl Default for ProbabilisticScoringDecayParameters {
+ fn default() -> Self {
Self {
liquidity_offset_half_life: Duration::from_secs(6 * 60 * 60),
historical_no_updates_half_life: Duration::from_secs(60 * 60 * 24 * 14),
}
}
-impl Default for ProbabilisticScoringDecayParameters {
- fn default() -> Self {
+#[cfg(test)]
+impl ProbabilisticScoringDecayParameters {
+ fn zero_penalty() -> Self {
Self {
liquidity_offset_half_life: Duration::from_secs(6 * 60 * 60),
historical_no_updates_half_life: Duration::from_secs(60 * 60 * 24 * 14),
}
}
}
+
/// Tracks the historical state of a distribution as a weighted average of how much time was spent
/// in each of 8 buckets.
#[derive(Clone, Copy)]
}
}
-impl ProbabilisticScoringFeeParameters {
- #[cfg(test)]
- fn zero_penalty() -> Self {
- Self {
- base_penalty_msat: 0,
- base_penalty_amount_multiplier_msat: 0,
- liquidity_penalty_multiplier_msat: 0,
- liquidity_penalty_amount_multiplier_msat: 0,
- historical_liquidity_penalty_multiplier_msat: 0,
- historical_liquidity_penalty_amount_multiplier_msat: 0,
- manual_node_penalties: HashMap::new(),
- anti_probing_penalty_msat: 0,
- considered_impossible_penalty_msat: 0,
- }
- }
-
- /// Marks the node with the given `node_id` as banned, i.e.,
- /// it will be avoided during path finding.
- pub fn add_banned(&mut self, node_id: &NodeId) {
- self.manual_node_penalties.insert(*node_id, u64::max_value());
- }
-
- /// Marks all nodes in the given list as banned, i.e.,
- /// they will be avoided during path finding.
- pub fn add_banned_from_list(&mut self, node_ids: Vec<NodeId>) {
- for id in node_ids {
- self.manual_node_penalties.insert(id, u64::max_value());
- }
- }
-
- /// Removes the node with the given `node_id` from the list of nodes to avoid.
- pub fn remove_banned(&mut self, node_id: &NodeId) {
- self.manual_node_penalties.remove(node_id);
- }
-
- /// Sets a manual penalty for the given node.
- pub fn set_manual_penalty(&mut self, node_id: &NodeId, penalty: u64) {
- self.manual_node_penalties.insert(*node_id, penalty);
- }
-
- /// Removes the node with the given `node_id` from the list of manual penalties.
- pub fn remove_manual_penalty(&mut self, node_id: &NodeId) {
- self.manual_node_penalties.remove(node_id);
- }
-
- /// Clears the list of manual penalties that are applied during path finding.
- pub fn clear_manual_penalties(&mut self) {
- self.manual_node_penalties = HashMap::new();
- }
-}
-
-impl Default for ProbabilisticScoringFeeParameters {
- fn default() -> Self {
- Self {
- base_penalty_msat: 500,
- base_penalty_amount_multiplier_msat: 8192,
- liquidity_penalty_multiplier_msat: 30_000,
- liquidity_penalty_amount_multiplier_msat: 192,
- manual_node_penalties: HashMap::new(),
- anti_probing_penalty_msat: 250,
- considered_impossible_penalty_msat: 1_0000_0000_000,
- historical_liquidity_penalty_multiplier_msat: 10_000,
- historical_liquidity_penalty_amount_multiplier_msat: 64,
- }
- }
-}
-
impl<T: Time> ChannelLiquidity<T> {
#[inline]
fn new() -> Self {
let mut anti_probing_penalty_msat = 0;
match usage.effective_capacity {
- EffectiveCapacity::ExactLiquidity { liquidity_msat } => {
- if usage.amount_msat > liquidity_msat {
+ EffectiveCapacity::ExactLiquidity { liquidity_msat: amount_msat } |
+ EffectiveCapacity::HintMaxHTLC { amount_msat } =>
+ {
+ if usage.amount_msat > amount_msat {
return u64::max_value();
} else {
return base_penalty_msat;
let usage = ChannelUsage {
amount_msat: 1,
inflight_htlc_msat: 0,
- effective_capacity: EffectiveCapacity::MaximumHTLC { amount_msat: 0 },
+ effective_capacity: EffectiveCapacity::AdvertisedMaxHTLC { amount_msat: 0 },
};
assert_eq!(scorer.channel_penalty_msat(42, &target, &source, usage, ¶ms), 2048);