Skip to content

fix: use 330 sat dust limit for P2TR/P2WPKH change outputs#8807

Open
Andezion wants to merge 2 commits intoElementsProject:masterfrom
Andezion:fix-p2tr-dust-limit
Open

fix: use 330 sat dust limit for P2TR/P2WPKH change outputs#8807
Andezion wants to merge 2 commits intoElementsProject:masterfrom
Andezion:fix-p2tr-dust-limit

Conversation

@Andezion
Copy link
Copy Markdown
Collaborator

(Fixes #8395)

Problem

When creating transactions, change outputs between 330-546 sat were being treated as dust and absorbed into fees. This caused users to overpay transaction fees.

The issue was that change_amount() function used chainparams->dust_limit (546 sat) for all output types, but P2TR and P2WPKH outputs have a lower dust limit of 330 sat according to Bitcoin Core standards.

Solution

Changed change_amount() in bitcoin/tx.c to use 330 sat dust limit for change outputs. This is correct because:

  • Change outputs are P2TR on Bitcoin mainnet
  • Change outputs are P2WPKH on Elements
  • Both types have 330 sat dust limit (not 546 sat like legacy P2PKH/P2SH)

Now change outputs between 330-546 sat are properly created instead of being absorbed into fees.

Testing

  • Added new test test_p2tr_change_dust.py that verifies change outputs in 330-546 sat range are created
  • Existing tests still pass: test_fundpsbt, test_withdraw_misc

Important

26.04 FREEZE March 11th: Non-bugfix PRs not ready by this date will wait for 26.06.

RC1 is scheduled on March 23rd

The final release is scheduled for April 15th.

Checklist

Before submitting the PR, ensure the following tasks are completed. If an item is not applicable to your PR, please mark it as checked:

  • The changelog has been updated in the relevant commit(s) according to the guidelines.
  • Tests have been added or modified to reflect the changes.
  • Documentation has been reviewed and updated as needed.
  • Related issues have been listed and linked, including any that this PR closes.
  • Important All PRs must consider how to reverse any persistent changes for tools/lightning-downgrade

@Andezion Andezion force-pushed the fix-p2tr-dust-limit branch from 7397c92 to 55c14f8 Compare December 23, 2025 13:43
@Andezion Andezion force-pushed the fix-p2tr-dust-limit branch 3 times, most recently from b5723ec to 67964a0 Compare January 25, 2026 14:56
@sangbida sangbida added this to the 26.06 milestone Mar 16, 2026
@madelinevibes madelinevibes modified the milestones: 26.06, v26.04 Mar 19, 2026
@Lagrang3
Copy link
Copy Markdown
Collaborator

@Andezion, please remove the first two commits that are not relevant to this PR.
Also, all formatting commits eg. "cleaned all whitespaces" should be squashed.

Comment thread .github/scripts/setup.sh
Comment on lines +7 to +10

sudo rm -f /etc/apt/sources.list.d/azure-cli.list || true
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list || true

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to modify this file.

Comment thread .github/workflows/ci.yaml Outdated
TEST_DEBUG: 1
run: |
VALGRIND=1 uv run eatmydata pytest tests/ -n 3 ${PYTEST_OPTS} ${{ matrix.PYTEST_OPTS }}
VALGRIND=1 uv run eatmydata pytest tests/ -n 1 ${PYTEST_OPTS} ${{ matrix.PYTEST_OPTS }}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to modify this file.

if is_withdraw:
acct = "external"
transfer_from = acct
acct = "external"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the motivation behind this change?

Comment thread tests/test_closing.py
assert not l2.daemon.is_in_log('bad reestablish')

# Remove mock so l2 can sync during teardown
l2.daemon.rpcproxy.mock_rpc('getblockhash', None)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please explain? This doesn't look related to the PR title.

Comment thread tests/utils.py Outdated
# Feerate can't be lower.
assert actual_feerate > expected_feerate - 2
if actual_feerate >= expected_feerate + 2:
assert actual_feerate >= expected_feerate - 10
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file as well should not be touched. The changes are not related to the title of the PR, and Rusty already addressed that issue (8a60a27)

Copy link
Copy Markdown
Collaborator

@Lagrang3 Lagrang3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First two commits should be removed.
Some changes afterwards seem unnecessary.
Also, the rest of the commits should be squashed into one, there is basically one
change and the rest is just formatting.

…ixes ElementsProject#8395

Fix by checking is_elements: Elements keeps 546 sat, Bitcoin uses 330 sat.
Changelog-Fixed: Transactions now correctly create change outputs >= 330 sat for P2TR/P2WPKH instead of absorbing them as fees
@Andezion Andezion force-pushed the fix-p2tr-dust-limit branch from f64669d to 765fa8a Compare March 20, 2026 11:49
@madelinevibes madelinevibes modified the milestones: v26.04, 26.06 Mar 22, 2026
@madelinevibes
Copy link
Copy Markdown
Collaborator

@Andezion can you update per Eduardo's comments, resolve the conflicts and clear CI by the end of this week so we can add this to 26.06? Release candidate planned for Monday 11 May.

If you can't we'll move it to 25.09

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

P2TR change outputs between 330 and 546 sat should not be absorbed into tx fees

4 participants