diff options
author | glozow <gloriajzhao@gmail.com> | 2022-03-07 13:46:49 +0000 |
---|---|---|
committer | glozow <gloriajzhao@gmail.com> | 2022-03-25 11:56:46 +0000 |
commit | a44236addd01cff4e4d751e0f379d399fbfc8eae (patch) | |
tree | 9fe5c345c1d1294d073b08875c5932b75f32dd86 /src/wallet/coinselection.h | |
parent | 1e52e6bd0a8888efb4ed247d74ec7ca9dfc2e002 (diff) |
[wallet] randomly generate change targets
If the wallet always chooses 1 million sats as its change target, it is
easier to fingerprint transactions created by the Core wallet.
Diffstat (limited to 'src/wallet/coinselection.h')
-rw-r--r-- | src/wallet/coinselection.h | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h index 480c9664ca..1da9f86cb5 100644 --- a/src/wallet/coinselection.h +++ b/src/wallet/coinselection.h @@ -17,6 +17,14 @@ namespace wallet { static constexpr CAmount MIN_CHANGE{COIN / 100}; //! final minimum change amount after paying for fees static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2; +//! lower bound for randomly-chosen target change amount +static constexpr CAmount CHANGE_LOWER{50000}; +//! upper bound for randomly-chosen target change amount +static constexpr CAmount CHANGE_UPPER{1000000}; +// Ensure that any randomly generated change targets are less than or equal to before. +// Otherwise, tests may fail if funds are not enough to cover change. +static_assert(CHANGE_UPPER <= MIN_CHANGE); +static_assert(CHANGE_LOWER <= MIN_FINAL_CHANGE); /** A UTXO under consideration for use in funding a new transaction. */ class COutput @@ -99,6 +107,8 @@ struct CoinSelectionParams { CAmount m_min_change_target{MIN_CHANGE}; /** Cost of creating the change output. */ CAmount m_change_fee{0}; + /** The pre-determined minimum value to target when funding a change output. */ + CAmount m_change_target{0}; /** Cost of creating the change output + cost of spending the change output in the future. */ CAmount m_cost_of_change{0}; /** The targeted feerate of the transaction being built. */ @@ -223,6 +233,21 @@ struct OutputGroup */ [[nodiscard]] CAmount GetSelectionWaste(const std::set<COutput>& inputs, CAmount change_cost, CAmount target, bool use_effective_value = true); + +/** Chooose a random change target for each transaction to make it harder to fingerprint the Core + * wallet based on the change output values of transactions it creates. + * The random value is between 50ksat and min(2 * payment_value, 1milsat) + * When payment_value <= 25ksat, the value is just 50ksat. + * + * Making change amounts similar to the payment value may help disguise which output(s) are payments + * are which ones are change. Using double the payment value may increase the number of inputs + * needed (and thus be more expensive in fees), but breaks analysis techniques which assume the + * coins selected are just sufficient to cover the payment amount ("unnecessary input" heuristic). + * + * @param[in] payment_value Average payment value of the transaction output(s). + */ +[[nodiscard]] CAmount GenerateChangeTarget(CAmount payment_value, FastRandomContext& rng); + struct SelectionResult { private: |