Skip to content

fix: purge confirmed txs from Dandelion stempool on block connect#392

Open
JohnnyLawDGB wants to merge 2 commits intoDigiByte-Core:feature/digidollar-v1from
JohnnyLawDGB:fix/dandelion-stempool-ancestor-leak
Open

fix: purge confirmed txs from Dandelion stempool on block connect#392
JohnnyLawDGB wants to merge 2 commits intoDigiByte-Core:feature/digidollar-v1from
JohnnyLawDGB:fix/dandelion-stempool-ancestor-leak

Conversation

@JohnnyLawDGB
Copy link

Summary

  • Root cause: removeForBlock() was called on m_mempool but not m_stempool in ConnectTip(). Confirmed transactions remained in the stempool indefinitely as phantom ancestors.
  • Effect: After ~25 chained transactions confirm, new stempool transactions hit the 25-ancestor limit → too-long-mempool-chain rejection. Affects all platforms (Windows Qt, Linux daemon, Linux Desktop).
  • Fix: Add m_stempool->removeForBlock() in ConnectTip() and m_stempool->removeRecursive() in DisconnectTip(), matching all other mempool/stempool cleanup paths that already handle both pools correctly.

Details

Every other cleanup path in validation.cpp already mirrors operations between mempool and stempool:

  • removeRecursive during reorg (line 324-325) ✅
  • removeForReorg (line 396-397) ✅
  • LimitMempoolSize (line 399-400) ✅
  • removeForBlock in ConnectTip (line 3483) ❌ ← this was the only one missing
  • removeRecursive in DisconnectTip (line 3355) ❌ ← also missing

The workaround (dandelion=0) disables Dandelion privacy entirely. This fix preserves full Dandelion++ privacy while keeping the stempool clean.

Test plan

  • test_digibyte --run_test=dandelion_tests — 2/2 pass
  • test_digibyte --run_test=validation_tests — 5/5 pass
  • test_digibyte --run_test=mempool_tests — 6/6 pass
  • Testnet validation: run with dandelion=1, send 30+ chained transactions, verify no "too-long-mempool-chain" errors after blocks confirm
  • Verify stempool size stays bounded during normal operation

🤖 Generated with Claude Code

JohnnyLawDGB and others added 2 commits March 7, 2026 16:04
When a wallet has too many small UTXOs (>400) to cover collateral in a
single transaction, mintdigidollar now automatically creates a
consolidation transaction using the wallet's standard coin selection,
then retries the mint using the consolidated output.

This fixes the "Too many small UTXOs" error that miners and pool
operators encounter when their wallet contains hundreds of small
mining reward UTXOs that individually don't cover the collateral
requirement within the 400-input transaction limit.

The consolidation is transparent — the response includes
consolidation_txid and utxos_consolidated fields when auto-
consolidation was performed. Both the consolidation and mint
transactions are broadcast together and chain in the mempool.

Tested with 500 x 600 DGB UTXOs (300,000 DGB total) where tier 0
minting requires ~246,000 DGB collateral. Without this fix, the mint
fails because 400 x 600 = 240,000 < 246,000. With this fix, the
wallet auto-consolidates and the mint succeeds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a block is connected, removeForBlock() was called on the mempool
but not the stempool. This caused confirmed transactions to remain in
the stempool indefinitely as phantom ancestors, inflating ancestor
counts for any new stempool transactions until they hit the 25-ancestor
limit and were rejected with "too-long-mempool-chain".

Also adds stempool cleanup during DisconnectTip reorg path for
consistency with all other mempool/stempool cleanup code paths.

Fixes: Dandelion stempool ancestor leak (Bug DigiByte-Core#7)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant