diff --git a/src/change_policy.rs b/src/change_policy.rs index 268d3bc..8b13789 100644 --- a/src/change_policy.rs +++ b/src/change_policy.rs @@ -1,54 +1 @@ -//! This module contains a collection of change policies. -//! -//! A change policy determines whether a given coin selection (presented by [`CoinSelector`]) should -//! construct a transaction with a change output. A change policy is represented as a function of -//! type `Fn(&CoinSelector, Target) -> Drain`. -#[allow(unused)] // some bug in <= 1.48.0 sees this as unused when it isn't -use crate::float::FloatExt; -use crate::{DrainWeights, FeeRate}; - -/// Describes when a change output (although it could represent several) should be added that drains -/// the excess in the coin selection. It includes the `drain_weights` to account for the cost of -/// adding this outupt(s). -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct ChangePolicy { - /// The minimum amount of excesss there needs to be add a change output. - pub min_value: u64, - /// The weights of the drain that would be added according to the policy. - pub drain_weights: DrainWeights, -} - -impl ChangePolicy { - /// Construct a change policy that creates change when the change value is greater than - /// `min_value`. - pub fn min_value(drain_weights: DrainWeights, min_value: u64) -> Self { - Self { - drain_weights, - min_value, - } - } - - /// Construct a change policy that creates change when it would reduce the transaction waste - /// given that `min_value` is respected. - pub fn min_value_and_waste( - drain_weights: DrainWeights, - min_value: u64, - target_feerate: FeeRate, - long_term_feerate: FeeRate, - ) -> Self { - // The output waste of a changeless solution is the excess. - let waste_with_change = drain_weights - .waste( - target_feerate, - long_term_feerate, - 0, /* ignore varint cost for now */ - ) - .ceil() as u64; - - Self { - drain_weights, - min_value: waste_with_change.max(min_value), - } - } -} diff --git a/src/coin_selector.rs b/src/coin_selector.rs index 1055ba8..a9c169e 100644 --- a/src/coin_selector.rs +++ b/src/coin_selector.rs @@ -1,7 +1,7 @@ use super::*; #[allow(unused)] // some bug in <= 1.48.0 sees this as unused when it isn't use crate::float::FloatExt; -use crate::{bnb::BnbMetric, change_policy::ChangePolicy, float::Ordf32, FeeRate, Target}; +use crate::{bnb::BnbMetric, float::Ordf32, ChangePolicy, FeeRate, Target}; use alloc::{borrow::Cow, collections::BTreeSet, vec::Vec}; /// [`CoinSelector`] selects/deselects coins from a set of canididate coins. diff --git a/src/drain.rs b/src/drain.rs index d59d119..e416cc5 100644 --- a/src/drain.rs +++ b/src/drain.rs @@ -1,3 +1,5 @@ +#[allow(unused)] // some bug in <= 1.48.0 sees this as unused when it isn't +use crate::float::FloatExt; use crate::{varint_size, FeeRate, TR_KEYSPEND_TXIN_WEIGHT, TR_SPK_WEIGHT, TXOUT_BASE_WEIGHT}; /// Represents the weight costs of a drain (a.k.a. change) output. @@ -93,3 +95,48 @@ impl Drain { !self.is_none() } } + +/// Describes when a change output (although it could represent several) should be added that drains +/// the excess in the coin selection. It includes the `drain_weights` to account for the cost of +/// adding this outupt(s). +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct ChangePolicy { + /// The minimum amount of excesss there needs to be add a change output. + pub min_value: u64, + /// The weights of the drain that would be added according to the policy. + pub drain_weights: DrainWeights, +} + +impl ChangePolicy { + /// Construct a change policy that creates change when the change value is greater than + /// `min_value`. + pub fn min_value(drain_weights: DrainWeights, min_value: u64) -> Self { + Self { + drain_weights, + min_value, + } + } + + /// Construct a change policy that creates change when it would reduce the transaction waste + /// given that `min_value` is respected. + pub fn min_value_and_waste( + drain_weights: DrainWeights, + min_value: u64, + target_feerate: FeeRate, + long_term_feerate: FeeRate, + ) -> Self { + // The output waste of a changeless solution is the excess. + let waste_with_change = drain_weights + .waste( + target_feerate, + long_term_feerate, + 0, /* ignore varint cost for now */ + ) + .ceil() as u64; + + Self { + drain_weights, + min_value: waste_with_change.max(min_value), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index f7b109d..e4c926b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,8 +22,6 @@ pub mod metrics; mod feerate; pub use feerate::*; -mod change_policy; -pub use change_policy::*; mod target; pub use target::*; mod drain; diff --git a/src/metrics.rs b/src/metrics.rs index 4554e3d..4b52572 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,8 +1,6 @@ //! Branch and bound metrics that can be passed to [`CoinSelector::bnb_solutions`] or //! [`CoinSelector::run_bnb`]. -use crate::{ - bnb::BnbMetric, change_policy::ChangePolicy, float::Ordf32, CoinSelector, Drain, Target, -}; +use crate::{bnb::BnbMetric, float::Ordf32, ChangePolicy, CoinSelector, Drain, Target}; mod lowest_fee; pub use lowest_fee::*; mod changeless; diff --git a/src/metrics/changeless.rs b/src/metrics/changeless.rs index 3dd784a..eddaa10 100644 --- a/src/metrics/changeless.rs +++ b/src/metrics/changeless.rs @@ -1,5 +1,5 @@ use super::change_lower_bound; -use crate::{bnb::BnbMetric, change_policy::ChangePolicy, float::Ordf32, CoinSelector, Target}; +use crate::{bnb::BnbMetric, float::Ordf32, ChangePolicy, CoinSelector, Target}; #[derive(Clone, Debug)] /// Metric for finding changeless solutions only. diff --git a/src/metrics/lowest_fee.rs b/src/metrics/lowest_fee.rs index 30e4f21..396fe03 100644 --- a/src/metrics/lowest_fee.rs +++ b/src/metrics/lowest_fee.rs @@ -1,6 +1,4 @@ -use crate::{ - change_policy::ChangePolicy, float::Ordf32, BnbMetric, CoinSelector, Drain, FeeRate, Target, -}; +use crate::{float::Ordf32, BnbMetric, ChangePolicy, CoinSelector, Drain, FeeRate, Target}; /// Metric that aims to minimize transaction fees. The future fee for spending the change output is /// included in this calculation.