Skip to content

Commit bdbe9c8

Browse files
committed
Smooth out channel liquidity bounds decay
Decaying the channel liquidity bounds by a half life can result in a large decrease, which may have an oscillating affect on whether a channel is retried. Approximate an additional three-quarter life when half of the next half life has passed to help smooth out the decay.
1 parent dba3e8f commit bdbe9c8

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

lightning/src/routing/scoring.rs

+34-5
Original file line numberDiff line numberDiff line change
@@ -1151,10 +1151,25 @@ impl<L: Deref<Target = u64>, BRT: Deref<Target = HistoricalBucketRangeTracker>,
11511151
}
11521152

11531153
fn decayed_offset_msat(&self, offset_msat: u64) -> u64 {
1154-
self.now.duration_since(*self.last_updated).as_secs()
1155-
.checked_div(self.decay_params.liquidity_offset_half_life.as_secs())
1156-
.and_then(|decays| offset_msat.checked_shr(decays as u32))
1157-
.unwrap_or(0)
1154+
let half_life = self.decay_params.liquidity_offset_half_life.as_secs();
1155+
if half_life != 0 {
1156+
// Decay the offset by the appropriate number of half lives. If half of the next half
1157+
// life has passed, approximate an additional three-quarter life to help smooth out the
1158+
// decay.
1159+
let elapsed_time = self.now.duration_since(*self.last_updated).as_secs();
1160+
let half_decays = elapsed_time / (half_life / 2);
1161+
let decays = half_decays / 2;
1162+
let decayed_offset_msat = offset_msat.checked_shr(decays as u32).unwrap_or(0);
1163+
if half_decays % 2 == 0 {
1164+
decayed_offset_msat
1165+
} else {
1166+
// 11_585 / 16_384 ~= core::f64::consts::FRAC_1_SQRT_2
1167+
// 16_384 == 2^14
1168+
(decayed_offset_msat as u128 * 11_585 / 16_384) as u64
1169+
}
1170+
} else {
1171+
0
1172+
}
11581173
}
11591174
}
11601175

@@ -2405,6 +2420,7 @@ mod tests {
24052420
scorer.payment_path_failed(&payment_path_for_amount(768), 42);
24062421
scorer.payment_path_failed(&payment_path_for_amount(128), 43);
24072422

2423+
// Initial penalties
24082424
let usage = ChannelUsage { amount_msat: 128, ..usage };
24092425
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), 0);
24102426
let usage = ChannelUsage { amount_msat: 256, ..usage };
@@ -2414,7 +2430,8 @@ mod tests {
24142430
let usage = ChannelUsage { amount_msat: 896, ..usage };
24152431
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), u64::max_value());
24162432

2417-
SinceEpoch::advance(Duration::from_secs(9));
2433+
// No decay
2434+
SinceEpoch::advance(Duration::from_secs(4));
24182435
let usage = ChannelUsage { amount_msat: 128, ..usage };
24192436
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), 0);
24202437
let usage = ChannelUsage { amount_msat: 256, ..usage };
@@ -2424,7 +2441,19 @@ mod tests {
24242441
let usage = ChannelUsage { amount_msat: 896, ..usage };
24252442
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), u64::max_value());
24262443

2444+
// Half decay (i.e., three-quarter life)
24272445
SinceEpoch::advance(Duration::from_secs(1));
2446+
let usage = ChannelUsage { amount_msat: 128, ..usage };
2447+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), 22);
2448+
let usage = ChannelUsage { amount_msat: 256, ..usage };
2449+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), 106);
2450+
let usage = ChannelUsage { amount_msat: 768, ..usage };
2451+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), 916);
2452+
let usage = ChannelUsage { amount_msat: 896, ..usage };
2453+
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), u64::max_value());
2454+
2455+
// One decay (i.e., half life)
2456+
SinceEpoch::advance(Duration::from_secs(5));
24282457
let usage = ChannelUsage { amount_msat: 64, ..usage };
24292458
assert_eq!(scorer.channel_penalty_msat(42, &source, &target, usage, &params), 0);
24302459
let usage = ChannelUsage { amount_msat: 128, ..usage };

0 commit comments

Comments
 (0)