Skip to content

Reevaluating 'Dust' Considerations When Adding Change in Transactions #86

@landabaso

Description

@landabaso

EDIT [Nov-19]: Upon further examination, it appears that Bitcoin Core indeed employs a similar approach. The main difference is that Core allows the user to set a custom dustRelayFee (default 3 sat/vbyte), which is independent of the feeRate. In contrast, the coinselect algorithm in this repository sets the dustRelayFee equal to the feeRate. This seems to be about optimizing blockchain efficiency, but I'm uncertain if the strategy of tying dustRelayFee directly to the current fee rates in this repo is the most effective approach. I'll keep this issue open for a while longer to welcome any additional feedback or insights.

This issue is raised for discussion, especially since I believe these algorithms are being utilized by various wallets (I am also working on similar ideas too).

I'd like to discuss a specific aspect of the coinselect algorithms, particularly concerning this line of code:

// is it worth a change output?

From a network efficiency perspective, avoiding the addition of Waste to transactions is beneficial, making this a good decision for network optimization (block space used).

However, when focusing on the user's interests, it's generally advantageous to receive change back, provided it aligns with the designated fee rate. Doing the opposite results in additional fees being ceded to miners. And in the future, should transaction fees decrease, these change UTXOs may become more viable for spending.

For example, look at the test fixtures, particularly this one:

"description": "inputs used in order of DESCENDING",

 {
    "description": "inputs used in order of DESCENDING",
    "feeRate": 10,
    "inputs": [
      20000,
      {
        "script": {
          "length": 300
        },
        "value": 10000
      },
      10000
    ],
    "outputs": [
      25000
    ],
    "expected": {
      "fee": 5000,
      "inputs": [
        {
          "i": 0,
          "value": 20000
        },
        {
          "i": 2,
          "value": 10000
        }
      ],
      "outputs": [
        {
          "value": 25000
        }
      ]
    }
  },

In this specific case, I believe the expected solution should include a change output. Assuming a P2PKH scenario, if you do the numbers, the change should have been 1260 sats.

A potential solution, if deemed appropriate, would be to bypass the Dust check when adding change.
A potential solution, if deemed appropriate, would be doing as Core:

  // is it worth a change output?
  if (remainderAfterExtraOutput > (148 + 34) * 3) {
    outputs = outputs.concat({ value: remainderAfterExtraOutput })
  }

I believe the criterion for Dust should primarily apply when deciding whether to add a new UTXO or not.

In terms of Dust, Bitcoin Core employs a specific policy for UTXOs: it avoids adding a UTXO if the value transferred is less than two-thirds of its total value a similar approach on new outputs.

You can find more details about this policy in their code:

https://github.com/bitcoin/bitcoin/blob/d752349029ec7a76f1fd440db2ec2e458d0f3c99/src/policy/policy.cpp#L26

As for the strategy concerning the addition of change outputs in transactions, especially in cases that might involve Dust, I have yet to investigate what Core does further.

I'm keen to hear thoughts on this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions