Skip to content

Latest commit

 

History

History
34 lines (28 loc) · 6.5 KB

CHANGELOG.md

File metadata and controls

34 lines (28 loc) · 6.5 KB

Unreleased

  • Breaking: Fee math is done in f64 instead of f32. FeeRate stores an f64, and from_sat_per_vb, from_sat_per_wu, from_btc_per_kvb, as_sat_vb and spwu take or return f64; so do Candidate::effective_value, value_pwu, effective_value_pwu, implied_fee and fee_per_value, CoinSelector::waste and DrainWeights::waste. BnbMetric::score and bound, CoinSelector::run_bnb and bnb_solutions use Ordf64 instead of Ordf32, and FloatExt is implemented for f64. f32 rounds by several sats at ~1 BTC values, which let LowestFee::bound exceed the true fee and prune the cheapest selection, and made fees of 2^24 sats or more score the same (#82).
  • Breaking: Every transaction is now priced as segwit, and Candidate::is_segwit is removed. Candidate::weight is the input's segwit-serialized weight (TxIn::segwit_weight), so legacy inputs include their 1 WU empty witness. A transaction that spends only legacy inputs is overestimated by 2 WU plus 1 WU per input, and never undershoots the target feerate. The same margin applies to Target::max_weight, so such a selection close to the cap can be rejected even though the real transaction fits. This fixes CoinSelector::input_weight undercounting candidates that group several legacy inputs in a segwit transaction.
  • Breaking: Candidate::new(value, satisfaction_weight, is_segwit) is now Candidate::new(value, satisfaction_weight), and satisfaction_weight now means the weight over an unsatisfied TxIn::default(), which is what miniscript's Descriptor::max_weight_to_satisfy returns for every script type. Previously it was documented as including the scriptSig length and the scriptWitness stack item count. To migrate, pass max_weight_to_satisfy()?.to_wu() directly. If you compute it by hand, it is the satisfied input's TxIn::segwit_weight() minus TxIn::default().segwit_weight().
  • Breaking: Public weight constants changed value without changing type. TXIN_BASE_WEIGHT is now 165 (was 164) and includes the stack item count of an empty scriptWitness. TX_FIXED_FIELD_WEIGHT is now 34 (was 32) and includes the segwit marker and flag. TR_KEYSPEND_SATISFACTION_WEIGHT is now 65 (was 66) and excludes the scriptWitness stack item count. TR_KEYSPEND_TXIN_WEIGHT is unchanged at 230.
  • Breaking: CoinSelector now owns its Target. CoinSelector::new(candidates, target) takes it and CoinSelector::target() returns it, and it is fixed for the life of the selector. Every method that took a target: Target argument no longer does, including excess, missing, rate_excess, implied_fee, is_funded, is_within_max_weight, drain, select_until_target_met, select_srd, run_bnb, and bnb_solutions. The same goes for arguments that merely restated part of the target: weight and implied_feerate no longer take TargetOutputs, fee no longer takes target_value, and effective_value and select_all_effective no longer take a FeeRate. BnbMetric's methods read the target from the CoinSelector they are given — they are now fn score(&mut self, cs: &CoinSelector<'_>) -> Option<Ordf64>, fn bound(&mut self, cs: &CoinSelector<'_>) -> Option<Ordf64> and fn drain(&mut self, cs: &CoinSelector<'_>) -> Drain — so LowestFee and Changeless no longer store a target field. This removes the target that Changeless<M> previously had to keep in sync with its inner metric. To measure a selection against a second target, use CoinSelector::with_target(target), which copies the selection, the bans and the candidate order over to the new target; CoinSelector::new starts from an empty selection.
  • Breaking: BnbMetric metrics now decide the change output themselves. The trait gains a drain(&mut self, cs) -> Drain method; call it on a branch-and-bound solution (or the LowestFee metric directly) to get the change output the metric optimized against, instead of computing a separate ChangePolicy.
  • Breaking: CoinSelector::run_bnb now returns (Ordf64, Drain) instead of just Ordf32, handing back the change output the metric decided on for the winning selection.
  • Breaking: LowestFee no longer takes a change_policy. It now takes dust_relay_feerate: FeeRate and drain_weights: DrainWeights, and adds change only when doing so lowers the long-term fee and the change would not be dust.
  • Add DrainWeights::dust_threshold(dust_relay_feerate), the minimum value a change output with these weights must have to not be dust.
  • Add CoinSelector::select_srd, a Single Random Draw selector (port of Bitcoin Core's SelectCoinsSRD) that adds candidates in random order until the change reaches change_lower, producing a healthy-sized (privacy-friendly) change output instead of minimizing fees. Adds the CHANGE_LOWER constant for Core's value.
  • Breaking: Changeless is now Changeless<M>, wrapping an inner metric it constrains to changeless solutions (e.g. Changeless<LowestFee>), replacing the previous tuple-composition approach.
  • Breaking: Removed the BnbMetric tuple implementations (impl BnbMetric for ((A, f32), ...)). Weighted composition of independent metrics is no longer supported; the only composition still provided is the changeless constraint, now expressed as Changeless<M>. If you relied on tuples to blend multiple objectives, there is no drop-in replacement.
  • Breaking: CoinSelector::selected_indices and CoinSelector::banned now return &Bitset instead of &BTreeSet<usize>. Bitset exposes contains/len/is_empty/iter (#46)
  • Replace the internal Cow<BTreeSet>/Cow<[usize]> selection state with a Bitset and an Arc-shared candidate order, making the per-branch clones in branch-and-bound substantially cheaper (#46)
  • Fix compilation error when building with --no-default-features (#36)

0.4.0

  • Use u64 for weights instead of u32
  • Fix feerate not being rounded up to vbytes #29
  • Fix new_tr_keyspend weight

0.3.0

  • Remove is_target_met_with_change_policy: it was redundant. If the target is met without a change policy it will always be met with it.
  • Remove min_fee in favour of replace which allows you to replace a transaction
  • Remove Drain argument from CoinSelector::select_until_target_met because adding a drain won't change when the target is met.
  • No more base_weight in CoinSelector. Weight of the outputs is tracked in target.
  • You now account for the number of outputs in both drain and target and their weight.
  • Removed waste metric because it was pretty broken and took a lot to maintain