Skip to content

Commit 909b21c

Browse files
committed
wip
1 parent 1717c0a commit 909b21c

File tree

4 files changed

+46
-18
lines changed

4 files changed

+46
-18
lines changed

Cargo.toml

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ readme = "README.md"
1414
rust-version = "1.63.0"
1515

1616
[dependencies]
17-
bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d" }
17+
bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f" }
1818
rand = { version = "0.8.5", default-features = false, optional = true }
1919

2020
[dev-dependencies]
21-
bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d", features = ["arbitrary"] }
21+
bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f", features = ["arbitrary"] }
2222
criterion = "0.3"
2323
bitcoin-coin-selection = {path = ".", features = ["rand"]}
2424
rand = "0.8.5"
@@ -31,10 +31,10 @@ name = "coin_selection"
3131
harness = false
3232

3333
[patch.crates-io]
34-
bitcoin_hashes = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d" }
35-
base58ck = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d" }
36-
bitcoin-internals = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d" }
37-
bitcoin-io = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d" }
38-
bitcoin-primitives = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d" }
39-
bitcoin-addresses = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d" }
40-
bitcoin-units = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "319e87c07c8aca3a4b56027ad3ba29ce359e760d" }
34+
bitcoin_hashes = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f" }
35+
base58ck = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f" }
36+
bitcoin-internals = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f" }
37+
bitcoin-io = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f" }
38+
bitcoin-primitives = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f" }
39+
bitcoin-addresses = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f" }
40+
bitcoin-units = { git = "https://github.com/rust-bitcoin/rust-bitcoin.git", rev = "52f9c13358c97c358543f3302b325f37ac49392f" }

src/branch_and_bound.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! This module introduces the Branch and Bound Coin-Selection Algorithm.
66
77
use bitcoin::amount::CheckedSum;
8-
use bitcoin::{Amount, FeeRate, SignedAmount};
8+
use bitcoin::{Amount, FeeRate};
99

1010
use crate::{Return, WeightedUtxo};
1111

@@ -193,8 +193,9 @@ pub fn select_coins_bnb<Utxo: WeightedUtxo>(
193193

194194
let mut available_value = available_value.to_sat();
195195

196-
// cast from Amount/SignedAmount to u64/i64 for more perfomant operations.
196+
// cast from Amount/SignedAmount to u64/i64 for more performant operations.
197197
let mut w_utxos: Vec<(u64, i64, &Utxo)> = w_utxos.map(|(e, w, u)| (e.to_sat(), w.to_sat(), u)).collect();
198+
let target = target.to_sat();
198199

199200
// descending sort by effective_value using satisfaction weight as tie breaker.
200201
w_utxos.sort_by(|a, b| {
@@ -209,7 +210,7 @@ pub fn select_coins_bnb<Utxo: WeightedUtxo>(
209210
// unchecked_add is used here for performance. Before entering the search loop, all
210211
// utxos are summed and checked for overflow. Since there was no overflow then, any
211212
// subset of addition will not overflow.
212-
if available_value + value < target.to_sat()
213+
if available_value + value < target
213214
// Provides an upper bound on the excess value that is permissible.
214215
// Since value is lost when we create a change output due to increasing the size of the
215216
// transaction by an output (the change output), we accept solutions that may be
@@ -232,11 +233,10 @@ pub fn select_coins_bnb<Utxo: WeightedUtxo>(
232233
}
233234
// * value meets or exceeds the target.
234235
// Record the solution and the waste then continue.
235-
else if value >= target.to_sat() {
236+
else if value >= target {
236237
backtrack = true;
237238

238-
// TODO checked
239-
let waste: i64 = value as i64 - (target.to_sat() as i64);
239+
let waste: i64 = (value as i64).checked_sub(target as i64)?;
240240
current_waste = current_waste.checked_add(waste)?;
241241

242242
// Check if index_selection is better than the previous known best, and
@@ -269,8 +269,7 @@ pub fn select_coins_bnb<Utxo: WeightedUtxo>(
269269
let (eff_value, utxo_waste, _) = w_utxos[index];
270270
current_waste = current_waste.checked_sub(utxo_waste)?;
271271

272-
// TODO this checked
273-
value = value - eff_value;
272+
value = value.checked_sub(eff_value)?;
274273
index_selection.pop().unwrap();
275274
}
276275
// * Add next node to the inclusion branch.

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const SEQUENCE_SIZE: u64 = 4;
3232
const OUT_POINT_SIZE: u64 = 32 + 4;
3333

3434
// https://github.com/rust-bitcoin/rust-bitcoin/blob/35202ba51bef3236e6ed1007a0d2111265b6498c/bitcoin/src/blockdata/transaction.rs#L249
35-
const BASE_WEIGHT: Weight = Weight::from_vb_unwrap(OUT_POINT_SIZE + SEQUENCE_SIZE);
35+
const BASE_WEIGHT: Weight = Weight::from_vb_unchecked(OUT_POINT_SIZE + SEQUENCE_SIZE);
3636

3737
/// Behavior needed for coin-selection.
3838
pub trait WeightedUtxo {

src/single_random_draw.rs

+29
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,35 @@ pub fn select_coins_srd<'a, R: rand::Rng + ?Sized, Utxo: WeightedUtxo>(
3939
weighted_utxos: &'a [Utxo],
4040
rng: &mut R,
4141
) -> Return<'a, Utxo> {
42+
let mut result: Vec<_> = weighted_utxos.iter().collect();
43+
let mut origin = result.to_owned();
44+
origin.shuffle(rng);
45+
46+
result.clear();
47+
48+
let threshold = (target + Amount::from_sat(CHANGE_LOWER).unwrap()).unwrap();
49+
let mut value = Amount::ZERO;
50+
51+
let mut iteration = 0;
52+
for w_utxo in origin {
53+
iteration += 1;
54+
let utxo_value = w_utxo.value();
55+
let utxo_weight = w_utxo.satisfaction_weight();
56+
let effective_value = effective_value(fee_rate, utxo_weight, utxo_value);
57+
58+
if let Some(e) = effective_value {
59+
if let Ok(v) = e.to_unsigned() {
60+
value = (value + v).unwrap();
61+
62+
result.push(w_utxo);
63+
64+
if value >= threshold {
65+
return Some((iteration, result));
66+
}
67+
}
68+
}
69+
}
70+
4271
None
4372
}
4473

0 commit comments

Comments
 (0)