Skip to content

Commit c2eb68f

Browse files
authored
Merge pull request #4406 from TheBlueMatt/2026-02-fix-msrv
Drop `proptest`s in `lightning-liquidity`
2 parents 927edf1 + 4deb2f7 commit c2eb68f

9 files changed

Lines changed: 51 additions & 223 deletions

File tree

ci/ci-tests.sh

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ PIN_RELEASE_DEPS # pin the release dependencies in our main workspace
1616
# The backtrace v0.3.75 crate relies on rustc 1.82
1717
[ "$RUSTC_MINOR_VERSION" -lt 82 ] && cargo update -p backtrace --precise "0.3.74" --quiet
1818

19-
# proptest 1.9.0 requires rustc 1.82.0
20-
[ "$RUSTC_MINOR_VERSION" -lt 82 ] && cargo update -p proptest --precise "1.8.0" --quiet
21-
2219
# Starting with version 1.2.0, the `idna_adapter` crate has an MSRV of rustc 1.81.0.
2320
[ "$RUSTC_MINOR_VERSION" -lt 81 ] && cargo update -p idna_adapter --precise "1.1.0" --quiet
2421

lightning-dns-resolver/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ rust-version = "1.75"
1111

1212
[dependencies]
1313
lightning = { version = "0.3.0", path = "../lightning", default-features = false }
14-
lightning-types = { version = "0.3.0", path = "../lightning-types", default-features = false }
14+
lightning-types = { version = "0.4.0", path = "../lightning-types", default-features = false }
1515
dnssec-prover = { version = "0.6", default-features = false, features = [ "std", "tokio" ] }
1616
tokio = { version = "1.0", default-features = false, features = ["rt"] }
1717

lightning-invoice/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ std = []
2020

2121
[dependencies]
2222
bech32 = { version = "0.11.0", default-features = false }
23-
lightning-types = { version = "0.3.0", path = "../lightning-types", default-features = false }
23+
lightning-types = { version = "0.4.0", path = "../lightning-types", default-features = false }
2424
serde = { version = "1.0", optional = true, default-features = false, features = ["alloc"] }
2525
bitcoin = { version = "0.32.4", default-features = false, features = ["secp-recovery"] }
2626

lightning-liquidity/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ _test_utils = []
2323

2424
[dependencies]
2525
lightning = { version = "0.3.0", path = "../lightning", default-features = false }
26-
lightning-types = { version = "0.3.0", path = "../lightning-types", default-features = false }
26+
lightning-types = { version = "0.4.0", path = "../lightning-types", default-features = false }
2727
lightning-invoice = { version = "0.35.0", path = "../lightning-invoice", default-features = false, features = ["serde"] }
2828
lightning-macros = { version = "0.2", path = "../lightning-macros" }
2929

@@ -39,7 +39,6 @@ lightning = { version = "0.3.0", path = "../lightning", default-features = false
3939
lightning-invoice = { version = "0.35.0", path = "../lightning-invoice", default-features = false, features = ["serde", "std"] }
4040
lightning-persister = { version = "0.3.0", path = "../lightning-persister", default-features = false }
4141

42-
proptest = "1.0.0"
4342
tokio = { version = "1.35", default-features = false, features = [ "rt-multi-thread", "time", "sync", "macros" ] }
4443
parking_lot = { version = "0.12", default-features = false }
4544

lightning-liquidity/src/lsps2/service.rs

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,64 +2351,58 @@ mod tests {
23512351

23522352
use crate::lsps0::ser::LSPSDateTime;
23532353

2354-
use proptest::prelude::*;
2355-
23562354
use bitcoin::{absolute::LockTime, transaction::Version};
23572355
use core::str::FromStr;
23582356

23592357
const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000;
23602358

2361-
fn arb_forward_amounts() -> impl Strategy<Value = (u64, u64, u64, u64)> {
2362-
(1u64..MAX_VALUE_MSAT, 1u64..MAX_VALUE_MSAT, 1u64..MAX_VALUE_MSAT, 1u64..MAX_VALUE_MSAT)
2363-
.prop_map(|(a, b, c, d)| {
2364-
(a, b, c, core::cmp::min(d, a.saturating_add(b).saturating_add(c)))
2365-
})
2366-
}
2359+
#[test]
2360+
fn rand_test_calculate_amount_to_forward() {
2361+
use std::collections::hash_map::RandomState;
2362+
use std::hash::{BuildHasher, Hasher};
2363+
2364+
let total_fee_msat = RandomState::new().build_hasher().finish() % MAX_VALUE_MSAT;
2365+
let htlc_count = (RandomState::new().build_hasher().finish() % 10) as u8;
2366+
2367+
let mut htlcs = Vec::new();
2368+
let mut total_received_msat = 0;
2369+
let mut htlc_values = Vec::new();
2370+
for i in 0..htlc_count {
2371+
let expected_outbound_amount_msat =
2372+
RandomState::new().build_hasher().finish() % MAX_VALUE_MSAT;
2373+
if total_received_msat + expected_outbound_amount_msat > MAX_VALUE_MSAT {
2374+
break;
2375+
}
2376+
total_received_msat += expected_outbound_amount_msat;
2377+
htlc_values.push(total_received_msat);
2378+
htlcs.push(InterceptedHTLC {
2379+
intercept_id: InterceptId([i; 32]),
2380+
expected_outbound_amount_msat,
2381+
payment_hash: PaymentHash([i; 32]),
2382+
});
2383+
}
23672384

2368-
proptest! {
2369-
#[test]
2370-
fn proptest_calculate_amount_to_forward((o_0, o_1, o_2, total_fee_msat) in arb_forward_amounts()) {
2371-
let htlcs = vec![
2372-
InterceptedHTLC {
2373-
intercept_id: InterceptId([0; 32]),
2374-
expected_outbound_amount_msat: o_0,
2375-
payment_hash: PaymentHash([0; 32]),
2376-
},
2377-
InterceptedHTLC {
2378-
intercept_id: InterceptId([1; 32]),
2379-
expected_outbound_amount_msat: o_1,
2380-
payment_hash: PaymentHash([0; 32]),
2381-
},
2382-
InterceptedHTLC {
2383-
intercept_id: InterceptId([2; 32]),
2384-
expected_outbound_amount_msat: o_2,
2385-
payment_hash: PaymentHash([0; 32]),
2386-
},
2387-
];
2385+
if total_fee_msat > total_received_msat {
2386+
return;
2387+
}
23882388

2389-
let result = calculate_amount_to_forward_per_htlc(&htlcs, total_fee_msat);
2390-
let total_received_msat = o_0 + o_1 + o_2;
2389+
let result = calculate_amount_to_forward_per_htlc(&htlcs, total_fee_msat);
23912390

2392-
if total_received_msat < total_fee_msat {
2393-
assert_eq!(result.len(), 0);
2394-
} else {
2395-
assert_ne!(result.len(), 0);
2396-
assert_eq!(result[0].0, htlcs[0].intercept_id);
2397-
assert_eq!(result[1].0, htlcs[1].intercept_id);
2398-
assert_eq!(result[2].0, htlcs[2].intercept_id);
2399-
assert!(result[0].1 <= o_0);
2400-
assert!(result[1].1 <= o_1);
2401-
assert!(result[2].1 <= o_2);
2402-
2403-
let result_sum = result.iter().map(|(_, f)| f).sum::<u64>();
2404-
assert_eq!(total_received_msat - result_sum, total_fee_msat);
2405-
let five_pct = result_sum as f32 * 0.05;
2406-
let fair_share_0 = (o_0 as f32 / total_received_msat as f32) * result_sum as f32;
2407-
assert!(result[0].1 as f32 <= fair_share_0 + five_pct);
2408-
let fair_share_1 = (o_1 as f32 / total_received_msat as f32) * result_sum as f32;
2409-
assert!(result[1].1 as f32 <= fair_share_1 + five_pct);
2410-
let fair_share_2 = (o_2 as f32 / total_received_msat as f32) * result_sum as f32;
2411-
assert!(result[2].1 as f32 <= fair_share_2 + five_pct);
2391+
if total_received_msat < total_fee_msat {
2392+
assert_eq!(result.len(), 0);
2393+
} else {
2394+
assert_eq!(result.len(), htlcs.len());
2395+
let result_sum = result.iter().map(|(_, f)| f).sum::<u64>();
2396+
assert_eq!(total_received_msat - result_sum, total_fee_msat);
2397+
let five_pct = result_sum as f32 * 0.05;
2398+
2399+
for ((htlc, htlc_value), res) in htlcs.iter().zip(htlc_values).zip(result.iter()) {
2400+
assert_eq!(res.0, htlc.intercept_id);
2401+
assert!(res.1 <= htlc_value);
2402+
2403+
let fair_share =
2404+
(htlc_value as f32 / total_received_msat as f32) * result_sum as f32;
2405+
assert!(res.1 as f32 <= fair_share + five_pct);
24122406
}
24132407
}
24142408
}

lightning-liquidity/src/lsps2/utils.rs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,33 +60,6 @@ pub fn compute_opening_fee(
6060
) -> Option<u64> {
6161
payment_size_msat
6262
.checked_mul(opening_fee_proportional)
63-
.and_then(|f| f.checked_add(999999))
64-
.and_then(|f| f.checked_div(1000000))
63+
.map(|f| f.div_ceil(1_000_000))
6564
.map(|f| core::cmp::max(f, opening_fee_min_fee_msat))
6665
}
67-
68-
#[cfg(test)]
69-
mod tests {
70-
use super::*;
71-
use proptest::prelude::*;
72-
73-
const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000;
74-
75-
fn arb_opening_fee_params() -> impl Strategy<Value = (u64, u64, u64)> {
76-
(0u64..MAX_VALUE_MSAT, 0u64..MAX_VALUE_MSAT, 0u64..MAX_VALUE_MSAT)
77-
}
78-
79-
proptest! {
80-
#[test]
81-
fn test_compute_opening_fee((payment_size_msat, opening_fee_min_fee_msat, opening_fee_proportional) in arb_opening_fee_params()) {
82-
if let Some(res) = compute_opening_fee(payment_size_msat, opening_fee_min_fee_msat, opening_fee_proportional) {
83-
assert!(res >= opening_fee_min_fee_msat);
84-
assert_eq!(res as f32, (payment_size_msat as f32 * opening_fee_proportional as f32));
85-
} else {
86-
// Check we actually overflowed.
87-
let max_value = u64::MAX as u128;
88-
assert!((payment_size_msat as u128 * opening_fee_proportional as u128) > max_value);
89-
}
90-
}
91-
}
92-
}

lightning-liquidity/src/lsps5/url_utils.rs

Lines changed: 0 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -102,138 +102,3 @@ impl Readable for LSPSUrl {
102102
Ok(Self(Readable::read(reader)?))
103103
}
104104
}
105-
106-
#[cfg(test)]
107-
mod tests {
108-
use super::*;
109-
use crate::alloc::string::ToString;
110-
use alloc::vec::Vec;
111-
use proptest::prelude::*;
112-
113-
#[test]
114-
fn test_extremely_long_url() {
115-
let url_str = format!("https://{}/path", "a".repeat(1000)).to_string();
116-
let url_chars = url_str.chars().count();
117-
let result = LSPSUrl::parse(url_str);
118-
119-
assert!(result.is_ok());
120-
let url = result.unwrap();
121-
assert_eq!(url.0 .0.chars().count(), url_chars);
122-
}
123-
124-
#[test]
125-
fn test_parse_http_url() {
126-
let url_str = "http://example.com/path".to_string();
127-
let url = LSPSUrl::parse(url_str).unwrap_err();
128-
assert_eq!(url, LSPS5ProtocolError::UnsupportedProtocol);
129-
}
130-
131-
#[test]
132-
fn valid_lsps_url() {
133-
let test_vec: Vec<&'static str> = vec![
134-
"https://www.example.org/push?l=1234567890abcopqrstuv&c=best",
135-
"https://www.example.com/path",
136-
"https://example.org",
137-
"https://example.com:8080/path",
138-
"https://api.example.com/v1/resources",
139-
"https://example.com/page#section1",
140-
"https://example.com/search?q=test#results",
141-
"https://user:pass@example.com/",
142-
"https://192.168.1.1/admin",
143-
"https://example.com://path",
144-
"https://example.com/path%20with%20spaces",
145-
"https://example_example.com/path?query=with&spaces=true",
146-
];
147-
for url_str in test_vec {
148-
let url = LSPSUrl::parse(url_str.to_string());
149-
assert!(url.is_ok(), "Failed to parse URL: {}", url_str);
150-
}
151-
}
152-
153-
#[test]
154-
fn invalid_lsps_url() {
155-
let test_vec = vec![
156-
"ftp://ftp.example.org/pub/files/document.pdf",
157-
"sftp://user:password@sftp.example.com:22/uploads/",
158-
"ssh://username@host.com:2222",
159-
"lightning://03a.example.com/invoice?amount=10000",
160-
"ftp://user@ftp.example.com/files/",
161-
"https://例子.测试/path",
162-
"a123+-.://example.com",
163-
"a123+-.://example.com",
164-
"https:\\\\example.com\\path",
165-
"https:///whatever",
166-
"https://example.com/path with spaces",
167-
];
168-
for url_str in test_vec {
169-
let url = LSPSUrl::parse(url_str.to_string());
170-
assert!(url.is_err(), "Expected error for URL: {}", url_str);
171-
}
172-
}
173-
174-
#[test]
175-
fn parsing_errors() {
176-
let test_vec = vec![
177-
"example.com/path",
178-
"https://bad domain.com/",
179-
"https://example.com\0/path",
180-
"https://",
181-
"ht@ps://example.com",
182-
"http!://example.com",
183-
"1https://example.com",
184-
"https://://example.com",
185-
"https://example.com:port/path",
186-
"https://:8080/path",
187-
"https:",
188-
"://",
189-
"https://example.com\0/path",
190-
];
191-
for url_str in test_vec {
192-
let url = LSPSUrl::parse(url_str.to_string());
193-
assert!(url.is_err(), "Expected error for URL: {}", url_str);
194-
}
195-
}
196-
197-
fn host_strategy() -> impl Strategy<Value = String> {
198-
prop_oneof![
199-
proptest::string::string_regex(
200-
"[a-z0-9]+(?:-[a-z0-9]+)*(?:\\.[a-z0-9]+(?:-[a-z0-9]+)*)*"
201-
)
202-
.unwrap(),
203-
(0u8..=255u8, 0u8..=255u8, 0u8..=255u8, 0u8..=255u8)
204-
.prop_map(|(a, b, c, d)| format!("{}.{}.{}.{}", a, b, c, d))
205-
]
206-
}
207-
208-
proptest! {
209-
#[test]
210-
fn proptest_parse_round_trip(
211-
host in host_strategy(),
212-
port in proptest::option::of(0u16..=65535u16),
213-
path in proptest::option::of(proptest::string::string_regex("[a-zA-Z0-9._%&=:@/-]{0,20}").unwrap()),
214-
query in proptest::option::of(proptest::string::string_regex("[a-zA-Z0-9._%&=:@/-]{0,20}").unwrap()),
215-
fragment in proptest::option::of(proptest::string::string_regex("[a-zA-Z0-9._%&=:@/-]{0,20}").unwrap())
216-
) {
217-
let mut url = format!("https://{}", host);
218-
if let Some(p) = port {
219-
url.push_str(&format!(":{}", p));
220-
}
221-
if let Some(pth) = &path {
222-
url.push('/');
223-
url.push_str(pth);
224-
}
225-
if let Some(q) = &query {
226-
url.push('?');
227-
url.push_str(q);
228-
}
229-
if let Some(f) = &fragment {
230-
url.push('#');
231-
url.push_str(f);
232-
}
233-
234-
let parsed = LSPSUrl::parse(url.clone()).expect("should parse");
235-
prop_assert_eq!(parsed.url(), url.as_str());
236-
prop_assert_eq!(parsed.url_length(), url.chars().count());
237-
}
238-
}
239-
}

lightning-types/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "lightning-types"
3-
version = "0.3.0+git"
3+
version = "0.4.0+git"
44
authors = ["Matt Corallo"]
55
license = "MIT OR Apache-2.0"
66
repository = "https://github.com/lightningdevkit/rust-lightning/"

lightning/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ grind_signatures = []
3434
default = ["std", "grind_signatures"]
3535

3636
[dependencies]
37-
lightning-types = { version = "0.3.0", path = "../lightning-types", default-features = false }
37+
lightning-types = { version = "0.4.0", path = "../lightning-types", default-features = false }
3838
lightning-invoice = { version = "0.35.0", path = "../lightning-invoice", default-features = false }
3939
lightning-macros = { version = "0.2", path = "../lightning-macros" }
4040

@@ -53,7 +53,7 @@ inventory = { version = "0.3", optional = true }
5353

5454
[dev-dependencies]
5555
regex = "1.5.6"
56-
lightning-types = { version = "0.3.0", path = "../lightning-types", features = ["_test_utils"] }
56+
lightning-types = { version = "0.4.0", path = "../lightning-types", features = ["_test_utils"] }
5757
lightning-macros = { path = "../lightning-macros" }
5858
parking_lot = { version = "0.12", default-features = false }
5959

0 commit comments

Comments
 (0)