From e93eeb81a212a1d096530f041ca183346e58c965 Mon Sep 17 00:00:00 2001 From: Philipp Hoenisch Date: Fri, 7 May 2021 09:37:10 +1000 Subject: [PATCH] Added some proptests. --- Cargo.lock | 76 +++++++++++++++++++++++++++++++++++++- swap/Cargo.toml | 1 + swap/src/bitcoin/wallet.rs | 61 +++++++++++++++++++++++++++++- 3 files changed, 134 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d578daff..c100705f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -323,6 +323,21 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitcoin" version = "0.26.0" @@ -2692,6 +2707,26 @@ dependencies = [ "unicode-xid 0.2.1", ] +[[package]] +name = "proptest" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0d9cc07f18492d879586c92b485def06bc850da3118075cd45d50e9c95b0e5" +dependencies = [ + "bit-set", + "bitflags", + "byteorder", + "lazy_static", + "num-traits", + "quick-error 2.0.0", + "rand 0.8.3", + "rand_chacha 0.3.0", + "rand_xorshift 0.3.0", + "regex-syntax", + "rusty-fork", + "tempfile", +] + [[package]] name = "prost" version = "0.7.0" @@ -2749,6 +2784,12 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quick-error" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ac73b1112776fc109b2e61909bc46c7e1bf0d7f690ffb1676553acce16d5cda" + [[package]] name = "quicksink" version = "0.1.2" @@ -2806,7 +2847,7 @@ dependencies = [ "rand_jitter", "rand_os", "rand_pcg", - "rand_xorshift", + "rand_xorshift 0.1.1", "winapi 0.3.9", ] @@ -2978,6 +3019,15 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.2", +] + [[package]] name = "rdrand" version = "0.4.0" @@ -3103,7 +3153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" dependencies = [ "hostname", - "quick-error", + "quick-error 1.2.3", ] [[package]] @@ -3197,6 +3247,18 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error 1.2.3", + "tempfile", + "wait-timeout", +] + [[package]] name = "rw-stream-sink" version = "0.2.1" @@ -3762,6 +3824,7 @@ dependencies = [ "pem", "port_check", "prettytable-rs", + "proptest", "rand 0.7.3", "rand_chacha 0.2.2", "reqwest", @@ -4492,6 +4555,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "want" version = "0.3.0" diff --git a/swap/Cargo.toml b/swap/Cargo.toml index 88c782dd..382fc526 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -36,6 +36,7 @@ monero = { version = "0.12", features = [ "serde_support" ] } monero-rpc = { path = "../monero-rpc" } pem = "0.8" prettytable-rs = "0.8" +proptest = "1" rand = "0.7" rand_chacha = "0.2" reqwest = { version = "0.11", features = [ "rustls-tls", "stream", "socks" ], default-features = false } diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index 5fb200c9..801091d8 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -745,6 +745,7 @@ impl fmt::Display for ScriptStatus { #[cfg(test)] mod tests { use super::*; + use proptest::prelude::*; #[test] fn given_depth_0_should_meet_confirmation_target_one() { @@ -821,7 +822,7 @@ mod tests { let relay_fee = bitcoin::Amount::ONE_SAT; let is_fee = estimate_fee(weight, amount, fee_rate, relay_fee); - // weight / 4.0 * sat_per_vb would be greater than 0.03% hence we take max + // weight / 4.0 * sat_per_vb would be greater than 3% hence we take max // relative fee. let should_fee = bitcoin::Amount::from_sat(30_000); assert_eq!(is_fee, should_fee); @@ -840,9 +841,65 @@ mod tests { let relay_fee = bitcoin::Amount::ONE_SAT; let is_fee = estimate_fee(weight, amount, fee_rate, relay_fee); - // weight / 4.0 * sat_per_vb would be greater than 0.03% hence we take total + // weight / 4.0 * sat_per_vb would be greater than 3% hence we take total // max allowed fee. let should_fee = bitcoin::Amount::from_sat(MAX_ABSOLUTE_TX_FEE); assert_eq!(is_fee, should_fee); } + + proptest! { + #[test] + fn given_randon_amount_random_fee_and_random_relay_rate_but_fix_weight_does_not_panic( + amount in prop::num::u64::ANY, + sat_per_vb in prop::num::f32::POSITIVE, + relay_fee in prop::num::u64::ANY + ) { + let weight = 400; + let amount = bitcoin::Amount::from_sat(amount); + + let fee_rate = FeeRate::from_sat_per_vb(sat_per_vb); + + let relay_fee = bitcoin::Amount::from_sat(relay_fee); + let _is_fee = estimate_fee(weight, amount, fee_rate, relay_fee); + + } + } + + proptest! { + #[test] + fn given_amount_in_range_fix_fee_fix_relay_rate_fix_weight_fee_always_smaller_max( + amount in 0u64..100_000_000, + ) { + let weight = 400; + let amount = bitcoin::Amount::from_sat(amount); + + let sat_per_vb = 100.0; + let fee_rate = FeeRate::from_sat_per_vb(sat_per_vb); + + let relay_fee = bitcoin::Amount::ONE_SAT; + let is_fee = estimate_fee(weight, amount, fee_rate, relay_fee); + + // weight / 4 * 1_000 is always lower than MAX_ABSOLUTE_TX_FEE + assert!(is_fee.as_sat() < MAX_ABSOLUTE_TX_FEE); + } + } + + proptest! { + #[test] + fn given_amount_high_fix_fee_fix_relay_rate_fix_weight_fee_always_max( + amount in 100_000_000u64.., + ) { + let weight = 400; + let amount = bitcoin::Amount::from_sat(amount); + + let sat_per_vb = 1_000.0; + let fee_rate = FeeRate::from_sat_per_vb(sat_per_vb); + + let relay_fee = bitcoin::Amount::ONE_SAT; + let is_fee = estimate_fee(weight, amount, fee_rate, relay_fee); + + // weight / 4 * 1_000 is always higher than MAX_ABSOLUTE_TX_FEE + assert!(is_fee.as_sat() >= MAX_ABSOLUTE_TX_FEE); + } + } }