Merge #856: spend: Scale down the number of BnB rounds in debug mode and with a high number of candidates

c002ab95799750c1957d9172d9e255a2f3511fe4 spend: scale down the number of BnB when not compiling with optimizations (Antoine Poinsot)
f18086c152ffa033def8cbed52895fd1d99ffc6d spend: scale down the number of BnB rounds as number of candidates increases (Antoine Poinsot)

Pull request description:

  Based on #842.

  Performing BnB with a large number of candidates can be computation expensive. Especially in debug mode. It can make the software lag in situations where it's called repeatedly.
  Reasonably scale down the number of rounds performed depending on the number of candidates and whether optimizations are enabled.

  Fixes #846

ACKs for top commit:
  jp1ac4:
    ACK c002ab9579.

Tree-SHA512: 83de99d54c427de86dad779549280b3316b0e72a9e3a5cb4af22d44eefa9832408b974f2a2aca0847b13ad5899e324ad43f32e99eb4efb69716c827f3ab47aaf
This commit is contained in:
Antoine Poinsot 2023-12-08 17:09:04 +01:00
commit fe14cbec58
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304

View File

@ -296,8 +296,8 @@ fn select_coins_for_spend(
let change_policy =
change_policy::min_value_and_waste(drain_weights, DUST_OUTPUT_SATS, long_term_feerate);
// Finally, run the coin selection algorithm. We use a BnB with 100k iterations and if it
// couldn't find any solution we fall back to selecting coins by descending value.
// Finally, run the coin selection algorithm. We use an opportunistic BnB and if it couldn't
// find any solution we fall back to selecting coins by descending value.
let target = Target {
value: out_value_nochange,
feerate: FeeRate::from_sat_per_vb(feerate_vb),
@ -312,7 +312,16 @@ fn select_coins_for_spend(
lowest_fee,
must_have_change,
};
if let Err(e) = selector.run_bnb(lowest_fee_change_cond, 100_000) {
// Scale down the number of rounds to perform if there is too many candidates. If the binary
// isn't optimized, scale it down further to avoid lags in hot loops.
let bnb_rounds = match candidate_coins.len() {
i if i >= 500 => 1_000,
i if i >= 100 => 10_000,
_ => 100_000,
};
#[cfg(debug)]
let bnb_rounds = bnb_rounds / 1_000;
if let Err(e) = selector.run_bnb(lowest_fee_change_cond, bnb_rounds) {
log::warn!(
"Coin selection error: '{}'. Selecting coins by descending value per weight unit...",
e.to_string()