Auto-convert basecoin and CT to RingCT on block confirmation#1055
Auto-convert basecoin and CT to RingCT on block confirmation#1055ohcee wants to merge 10 commits into
Conversation
…ion in AutoConvertToRingCT
✅ Additional Testing — June 10, 2026Completed full end-to-end test on fresh wallet using latest binary (commit Transaction Flow
Debug Log2026-06-10T18:35:22Z AutoConvert: converting 10.00 basecoin -> CT On-Chain Verification
|
f456afc to
e847010
Compare
|
This PR auto-converts basecoin and CT to RingCT on every block, closing #1033 and #1054. Tested on mainnet, conversions confirm correctly each block, and autoconvert=0 is available for anyone who needs funds to stay at the base layer instead. @seanPhill — given your comment confirmed this solves the issues you raised, do we want more testing? Let me know if there's additional testing you'd want to see, or any case you think isn't covered yet. |
Summary
Implements native automatic conversion of basecoin and CT balances to RingCT, addressing #1033 and #1054.
A working proof of concept was built as a Python ZMQ script and tested on mainnet. This PR is the native C++ implementation.
How It Works
Hooks into
BlockConnectedinwallet.cpp. On each new block:AddStandardInputsAddBlindedInputsThe two-hop flow:
Basecoin → CT
CT → RingCT
Configuration
Disabled by default (opt-in). To enable, add to
veil.conf:autoconvert=1
-autoconvertis registered as a wallet startup option and shows up inveild -help.Safety
IsInitialBlockDownload())walletpassphrase "passphrase" timeout true) is not sufficient. If the wallet is locked or staking-only unlocked, AutoConvert will silently skip until the wallet is fully unlocked.Implementation Notes
GetBlindBalance()is used instead ofGetAvailableBlindBalance()for the CT balance check.GetAvailableBlindBalance()internally callsAvailableBlindedCoins()which requiresAssertLockHeldand performs UTXO set checks viaview.HaveCoin()that do not work correctly in this context.GetBlindBalance()iteratesmapRecordsdirectly and correctly returns the spendable CT balance.Balance checks are performed inside a scoped
LOCK2(cs_main, cs_wallet)block that is released before the transaction is built and committed, avoiding deadlocks.Zerocoin balances are completely untouched. Only basecoin and CT are converted.
BlockConnectedfires for all block types in Veil — PoS, ProgPow, RandomX, and SHA256d — so AutoConvert works correctly regardless of which algorithm produces the next block.Known Limitations
CT amounts below the 1 VEIL minimum floor will remain as CT indefinitely and will not be converted. This is intentional to avoid conversion transactions where the fee exceeds a significant percentage of the amount being converted.
The conversion fee is approximately 0.015 VEIL per transaction at current fee rates, representing roughly 1.5% overhead at the 1 VEIL minimum.
Wallet lock behavior has not been explicitly tested. The implementation skips conversion if
pAnonWalletMain->IsLocked()returns true, which covers both fully locked and staking-only unlock states. Users with encrypted wallets should verify behavior independently.Testing
All tests performed on mainnet on M4 Mac Mini running macOS.
autoconvert=0opt-outCloses
#1033
#1054