Skip to content

Commit

Permalink
Add BnB proptest
Browse files Browse the repository at this point in the history
  • Loading branch information
yancyribbens committed Jul 27, 2024
1 parent 12d4d33 commit 8a0adae
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = [
"bitcoin-coin-selection", "fuzz",
"bitcoin-coin-selection", "fuzz", "prop",
]
resolver = "1"
10 changes: 10 additions & 0 deletions prop/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "prop"
version = "0.1.0"
edition = "2021"

[dependencies]
proptest = "1.5.0"
bitcoin-coin-selection = { path = "../bitcoin-coin-selection", features = ["rand"] }
bitcoin = { git = "https://github.com/yancyribbens/rust-bitcoin.git", rev = "edcd2fb5d78be71a60709d18fb367fd56171ff26" }
rand = "0.8.5"
79 changes: 79 additions & 0 deletions prop/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use bitcoin::Amount;
use bitcoin::FeeRate;
use bitcoin::ScriptBuf;
use bitcoin::TxOut;
use bitcoin::Weight;
use proptest::prelude::*;

use bitcoin_coin_selection::select_coins_bnb;
use bitcoin_coin_selection::WeightedUtxo;

#[derive(Clone, Debug)]
pub struct Utxo {
output: TxOut,
satisfaction_weight: Weight,
}

impl WeightedUtxo for Utxo {
fn satisfaction_weight(&self) -> Weight {
self.satisfaction_weight
}

fn value(&self) -> Amount {
self.output.value
}
}

proptest! {
#[test]
fn test_bnb(ref mut vec in any::<Vec<u8>>()) {
vec.truncate(10);

let pool: Vec<Utxo> = vec.into_iter()
.map(|u| u64::from(*u))
.map(|i| Amount::from_sat(i))
.map(|a| {
let output = TxOut {
value: a,
script_pubkey: ScriptBuf::new()
};

let satisfaction_weight = Weight::ZERO;

Utxo {
output,
satisfaction_weight
}
})
.collect();

// Pick a random subset of coins by choosing only the evens
let solution: Vec<Amount> = pool.clone().into_iter().map(|i| {
if i.value() % 2 == Amount::ZERO {
i.value()
} else {
Amount::ZERO
}
}).collect();

// Set the target to be the sum of evens
let target: Amount = solution.clone().into_iter().sum();

let selection: Vec<Amount> =
select_coins_bnb(
target,
Amount::ZERO,
FeeRate::ZERO,
FeeRate::ZERO,
&pool)
.unwrap()
.map(|i| i.value()).collect();

let sum: Amount = selection.into_iter().sum();
assert_eq!(target, sum);
}
}

fn main() {
test_bnb();
}

0 comments on commit 8a0adae

Please sign in to comment.