Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
yancyribbens committed Dec 1, 2023
1 parent 876e503 commit a1d73e6
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 66 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ keywords = ["crypto", "bitcoin"]
readme = "README.md"

[dependencies]
bitcoin = { git="https://github.com/rust-bitcoin/rust-bitcoin", branch="master" }
bitcoin = { git="https://github.com/yancyribbens/rust-bitcoin", branch="add-effective-value-calculation" }
rand = {version = "0.8.5", default-features = false, optional = true}

[dev-dependencies]
rust-bitcoin-coin-selection = {path = ".", features = ["rand"]}
rand = "0.8.5"

[patch.crates-io]
bitcoin_hashes = { git="https://github.com/rust-bitcoin/rust-bitcoin.git" }
bitcoin-io = { git = "https://github.com/yancyribbens/rust-bitcoin", branch = "add-effective-value-calculation" }
26 changes: 0 additions & 26 deletions src/errors.rs

This file was deleted.

17 changes: 5 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#![deny(non_snake_case)]
#![deny(unused_mut)]
#![deny(missing_docs)]

// Experimental features we need.
#![cfg_attr(bench, feature(test))]
#![cfg_attr(docsrs, feature(doc_cfg))]
Expand All @@ -19,15 +18,13 @@ extern crate test;

use std::cmp::Reverse;

mod errors;
mod single_random_draw;

use bitcoin::Amount;
use bitcoin::FeeRate;
use bitcoin::TxOut;
use bitcoin::Weight;

use crate::errors::Error;
use crate::single_random_draw::select_coins_srd;
use rand::thread_rng;

Expand All @@ -47,9 +44,9 @@ const CHANGE_LOWER: Amount = Amount::from_sat(50_000);
/// <https://github.com/bitcoindevkit/bdk/blob/feafaaca31a0a40afc03ce98591d151c48c74fa2/crates/bdk/src/types.rs#L181>
#[derive(Clone, Debug, PartialEq)]
pub struct WeightedUtxo {
/// The satisfaction_weight is the size of the required params to satisfy the UTXO.
/// The satisfaction_weight is the size of the required params to satisfy the UTXO.
pub satisfaction_weight: Weight,
/// The corresponding UTXO.
/// The corresponding UTXO.
pub utxo: TxOut,
}

Expand All @@ -66,14 +63,10 @@ pub fn select_coins<T: Utxo>(
fee_rate: FeeRate,
weighted_utxos: &mut [WeightedUtxo],
utxo_pool: &mut [T],
) -> Result<Vec<TxOut>, Error> {
) -> Option<Vec<WeightedUtxo>> {
match select_coins_bnb(target.to_sat(), cost_of_change, utxo_pool) {
Some(_res) => Ok(Vec::new()),
None => Ok(select_coins_srd(target, fee_rate, weighted_utxos, &mut thread_rng())
.unwrap()
.into_iter()
.map(|w| w.utxo)
.collect()),
Some(_res) => Some(Vec::new()),
None => select_coins_srd(target, fee_rate, weighted_utxos, &mut thread_rng()),
}
}

Expand Down
44 changes: 18 additions & 26 deletions src/single_random_draw.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
//! This library provides efficient algorithms to compose a set of unspent transaction outputs
//! (UTXOs).

use crate::errors::Error;
use crate::WeightedUtxo;
use crate::CHANGE_LOWER;
use bitcoin::Amount;
use bitcoin::SignedAmount;
use bitcoin::Weight;
use bitcoin::FeeRate;
use bitcoin::SignedAmount;
use rand::seq::SliceRandom;

/// Randomly select coins for the given target by shuffling the UTXO pool and
Expand Down Expand Up @@ -35,7 +33,7 @@ pub fn select_coins_srd<R: rand::Rng + ?Sized>(
fee_rate: FeeRate,
weighted_utxos: &mut [WeightedUtxo],
rng: &mut R,
) -> Result<Vec<WeightedUtxo>, Error> {
) -> Option<Vec<WeightedUtxo>> {
let mut result: Vec<WeightedUtxo> = Vec::new();

weighted_utxos.shuffle(rng);
Expand All @@ -44,26 +42,23 @@ pub fn select_coins_srd<R: rand::Rng + ?Sized>(
let mut value = Amount::ZERO;

for w_utxo in weighted_utxos {
let effective_value: Option<SignedAmount> = w_utxo.utxo.effective_value(fee_rate, Weight::ZERO);

match effective_value {
Some(e) => {
if e.is_positive() {
value += Amount::from_sat(e.to_sat() as u64)
}
},
None => continue // this could be due to overflow,
}
let effective_value: SignedAmount =
w_utxo.utxo.effective_value(fee_rate, w_utxo.satisfaction_weight)?;

println!("{}", effective_value);
value += match effective_value.to_unsigned() {
Ok(amt) => amt,
Err(_) => Amount::ZERO,
};

result.push(w_utxo.clone());

if value >= threshold {
return Ok(result);
return Some(result);
}
}

Ok(Vec::new())
Some(Vec::new())
}

#[cfg(test)]
Expand Down Expand Up @@ -172,11 +167,8 @@ mod tests {
let target: Amount = Amount::from_str("2 cBTC").unwrap();
let mut weighted_utxos: Vec<WeightedUtxo> = create_weighted_utxos();

let result: Error =
select_coins_srd(target, FeeRate::MAX, &mut weighted_utxos, &mut get_rng())
.expect_err("expected error");

assert_eq!(result.to_string(), "204 * 18446744073709551615 exceeds u64 Max");
let result = select_coins_srd(target, FeeRate::MAX, &mut weighted_utxos, &mut get_rng());
assert!(result.is_none());
}

#[test]
Expand All @@ -195,7 +187,9 @@ mod tests {
let target: Amount = Amount::from_str("1.905 cBTC").unwrap();
// The high fee_rate will cause both utxos to be consumed
// instead of just one.
let fee_rate: FeeRate = FeeRate::from_sat_per_kwu(250);
//
// TODO double check the math.
let fee_rate: FeeRate = FeeRate::from_sat_per_kwu(200_000);
let mut weighted_utxos: Vec<WeightedUtxo> = create_weighted_utxos();

let result = select_coins_srd(target, fee_rate, &mut weighted_utxos, &mut get_rng())
Expand All @@ -216,9 +210,7 @@ mod tests {
},
}];

let result: Error = select_coins_srd(target, FEE_RATE, &mut weighted_utxos, &mut get_rng())
.expect_err("expected error");

assert_eq!(result.to_string(), "18446744073709551615 + 40 exceeds u64 Max");
let result = select_coins_srd(target, FEE_RATE, &mut weighted_utxos, &mut get_rng());
assert!(result.is_none());
}
}

0 comments on commit a1d73e6

Please sign in to comment.