Skip to content

Commit 9087748

Browse files
committed
f - Add test coverage for offset decay
1 parent a147de9 commit 9087748

File tree

1 file changed

+111
-1
lines changed

1 file changed

+111
-1
lines changed

lightning/src/routing/scoring.rs

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1726,7 +1726,117 @@ mod tests {
17261726
assert_eq!(scorer.channel_penalty_msat(43, 250, 1_000, &target, &recipient), 300);
17271727
}
17281728

1729-
// TODO: Add test coverage for offset decay
1729+
#[test]
1730+
fn decays_liquidity_bounds_over_time() {
1731+
let network_graph = network_graph();
1732+
let params = ProbabilisticScoringParameters {
1733+
liquidity_penalty_multiplier_msat: 1_000,
1734+
liquidity_offset_half_life: Duration::from_secs(10),
1735+
};
1736+
let mut scorer = ProbabilisticScorer::new(params, sender_pubkey(), &network_graph);
1737+
let source = source_node_id();
1738+
let target = target_node_id();
1739+
1740+
assert_eq!(scorer.channel_penalty_msat(42, 0, 1_024, &source, &target), 0);
1741+
assert_eq!(scorer.channel_penalty_msat(42, 1_024, 1_024, &source, &target), 3_010);
1742+
1743+
scorer.payment_path_failed(&payment_path_for_amount(768).iter().collect::<Vec<_>>(), 42);
1744+
scorer.payment_path_failed(&payment_path_for_amount(128).iter().collect::<Vec<_>>(), 43);
1745+
1746+
assert_eq!(scorer.channel_penalty_msat(42, 128, 1_024, &source, &target), 0);
1747+
assert_eq!(scorer.channel_penalty_msat(42, 256, 1_024, &source, &target), 92);
1748+
assert_eq!(scorer.channel_penalty_msat(42, 768, 1_024, &source, &target), 1_424);
1749+
assert_eq!(scorer.channel_penalty_msat(42, 896, 1_024, &source, &target), u64::max_value());
1750+
1751+
SinceEpoch::advance(Duration::from_secs(9));
1752+
assert_eq!(scorer.channel_penalty_msat(42, 128, 1_024, &source, &target), 0);
1753+
assert_eq!(scorer.channel_penalty_msat(42, 256, 1_024, &source, &target), 92);
1754+
assert_eq!(scorer.channel_penalty_msat(42, 768, 1_024, &source, &target), 1_424);
1755+
assert_eq!(scorer.channel_penalty_msat(42, 896, 1_024, &source, &target), u64::max_value());
1756+
1757+
SinceEpoch::advance(Duration::from_secs(1));
1758+
assert_eq!(scorer.channel_penalty_msat(42, 64, 1_024, &source, &target), 0);
1759+
assert_eq!(scorer.channel_penalty_msat(42, 128, 1_024, &source, &target), 34);
1760+
assert_eq!(scorer.channel_penalty_msat(42, 896, 1_024, &source, &target), 1_812);
1761+
assert_eq!(scorer.channel_penalty_msat(42, 960, 1_024, &source, &target), u64::max_value());
1762+
1763+
// Fully decay liquidity lower bound.
1764+
SinceEpoch::advance(Duration::from_secs(10 * 7));
1765+
assert_eq!(scorer.channel_penalty_msat(42, 0, 1_024, &source, &target), 0);
1766+
assert_eq!(scorer.channel_penalty_msat(42, 1, 1_024, &source, &target), 0);
1767+
assert_eq!(scorer.channel_penalty_msat(42, 1_023, 1_024, &source, &target), 2_709);
1768+
assert_eq!(scorer.channel_penalty_msat(42, 1_024, 1_024, &source, &target), 3_010);
1769+
1770+
// Fully decay liquidity upper bound.
1771+
SinceEpoch::advance(Duration::from_secs(10));
1772+
assert_eq!(scorer.channel_penalty_msat(42, 0, 1_024, &source, &target), 0);
1773+
assert_eq!(scorer.channel_penalty_msat(42, 1_024, 1_024, &source, &target), 3_010);
1774+
1775+
SinceEpoch::advance(Duration::from_secs(10));
1776+
assert_eq!(scorer.channel_penalty_msat(42, 0, 1_024, &source, &target), 0);
1777+
assert_eq!(scorer.channel_penalty_msat(42, 1_024, 1_024, &source, &target), 3_010);
1778+
}
1779+
1780+
#[test]
1781+
fn decays_liquidity_bounds_without_shift_overflow() {
1782+
let network_graph = network_graph();
1783+
let params = ProbabilisticScoringParameters {
1784+
liquidity_penalty_multiplier_msat: 1_000,
1785+
liquidity_offset_half_life: Duration::from_secs(10),
1786+
};
1787+
let mut scorer = ProbabilisticScorer::new(params, sender_pubkey(), &network_graph);
1788+
let source = source_node_id();
1789+
let target = target_node_id();
1790+
assert_eq!(scorer.channel_penalty_msat(42, 256, 1_024, &source, &target), 124);
1791+
1792+
scorer.payment_path_failed(&payment_path_for_amount(512).iter().collect::<Vec<_>>(), 42);
1793+
assert_eq!(scorer.channel_penalty_msat(42, 256, 1_024, &source, &target), 281);
1794+
1795+
// An unchecked right shift 64 bits or more in DirectedChannelLiquidity::decayed_offset_msat
1796+
// would cause an overflow.
1797+
SinceEpoch::advance(Duration::from_secs(10 * 64));
1798+
assert_eq!(scorer.channel_penalty_msat(42, 256, 1_024, &source, &target), 124);
1799+
1800+
SinceEpoch::advance(Duration::from_secs(10));
1801+
assert_eq!(scorer.channel_penalty_msat(42, 256, 1_024, &source, &target), 124);
1802+
}
1803+
1804+
#[test]
1805+
fn restricts_liquidity_bounds_after_decay() {
1806+
let network_graph = network_graph();
1807+
let params = ProbabilisticScoringParameters {
1808+
liquidity_penalty_multiplier_msat: 1_000,
1809+
liquidity_offset_half_life: Duration::from_secs(10),
1810+
};
1811+
let mut scorer = ProbabilisticScorer::new(params, sender_pubkey(), &network_graph);
1812+
let source = source_node_id();
1813+
let target = target_node_id();
1814+
1815+
assert_eq!(scorer.channel_penalty_msat(42, 512, 1_024, &source, &target), 300);
1816+
1817+
// More knowledge gives higher confidence (256, 768), meaning a lower penalty.
1818+
scorer.payment_path_failed(&payment_path_for_amount(768).iter().collect::<Vec<_>>(), 42);
1819+
scorer.payment_path_failed(&payment_path_for_amount(256).iter().collect::<Vec<_>>(), 43);
1820+
assert_eq!(scorer.channel_penalty_msat(42, 512, 1_024, &source, &target), 281);
1821+
1822+
// Decaying knowledge gives less confidence (128, 896), meaning a higher penalty.
1823+
SinceEpoch::advance(Duration::from_secs(10));
1824+
assert_eq!(scorer.channel_penalty_msat(42, 512, 1_024, &source, &target), 293);
1825+
1826+
// Reducing the upper bound gives more confidence (128, 832) that the payment amount (512)
1827+
// is closer to the upper bound, meaning a higher penalty.
1828+
scorer.payment_path_successful(&payment_path_for_amount(64).iter().collect::<Vec<_>>());
1829+
assert_eq!(scorer.channel_penalty_msat(42, 512, 1_024, &source, &target), 333);
1830+
1831+
// Increasing the lower bound gives more confidence (256, 832) that the payment amount (512)
1832+
// is closer to the lower bound, meaning a lower penalty.
1833+
scorer.payment_path_failed(&payment_path_for_amount(256).iter().collect::<Vec<_>>(), 43);
1834+
assert_eq!(scorer.channel_penalty_msat(42, 512, 1_024, &source, &target), 247);
1835+
1836+
// Further decaying affects the lower bound more than the upper bound (128, 928).
1837+
SinceEpoch::advance(Duration::from_secs(10));
1838+
assert_eq!(scorer.channel_penalty_msat(42, 512, 1_024, &source, &target), 280);
1839+
}
17301840

17311841
// TODO: Add test coverage for serialization
17321842
}

0 commit comments

Comments
 (0)