+ fn payment_path_failed(&mut self, _path: &Vec<RouteHop>, short_channel_id: u64) {
+ let failure_penalty_msat = self.params.failure_penalty_msat;
+ #[cfg(not(feature = "no-std"))]
+ {
+ let half_life = self.params.failure_penalty_half_life;
+ self.channel_failures
+ .entry(short_channel_id)
+ .and_modify(|(penalty_msat, last_failure)| {
+ let decayed_penalty = decay_from(*penalty_msat, last_failure, half_life);
+ *penalty_msat = decayed_penalty + failure_penalty_msat;
+ *last_failure = Instant::now();
+ })
+ .or_insert_with(|| (failure_penalty_msat, Instant::now()));
+ }
+ #[cfg(feature = "no-std")]
+ self.channel_failures
+ .entry(short_channel_id)
+ .and_modify(|penalty_msat| *penalty_msat += failure_penalty_msat)
+ .or_insert(failure_penalty_msat);
+ }
+}
+
+#[cfg(not(feature = "no-std"))]
+fn decay_from(penalty_msat: u64, last_failure: &Instant, half_life: Duration) -> u64 {
+ let decays = last_failure.elapsed().as_secs().checked_div(half_life.as_secs());
+ match decays {
+ Some(decays) => penalty_msat >> decays,
+ None => 0,
+ }