Open Saicere opened 5 years ago
I've used this algo https://www.geeksforgeeks.org/subarray-whose-sum-is-closest-to-k/ to detect that Electrum generated a 0.00800000 UTXOs when sending 0.01150000 while it could have sent an extra 0.00003498 BTC 25cent, and avoid creating an extra UTXO.
For comparison the dust threshold for Wasabi is 0.0001 (75 cents)
There is clearly no "one-size-fits-all" solution to coin-selection. Different users have different needs.
You could subclass CoinChooser (e.g. CoinChooserRandom
) and implement a different policy (e.g. penalty_func
). At one point we had two policies (priority and privacy) but then one was removed (priority; as Bitcoin Core mining policy changed).
I can assure you that there would be some users who complained if the default policy sometimes burned 10000 satoshis.
On another note, the algorithm you linked to is only testing contiguous blocks "subarrays", and not any subset, which is what you would actually want in this case (although that might end up being computationally too expensive).
Why is the dust threshold hard-coded in the first place? How about having an obscure way of changing the threshold? Do you think it would work as I expect if we just fork it and simply change that number? https://github.com/spesmilo/electrum/blob/f3eeb8817e847cf5b1f8fd7db92b8486937e6da9/electrum/tests/test_lnutil.py#L22
Why do you say burn? I thought the feature would over-send to the recipient.
The dust limit of 546 satoshis is hardcoded as such because that is the number also in Bitcoin Core. You cannot create an output of fewer than 546 satoshis (it's a standardness rule).
These satoshis go towards fees ("burned") instead of increasing the other outputs. Again, different users might want different things here. Putting it towards fee increases the probability of a fast confirmation.
So this would therefor be a completely new feature that is very similar to how every time people pay something with cash they round up the amount or "tip" to the closest 1$ or 5$ in order to avoid small change.
I think this one should be prioritized now that transaction fee have been organically hovering above 2$ per UTXO,
I just had an experience where the change generated would have been worth less than the relative transaction fee to add that extra UTXO.
I think we could add a config variable, e.g. min_change_utxo_threshold
, which would affect the behaviour of the CoinChooser.
The CoinChooser would never create change outputs with a value below this threshold.
min_change_utxo_threshold
is distinct from and mostly orthogonal to the dust limit, which we could leave unchanged.Thoughts?
I think we should be careful with adding a new setting, especially one that will need to be periodically revised depending on mempool conditions. That new setting is somewhat redundant with the dust threshold that already exists at the protocol level.
The dust threshold is equivalent to a native segwit UTXO that cannot even be spent above 5 sat/vB or so, which means it so far this year, it couldn't even have been (economically) spent since early January.
Rather than using a fixed default value that would need to be revised based on current network conditions, could you not use a value calculated from the transaction fee of the transaction generating the change UTXO if it is not set? As it is today, for a simple transaction with 1 input and 1 (payment) output, it will happily add a change output orders of magnitude smaller than the fee paid for the transaction, which damages privacy with little to no benefit to the user.
we should be careful with adding a new setting, especially one that will need to be periodically revised depending on mempool conditions
Right... not sure how to define it in a way so that it ~never needs updating. Still, I think even if we just set it to a static value such as 5000 sat, it would not need updating too often (say, less than once a year).
Just look at similar hardcoded values in the coinchooser, for example: https://github.com/spesmilo/electrum/blob/8f95dc26406a54c01436cbe2b2f2fbcbdea82756/electrum/coinchooser.py#L472-L473 That line penalising "large change", defined as 5 BTC or larger was added in 2015. While we could have most likely lowered that value, I think it's still ~fine as-is today.
That new setting is somewhat redundant with the dust threshold that already exists at the protocol level.
I would argue the setting (or equivalent functionality) would not be redundant: the dust threshold as defined by bitcoind policy is set to an extremely low value; it assumes the UTXO will be spent using a 1 sat/vbyte feerate tx.
It is uncertain whether such low fee txs ever get mined again, and even if they do, ideally we would only create change that is realistically spendable with a positive effective value and not just during rare short-lived time periods - we should not expect the user to monitor mempool conditions to be able to spend UTXOs that we automatically create.
Rather than using a fixed default value that would need to be revised based on current network conditions, could you not use a value calculated from the transaction fee of the transaction generating the change UTXO if it is not set?
I guess it is a reasonable idea at first glance but the issue is that feerates vary wildly. A user might sometimes create txs that are extremely urgent other times they might create self-transfers with very low fees that they are willing to wait for. Would we want to risk burning a million sats just because there is a mempool spike and the user is creating an urgent tx with a 1000 sat/byte fee? I think not. Ideally we should set this limit (in whatever way) to target the low end of realistic feerates (i.e. mempool spikes either up or down are outliers).
Also note that the dust threshold was set with p2pkh scripts in mind (although there is a different lower threshold used by policy for segwit outputs calculated using p2wpkh scripts). Ideally we would set different change thresholds for e.g. multisig wallets.
I think the use case and usefulness here is clear. Just imagine having a 3 of 5 multisig wallet and having the coinchooser create a 546 sat change output: It is technically above the dust threshold but would you ever want to spend it?
It is uncertain whether such low fee txs ever get mined again, and even if they do, ideally we would only create change that is realistically spendable with a positive effective value and not just during rare short-lived time periods - we should not expect the user to monitor mempool conditions to be able to spend UTXOs that we automatically create.
I originally submitted this as a suggestion for privacy reasons, but it is probably worth emphasizing the fee advantage of dropping a tiny change output. A standard native segwit 1-in 2-out transaction is about 141 vbytes, while a 1-in 1-out transaction is about 110 vbytes. So dropping a 546 sat change output will only increase the fee of the transaction by 546 sats, but will boost the fee rate (sats/vbyte) of the transaction by around 35%. Which is a lot, transaction fees being what they are right now.
As a practical example, a 1-in 2-out transaction I created with a 600 sat change output and a fee of 10520 sats had a fee rate of 74.6 sat/vbyte; dropping said change output changed the fee to 11120 sats and the fee rate to 101.1 sat/vbyte.
For wallets with a moderate to large number of UTXOs, it is often possible to create a transaction with inputs that sum up to reasonably close to a required value. Even so, you will usually end up with a small change output, which will reduce user privacy whenever it spent in a different transaction.
As such, it would be nice if Electrum exposed a setting in the GUI or even just in the config file where you could set the smallest change transaction you wish to create; that is, what the wallet considers "dust" when creating change UTXOs.
While you can manually select coins and/or manually set the fee to match the change output today to get this behavior, this is fiddly and time-consuming, and not something most people would bother with. Obviously, a computer is also able to test a much larger combination of UTXOs than a human would ever be able to.