From 475057abda233d7599cb1cbc375b4788402f0098 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Aug 2021 18:12:40 +1000 Subject: [PATCH] Add proptest for max_giveable and signing PSBT --- swap/proptest-regressions/bitcoin/wallet.txt | 7 +++++++ swap/src/bitcoin/wallet.rs | 17 +++++++++++++++++ swap/src/proptest.rs | 12 ++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 swap/proptest-regressions/bitcoin/wallet.txt diff --git a/swap/proptest-regressions/bitcoin/wallet.txt b/swap/proptest-regressions/bitcoin/wallet.txt new file mode 100644 index 00000000..843cefb4 --- /dev/null +++ b/swap/proptest-regressions/bitcoin/wallet.txt @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 849f8b01f49fc9a913100203698a9151d8de8a37564e1d3b1e3b4169e192f58a # shrinks to funding_amount = 290250686, num_utxos = 3, sats_per_vb = 75.35638, key = ExtendedPrivKey { network: Regtest, depth: 0, parent_fingerprint: 00000000, child_number: Normal { index: 0 }, private_key: [private key data], chain_code: 0b7a29ca6990bbc9b9187c1d1a07e2cf68e32f5ce55d2df01edf8a4ac2ee2a4b }, alice = Point(0299a8c6a662e2e9e8ee7c6889b75a51c432812b4bf70c1d76eace63abc1bdfb1b), bob = Point(027165b1f9924030c90d38c511da0f4397766078687997ed34d6ef2743d2a7bbed) diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index b544e650..82be3dc6 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -1201,4 +1201,21 @@ DEBUG swap::bitcoin::wallet: Bitcoin transaction status changed txid=00000000000 fn confs(confirmations: u32) -> ScriptStatus { ScriptStatus::from_confirmations(confirmations) } + + proptest::proptest! { + #[test] + fn funding_never_fails_with_insufficient_funds(funding_amount in 3000u32.., num_utxos in 1..5u8, sats_per_vb in 1.0..500.0f32, key in crate::proptest::bitcoin::extended_priv_key(), alice in crate::proptest::ecdsa_fun::point(), bob in crate::proptest::ecdsa_fun::point()) { + proptest::prop_assume!(alice != bob); + + tokio::runtime::Runtime::new().unwrap().block_on(async move { + let wallet = WalletBuilder::new(funding_amount as u64).with_key(key).with_num_utxos(num_utxos).with_fees(sats_per_vb, 1000).build(); + + let amount = wallet.max_giveable(TxLock::script_size()).await.unwrap(); + let psbt: PartiallySignedTransaction = TxLock::new(&wallet, amount, PublicKey::from(alice), PublicKey::from(bob), wallet.new_address().await.unwrap()).await.unwrap().into(); + let result = wallet.sign_and_finalize(psbt).await; + + result.expect("transaction to be signed"); + }); + } + } } diff --git a/swap/src/proptest.rs b/swap/src/proptest.rs index 0c7ee7b3..41b28785 100644 --- a/swap/src/proptest.rs +++ b/swap/src/proptest.rs @@ -15,3 +15,15 @@ pub mod ecdsa_fun { }) } } + +pub mod bitcoin { + use super::*; + use ::bitcoin::util::bip32::ExtendedPrivKey; + use ::bitcoin::Network; + + pub fn extended_priv_key() -> impl Strategy { + prop::array::uniform8(0..255u8).prop_filter_map("invalid secret key generated", |bytes| { + ExtendedPrivKey::new_master(Network::Regtest, &bytes).ok() + }) + } +}