diff --git a/Cargo.toml b/Cargo.toml index a551c9b0..1905aaf1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ keywords = ["crypto", "bitcoin"] readme = "README.md" [dependencies] -bitcoin = { git="https://github.com/yancyribbens/rust-bitcoin", branch = "tmp/mark-txin-base-weight-public" } +bitcoin = { git="https://github.com/yancyribbens/rust-bitcoin", rev="254fafdf71b30ae9156b43d57b336cf4a251ed33" } rand = {version = "0.8.5", default-features = false, optional = true} [dev-dependencies] @@ -24,10 +24,10 @@ rust-bitcoin-coin-selection = {path = ".", features = ["rand"]} rand = "0.8.5" [patch.crates-io] -bitcoin_hashes = { git = "https://github.com/yancyribbens/rust-bitcoin", branch = "tmp/mark-txin-base-weight-public" } -bitcoin-io = { git = "https://github.com/yancyribbens/rust-bitcoin", branch = "tmp/mark-txin-base-weight-public" } -bitcoin-units = { git = "https://github.com/yancyribbens/rust-bitcoin", branch = "tmp/mark-txin-base-weight-public" } -bitcoin-internals = { git = "https://github.com/yancyribbens/rust-bitcoin", branch = "tmp/mark-txin-base-weight-public" } +bitcoin_hashes = { git = "https://github.com/yancyribbens/rust-bitcoin", rev="254fafdf71b30ae9156b43d57b336cf4a251ed33" } +bitcoin-io = { git = "https://github.com/yancyribbens/rust-bitcoin", rev="254fafdf71b30ae9156b43d57b336cf4a251ed33" } +bitcoin-units = { git = "https://github.com/yancyribbens/rust-bitcoin", rev="254fafdf71b30ae9156b43d57b336cf4a251ed33" } +bitcoin-internals = { git = "https://github.com/yancyribbens/rust-bitcoin", rev="254fafdf71b30ae9156b43d57b336cf4a251ed33" } [[bench]] name = "coin_selection" diff --git a/src/branch_and_bound.rs b/src/branch_and_bound.rs index f5dd1015..e6277452 100644 --- a/src/branch_and_bound.rs +++ b/src/branch_and_bound.rs @@ -214,7 +214,11 @@ pub fn select_coins_bnb( // * not enough value to make it to the target. // Therefore, explore a new new subtree. - if available_value + value < target { + // + // unchecked_add is used here for performance. Before entering the search loop, all + // utxos are summed and checked for overflow. Since there was no overflow then, any + // subset of addition will not overflow. + if available_value.unchecked_add(value) < target { backtrack_subtree = true; } // This optimization provides an upper bound on the amount of waste that is acceptable. @@ -233,7 +237,9 @@ pub fn select_coins_bnb( // it's high fee_rate environment. During low fee environments, a utxo may // have negative waste, therefore adding more utxos in such an environment // may still result in reduced waste. - else if value > target + cost_of_change + else if value > target.unchecked_add(cost_of_change) //TODO we can check this for overflow + //before the loop begins by adding + //target to utxo_pool sum. || current_waste > best_waste && fee_rate > long_term_fee_rate { backtrack = true; @@ -285,9 +291,11 @@ pub fn select_coins_bnb( // The available value of the next iteration. This should never overflow // since the value is always less than the last available_value calculation. + // TODO - can this be use sum() in Amount instead. + // TODO - Amount should have unchecked_sum() for this case. available_value = w_utxos[index + 1..].iter().fold(Amount::ZERO, |mut s, &(v, _, _)| { - s += v; + s = s.unchecked_add(v); s }); @@ -306,7 +314,10 @@ pub fn select_coins_bnb( current_waste += utxo_waste; index_selection.push(index); - value += eff_value; + + // unchecked add is used her for performance. since the sum of all utxo values + // did not overflow, then any positive subset of the sum will not overflow. + value = value.unchecked_add(eff_value); available_value -= eff_value; }