Skip to content

Commit aaa12ae

Browse files
committed
f - Add test coverage for offset decay
1 parent 56339be commit aaa12ae

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
@@ -1709,7 +1709,117 @@ mod tests {
17091709
assert_eq!(scorer.channel_penalty_msat(43, 250, 1_000, &target, &recipient), 300);
17101710
}
17111711

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

17141824
// TODO: Add test coverage for serialization
17151825
}

0 commit comments

Comments
 (0)