DigiByte v9.26.2 - Current Implementation Status
Updated: 2026-05-20
Implementation Status: V1 / feature/digidollar-v1
Document Version: 6.8 - Validated against codebase
Validation Status: Validated Against Codebase (2026-05-20)
DigiDollar is a decentralized USD-denominated token design built natively on DigiByte's UTXO model. Unlike traditional stablecoins controlled by companies or banks, DigiDollar does not use custodial bank reserves. Every DigiDollar is backed by locked DigiByte (DGB) coins held in secure, time-locked digital vaults that users control with their own private keys.
Think of it like this: Imagine you have $1,000 worth of gold that you want to convert to cash for spending, but you don't want to sell the gold and lose future gains. DigiDollar lets you lock that gold in a secure vault and get $500 in spending money today. The gold never leaves your vault - you just can't access it until the time-lock expires. When it does, you can burn the $500 DigiDollar and get your gold back, keeping all the appreciation.
The DigiDollar V1 stack on feature/digidollar-v1 is feature-complete; remaining work is operational hardening and mainnet rollout. Highlights:
- Address System — DD/TD/RD addresses live on mainnet/testnet/regtest (
src/base58.{h,cpp}). - Minting / Transferring / Redeeming — Full P2TR pipeline (
src/digidollar/txbuilder.cpp,src/digidollar/validation.cpp). - Confirmed-only DD chaining — Consensus refuses
MEMPOOL_HEIGHTDD inputs for transfers and redeems (src/digidollar/validation.cpp:1811, 1955). - Network-Wide Tracking —
SystemHealthMonitor::ScanUTXOSetplus incrementalOnMintConnected/OnRedeemConnectedhooks (src/digidollar/health.cpp);DigiDollarStatsIndexprovides per-block aggregates (src/index/digidollarstatsindex.{cpp,h}). - Protection Systems — DCA (
src/consensus/dca.cpp), ERR (src/consensus/err.cpp) and Volatility (src/consensus/volatility.cpp) all production-wired. ERR enforces extra DD burn (no DGB haircut) via integer__int128math. - Canonical Lock Tiers — Mint OP_RETURNs must declare tier 0-9. Validation accepts only the claimed canonical tier window
[tier_blocks, tier_blocks + 100], so under-locked/custom terms are rejected while delayed mining remains valid. - OP_CHECKPRICE reserved opcode —
OP_CHECKPRICEis reserved and deterministically disabled; the interpreter consumes its operand and pushes false instead of reading node-local oracle state (src/script/interpreter.cpp:708-735). - MuSig2 V1 oracle path only — Block validation rejects pre-V1 (legacy) oracle bundles in coinbase once DigiDollar is active (
src/validation.cpp:185-217); mempool acceptance requires a recent valid MuSig2 oracle quote (src/validation.cpp:224-283). - Mining graceful degradation — DD txs that fail validation are stripped from
mapModifiedTxrather than blocking block assembly (src/node/miner.cpp:707-744). - Comprehensive Testing — Unit tests under
src/test/digidollar_*andsrc/test/rh*/src/test/oracle_*/src/test/musig2_*; functional tests undertest/functional/digidollar_*.pyandtest/functional/wallet_digidollar_*.py. SeeREPO_MAP_DIGIDOLLAR.mdfor the full inventory.
This document explains how each piece works, where the code lives, and how the runtime gates are wired together.
Think of DigiDollar like a high-tech bank vault system where you're always in control:
- 🏦 MINT (Create DigiDollars): Lock your DGB in a digital vault, get DigiDollars to spend
- 💸 SEND (Transfer DigiDollars): Send DigiDollars to anyone with a DD address
- 📨 RECEIVE (Get DigiDollars): Generate DD addresses to receive DigiDollars from others
- 🔓 REDEEM (Get Your DGB Back): Burn DigiDollars to unlock your original DGB
The DigiDollar system is split across these directories:
src/digidollar/— Core DigiDollar logic (digidollar,health,scripts,txbuilder,validation)src/consensus/— DigiDollar consensus rules (digidollar,digidollar_transaction_validation,digidollar_tx,dca,err,volatility)src/oracle/— Oracle daemon, exchange aggregator, MuSig2 (bundle_manager,exchange,mock_oracle,node,signing_orchestrator,musig2_*)src/primitives/oracle.{h,cpp}— Price message + bundle typessrc/index/digidollarstatsindex.{h,cpp}— Block-level DD supply / collateral / vault count indexsrc/script/script.h— DigiDollar opcode definitions (0xbb–0xbf)src/script/interpreter.cpp—SCRIPT_VERIFY_DIGIDOLLARevaluation, OP_CHECKPRICE/OP_CHECKCOLLATERAL/OP_DDVERIFY/OP_DIGIDOLLAR/OP_ORACLEsrc/rpc/digidollar.{cpp,h}— Registered DigiDollar RPC surfacesrc/wallet/digidollarwallet.{cpp,h},src/wallet/ddcoincontrol.{cpp,h}— Wallet integrationsrc/qt/digidollar*.{cpp,h}— Qt widgetssrc/test/,src/wallet/test/,src/qt/test/,src/test/fuzz/,test/functional/— Tests
src/rpc/digidollar_transactions.{cpp,h} declares getdigidollarinfo, transferdigidollar, createrawddtransaction, listredeemablepositions and a GetDigiDollarTransactionRPCCommands() helper, but the helper has no caller — treat that file as legacy/dead code unless explicitly rewired.
Phase 1 (data structures, P2TR scripts, DD addresses, transaction versioning) and Phase 2 (mint/transfer/redeem core operations) are complete. The current branch (feature/digidollar-v1) lands the V1 production gates: live MuSig2 oracle bundles, reserved/disabled OP_CHECKPRICE, confirmed-only DD chaining, integer-only DCA/ERR math, and the supply alert (no hard cap).
┌─────────────────┐
│ USER ACTION │
└────────┬────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ DETERMINE ACTION TYPE │
├─────────────────────────────────────────────────────────────┤
│ • Mint: Create new DigiDollars │
│ • Transfer: Send DigiDollars to DD address │
│ • Redeem: Burn DigiDollars, recover DGB │
│ • Receive: Generate DD addresses, detect incoming DD │
└─────────────────────────────────────────────────────────────┘
│
┌────┴────┬──────────┬───────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌─────────┐ ┌─────────┐
│ MINT │ │ TRANSFER │ │ RECEIVE │ │ REDEEM │
└────┬───┘ └────┬─────┘ └────┬────┘ └────┬────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────┐
│ MINT PROCESS │
├─────────────────────────────────────────────┤
│ 1. Select lock period (1h to 10y) │
│ 2. Get current oracle price │
│ 3. Check system health (DCA status) │
│ 4. Calculate required collateral: │
│ Base Ratio × DCA Multiplier × DD Amount │
│ 5. Lock DGB in P2TR output with MAST │
│ 6. Create DigiDollar P2TR output │
│ 7. Record collateral position in database │
│ 8. Sign transaction with Schnorr + ECDSA │
│ 9. Broadcast to network via wallet chain │
└──────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ TRANSFER PROCESS │
├─────────────────────────────────────────────┤
│ 1. Validate DD address (DD/TD/RD prefix) │
│ 2. Select DD UTXOs for input (greedy) │
│ 3. Select DGB UTXOs for fees │
│ 4. Create DD outputs to recipient │
│ 5. Add DD change output if needed │
│ 6. Sign DD inputs with Schnorr (P2TR) │
│ 7. Sign fee inputs with ECDSA │
│ 8. Broadcast via wallet chain interface │
│ 9. Update UTXO database (remove spent) │
│ 10. Add new UTXOs (change, self-transfers) │
└──────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ RECEIVE PROCESS │
├─────────────────────────────────────────────┤
│ 1. Generate new P2TR DD address │
│ 2. Encode with DD/TD/RD prefix │
│ 3. Create QR code for payment request │
│ 4. Add to address book with label │
│ 5. Monitor incoming transactions │
│ 6. Detect DD outputs via SyncTransaction │
│ 7. Verify ownership with IsMine() │
│ 8. Extract DD amount from script │
│ 9. Add to UTXO tracking database │
│ 10. Update balance and notify (pending) │
└──────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ REDEMPTION PROCESS │
├─────────────────────────────────────────────┤
│ 1. Check redemption path (exactly 2 paths │
│ in the MAST tree, both timelock-gated): │
│ • Normal: Timelock expired, health ≥100% │
│ → Burn original DD, get 100% collateral│
│ • ERR: Timelock expired, health < 100% │
│ → Burn MORE DD (up to 125% via integer │
│ ceil math), get 100% collateral back │
│ 2. DD inputs MUST be confirmed — consensus │
│ rejects DD inputs with nHeight = │
│ MEMPOOL_HEIGHT (commit 0b4959f563). │
│ 3. Select DD UTXOs to burn: │
│ • Normal: Burn original minted amount │
│ • ERR: ceil(originalDD * 10000 / │
│ ratioBps) (src/consensus/err.cpp:122) │
│ 4. Create redemption transaction with: │
│ • Input 0: Collateral vault (P2TR │
│ script-path; CLTV must be expired) │
│ • Input 1+: DD tokens to burn │
│ • Input N: DGB for fees │
│ 5. Sign inputs: │
│ • Collateral: Schnorr script-path sig │
│ (NUMS internal key blocks key-path) │
│ • DD tokens: Schnorr key-path sig │
│ • Fees: Standard ECDSA │
│ 6. Validation: ValidateCollateralRelease │
│ Amount enforces full burn AND full │
│ collateral release (no partial). │
│ 7. Release FULL collateral to owner. │
│ 8. Close position in wallet database. │
└──────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ PROTECTION SYSTEMS CHECK │
├─────────────────────────────────────────────┤
│ DCA (src/consensus/dca.cpp HEALTH_TIERS): │
│ • >=150%: Healthy (1.00x / 10000 bps) │
│ • 120-149%: Warning (1.25x / 12500 bps) │
│ • 110-119%: Critical (1.50x / 15000 bps) │
│ • <110%: Emergency (2.00x / 20000 bps) │
│ Health and DCA use __int128 ceiling math │
│ (commit 9cca6970ae) and ApplyDCA fails │
│ closed when canonical health is missing. │
├─────────────────────────────────────────────┤
│ ERR (src/consensus/err.cpp ERR_TIERS): │
│ * BURNS MORE DD, NOT LESS COLLATERAL * │
│ • 95-100%: 1/0.95 -> 105.3% DD burn │
│ • 90-95%: 1/0.90 -> 111.1% DD burn │
│ • 85-90%: 1/0.85 -> 117.6% DD burn │
│ • <85%: 1/0.80 -> 125.0% DD burn │
│ requiredDD = ceil(originalDD*10000/ratioBps)│
│ (commit 55926c372a). Collateral always 100%;│
│ ShouldBlockMinting() blocks new mints while │
│ active. │
├─────────────────────────────────────────────┤
│ Volatility (src/consensus/volatility.cpp): │
│ • 1h vol > 20% -> freeze new mints │
│ • 24h vol > 30% -> freeze ALL DD ops │
│ • Cooldown: 8640 blocks (~36h) │
│ • Pre-mutation gate: WouldCandidateFreeze │
│ Minting() rejects bad mints before they │
│ can poison the history (03f4af47a7). │
├─────────────────────────────────────────────┤
│ Oracle System Integration: │
│ • V1 mainnet/testnet: 35 active oracle │
│ slots, 7 MuSig2 signatures │
│ required (BIP-340 aggregate, │
│ BIP-327 MuSig2) │
│ • Regtest: 4-of-7 (chainparams override) │
│ • Median price in micro-USD format │
│ • 6 active exchange APIs via libcurl │
└──────────────────────────────────────────────┘
Simple Explanation: Every DigiDollar transaction creates digital "receipts" that track exactly how much you have and where it came from. Think of it like a sophisticated digital ledger that never loses track of your money.
Where the code lives: /src/digidollar/digidollar.h - CDigiDollarOutput class
What it stores:
- Amount: How many DigiDollars (stored in cents internally, 100 cents = $1.00 DD)
- Vault Connection: Which DGB vault this came from (if any)
- Lock Time: When a vault can be opened (measured in blocks)
- Digital Keys: Cryptographic data for security and privacy
For developers: Complete Taproot/P2TR integration with MAST support, robust serialization, overflow protection, and links to collateral positions.
Status: ✅ 100% Complete and Production Ready
Where the code lives: /src/digidollar/digidollar.h - CCollateralPosition class
Simple Explanation: Every time you create DigiDollars by locking DGB, the system creates a "vault record" that tracks your locked DGB and gives you multiple ways to get it back.
What each vault record contains:
- Vault Location: Exactly where your DGB is locked on the blockchain
- DGB Amount: How much DGB you locked up
- DigiDollars Created: How many DigiDollars you got for locking the DGB
- Unlock Date: When you can normally get your DGB back (measured in block height)
- Safety Ratio: How much extra DGB you locked (200%-1000% depending on time period)
- Exit Options: 2 functional redemption paths (see below)
The 2 Ways to Get Your DGB Back (Verified in Code):
- Normal: Timelock expired + system health ≥100% → Burn original DD, get 100% collateral back
- ERR (Emergency Redemption Ratio): Timelock expired + system health <100% → Burn MORE DD (105-125%), get 100% collateral back (FULL amount always returned)
CRITICAL RULE: DGB locked as collateral CAN NEVER BE UNLOCKED until the timelock expires. No exceptions. No early redemption. Ever. Both paths REQUIRE the timelock to be expired first.
For developers: Advanced features include real-time health calculations, dynamic path management, integration with system monitoring, and overflow protection.
Status: ✅ V1 production-wired; wallet/GUI polish tracked in their sections
Status: ✅ Complete with Full Network Support
class CDigiDollarAddress {
// Network prefixes (2-byte Base58Check version bytes)
DD_P2TR_MAINNET = {0x52, 0x85}, // "DD" prefix
DD_P2TR_TESTNET = {0xb1, 0x29}, // "TD" prefix
DD_P2TR_REGTEST = {0xa3, 0xa4} // "RD" prefix
};Implementation Highlights:
- ✅ Proper 2-byte version prefixes for Base58Check encoding
- ✅ Only supports P2TR (Taproot) destinations for future extensibility
- ✅ Complete validation and error handling
- ✅ Full serialization support for wallet persistence
Address Examples:
- Mainnet:
DD1q2w3e4r5t6y7u8i9o0p1a2s3d4f5g6h7j8k9l0m1n2 - Testnet:
TD1q2w3e4r5t6y7u8i9o0p1a2s3d4f5g6h7j8k9l0m1n2 - Regtest:
RD1q2w3e4r5t6y7u8i9o0p1a2s3d4f5g6h7j8k9l0m1n2
// Transaction type encoding in nVersion field
// Bits 0-15 (DD_VERSION_MASK 0x0000FFFF) — marker (low 16 bits = 0x0770)
// Bits 16-23 (DD_FLAGS_MASK 0x00FF0000) — flags (currently unused)
// Bits 24-31 (DD_TYPE_MASK 0xFF000000) — transaction type
// Full constructed marker: DD_TX_VERSION = 0x0D1D0770. HasDigiDollarMarker
// only checks the low 16 bits, so the upper 16 bits encode (type, flags).
static constexpr int32_t DD_TX_VERSION = 0x0D1D0770;
enum DigiDollarTxType : uint8_t {
DD_TX_NONE = 0, // Not a DD transaction
DD_TX_MINT = 1, // Lock DGB, create DigiDollars
DD_TX_TRANSFER = 2, // Transfer DigiDollars between addresses
DD_TX_REDEEM = 3, // Burn DigiDollars, unlock DGB (NORMAL or ERR path)
DD_TX_MAX = 4 // Sentinel for validation
};
// ERR is a redemption *path* in the MAST tree, not a transaction type.
// Both NORMAL and ERR redemptions are DD_TX_REDEEM; the path is selected
// at spend time and the burn requirement adjusts via err.cpp.
inline int32_t MakeDigiDollarVersion(DigiDollarTxType type, uint8_t flags = 0); // (type << 24) | (flags << 16) | (DD_TX_VERSION & 0xFFFF)This unique marker prevents collisions with non-DD transactions, allows policy/relay code to detect DD txs cheaply, and lets IsStandardTx whitelist DD-specific output shapes (e.g. zero-value DD token outputs) without affecting standard transactions.
flowchart TD
A[User Initiates Mint] --> B[Parameter Validation]
B --> C[Get Oracle Price]
C --> D[Calculate Collateral Requirement]
D --> E[Apply DCA Multiplier]
E --> F[Select UTXOs]
F --> G[Build Transaction]
G --> H[Create P2TR Outputs]
H --> I[Sign Transaction]
I --> J[Broadcast]
J --> K[Update Position Database]
C --> L[Check Volatility Freeze]
L --> M{Frozen?}
M -->|Yes| N[Reject Mint]
M -->|No| D
D --> O[Check System Health]
O --> P{DCA Active?}
P -->|Yes| Q[Increase Requirement]
P -->|No| E
Q --> E
Status: ✅ Production Ready
| Lock Period | Collateral Ratio | Rationale |
|---|---|---|
| 1 hour | 1000% | Testing/onboarding tier (canonical on all networks) |
| 30 days | 500% | Maximum safety for short-term |
| 3 months | 400% | High collateral for quarterly |
| 6 months | 350% | Semi-annual with strong buffer |
| 1 year | 300% | Annual with 3x safety |
| 2 years | 275% | Medium-term commitment |
| 3 years | 250% | Medium-term stability |
| 5 years | 225% | Long-term commitment |
| 7 years | 212% | Extended positions |
| 10 years | 200% | Minimum 2x for maximum lock |
// DCA class HEALTH_TIERS in src/consensus/dca.cpp (basis points):
// >=150% : 10000 bps (1.00x) "healthy"
// 120-149% : 12500 bps (1.25x) "warning"
// 110-119% : 15000 bps (1.50x) "critical"
// <110% : 20000 bps (2.00x) "emergency"
//
// Both ConsensusParams::dcaLevels (src/consensus/digidollar.h) and the runtime
// DCA::HEALTH_TIERS use the same values; the runtime tier table is the
// authoritative source consulted by ApplyDCA().
//
// ApplyDCA() runs ceil(baseRatio * multiplierBps / 10000) using __int128 to
// avoid overflow (commit 9cca6970ae) and fails closed (returns INT_MAX) when
// the caller-supplied health is stale relative to the canonical cached value.
int DynamicCollateralAdjustment::ApplyDCA(int baseRatio, int systemHealth);Status: ✅ Advanced Implementation
Core Features:
- ✅ Real-time collateral calculation with DCA integration
- ✅ Sophisticated UTXO selection with overflow protection
- ✅ OP_RETURN metadata for cross-node validation
- ✅ Proper fee estimation and change handling
- ✅ Dual P2TR output creation: collateral with MAST, DD token with key-path only
- ✅ Canonical lock-tier validation: OP_RETURN stores tier/lock height/owner key, and consensus checks the remaining lock blocks against
[canonical_blocks, canonical_blocks + 100]
Transaction Output Structure (~lines 344-370):
// Output 0: Collateral vault (P2TR with CLTV timelock)
CScript collateralScript = CreateCollateralScript(params); // MAST structure
tx.vout.push_back(CTxOut(result.collateralRequired, collateralScript));
// Output 1: DD token (SIMPLE P2TR - key-path only, NO MAST, NO CLTV)
// DD tokens must be freely transferable, unlike collateral which has timelock
CScript ddScript = CreateDDOutputScript(params.ownerKey, params.ddAmount);
tx.vout.push_back(CTxOut(0, ddScript)); // 0 DGB valueCritical Design Decision:
- Collateral (vout[0]): P2TR with CLTV timelock (2 redemption paths: Normal and ERR, both require timelock expiry)
- DD Token (vout[1]): Simple P2TR key-path only - freely transferable, no scripts, no timelock
- Why Different: DD tokens need to move freely between users; only collateral needs locking/redemption paths
Witness Structure:
- Collateral spending (redemption):
[signature] [script] [control_block]- SCRIPT-PATH - DD token spending (transfers):
[signature]- KEY-PATH (64 bytes only)
Recent Refactoring Highlights:
- Enhanced system health integration for DCA
- Improved fee calculation and UTXO management
- Better error handling and validation
- Optimized coin selection algorithms
- Fixed DD token output: Changed from CreateCollateralScript() to CreateDDOutputScript() for free transferability
Status: ✅ Complete User Interface
Features:
- ✅ Lock period dropdown with 10 tiers
- ✅ Real-time collateral calculator
- ✅ Oracle price display from the live consensus/MuSig2 price source
- ✅ Available balance checking
- ✅ Progress indicators and error handling
- ✅ Theme-aware styling
Backend Integration:
- ✅ Connected to WalletModel::mintDigiDollar()
- ✅ Real-time parameter validation
- ✅ Transaction confirmation dialogs
- ✅ Uses live oracle pricing on mainnet/testnet; regtest may use deterministic mock helpers
flowchart TD
A[User Input DD Address] --> B[Validate DD Address Format]
B --> C[Check DD Balance]
C --> D[Select DD UTXOs]
D --> E[Select Fee UTXOs]
E --> F[Build Transfer Transaction]
F --> G[Create DD Outputs]
G --> H[Calculate Change]
H --> I[Sign DD Inputs]
I --> J[Sign Fee Inputs]
J --> K[Broadcast Transaction]
K --> L[Update UTXO Database]
Status: ✅ Sophisticated Implementation
// Maps (txid, vout) → DD amount in cents
std::map<COutPoint, CAmount> dd_utxos;
// UTXO selection for transfers
std::vector<COutput> SelectDDCoins(CAmount target) {
// Greedy selection with dust awareness
// Overflow protection
// Change calculation optimization
}Key Innovation: Solves the challenge of tracking DigiDollar amounts through transfers by maintaining explicit UTXO-to-amount mapping rather than relying on position-based assumptions.
Status: ✅ Complete Implementation
Address validation is integrated directly into the send widget, using CDigiDollarAddress::IsValidDigiDollarAddress() from src/base58.h to validate DD/TD/RD prefixes and Base58Check format in real-time.
Note: There is no separate
digidollaraddressvalidator.cppfile; validation logic resides inCDigiDollarAddressand the send widget.
Status: ✅ Complete Schnorr Implementation
- ✅ Schnorr signatures for DigiDollar P2TR inputs
- ✅ Standard ECDSA signatures for DGB fee inputs
- ✅ Multi-input coordination
- ✅ Key management for DD positions
Verification: The claim that "send/sign/broadcast is complete" is confirmed accurate by this analysis.
flowchart TD
A[Generate DD Address] --> B[Display QR Code]
B --> C[Wait for Incoming TX]
C --> D[Detect DD Output]
D --> E[Verify Ownership]
E --> F[Add to UTXO Set]
F --> G[Update Balance]
G --> H[Notify User]
D --> I[Process Transaction]
I --> J[Extract DD Amount]
J --> K[Validate Script]
K --> F
-
Address Generation (
/src/qt/digidollarreceivewidget.cpp)- Complete GUI with QR code generation
- Proper DD address encoding
- Address book integration
- Payment request management
-
Incoming Transaction Detection (
/src/wallet/digidollarwallet.cpp)DetectIncomingDDOutputs()scans all transactions- Automatic processing via
SyncTransaction()integration - Proper ownership verification with
IsMine()
-
UTXO Management
AddReceivedDDUTXO()adds to spendable set- Database persistence via DD_OUTPUT records
- Balance calculation from UTXO aggregation
-
GUI Balance Notifications
- Core detection works, but missing
Q_EMIT digidollarBalanceChanged()signals - Real-time balance updates in receive widget pending
- Core detection works, but missing
-
Recent Requests Loading
- Payment requests persist in table model
populateRecentRequests()contains TODO for database loading
-
Enhanced Error Handling
- Basic validation present
- Could benefit from more comprehensive edge case handling
Assessment: Receive-side detection and persistence are wired end-to-end; outstanding items are GUI-side notification polish tracked in the Qt section, not in the protocol layer.
DigiDollar consensus consumes consensus prices from the oracle subsystem; the full oracle architecture (exchange aggregation, MuSig2 ceremony, P2P relay) lives in DIGIDOLLAR_ORACLE_ARCHITECTURE.md. This section only catalogs how the protocol layer touches it.
Price format. Micro-USD per DGB (1,000,000 = $1.00). DD amounts are stored in cents (100 = $1.00 USD). Conversions for system health use priceMillicents = priceMicroUSD / 10 (src/consensus/dca.cpp:243).
Where DigiDollar reads the price.
src/script/interpreter.cpp—OP_CHECKPRICEis reserved and deterministically disabled. It consumes its operand and pushes false; it does not consult any node-local oracle cache.src/digidollar/validation.cpp—ValidateMintTransaction()requiresctx.oraclePriceMicroUSD > 0(rejects withbad-oracle-priceotherwise) andShouldBlockMintingDuringERR()callsEmergencyRedemptionRatio::ShouldBlockMinting()which pulls the oracle price fromMockOracleManageron regtest andOracleBundleManager::GetLatestPrice()elsewhere, failing closed when the price is unavailable.src/validation.cpp:185-283— Block validation rejects coinbase oracle bundles that fail extraction withbad-oracle-malformedonceIsDigiDollarEnabledis true (the canonical reason for raw v0x01/v0x02 wire payloads, sinceExtractOracleBundleshort-circuits atsrc/oracle/bundle_manager.cpp:1065-1069). Thebad-oracle-legacyreason is kept as a defense-in-depth gate for hypothetical bundles that parse successfully but report a non-MuSig2version. Mempool acceptance requires a recent valid MuSig2 oracle quote (HasRecentValidMuSig2OracleQuote).src/digidollar/health.cpp—SystemHealthMonitorcaches the last oracle price (SystemMetrics::lastOraclePrice) and feeds DCA/ERR.
Mock oracle (regtest only). MockOracleManager (src/oracle/mock_oracle.cpp) is a regtest helper used by setmockoracleprice/enablemockoracle/simulatepricevolatility RPCs and by EmergencyRedemptionRatio::ShouldBlockMinting() when running on regtest. It is not a production fallback for any consensus path; mainnet/testnet ShouldBlockMinting consults the real OracleBundleManager, while OP_CHECKPRICE is reserved and deterministically disabled.
Oracle quote requirement at mempool admission. Mainnet/testnet nodes refuse to admit DigiDollar transactions when no recent valid MuSig2 oracle quote is available (HasRecentValidMuSig2OracleQuote, commit 81bf974f40); reorg-resurrected DD transactions are likewise removed if no quote is available (src/validation.cpp:601-602).
Status: ✅ Complete
- 10-tier system from 1000% (1 hour) to 200% (10 years)
- Provides substantial buffer against price volatility
- Treasury model rewards longer commitments
Implemented in /src/consensus/dca.cpp.
System health is computed once per snapshot and cached on SystemHealthMonitor; DCA always reads the cached value (single source of truth, commit 2de69c94d9):
// Cached metrics drive DCA. Inputs:
// totalCollateral — DGB satoshis from ScanUTXOSet + OnMint/OnRedeemConnected
// totalDDSupply — DD cents from the same incremental hooks
// oraclePrice — micro-USD per DGB from the consensus price (live MuSig2)
//
// CalculateSystemHealth() returns an int percentage in [0, 30000]; the math
// uses signed __int128 (commit 9cca6970ae) to avoid overflowing on large
// collateral × price products.
int health = DCA::DynamicCollateralAdjustment::CalculateSystemHealth(
totalCollateral, totalDDSupply, oraclePriceMillicents);DCA tiers (HEALTH_TIERS in src/consensus/dca.cpp:53-59):
| Health | Multiplier | Basis Points | Status |
|---|---|---|---|
| ≥150% | 1.00x | 10000 | healthy |
| 120–149% | 1.25x | 12500 | warning |
| 110–119% | 1.50x | 15000 | critical |
| <110% | 2.00x | 20000 | emergency |
ConsensusParams::dcaLevels (in src/consensus/digidollar.h) carries the same tier values. ApplyDCA(baseRatio, health) applies ceil(baseRatio * multiplierBps / 10000) and fails closed (returns INT_MAX) when the caller-supplied health is stale relative to the canonical cached value.
Implemented in /src/consensus/err.cpp.
ERR increases DD burn requirement; collateral return is always 100%. The DGB haircut model was removed (commit 55926c372a); GetAdjustedRedemption is a deprecated identity passthrough kept for ABI compatibility.
// src/consensus/err.cpp ERR_TIERS basis-point table:
// {95, 9500}, {90, 9000}, {85, 8500}, {0, 8000}
//
// Required burn formula (consensus-visible):
// RequiredDD = ceil(originalDDMinted * 10000 / ratioBps)
// Computed with signed __int128 to avoid overflow on large CAmount values
// (commit 55926c372a / 9cca6970ae).
CAmount EmergencyRedemptionRatio::GetRequiredDDBurn(CAmount originalDDMinted, int systemHealth) {
if (originalDDMinted <= 0) return 0;
if (systemHealth >= 100) return originalDDMinted;
int ratioBps = CalculateERRRatioBps(systemHealth);
const __int128 numerator = (__int128)originalDDMinted * 10000;
const __int128 required = (numerator + ratioBps - 1) / ratioBps; // ceil
return required > std::numeric_limits<CAmount>::max()
? std::numeric_limits<CAmount>::max()
: static_cast<CAmount>(required);
}ERR tiers (DD burn multiplier; collateral return always 100%):
| Health | ratioBps | DD Burn (= 10000/ratioBps) |
|---|---|---|
| 95–100% | 9500 | 1.053× |
| 90–95% | 9000 | 1.111× |
| 85–90% | 8500 | 1.176× |
| <85% | 8000 | 1.250× |
Mint blocking. ShouldBlockMinting(oraclePriceOverride) blocks new mints whenever ERR is active OR no oracle price is available; it fails closed during oracle outages so health uncertainty cannot allow new DD issuance (commit 8bbbfedf70). Block validation enforces this independently of the local mempool sync flag (src/digidollar/validation.cpp:2683-2685, ShouldBlockMintingDuringERR at 3004-3007).
Mint-time burn enforcement. ValidateCollateralReleaseAmount() (src/digidollar/validation.cpp:2316+) requires the redeemer to burn at least requiredDDBurn and to release the FULL locked collateral; partial-burn releases are rejected as bad-collateral-release-partial-burn. Non-DD transactions that try to spend a registered collateral vault are rejected with bad-collateral-spend-missing-dd-burn (commit 46cf97e804).
Status: ✅ FULLY IMPLEMENTED AND PRODUCTION-READY (/src/consensus/volatility.cpp)
// DigiDollar::Volatility::VolatilityMonitor (src/consensus/volatility.h)
class VolatilityMonitor {
static bool ShouldFreezeMinting(); // True if 1-hour volatility > 20%
static bool ShouldFreezeAll(); // True if 24-hour volatility > 30%
static bool InCooldownPeriod(); // Post-freeze cooldown (8640 blocks)
};Status: ✅ Comprehensive Implementation
Monitoring Capabilities:
- ✅ Real-time system health calculation
- ✅ Per-tier breakdown analysis
- ✅ Alert threshold monitoring
- ✅ Historical health tracking
- ✅ Integration with all protection systems
Health Metrics Tracked:
- Total DGB locked across all positions
- Total DD supply in circulation
- Overall system collateral ratio
- Per-tier health ratios
- Protection system status (DCA/ERR/Volatility)
Status: ✅ FULLY IMPLEMENTED AND TESTED (/src/digidollar/health.cpp:307)
This is a major implementation that was completely missing from the architecture document.
What It Does: DigiDollar implements true network-wide tracking by scanning the entire blockchain UTXO set, not just individual wallets. This means:
- Every node sees identical total DD supply and collateral
- System health is calculated network-wide, not per-wallet
- New nodes immediately see full network state
- No wallet needs to be loaded to see system statistics
Implementation Details:
void SystemHealthMonitor::ScanUTXOSet(CCoinsView* view,
CCoinsView* validation_view,
const node::BlockManager* blockman,
const CTxMemPool* mempool,
const CChain* chain,
const Consensus::Params* consensus)
{
// Create cursor to iterate ALL UTXOs (similar to gettxoutsetinfo)
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
// Iterate through entire blockchain UTXO set
while (pcursor->Valid()) {
COutPoint key;
Coin coin;
// Find DigiDollar vault outputs (P2TR with value > 0 at output 0)
if (key.n == 0 && coin.out.scriptPubKey[0] == OP_1 && coin.out.nValue > 0) {
// v9.26.4: coins created below the DigiDollar activation floor can
// never be DD vaults — skip them (their blocks may be pruned away)
// Fetch FULL transaction: txindex when available, otherwise read it
// straight from the retained block at the coin's height (works on
// pruned nodes, which keep every block at/above the DD floor)
const CBlockIndex* creating_block = chain ? (*chain)[coin.nHeight] : nullptr;
CTransactionRef tx = node::GetTransaction(creating_block, mempool, txid,
hashBlock, *blockman);
// Validate DD mint structure:
// - Output 0: P2TR collateral vault (has DGB value)
// - Output 1: P2TR DD token (value = 0)
// - Output 2: OP_RETURN with exact DD metadata
// Extract exact DD amount from OP_RETURN
if (DigiDollar::ExtractDDAmount(tx->vout[2].scriptPubKey, ddAmount)) {
s_currentMetrics.totalDDSupply += ddAmount;
s_currentMetrics.totalCollateral += collateral;
}
}
pcursor->Next();
}
}Key Innovations:
-
Full Transaction Access: Unlike simple UTXO scans, this implementation fetches full transaction data from BlockManager to access OP_RETURN metadata
-
Exact Amount Extraction: Reads precise DD amounts from OP_RETURN (output 2), not estimated from collateral
-
Network Consensus: All nodes scan the same UTXO set → identical results everywhere
-
Performance: Efficient streaming cursor, ~100ms for 1000 vaults, read-only
Integration Points:
- RPC Command:
getdigidollarstatscallsScanUTXOSet()with chainstate access (full re-scan; expensive). - Incremental hooks:
OnMintConnected/OnRedeemConnected(src/digidollar/health.h:222-248) updates_currentMetricsin O(1) undercs_mainwhenever a DD tx is connected during normal block processing; the symmetricOnMintDisconnected/OnRedeemDisconnectedreverse the update on reorg. - Block-level index:
DigiDollarStatsIndex(src/index/digidollarstatsindex.{h,cpp}) persists per-height totals (total_dd_supply,total_collateral,vault_count) so historical lookups don't require a re-scan. - Qt GUI: Overview widget displays network totals via RPC.
- Protection Systems: DCA/ERR read the cached
SystemMetrics(commit2de69c94d9) so health comes from one canonical source.
Verification:
✅ Functional Test: test/functional/digidollar_network_tracking.py - PASSING
- Creates 2 nodes (Bob and Alice)
- Bob mints DD on node 0
- Verifies both nodes see identical network statistics
- Proves UTXO scanning works across network
✅ Documented Proof: NETWORK_TRACKING_PROOF.md
- Complete test output showing identical stats
- Technical implementation details
- Performance characteristics
Example Output:
Bob (node 0) sees:
Total DD Supply: 20043 cents ($200.43)
Total Collateral: 633.00000000 DGB
Alice (node 1) sees:
Total DD Supply: 20043 cents ($200.43) ← IDENTICAL!
Total Collateral: 633.00000000 DGB ← IDENTICAL!
Impact on Architecture:
This is a critical differentiator from account-based stablecoin systems. Rather than relying on contract state, DigiDollar tracks protocol state through:
- Native UTXO set integration
- Blockchain-wide visibility
- No reliance on external indexers or APIs
- Consensus-compatible read-only queries
Files Implementing This Feature:
src/digidollar/health.h-ScanUTXOSet()declaration with validation_view + BlockManager parameterssrc/digidollar/health.cpp- Full UTXO scanning implementation with tx data extractionsrc/rpc/digidollar.cpp- RPC integration with chainstate accesssrc/qt/digidollaroverviewwidget.cpp- Qt GUI network statistics displaytest/functional/digidollar_network_tracking.py- Comprehensive verification test
Status: ✅ Production-Ready - Fully implemented, tested, and documented
The DigiDollar GUI implementation is 90% complete with all major widgets functional and integrated.
Status: ✅ Complete Implementation
class DigiDollarTab : public QWidget {
// 7 main sub-widgets, all functional:
DigiDollarOverviewWidget* m_overviewWidget;
DigiDollarReceiveWidget* m_receiveWidget;
DigiDollarSendWidget* m_sendWidget;
DigiDollarMintWidget* m_mintWidget;
DigiDollarRedeemWidget* m_redeemWidget;
DigiDollarPositionsWidget* m_positionsWidget; // Vault/Positions Manager
DigiDollarTransactionsWidget* m_transactionsWidget; // Transaction History
};Status: ✅ 95% Complete
- ✅ Total DD balance display
- ✅ DGB locked collateral tracking
- ✅ Current oracle price display from the live consensus/MuSig2 price source
- ✅ System health indicators (network-wide UTXO scanning)
- ✅ Recent transaction summary
- 🔄 Real-time balance updates (minor notification gap)
Status: ✅ 100% Complete
- ✅ DD address validation (DD/TD/RD prefixes)
- ✅ Amount input with balance checking
- ✅ Fee estimation and preview
- ✅ Transaction confirmation and broadcasting
- ✅ Backend integration with WalletModel
Status: ✅ 95% Complete
- ✅ DD address generation
- ✅ QR code creation
- ✅ Address book integration
- ✅ Payment request management
- 🔄 Recent requests loading from database (minor gap)
Status: ✅ 90% Complete
- ✅ Lock period selection (10 tiers)
- ✅ Real-time collateral calculator
- ✅ Oracle price display from the live consensus/MuSig2 price source
- ✅ Mint confirmation and execution
- ✅ Uses live oracle pricing on mainnet/testnet;
setmockoraclepriceis a regtest-only helper
Status: ✅ 85% Complete
- ✅ Position selection interface
- ✅ Redemption paths (Normal and ERR - both require timelock expiry)
- ✅ Required DD calculation display
- ✅ Time remaining indicators
- ✅ Full normal and ERR redemption validation; both paths require timelock expiry
Status: ✅ 90% Complete
- ✅ Comprehensive vault table display
- ✅ Health status indicators
- ✅ Sortable columns and context menus
- ✅ Position management interface
- 🔄 Real-time health updates (depends on oracle)
Strengths:
- ✅ Professional Qt implementation following DigiByte design standards
- ✅ Proper MVC architecture with signal/slot connections
- ✅ Real-time validation and user feedback
- ✅ Theme-aware styling and responsive design
- ✅ Comprehensive error handling and progress indicators
Minor Gaps:
- 🔄 Some real-time notifications depend on oracle system completion
- 🔄 Database loading for recent requests needs completion
- 🔄 Advanced error scenarios could use better user messaging
DigiDollar uses HD (Hierarchical Deterministic) key derivation from the wallet's seed for all DigiDollar operations. This enables wallet restore via descriptors.
Implementation Location: src/wallet/wallet.cpp:2741-2836 (CWallet::GetHDKeyForDigiDollar). Callers: src/rpc/digidollar.cpp:1439 (mintdigidollar RPC), src/rpc/digidollar.cpp:2845 (getdigidollaraddress RPC), src/qt/walletmodel.cpp:892 (Qt mint flow).
CKey CWallet::GetHDKeyForDigiDollar(const std::string& label)
{
// Returns an empty/invalid CKey if:
// - WALLET_FLAG_DISABLE_PRIVATE_KEYS is set, or
// - the wallet has no HD seed / no available keypool, or
// - extraction from the produced destination fails.
// Otherwise tries BECH32M (Taproot) first, falls back to BECH32.
// Uses GetSigningProviderWithKeys() for private-key access
// (NOT GetSolvingProvider()).
// Labels used: "dd-owner", "dd-address".
}Key Design Decisions:
- Uses
GetSigningProviderWithKeys(): critical for Taproot —GetSolvingProvider()returns keys without private-key access, causing signing failures. - No random-key or legacy-wallet fallback in V1. Earlier revisions of this section described a
MakeNewKey(true)fallback for legacy wallets; current code rejects non-descriptor wallets before any legacy key extraction (src/wallet/wallet.cpp:2757-2759). On any failure path the helper returns an invalidCKeyand the calling RPC throwsRPC_WALLET_ERROR "DigiDollar mint requires a descriptor/bech32m HD wallet with private keys enabled"(src/rpc/digidollar.cpp:1441). The Qt mint flow surfaces the same error to the user (src/qt/walletmodel.cpp:894-896). DigiDollar mint therefore requires a descriptor/bech32m HD wallet with private keys; non-HD/legacy/private-keys-disabled wallets fail clearly without minting. - Database persistence: keys stored via
StoreOwnerKey()andStoreAddressKey()before the mint transaction is broadcast (commit1e95478b7e), so a crash between broadcast and persistence cannot lose the owner key.
| Operation | Label | Called From |
|---|---|---|
| Mint DigiDollars | "dd-owner" |
mintdigidollar RPC (src/rpc/digidollar.cpp:1439) and Qt mint (src/qt/walletmodel.cpp:892) |
| Generate DD Address | "dd-address" |
getdigidollaraddress RPC (src/rpc/digidollar.cpp:2845) |
Note: redeemdigidollar RPC does not call GetHDKeyForDigiDollar() — it uses stored owner keys from the position database. The label "dd-redeem" is NOT used anywhere in the codebase; only "dd-owner" and "dd-address" are used.
Because DD keys are derived from the wallet seed (when using descriptor wallets):
- Keys can be regenerated from descriptors
listdescriptors trueexports HD seedimportdescriptors+rescanblockchainrestores positions- Legacy / non-HD / private-keys-disabled wallets cannot mint at all (mint RPC and Qt mint both throw immediately); there is no V1 fallback that produces an unrecoverable random key
When a wallet is restored via descriptors and rescanned, DD positions must be reconstructed from blockchain data.
Implementation Location: src/wallet/digidollarwallet.cpp (~line 1920)
Called from SyncTransaction() in wallet.cpp when rescanning_old_block=true:
void DigiDollarWallet::ProcessDDTxForRescan(
const CTransactionRef& ptx,
int block_height)
{
// Handles MINT (type=1) and REDEEM (type=3) transactions
// Reconstructs positions from OP_RETURN metadata
}Problem: Standard IsMine(vout[0]) fails for DigiDollar MAST scripts because the wallet doesn't recognize complex Taproot scripts as its own.
Solution: Detect ownership via input inspection:
// Check if any input belongs to this wallet
bool is_our_mint = false;
for (const CTxIn& txin : tx.vin) {
auto it = m_wallet->mapWallet.find(txin.prevout.hash);
if (it != m_wallet->mapWallet.end()) {
if (m_wallet->IsMine(it->second.tx->vout[txin.prevout.n]) != wallet::ISMINE_NO) {
is_our_mint = true;
break;
}
}
}Why this works: If the wallet owns the inputs to a mint transaction, it must own the resulting position.
All position data is extracted from on-chain OP_RETURN metadata:
dd_minted: From OP_RETURNdgb_collateral: Fromvout[0].nValueunlock_height: From OP_RETURNlock_tier: Extracted from explicit mint OP_RETURN metadata viaExtractTierFromOpReturn()(required)dd_timelock_id: Transaction hashis_active: Check if vault UTXO is spent
Implementation: ExtractTierFromOpReturn() in src/wallet/digidollarwallet.cpp
// vout[2]: OP_RETURN ("DD" | txType=1 | dd_minted | unlock_height | lock_tier)
if (!ExtractTierFromOpReturn(tx, lock_tier)) {
return false; // Old/no-tier mint formats unsupported for V1
}Note: DeriveLockTierFromHeight() remains in wallet code only as a deprecated diagnostic helper. V1 position reconstruction does not use a height-derived fallback: old/no-tier mint formats are unsupported, and live restore requires lock_tier in OP_RETURN so all ten canonical tiers, including the 2-year tier, remain unambiguous.
┌──────────────────────────────────────────────────────────────┐
│ WALLET RESTORE WORKFLOW │
└──────────────────────────────────────────────────────────────┘
1. EXPORT FROM ORIGINAL WALLET
═══════════════════════════════
$ digibyte-cli listdescriptors true
Returns: {
"descriptors": [
{"desc": "tr([fingerprint/86'/20'/0']xprv.../0/*)", ...},
...
]
}
2. CREATE NEW WALLET & IMPORT
═══════════════════════════════
$ digibyte-cli createwallet "restored" false false "" false true
$ digibyte-cli -rpcwallet=restored importdescriptors '[...]'
3. RESCAN BLOCKCHAIN
═══════════════════════════════
$ digibyte-cli -rpcwallet=restored rescanblockchain
During rescan, for each block:
└─► SyncTransaction() called
└─► if (rescanning_old_block)
└─► ProcessDDTxForRescan()
└─► Extract position from OP_RETURN
└─► Check ownership via inputs
└─► Rebuild collateral_positions map
└─► Restore dd_utxos map
4. VERIFICATION
═══════════════════════════════
$ digibyte-cli -rpcwallet=restored listdigidollarpositions
$ digibyte-cli -rpcwallet=restored getdigidollarbalance
| Data | Stored In | Restoration Method |
|---|---|---|
| HD Keys | Descriptors | Imported directly |
| DGB UTXOs | Blockchain | Standard rescan |
| DD Positions | Blockchain OP_RETURN | ProcessDDTxForRescan() |
| DD UTXOs | Blockchain | ProcessDDTxForRescan() |
| Address Labels | Descriptors | Imported directly |
These maps are rebuilt during rescan, not exported:
dd_owner_keys- Rebuilt from HD derivationdd_utxos- Rebuilt from blockchain scandd_address_keys- Rebuilt from HD derivationcollateral_positions- Rebuilt from OP_RETURN data
Location: test/functional/wallet_digidollar_restore.py
Tests the complete workflow:
- Create wallet, mint DD positions
- Export descriptors
- Create new wallet, import descriptors
- Rescan blockchain
- Verify positions and balances match
Status: ✅ 100% Complete (tested via wallet_digidollar_persistence_restart.py)
// Core data structures with wallet.dat integration
// Database keys (string-based, in walletdb.cpp DBKeys namespace):
// "ddutxo" (DD_OUTPUT) - UTXO tracking
// "ddbalance" (DD_BALANCE) - Address-based balances
// "ddposition" (DD_POSITION) - Collateral positions
// "ddtx" (DD_TRANSACTION) - Transaction history✅ Working Components:
- DD Output Tracking: UTXOs with amounts persist across restarts
- Position Storage: Collateral positions save to wallet.dat
- Address Book: DD addresses integrate with existing address book
- Transaction History: Basic DD transaction tracking
🔄 Gaps Remaining:
- Recent Requests Loading:
populateRecentRequests()needs database integration - Full Transaction Metadata: Some transaction details load simplified
- Migration Logic: Wallet upgrade handling for DD data could be enhanced
Status: ✅ Advanced Implementation
// Primary UTXO tracking map
std::map<COutPoint, CAmount> dd_utxos;
// Database operations (integrated into wallet infrastructure)
void AddDDUTXO(const COutPoint& outpoint, CAmount dd_amount); // ✅ Working
void RemoveDDUTXO(const COutPoint& outpoint); // ✅ Working
size_t LoadFromDatabase(); // ✅ Working - loads all DD data including UTXOsKey Features:
- ✅ Persistent UTXO tracking across wallet restarts
- ✅ Efficient lookup for balance calculations
- ✅ Integration with coin selection algorithms
- ✅ Automatic cleanup of spent UTXOs
35 Total RPC Commands (18 Node-Context + 17 Wallet-Context) (/src/rpc/digidollar.cpp + /src/wallet/rpc/wallet.cpp)
Status: ✅ 90% Complete
All RPC Commands defined in /src/rpc/digidollar.cpp (18 registered directly, others via wallet-layer):
| Category | Command | Status | Notes |
|---|---|---|---|
| System Health | getdigidollarstats |
✅ Complete | Network-wide UTXO scanning + system health |
getdcamultiplier |
✅ Complete | DCA multiplier calculations | |
getdigidollardeploymentinfo |
✅ Complete | BIP9 deployment activation info | |
getprotectionstatus |
✅ Complete | DCA/ERR/volatility status | |
| Collateral | calculatecollateralrequirement |
✅ Complete | Real-time collateral calculation |
estimatecollateral |
✅ Complete | Quick collateral estimation | |
getredemptioninfo |
✅ Complete | Redemption requirements | |
| Addresses | validateddaddress |
✅ Complete | DD/TD/RD address validation |
listdigidollaraddresses |
✅ Complete | List all DD addresses | |
importdigidollaraddress |
Validates DD address only; returns a no-op warning and does not mutate wallet state | ||
| Oracle System | getoracleprice |
✅ Complete | Returns the live consensus/MuSig2 oracle price on mainnet/testnet; regtest may use mock helpers |
getalloracleprices |
✅ Complete | Returns all oracle price data | |
sendoracleprice |
❌ Removed | Removed — security vulnerability (fake price injection) | |
getoracles |
✅ Complete | Shows configured oracle nodes | |
getoraclesigners |
✅ Complete | Lists oracle signers for a block (not activation-gated) | |
listoracle |
✅ Complete | List oracle details | |
stoporacle |
✅ Complete | Stop local oracle participant | |
getoraclepubkey |
✅ Complete | Get oracle public key by ID | |
submitoracleprice |
❌ Not present | Never implemented — no string match in src/rpc or src/wallet/rpc; oracle prices come from live exchange aggregation only |
|
| Mock Oracle | setmockoracleprice |
✅ Complete | Set test price (RegTest only) |
getmockoracleprice |
✅ Complete | Get current mock price | |
simulatepricevolatility |
✅ Complete | Test volatility protection | |
enablemockoracle |
✅ Complete | Enable/disable mock oracle |
Wallet-Layer Commands (17 in /src/wallet/rpc/wallet.cpp, require wallet context):
| Command | Status | Notes |
|---|---|---|
mintdigidollar |
✅ Complete | Create DD by locking DGB collateral |
senddigidollar |
✅ Complete | Transfer DD to another address |
sendmanydigidollar |
✅ Complete | Transfer DD to multiple addresses in one transaction |
redeemdigidollar |
✅ Complete | Burn DD to unlock DGB collateral |
getdigidollaraddress |
✅ Complete | Generate new DD address |
getdigidollarbalance |
✅ Complete | Get total DD balance |
listdigidollarpositions |
✅ Complete | List all collateral positions |
listdigidollaraddresses |
✅ Complete | List all DD addresses in wallet |
getredemptioninfo |
✅ Complete | Redemption details for a position |
listdigidollartxs |
✅ Complete | List DD transaction history |
listdigidollarunspent |
✅ Complete | List spendable DD UTXOs for coin control |
listdigidollarutxos |
✅ Complete | Alias for DD UTXO listing |
validateddaddress |
✅ Complete | Validate DD address format |
createoraclekey |
✅ Complete | Generate oracle signing key pair |
exportoracleprivkey |
✅ Complete | Export wallet-stored oracle private key for backup/migration |
importoracleprivkey |
✅ Complete | Import wallet-stored oracle private key for recovery/migration |
startoracle |
✅ Complete | Start local oracle participant from wallet key |
Important Notes:
- All wallet commands are fully functional through the Qt GUI
- Oracle system uses mock prices for deterministic regtest tests; mainnet/testnet operators use live exchange aggregation and MuSig2 v0x03 bundles
- Regtest mock price defaults to $0.0065 per DGB = 6500 micro-USD and can be changed with
setmockoracleprice - Production oracle validation does not fall back to mock prices or legacy bundle formats
Strengths:
- ✅ Complete parameter validation and error handling
- ✅ JSON-RPC compliance with proper response formatting
- ✅ Integration with existing Bitcoin Core RPC infrastructure
- ✅ Comprehensive help documentation for all commands
- ✅ Security considerations with access control
Current Limitations:
- ✅ Oracle commands use deterministic mock prices on regtest only; mainnet/testnet use live libcurl exchange aggregation when
HAVE_LIBCURLis defined - ✅ Oracle daemon commands operate on wallet-managed oracle keys and live P2P/MuSig2 messages
- ✅ All system health and monitoring commands fully functional
┌─────────────────────────────────────┐
│ USER WANTS TO MINT DD │
│ (Lock DGB, Get DigiDollars) │
└─────────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ UI: CHOOSE PARAMETERS │
├─────────────────────────────────────────────────────────────┤
│ 1. Lock Period (10 tiers): 1h→10y (1000%→200% collateral) │
│ 2. DD Amount: $100 - $100,000 range │
│ 3. Real-time collateral calculator shows required DGB │
│ CODE: /src/qt/digidollarmintwidget.cpp │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SAFETY CHECKS & VALIDATION │
├─────────────────────────────────────────────────────────────┤
│ 1. Volatility Check: VolatilityMonitor::ShouldFreezeMinting │
│ → If 20%+ price swing in 1hr = REJECT MINT │
│ 2. Oracle Price: Get current DGB/USD from oracles │
│ → Live consensus/MuSig2 price; regtest may use mock │
│ 3. System Health: DCA multiplier (1.0x - 2.0x) │
│ 4. Balance Check: Ensure sufficient DGB available │
│ CODE: /src/digidollar/validation.cpp │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ COLLATERAL CALCULATION ENGINE │
├─────────────────────────────────────────────────────────────┤
│ Required DGB = (dd_cents × COIN × ratio_percent × dca_bps) │
│ / (oracle_micro_usd × 100) │
│ │
│ Example: $10 DD, 1yr lock, healthy system, 6500 µUSD/DGB: │
│ Required = (1000¢ × COIN × 300 × 10000)/(6500 × 100) │
│ ≈ 4615.38 DGB │
│ │
│ CODE: /src/digidollar/txbuilder.cpp - MintTxBuilder │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ BUILD MINT TRANSACTION │
├─────────────────────────────────────────────────────────────┤
│ 1. Select DGB UTXOs (greedy algorithm for collateral+fees) │
│ 2. Create vout[0]: Collateral vault (P2TR with timelock) │
│ • 2 redemption paths: Normal and ERR extra-burn paths │
│ • CLTV timelock for lock period enforcement │
│ • CreateCollateralScript() - P2TR with timelock │
│ 3. Create vout[1]: DD token (SIMPLE P2TR, key-path only) │
│ • NO MAST, NO CLTV - freely transferable │
│ • CreateDDOutputScript() - just Taproot tweak │
│ • Witness when spending: [64-byte signature] only │
│ 4. Create vout[2]: OP_RETURN metadata (tx type + amounts) │
│ 5. Calculate fees and create change outputs │
│ CODE: /src/digidollar/txbuilder.cpp lines 344-370 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SIGN & BROADCAST TRANSACTION │
├─────────────────────────────────────────────────────────────┤
│ 1. Sign all DGB inputs with ECDSA signatures │
│ 2. Verify transaction structure and collateral compliance │
│ 3. Submit to mempool via wallet.chain().broadcastTransaction│
│ 4. Create WalletCollateralPosition database record │
│ 5. Add DD UTXO as pending; consensus spends require │
│ confirmed DD inputs │
│ 6. Update GUI with new vault and DD balance │
│ CODE: /src/wallet/digidollarwallet.cpp - MintDigiDollar │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ ✅ MINT COMPLETE │
│ • DGB locked in time-locked vault (NO early exit possible) │
│ • DigiDollars available for spending immediately │
│ • Vault position tracked in database with health monitoring│
│ • User can view in "Vault Manager" tab │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────┐
│ USER WANTS TO SEND DD │
│ (Transfer DigiDollars to Someone) │
└─────────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ UI: ENTER SEND DETAILS │
├─────────────────────────────────────────────────────────────┤
│ 1. Recipient DD Address: Real-time validation (DD/TD/RD) │
│ 2. Amount: Min $1.00, real-time balance checking │
│ 3. Review: Address confirmation, fee estimation │
│ 4. Base58Check validation & P2TR structure verification │
│ CODE: /src/qt/digidollarsendwidget.cpp │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SMART UTXO SELECTION ENGINE │
├─────────────────────────────────────────────────────────────┤
│ 1. DD UTXO Scan: Query dd_utxos map (COutPoint → CAmount) │
│ → Filter spendable, sort by amount for efficiency │
│ 2. DD Selection: Greedy algorithm until target reached │
│ → Example: Send $5, have [$10, $3, $2] → Select $10 │
│ → Calculate change: $10 - $5 = $5 DD change │
│ 3. Fee UTXO Selection: Standard wallet coin selection │
│ → Estimate fee, select DGB UTXOs for payment │
│ CODE: /src/wallet/digidollarwallet.cpp - SelectDDCoins │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ BUILD TRANSFER TRANSACTION │
├─────────────────────────────────────────────────────────────┤
│ 1. Transaction Version: 0x02000770 (DD_TX_TRANSFER) │
│ 2. Add Inputs: DD UTXOs + DGB fee UTXOs │
│ 3. Create Outputs: │
│ • Recipient DD Output (P2TR, 0 DGB, DD in metadata) │
│ • DD Change Output (if needed, to sender's new address) │
│ • DGB Fee Change (if DGB UTXOs > actual fee) │
│ 4. DD Conservation Check: Total DD In = Total DD Out │
│ CODE: /src/digidollar/txbuilder.cpp - TransferTxBuilder │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 🔑 TAPROOT SIGNING: KEY-PATH vs SCRIPT-PATH (Critical) │
├─────────────────────────────────────────────────────────────┤
│ ⚠️ Transfer transactions set LOCKTIME = 0 (no timelock) │
│ │
│ SIGNING PROCESS (SignDDInputs, ~line 5098): │
│ │
│ 1. Sign DGB Fee Inputs FIRST: │
│ → wallet's SignTransaction() creates ECDSA signatures │
│ → (Taproot sighash includes witness data of other inputs)│
│ │
│ 2. For EACH DD Input - Check Output Index (outpoint.n): │
│ │
│ IF outpoint.n == 1 (DD token output): │
│ ✅ USE KEY-PATH SIGNING: │
│ • DD tokens are simple P2TR (no MAST tree) │
│ • Tweak key with EMPTY merkle root │
│ • Sign with Schnorr signature │
│ • Witness stack: [64-byte signature] (key-path) │
│ • This is the standard transfer case! │
│ │
│ ELSE (outpoint.n == 0, collateral vault): │
│ 🔒 COLLATERAL REDEMPTION: │
│ • Collateral uses P2TR with timelock │
│ • 2 paths: Normal or ERR extra-DD-burn redemption │
│ • Must wait for timelock to expire │
│ • Sign with Taproot script-path witness │
│ • Only used during redemption, not transfers! │
│ │
│ 3. Validate: Check signatures, amounts, DD conservation │
│ │
│ KEY INSIGHT: Transfer txs spend vout[1] (DD tokens) using │
│ simple key-path signing. Only redemptions spend vout[0] │
│ (collateral) which requires complex script-path signing. │
│ │
│ CODE: /src/wallet/digidollarwallet.cpp - SignDDInputs │
│ ~Line 5098+ contains the vout index check logic │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ BROADCAST & UPDATE DATABASE │
├─────────────────────────────────────────────────────────────┤
│ 1. Network Broadcast: │
│ → wallet.chain().broadcastTransaction() to mempool │
│ → Relay to network peers automatically │
│ 2. UTXO Database Updates (CRITICAL): │
│ → Remove spent DD UTXOs from dd_utxos map │
│ → Add new DD UTXOs (change, self-transfers) │
│ → NEVER touch collateral positions (they stay locked!) │
│ 3. Transaction History & Balance Updates │
│ CODE: /src/wallet/digidollarwallet.cpp - TransferDigiDollar │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ ✅ TRANSFER COMPLETE │
│ • DigiDollars sent to recipient's address │
│ • Change DigiDollars returned to sender's new address │
│ • All collateral vaults remain locked and untouched │
│ • Transaction appears in both wallets' history │
│ • Network propagation ensures global consistency │
└─────────────────────────────────────────────────────────────┘
- Current: 6 active exchange API fetchers (libcurl).
MockOracleManageris a regtest helper for test scenarios;OP_CHECKPRICEis reserved and deterministically disabled, so no production script path can read mock or live node-local prices. - Exchange APIs: Binance, KuCoin, Gate.io, HTX (Huobi), Crypto.com, CoinGecko (Coinbase, Kraken, CoinMarketCap removed: DGB not tradeable / paid-key incompatible with decentralized design)
- Status: ✅ Real API implementation exists (conditional on HAVE_LIBCURL); regtest mock available for scripted tests
- Remaining: Mainnet oracle operator deployment and end-to-end testnet verification
- Current: Uses standard Bitcoin Core transaction relay + Oracle P2P protocol
- Status: ✅ Working for transaction propagation and oracle message relay
- Oracle P2P: BroadcastMessage() sends oracle prices to all peers via ORACLEPRICE msg type
- Message Types: MSG_ORACLE_PRICE, MSG_ORACLE_BUNDLE, MSG_ORACLE_CONSENSUS, MSG_ORACLE_ATTESTATION
- Current: ScanUTXOSet provides full blockchain UTXO scanning; incremental tracking via OnMintConnected/OnRedeemConnected
- Status: ✅ Production-ready - network-wide tracking verified across multi-node tests
- Implementation:
src/digidollar/health.cpp(ScanUTXOSet) +src/index/digidollarstatsindex.cpp(block-level index)
- Status: ✅ Complete integration with DigiByte consensus rules
- Features: Soft fork activation, block validation, transaction validation
- Quality: Production-ready with comprehensive error handling
- Status: ✅ 90% complete with minor notification gaps
- Features: UTXO management, key handling, transaction creation
- Quality: Well-integrated with existing Bitcoin Core wallet infrastructure
- Status: ✅ 90% complete with professional implementation
- Features: All 7 widgets functional, theme integration, real-time updates
- Quality: Follows Qt best practices and DigiByte design standards
Architecture and Design:
- ✅ Sophisticated UTXO Management: Advanced tracking system for DigiDollar amounts
- ✅ Proper Taproot Integration: Complete P2TR implementation with MAST support
- ✅ Overflow Protection: Consistent use of 64-bit arithmetic for financial calculations
- ✅ Error Handling: Comprehensive validation and error reporting throughout
- ✅ Separation of Concerns: Well-layered architecture with clear component boundaries
Implementation Quality:
- ✅ Bitcoin Core Compliance: Follows Bitcoin Core coding standards and patterns
- ✅ Test Coverage: Extensive DD/oracle unit, Qt, functional, and fuzz coverage; the current runner registers 80 DD/oracle/wallet functional entries and the Wave 23 all-target fuzz gate enumerates 247 registered fuzz targets
- ✅ Documentation: Well-documented code with clear intent and usage examples
- ✅ Security Awareness: Proper input validation, overflow protection, and access control
Integration Quality:
- ✅ GUI Implementation: Professional Qt implementation with proper MVC patterns
- ✅ RPC Interface: Complete command set with proper parameter validation
- ✅ Database Integration: Robust persistence layer using Bitcoin Core patterns
Production Readiness:
- 🔄 Oracle Operations: Mainnet/testnet consensus parameters are wired; operator rollout and monitoring remain operational work.
- ✅ UTXO Scanning: Production-ready UTXO set scanning implemented (ScanUTXOSet + incremental tracking)
- ✅ Collateral Witness Path: Wallet/RPC redemption signs collateral through the Taproot script path; DD token transfers remain key-path only.
Performance Optimization:
- 🔄 Coin Selection: Implement more sophisticated UTXO selection algorithms
- ✅ Caching: Oracle quote and health/state caches are wired; future work is bounded-memory and telemetry tuning.
- 🔄 Database Indexing: Optimize database queries for large UTXO sets
Feature Completion:
- 🔄 GUI Notifications: Complete real-time balance update notifications
- ✅ P2P Oracle Relay: Oracle message broadcasting implemented (BroadcastMessage via ORACLEPRICE msg)
- 🔄 Witness Diagnostics: Standard Taproot script validation enforces the spend; explicit DD-aware witness-shape diagnostics could still be expanded.
The V1 branch (feature/digidollar-v1) closed a series of consensus and policy gaps that materially affect protocol behavior. Listed in approximate code order, with the commit hash for traceability.
| Area | Behavior | Reference |
|---|---|---|
| OP_CHECKPRICE | Reserved and deterministically disabled; consumes one operand and pushes false. It does not read live oracle state or production mock state. | b9ddae031e / 3668971ab2 (src/script/interpreter.cpp:708-735) |
| MuSig2 V1 only | Coinbase oracle bundles in DigiDollar-active blocks must carry the V1 MuSig2 v0x03 format. Raw v0x01/v0x02 OP_RETURN payloads fail extraction (src/oracle/bundle_manager.cpp:1065-1069) and surface as bad-oracle-malformed; the bad-oracle-legacy branch is kept as defense-in-depth for bundles that parse but report a non-MuSig2 version. Mempool acceptance requires a recent valid MuSig2 quote. |
f2bb0a19a4, bbb85cf363 (src/validation.cpp:185-283) |
| Mainnet/testnet validator parity | The mainnet oracle-validation short-circuit was removed; both networks honor the same V1 oracle-bundle gates. | f0d9a7b2c7 |
| DCA / health overflow | DCA and health math use signed __int128 throughout to prevent collateral × price overflow. |
9cca6970ae |
| ERR burn math | Required burn = ceil(originalDD * 10000 / ratioBps) in __int128; GetAdjustedRedemption is a deprecated identity passthrough. |
55926c372a |
| Collateral spend rule | Non-DD spends of registered collateral vaults are rejected as bad-collateral-spend-missing-dd-burn. |
46cf97e804 |
| Confirmed-only DD chaining | Consensus refuses DD inputs at MEMPOOL_HEIGHT for transfers and redeems. |
0b4959f563 |
| Pre-mutation volatility check | WouldCandidateFreezeMinting() runs before any mutation so a rejected mint cannot poison volatility history. |
03f4af47a7 |
| Missing system health fail-closed | Mint validation requires deterministic system health and rejects with bad-system-health otherwise. |
8bbbfedf70 (src/digidollar/validation.cpp:1581-1584) |
| Mempool oracle quote | DD mempool acceptance requires a recent valid MuSig2 oracle quote; without one, DD txs are rejected and reorg-resurrected DD txs are removed. | 81bf974f40 |
| Mining graceful degradation | DD txs failing validation are skipped during package selection and price-dependent DD txs are removed before retrying block validity when no valid oracle bundle is ready. | 6b5ff516c3 (src/node/miner.cpp:523-538, 561-584, 849-864) |
| Lock tier canonical window | Custom/under-locked durations are rejected; mint OP_RETURN must record the canonical tier and the remaining lock blocks must be in [tier_blocks, tier_blocks + 100]. |
e1dd69f99b, 11728a6980 (src/digidollar/validation.cpp:1342-1397, 1603-1611) |
| DD supply alert (not a cap) | AlertThresholds::ALERT_DD_SUPPLY = 100M DD is a monitoring threshold, not a hard cap; MAX_DIGIDOLLAR is a per-output serialization bound. |
99b1f79480 (src/digidollar/health.h:83) |
| Coinbase price-cache poisoning | Coinbase oracle-price extraction is gated on DEPLOYMENT_DIGIDOLLAR, and global UpdatePriceCache mutation is deferred until after block checks succeed, so a coinbase OP_ORACLE cannot poison the price cache pre-activation or from an invalid block. |
rh61 (src/validation.cpp:3077-3099, 3373-3380) |
| Single source of system health | DCA/ERR consume SystemHealthMonitor::GetCachedMetrics(); stale callers fail closed in ApplyDCA. |
2de69c94d9 |
- Mainnet oracle infrastructure rollout — The 35 active oracle slots (mainnet/testnet) require operator deployment; consensus is wired and tested.
- Supplemental witness diagnostics — Collateral outputs use a NUMS internal key and wallet/RPC redemption signs via Taproot script path today.
ValidateScriptPathSpending()is only a supplemental DD helper that logs/returns true; standard Taproot validation plus NUMS output reconstruction carry consensus enforcement. - GUI notification polish — Real-time balance signals and recent-requests persistence are tracked outside this protocol document.
AUDIT NOTE (2026-05-20): Do not describe ValidateScriptPathSpending() as the consensus witness validator. The code constructs collateral with a NUMS internal key, reconstructs the expected 2-leaf MAST output during mint validation, and spends collateral through Taproot script path in wallet/RPC redemption; the helper remains a structural hook for future DD-specific diagnostics.
- UTXO-native stablecoin. DD amounts live in P2TR outputs; no shared global state, no smart-contract VM. The DD token output is a key-path-only P2TR; the collateral output is a 2-leaf MAST P2TR with a NUMS internal key (so key-path spending is impossible — the owner must take a script-path that enforces CLTV).
- Treasury-model collateral. 10 lock tiers (1 hour … 10 years) carrying ratios 1000% → 200% encode a soft incentive for longer commitments while preserving solvency under price shocks.
- Defense in depth. Four protection layers operate cooperatively: tier-based base ratio, DCA multiplier on system health, ERR DD-burn premium below 100% health, and the volatility freeze with
WouldCandidateFreezeMinting()pre-mutation gate. - Address namespacing. DD/TD/RD prefixes (mainnet/testnet/regtest) prevent cross-network errors when interacting with DigiDollar specifically.
- No early redemption ever. Both MAST leaves enforce CLTV expiry; there is no key-path spend, no oracle override, no liquidation.
The full unit/fuzz/functional test inventory is maintained in REPO_MAP_DIGIDOLLAR.md. The tables below name the protocol-layer test files most directly relevant to the architecture above; running ./src/test/test_digibyte --list_content | grep -Ei 'digidollar|oracle|musig|^rh' is the authoritative way to discover everything currently compiled.
Location: src/test/
| Test File | Coverage Area |
|---|---|
| digidollar_activation_tests.cpp | Activation height logic |
| digidollar_address_tests.cpp | DD/TD/RD address validation |
| digidollar_change_tests.cpp | DD change output creation, dust handling |
| digidollar_consensus_tests.cpp | Consensus rules |
| digidollar_dca_tests.cpp | Dynamic Collateral Adjustment |
| digidollar_err_tests.cpp | ERR activation, adjustment ratios |
| digidollar_health_tests.cpp | SystemHealthMonitor metrics |
| digidollar_key_encryption_tests.cpp | DD key encryption |
| digidollar_mint_tests.cpp | Minting process |
| digidollar_opcodes_tests.cpp | DD opcodes (OP_DIGIDOLLAR etc.) |
| digidollar_oracle_tests.cpp | Oracle integration |
| digidollar_p2p_tests.cpp | P2P networking |
| digidollar_persistence_keys_tests.cpp | Database key handling |
| digidollar_persistence_serialization_tests.cpp | Serialization |
| digidollar_persistence_walletbatch_tests.cpp | Wallet database operations |
| digidollar_redeem_tests.cpp | Redemption tx building |
| digidollar_redteam_tests.cpp | Security-focused (RED HORNET audit) |
| digidollar_restore_tests.cpp | Wallet restore from rescan |
| digidollar_rpc_tests.cpp | RPC command validation |
| digidollar_scripts_tests.cpp | P2TR script creation |
| digidollar_skip_oracle_tests.cpp | Oracle skip during IBD |
| digidollar_structures_tests.cpp | Data structure validation |
| digidollar_t2_05_tests.cpp | Task 2.05 specific tests |
| digidollar_timelock_tests.cpp | CLTV timelock logic |
| digidollar_transaction_tests.cpp | Transaction building |
| digidollar_transfer_tests.cpp | DD transfer conservation |
| digidollar_txbuilder_tests.cpp | Transaction builder |
| digidollar_utxo_lifecycle_tests.cpp | DD UTXO lifecycle tracking |
| digidollar_validation_tests.cpp | Validation functions |
| digidollar_volatility_tests.cpp | Volatility monitoring |
| digidollar_wallet_tests.cpp | Wallet operations |
Location: src/test/ — protocol layer only depends on the bundle/MuSig2 surface; full oracle test inventory lives in DIGIDOLLAR_ORACLE_ARCHITECTURE.md and REPO_MAP_DIGIDOLLAR.md.
| Test File | Coverage Area |
|---|---|
| oracle_block_validation_tests.cpp | Block validation rules |
| oracle_bundle_manager_tests.cpp | Bundle creation/management |
| oracle_bundle_timing_tests.cpp | Bundle timing edge cases |
| oracle_config_tests.cpp | Oracle configuration |
| oracle_consensus_threshold_tests.cpp | Consensus threshold testing |
| oracle_exchange_tests.cpp | Exchange API integration |
| oracle_integration_tests.cpp | System integration |
| oracle_message_tests.cpp | Message creation/validation |
| oracle_miner_tests.cpp | Miner integration |
| oracle_p2p_tests.cpp | P2P oracle messaging |
| oracle_phase2_tests.cpp | Legacy Phase 2 / MuSig2 oracle validation regressions |
| oracle_price_feed_rh09_tests.cpp | Price feed RH-09 regression |
| oracle_price_staleness_tests.cpp | Price staleness detection |
| oracle_rpc_tests.cpp | Oracle RPC commands |
| oracle_wallet_autostart_tests.cpp | Oracle wallet auto-start |
| oracle_wallet_key_tests.cpp | Oracle key generation/storage |
| redteam_phase2_audit_tests.cpp | RED HORNET legacy Phase 2 exploit regressions |
| rh62_senddigidollar_amount_parser_tests.cpp | Send amount parser regression coverage |
| rh63_oracle_validator_escape_hatches_tests.cpp | Oracle validator escape-hatch regressions |
| rh64_dca_table_disagreement_tests.cpp | DCA table disagreement regressions |
Location: test/functional/ — full DD/oracle/wallet/Qt functional inventory in REPO_MAP_DIGIDOLLAR.md.
| Test File | Purpose |
|---|---|
| digidollar_activation.py | Activation height testing |
| digidollar_activation_boundary.py | Activation edge cases |
| digidollar_basic.py | Basic DD functionality |
| digidollar_bug11_bug13_regression.py | Bug 11/13 regression tests |
| digidollar_collateral_spend_guards.py | Collateral vault spend guards and DD burn enforcement |
| digidollar_lock_tier_canonical.py | Canonical tier window acceptance/rejection |
| digidollar_verifychain_cache_side_effect.py | Verifychain cache side-effect regression |
| digidollar_wave14_multinode_ibd_reorg.py | Multi-node IBD/reorg DD/oracle state replay |
| digidollar_wave17_spendability.py | DD spendability/watch-only/locked-wallet regressions |
| digidollar_wave18_rpc_matrix.py | DD RPC matrix across wallet/network/activation states |
| digidollar_wave26_mixed_node_compat.py | Mixed-node activation compatibility |
| digidollar_encrypted_wallet.py | DD with encrypted wallet |
| digidollar_mint.py | End-to-end minting |
| digidollar_network_relay.py | P2P transaction relay |
| digidollar_network_tracking.py | Network-wide UTXO scanning |
| digidollar_oracle.py | Oracle integration (full cycle) |
| digidollar_oracle_consistency.py | Oracle consistency across nodes |
| digidollar_oracle_keygen.py | Oracle key generation |
| digidollar_oracle_bundle_reject_matrix.py | Oracle bundle reject matrix |
| digidollar_oracle_price.py | Oracle price feed testing |
| digidollar_persistence.py | Database save/load |
| digidollar_mempool_miner_parity.py | DD mempool/miner/ConnectBlock parity |
| digidollar_protection.py | DCA/ERR/Volatility systems |
| digidollar_protection_status.py | Protection status display |
| digidollar_redeem.py | Redemption process |
| digidollar_redeem_stats.py | Redemption statistics |
| digidollar_redemption_amounts.py | Amount calculations |
| digidollar_redemption_e2e.py | End-to-end redemption |
| digidollar_rpc.py | General RPC testing |
| digidollar_rpc_addresses.py | Address RPC commands |
| digidollar_rpc_collateral.py | Collateral RPC commands |
| digidollar_rpc_dca.py | DCA RPC commands |
| digidollar_rpc_deployment.py | Deployment status RPC |
| digidollar_rpc_display_bugs.py | RPC display bug fixes |
| digidollar_rpc_position_fields.py | Position field validation |
| digidollar_rpc_estimate.py | Collateral estimation RPC |
| digidollar_rpc_gating.py | RPC activation gating |
| digidollar_rpc_oracle.py | Oracle RPC commands |
| digidollar_rpc_protection.py | Protection status RPC |
| digidollar_rpc_redemption.py | Redemption RPC commands |
| digidollar_send.py | DD send workflow |
| digidollar_stress.py | Stress/load testing |
| digidollar_transaction_fees.py | Transaction fee handling |
| digidollar_transactions.py | Transaction handling |
| digidollar_transfer.py | Transfer operations |
| digidollar_tx_amounts_debug.py | Transaction amount debugging |
| digidollar_validate_address.py | DD address validation |
| digidollar_wallet.py | Wallet integration |
| digidollar_wallet_restore_redeem.py | Wallet restore + redeem |
| digidollar_watchonly_rescan.py | Watch-only wallet rescan |
| wallet_digidollar_backup.py | Wallet backup |
| wallet_digidollar_descriptors.py | Descriptor wallet compat |
| wallet_digidollar_encryption.py | Wallet encryption impact |
| wallet_digidollar_persistence_restart.py | Position recovery on restart |
| wallet_digidollar_rescan.py | Wallet rescan |
| wallet_digidollar_restore.py | Wallet restore testing |
| feature_oracle_p2p.py | Oracle P2P networking |
| digidollar_wave20_oracle_p2p.py | Oracle P2P pending-bundle flow |
# Whole DD/oracle/MuSig2/Red Hornet unit suite
./src/test/test_digibyte --list_content | grep -Ei 'digidollar|oracle|musig|^rh' | xargs -n1 ./src/test/test_digibyte --run_test=
# Single suite
./src/test/test_digibyte --run_test=digidollar_validation_tests
# Functional smoke test
test/functional/digidollar_basic.py| Specified Behavior | Code Reality | Reference |
|---|---|---|
| MAST has exactly 2 leaves (Normal + ERR) | CreateCollateralP2TR adds only CreateNormalRedemptionPath and CreateERRPath at depth 1 |
src/digidollar/scripts.cpp:117-177 |
CreateEmergencyPath removed |
Function deleted; explicit comment at line 85 records the removal | src/digidollar/scripts.cpp:85-86 |
| Both MAST leaves require CLTV expiry | Both scripts begin with <lockHeight> OP_CHECKLOCKTIMEVERIFY OP_DROP |
src/digidollar/scripts.cpp:73-99 |
| ERR increases DD burn; collateral return is full | GetRequiredDDBurn uses __int128 ceiling math; GetAdjustedRedemption is deprecated identity passthrough |
src/consensus/err.cpp:100-149 |
| Mint blocked while ERR active or oracle missing | EmergencyRedemptionRatio::ShouldBlockMinting fails closed on missing oracle |
src/consensus/err.cpp:417-469 |
| Partial redemption rejected | bad-collateral-release-partial-burn raised when ddBurned < requiredDDBurn |
src/digidollar/validation.cpp:2529-2536 |
| Non-DD spends of registered collateral rejected | bad-collateral-spend-missing-dd-burn in ValidateDigiDollarTransaction |
src/digidollar/validation.cpp:2631-2655 |
| Confirmed-only DD chaining | DD inputs at MEMPOOL_HEIGHT rejected as dd-input-amounts-unknown |
src/digidollar/validation.cpp:1811, 1955 |
| Lock tier canonical window on mint | bad-mint-lock-tier for tier outside 0–9; bad-mint-lock-tier-duration if remaining lock blocks are outside [canonical_blocks, canonical_blocks + 100]; bad-mint-lock-period if not in collateralRatios |
src/digidollar/validation.cpp:1342-1397, 1603-1611 |
| Oracle price required | bad-oracle-price rejection in mint validation when ctx.oraclePriceMicroUSD <= 0 |
src/digidollar/validation.cpp:1147-1153 |
| Pre-mutation volatility freeze | WouldCandidateFreezeMinting checked before RecordPrice; rejected mints can't poison history |
src/digidollar/validation.cpp:2688-2689, 2753 |
| Mainnet/testnet validator parity | Mainnet short-circuit removed; both networks honor identical V1 oracle-bundle gates | src/validation.cpp:185-283 |
OP_CHECKPRICE reserved/disabled |
Interpreter consumes one operand and pushes false; no live or mock price lookup | src/script/interpreter.cpp:708-735 |
| DD amount in cents (100 = $1) | Stored amounts in cents; oracle prices in micro-USD; conversion priceMillicents = priceMicroUSD / 10 for health math |
src/consensus/digidollar.h:70-73, src/consensus/dca.cpp:239-243 |
| Transaction types fixed at 4 | DD_TX_NONE=0, DD_TX_MINT=1, DD_TX_TRANSFER=2, DD_TX_REDEEM=3, DD_TX_MAX=4 |
src/primitives/transaction.h:38-44 |
| Redemption paths fixed at 2 | RedemptionPath { PATH_NORMAL=0, PATH_ERR=1 } |
src/digidollar/digidollar.h:70-73 |
| DD supply alert (not cap) | AlertThresholds::ALERT_DD_SUPPLY = 100M DD is monitoring threshold; MAX_DIGIDOLLAR is per-output bound |
src/digidollar/health.h:83, src/digidollar/digidollar.h:19 |
Document last validated 2026-06-25 against the source on feature/digidollar-v1. RPC commands: 35 registered total (18 registered in RegisterDigiDollarRPCCommands at src/rpc/digidollar.cpp, 17 in GetWalletRPCCommands at src/wallet/rpc/wallet.cpp, including sendmanydigidollar, listdigidollarunspent, listdigidollarutxos, exportoracleprivkey, and importoracleprivkey). DD price/position/transaction/oracle-operation RPCs are activation-gated; getdigidollardeploymentinfo and wallet-local oracle key-management RPCs (createoraclekey, exportoracleprivkey, importoracleprivkey) remain usable before activation. Oracle aggregation: 6 active exchange fetchers via libcurl (Binance, KuCoin, Gate.io, HTX, Crypto.com, CoinGecko). MockOracleManager is a regtest helper only. DigiDollar transfers/redeems are confirmed-only (commit 0b4959f563). sendoracleprice RPC was removed as a fake-price-injection vulnerability and submitoracleprice does not exist anywhere in the source tree. Pre-V1 oracle bundle versions are rejected at block validation once DigiDollar is active (commit f2bb0a19a4).