Skip to content

Fix/bech32 address handling#1059

Merged
seanPhill merged 4 commits into
Veil-Project:masterfrom
ohcee:fix/bech32-address-handling
Jun 20, 2026
Merged

Fix/bech32 address handling#1059
seanPhill merged 4 commits into
Veil-Project:masterfrom
ohcee:fix/bech32-address-handling

Conversation

@ohcee

@ohcee ohcee commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Fix bech32 (bv1q) address handling crashes in GUI and RPC

Summary

Fixes a Qt GUI crash triggered when viewing transactions involving bv1q bech32 basecoin addresses in mixed-output transactions. Confirmed on current master. Also fixes incorrect bech32 address detection and defensive handling for boost::get in listunspent.

How it was found

While testing the feature/auto-ct-to-ringct branch, receiving basecoin to a bv1q address via mixed-output transactions (RingCT input → basecoin + RingCT outputs) caused the Qt GUI to crash on launch. The crash was reproduced on unfixed master (v1.4.2.99) opening the wallet with the offending transaction present triggers an immediate crash.

Crash log (unfixed master)

Assertion failed: (false), function forced_return, file boost/variant/detail/forced_return.hpp, line 45. abort ./veil-qt

Root cause

Several functions incorrectly assume basecoin addresses will always be legacy or P2SH format, but getnewbasecoinaddress defaults to bech32 (DEFAULT_ADDRESS_TYPE = OutputType::BECH32). When bv1q addresses appear in mixed-output transactions, three things break:

  1. Bech32 detection in decomposeTransaction checked for CScriptID (P2SH) instead of WitnessV0KeyHash / WitnessV0ScriptHash
  2. boost::get<CScriptID>(address) in listunspent uses the value form which throws an exception on non-P2SH addresses instead of the safe pointer form
  3. txout_address and txout_is_mine vectors go out of sync on non-RTX transactions with mixed output types, causing out-of-bounds access

Trigger conditions

  • Transaction with mixed output types (RingCT/CT + basecoin)
  • Basecoin destination is a bv1q bech32 address
  • View that transaction in Qt GUI

Why it wasn't reported sooner

Unclear. DEFAULT_ADDRESS_TYPE is BECH32, so all wallets generate bv1q addresses by default. However, the crash only triggers on mixed-output transactions, not plain basecoin receives. Cross-type transactions like zerocoin spends to basecoin or faucet payouts are less common, which likely limited exposure.

Fixes

Commit File Fix
3f954a5 transactionrecord.cpp Correct bech32 detection: check WitnessV0KeyHash / WitnessV0ScriptHash instead of CScriptID
523d097 transactionrecord.cpp Same bech32 fix in second code path, using correct nOut index
32732a1 rpcwallet.cpp Use pointer form of boost::get<CScriptID> to prevent exception on non-P2SH addresses in listunspent
c475419 wallet.cpp Keep txout_address in sync with txout_is_mine to prevent out-of-bounds crash on mixed-output transactions

Testing

Test Unfixed master This PR
Open Qt with mixed-output bv1q transaction ❌ crash (abort) ✅ opens clean
Transaction list displays bv1q address ❌ crash ✅ displays correctly
Transaction detail view ❌ crash ✅ shows "Sent to: bv1q..." and mixed outputs
listunspent via daemon No crash No crash
getbalances Reports correctly Reports correctly

Related Issues

Likely fixes #1046 (stuck basecoin UTXO from RingCT→basecoin faucet payout). The symptoms described; wrong address displayed in GUI, UTXO missing from listunspent and Coin Control despite showing in getbalances match the txout_address / txout_is_mine vector desync fixed in this PR. The original issue documents a faucet payout from RingCT to a bv1q basecoin address, the exact same trigger condition confirmed here.

@seanPhill seanPhill left a comment

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.

Nice work! Thanks!

@seanPhill
seanPhill merged commit 779792d into Veil-Project:master Jun 20, 2026
8 checks passed
@ohcee
ohcee deleted the fix/bech32-address-handling branch June 21, 2026 23:03
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.

Releasing rare stuck basecoin UTXO

2 participants