Repository navigation
Merge v9.26.6 into develop - #452
Merged
Merged
Conversation
…g noise What was wrong: live nodes crashed (a null read during block connect on the message-handler thread), live nodes froze (two threads taking the same two locks in opposite order), a decimal-point typo could send or redeem 100 times the intended DigiDollar amount, and three log lines were written for every transaction on every node regardless of settings. What changed, one line per item: - Crash: during a reorg the mempool's index update was run on entries that belonged to the Dandelion stempool, re-linking stempool entries into the mempool's indexes and cross-wiring both pools; the next block connect walked a broken structure. Each pool now only updates its own entries. - Crash hardening: the stempool's self-check was hard-wired off; it now follows -checkmempool (on in tests, off on mainnet by default), and the stempool lock is asserted at block connect and disconnect. - Crash: the wallet's fallback broadcast path (used when no Dandelion peer is available) changed the stempool and ran mempool acceptance with no locks; it now takes cs_main and the stempool lock in the same order as every other stempool writer. - Crash: on UTXO-snapshot activation the stempool stayed on the old chainstate, an inconsistent lock order; it now moves with the mempool. - Deadlock: the once-a-second embargo check held the Dandelion embargo lock while taking the chain lock, the opposite order from the network thread. The embargo lock is now a true leaf lock: the map is copied under it and nothing else, and every pool lookup and the mempool move happen unlocked. - Deadlock: when a peer disconnected with Dandelion transactions still queued, FinalizeNode held that peer's lock while taking global locks in the opposite order from the stem push path; it now copies the list out first. - Deadlock: the inventory handler asked "is this a Dandelion peer" while holding that peer's lock, again in the opposite order, on every connection; it now asks first. - Money at risk: senddigidollar and redeemdigidollar reject any amount above $100,000 before any coin selection or transaction construction, as sendmanydigidollar already did. The explicit amount-unit contract comes in a later wave. - Disk fills up: the three unconditional per-transaction log lines are gone. - Baseline repair: a unit test looked for deploy_testnet_oracle.sh at the repo root after the scripts cleanup moved it to contrib/; it looks there too. Why this fix: each repair is the smallest change that removes the established defect, keeps every existing lock order that other code depends on, and leaves block validity untouched (relay pools, locks, RPC input checks, logging and tests only). The original crash report (GitHub #445) had no stack trace, so it stays classified "investigated, cause unconfirmed"; the repaired reorg defect matches its thread, function, fault address and workload. How it was tested: every fix has a regression test that fails before and passes after (p2p_dandelion_lockorder.py and four dandelion_tests cases; dandelion_stempool_reorg_tests, p2p_dandelion_stempool_reorg.py, p2p_dandelion_stempool_race.py, wallet_dandelion_fallback_lock.py; digidollar_rpc_amount_cap.py, digidollar_isstandardtx_no_log.py). On this tree: full unit suite passes; Qt suite on a real display passes with no skips; extended functional suite 374 of 374; the Dandelion tests pass on a DEBUG_LOCKORDER build, an address-sanitizer build and a thread-sanitizer build with zero sanitizer reports (the race test asserts that embargo expiries ran while blocks were being connected); every fuzz target ran over a generated corpus with no findings; the Qt wallet minted, sent and redeemed DigiDollar on regtest with screenshots of every DigiDollar tab. Claude-Session: https://claude.ai/code/session_01KmXsuD4LyZWpsaytcei9ma
… fields and tests
What was wrong: the release needs every consensus change (the mint-only
volatility rule, open-vault health accounting, canonical vault identity) to
switch on together at one agreed block height, but the code had no such
height, no shared way to ask "do the Thaw Day rules apply to this block", no
way to schedule it on regtest for boundary tests, and no way to see its
status.
What changed, one line per item:
- Consensus::Params gains nDDThawDayHeight; the maximum int value means "not
scheduled". Mainnet, testnet26, signet and regtest all set it explicitly
to "not scheduled" with a comment saying who sets the real value and when
(mainnet: the release owner at tagging; testnet: when the September 21
rehearsal candidate is built).
- Two pure functions, DigiDollar::IsThawDayScheduled and
DigiDollar::IsThawDayActive(params, candidate_height): active only when
scheduled, when the DigiDollar deployment is enabled and active at that
height, and when the height is at or past the Thaw Day height. Callers pass
the height of the block being checked, the intended mining height, or the
next block height; the sentinel is only compared, never added to.
- Regtest-only startup option -ddthawdayheight=<n>, strictly parsed, a clean
startup error on any public network.
- getdigidollardeploymentinfo gains a thaw_day object (scheduled, height when
scheduled, tip_height, next_block_height, active_at_tip,
active_next_block), computed only through the shared predicate.
- Tests: predicate edge cases; a 40-row activation table over every
combination of scheduling and DigiDollar activation; the "which height each
caller uses" contract; the network-configuration matrix; a four-node
functional test of H-1/H/H+1 status, invalidateblock/reconsiderblock, a
competing branch, restarts and knob rejection; and an extension of the
deployment RPC test. Deliberate mutations of the predicate and of the RPC
were shown to fail these tests.
Why this fix: one field and one pure predicate keyed on the candidate block's
own height mean a block's rule set never depends on where the node's tip is,
so reindex, reorg and replay agree, and every later rule change keys off the
same height. No production rule calls the predicate yet; block validity is
unchanged in this wave.
How it was tested: full unit suite, Qt suite on a real display, extended
functional suite and every fuzz target on the merged tree (see
v9.26.6/reviews/wave-2/); per-agent evidence including before/after logs and
mutation runs in v9.26.6/reviews/wave-2/agent-{a,b,c}/.
Claude-Session: https://claude.ai/code/session_01KmXsuD4LyZWpsaytcei9ma
… at Thaw Day What was wrong: DigiDollar validation used local volatility state and health accounting that could differ after restart. A separate oracle aggregation path discarded the parity of supplied compressed public keys. What changed: - C1: use one mint-only rule at the shared Thaw Day height. Compare the block's committed quote with the lower median of the nearest 15 eligible ancestor prices at depths 240 through 1440. Keep legacy checks below that height. Use the same candidate state for mining, wallets and RPC status. - C2: keep open-vault principal, collateral and vault count in chainstate, with the UTXO database writes and undo. Use that state for health after Thaw Day. Keep circulating token supply separate and report it as unavailable when historical amounts cannot be recovered reliably. - C2: reconstruct and check required state during startup, recover interrupted writes, support cancellation, and revalidate affected history on late upgrades. Preserve pre-activation validation and rollback behavior. - C2: use verified creating outputs for vault accounting and keep block transaction order. Apply the resulting emergency requirements to wallet selection, signed fees, mining and Qt redemption status. - C3: aggregate the supplied full compressed keys through one shared path. Preserve active production aggregation and network separation. - Tests: add activation, accounting, restart, migration, database interruption, reorg, lock-order, mining, oracle and Qt coverage. Correct generic pruning fixtures while keeping their original assertions and add retention coverage. Why this fix: all changed block-validity rules use the same candidate height. The post-activation health calculation comes from the accepted chainstate and survives restart. Public activation heights remain disabled until scheduled. How it was tested: clean make -j8 build; 3,517 unit cases including three warning cases; 127 Qt cases without failures or skips. The broad functional run passed 356 entries and skipped 15; four startup port failures passed in isolated reruns on unchanged source, giving 360 distinct passing entries. An actual Qt wallet minted, sent, completed an emergency redemption, and restored the same accounting and wallet balance after restart. Additional evidence: 37 selected lock-order cases and ten sanitizer input collections passed on an earlier build with unchanged relevant tracked compilation inputs. The previous-binary compatibility check also passed; only a Qt test changed afterward. Independent source and verification reviews cover the recorded candidate. Failed attempts remain in private evidence. Limits: every node reindex is deferred by the owner, excluding 21 registered variants. Fifteen functional entries lacked required host, tracing, signet or historical-release prerequisites. External unit script assets were unavailable; two partial mint setups produced the other warnings. Public activation and the seven-day testnet run are pending. This commit records local code work, not release or network approval.
…e sent, and amounts say what they mean What was wrong: people could not get their money out. Redeeming a vault failed with "owner key not found" when the wallet's note of the key had gone missing, even though the key was still in the wallet. A mint sent its transaction first and saved its record afterwards, so a node that stopped in between left coins locked in a vault with nothing in the wallet to redeem it, and the writes that saved it could not even report failure. A mint that could no longer be mined kept its coins reserved for ever and showed as pending. A redemption guessed its own size, picked its fee coins once, and gave up if they fell short, which is what happens to a wallet whose coins are in many small pieces. And the commands read "10000" as ten thousand cents but "10000.00" as ten thousand dollars, so a habitual decimal point asked for a hundred times the intended amount and the node did it without a word. What changed, one line per issue: - Issue 8: a mint writes its owner key and its record to the wallet before it sends the transaction, from the console and from the wallet window, and every write reports whether it worked. If a write fails, nothing is sent. - Issues 1 and 2: redeeming a vault whose key record is missing looks for that key among the wallet's own keys, including the unused ones it keeps ready, and accepts only a key that reproduces the vault's own output on the chain. It never invents a key. Five distinct messages replace one, so a locked wallet, a watch-only wallet and a genuinely missing key can be told apart. - Issue 3: a mint the chain can no longer accept releases the coins it was holding and is reported as an expired mint, while keeping the key and the record so a reorg or a late block brings the vault back. - Issue 6: a redemption measures the transaction its candidate coins would produce and asks the wallet for more until they cover it, instead of guessing a fixed size once. Leftover coins after the fee can no longer follow an address the caller typed in, such as an exchange deposit address. - Issue 11: every command that takes a DigiDollar amount now takes the unit with it, cents or dollars. A whole number with no unit still means cents, so nothing that worked before stops working. A decimal with no unit is refused with a message naming the fix. - Issue 30: which fee settings DigiDollar actually uses is now written down. No behaviour changed. - Issues 5 and 7: on a locked wallet the Redeem button stays enabled and asks for the passphrase, instead of being greyed out so the prompt never appeared. A wallet with no private keys is still refused, and says why. - Issue 4: investigated, cause unconfirmed. The repaired fee path explains the report well, but two other faults fixed here look identical from outside. The five things the reporter would need to send are recorded. - Two faults found during Wave 1 are closed here: the DigiDollar wallet locks are now visible to the lock checker, and the wallet no longer asks the chain a question while holding a wallet lock, which is how a node ends up stuck. Coin selection can no longer add past the largest number a total can hold. Why this fix: every one of these was a way for a person to lose access to money they still owned, or to move more of it than they meant to. The order of a save and a send is the difference between a recoverable vault and a lost one. How it was tested: eight new node tests and a dozen new unit and wallet-window tests, each shown failing on the code before the fix with the exact error from the user reports. The whole unit binary passes with no errors, the wallet-window suite passes after a clean rebuild, and the node suite runs in full. The lock work was proved on a build with lock checking turned on: before the fix four separate routes stopped a node and named the exact lock and line, and after it none does. Evidence in the private review folder for this release. Claude-Session: https://claude.ai/code/session_01KmXsuD4LyZWpsaytcei9ma
…ge can never go to a lost address What was wrong: the wallet showed a mint as money sent away and then received back, because the code that turns a transaction into rows handled redemptions and transfers but not mints. The same code folded the fee into the first row, which on a mint is the collateral, so the wallet claimed more DigiByte was locked than really was. One column held DigiByte figures on some rows and dollar figures on others, so it could not be sorted, added up, or exported into a spreadsheet. The details window had no DigiDollar knowledge at all and printed lines reading zero. The DigiDollars a redemption hands back were called "Redemption Change", which says the opposite of what happens, and nothing explained them. And when a builder had nowhere to send leftover DigiByte it made up an address: on a mint it created a key, paid the change to it and threw the key away, which is money gone for good. What changed, one line per issue: - Issue 13: a mint has its own row showing the DigiDollars it created, with the collateral and the fee on their own rows and the fee shown once. The collateral row carries the collateral alone, which is the figure you need when you decide whether to redeem. - Issue 14: DigiByte and DigiDollar amounts have their own columns, each sorting on its own number, each exported under its own heading. The DigiByte column still follows the display unit you picked, and the minimum-amount box no longer hides every DigiDollar row. - Issue 15: the details window reads the DigiDollar facts out of the transaction and shows them: the amount, the collateral locked or returned, the lock period, the block the collateral unlocks at, and the vault. Where a number is genuinely not in the transaction it says so rather than printing a zero, because a zero reads as a real amount. - Issue 16: returned change is called "DigiDollar change returned" and carries one sentence saying where it came from: the wallet spends whole DigiDollar inputs, and if they add up to more than the redemption burns the extra comes back. A vault is always closed in full, never in part. - Issue 17: a mint, a send or a redemption with nowhere safe to send leftover DigiByte now stops with a plain error and produces no transaction, instead of paying it to an address nobody keeps the key for. A mint also refuses a taproot change address, because the network allows a mint only one taproot output holding DigiByte, the locked collateral. Why this fix: a wallet that reports the wrong number teaches people to distrust the right one, and a builder that picks an address for your leftover money is guessing with funds that are not its own. Refusing to build can always be retried; paying to a key nobody keeps cannot be undone. How it was tested: three new wallet-window test classes and ten new unit tests, each shown failing on the code before the fix. The whole unit binary passes with no errors and the wallet-window suite passes 148 with none failed after a clean rebuild of the window code. A wallet was driven by hand on a private chain through mint, send and redeem, with the transaction list, the details windows and an exported file captured at every step. Evidence in the private review folder for this release. Claude-Session: https://claude.ai/code/session_01KmXsuD4LyZWpsaytcei9ma
…ine logs What was wrong: routine DigiDollar logs were noisy, oracle names were unclear, and unsupported wallets could fail late in minting. Integration instructions also described amount handling that Wave 4 has replaced. What changed: keep oracle names as local display metadata; check mint wallet capabilities before confirmation; gate routine logs while retaining errors; and update the operator, wallet, exchange and oracle guides. Apply these changes after Waves 4 and 5 without replacing their persistence, amount or change logic. The exchange guide now requires explicit dollar units for decimal amounts. The two new mint-save success messages use the DigiDollar debug category. Why this fix: users get clearer errors and operators keep useful diagnostics. Names do not change signing or serialization. No activation height, validity rule or wallet ownership decision changes in this wave. How it was tested: the original isolated Wave 6 source passed its recorded unit and functional checks and independent source review. The rebase was compared against both original waves and the completed Waves 4 and 5. Combined clean build, tests and independent review are pending on this private candidate. Original results are not a pass for the combined source. Limits: node reindex remains deferred by the owner. Public activation, network soak, mobile-client checks and final release verification remain pending. This is a local implementation commit, not release approval. Nothing is pushed.
…tory What was wrong: startup repeated oracle work, long reconstruction lacked useful progress, interrupted scans could publish partial cached metrics, and pruning could remove required early files when no height was eligible. What changed: reuse parsed oracle bundles and parameter-bound verification resources; publish completed scans; report progress, cancellation and source errors; retain independent durable accounting checks and recovery. Preserve fixed DigiDollar retention floors during disconnect and an empty pruning range. Count recovery blocks from the height where both required deployments are active. Add cancellation, storage and progress regression coverage. Refresh operator guidance and document the explicit RPC amount-unit compatibility change. Why this fix: startup and recovery report their actual work and preserve the source data needed for validation. Successful legacy rules remain unchanged. No activation height, validity rule, accounting format, oracle key, checkpoint, assumevalid or peer policy changes. No earlier legacy readiness barrier is added. How it was tested: original isolated Wave 7 verification and source review are recorded separately. The rebased combined source passed a fresh configure and make -j8 build. The new progress regression first failed on the old count, reporting six blocks where only three require recovery. The correction and combined full unit, Qt and extended functional checks are pending on this private candidate; earlier results do not certify the combined source. Limits: all node reindex remains deferred by the owner. Known wallet and concurrency follow-ups, real-history verification, public activation, network soak, mobile-client checks and final release review remain open. This local commit is not release approval. Nothing is pushed.
…ulty is unchanged What was wrong: every block header the node held in memory carried an array of eight pointers, one per mining algorithm, recording the last block that used it. It existed so the difficulty rules could find that block without walking back through the chain. It cost 64 bytes for every block header, on a chain with 24 million of them, and two of its eight slots were for algorithms that were never switched on. What changed: the array is gone, along with the lookup that read it. The two places that used it now use the walk that the difficulty rules have always used for everything else. Nothing else changed. The walk itself is byte for byte the code that was already there. Why this fix: on the owner's own synced mainnet node this frees 1.56 GB, which is 14 per cent of everything the node was holding. Startup got 3 to 4 per cent faster rather than slower. Connecting a block costs about two millionths of a second more, which is half a per cent, because the walk goes back an average of 3.8 blocks on mainnet and the difficulty rule that calls it already steps back fifty blocks on every call before it does anything else. How it was tested: the node reports exactly the same difficulty for all five algorithms on both mainnet and the test network, and reaches exactly the same chain tip. The whole public test network chain was replayed from the first block with every signature checked, on this build and on the build without it, and both reached the same recorded block. Before the array was deleted the two lookups were run side by side over every algorithm, every difficulty rule, every era, and the special case for minimum-difficulty blocks, and their answers were written down as plain numbers that the tests still check. Nothing on disk changed: the stored block record never held these pointers. The whole unit binary passes with 3,587 cases, the wallet window tests pass 157 of 157 on a real screen, and the node suite passes 377 of 403 with every failure shown to happen the same way without this change. The memory figure was measured two independent ways that agree within one per cent: reading the record size out of each compiled binary, 208 bytes against 144, and watching what two real nodes actually held while replaying a real chain. Limits: one measurement is not yet explained. On the test network the phase that loads a stored block index takes 22 per cent longer with this build, while the same phase on mainnet got faster. It is real processor work, measured five times with the order reversed. The likely reason is that it sits inside a loop mainnet skips, because off mainnet the node recomputes a hash for every block index entry, but that is not yet proved and it is being investigated. The full mainnet replay from genesis belongs to the final build and has not been run. Claude-Session: https://claude.ai/code/session_01KmXsuD4LyZWpsaytcei9ma
Add agreement checks for running, restarted, newly synced, pruned, and reindexed nodes across Thaw Day. Update the operator documentation and release notes to describe the completed behavior and remaining release gates. Final verification covers the complete candidate, including the consolidated corrections and memory changes. Historical reindex and public testnet checks remain separate release requirements.
…lifetimes Cached coin scans now use the database's serialized key order. Accounting recognizes historical vaults consistently, bounds arithmetic, and applies the planned sync-state rules at the shared Thaw Day height. Wallet keys and mint records survive failed writes and rejected transactions. Redemptions require a real destination. Wallet operations wait for current chain notifications, and the GUI reports amounts and failures accurately. Oracle startup and shutdown preserve object lifetimes. Signing retries send stored public messages, retain unsent messages, and report reached peers. This combines the eight correction and repair commits around Waves 8 and 9. The resulting tracked files match the reviewed release source at 6ab9d865ed. Independent reviews covered accounting, wallet writes, and oracle startup and shutdown. Full unit, functional, and fuzz validation covers the complete candidate with Feather.
Keep frequently used block fields in smaller pooled records. Read saved Merkle roots and nonces from the existing block database through a bounded cache. Keep new header data in memory until a successful database sync. Full 256-bit chainwork, stored formats, and validation rules are preserved. Use buffered database reads with explicit file-handle budgets. Remove the extra block-counting pass, build chain candidates after coins recovery, and skip warning scans that cannot produce a warning. Cover storage errors, cache lifetimes, flush ordering, historical algorithms, chain selection, and descriptor limits. Document the design and measured memory use in RAM_IMPROVE.md. The complete candidate passed 3,718 C++ unit cases, the Qt suite, 391 functional invocations with 17 documented skips, 120 focused sanitizer cases, and all 255 public fuzz targets plus 28 longer fuzz runs. Repeat full verification on the consolidated release commit.
Verify saved token supply against chain data without changing the debt used for health. Preserve accepted legacy metadata, repair matching saved totals, and keep reorg recovery consistent. Configure oracles before callbacks and synchronize shared settings and proposal epochs. Correct mint collateral details and the activation context of exported script tests. Add signed price, extra-burn, restart, reorg, interrupted-write, signing retry, and concurrency regressions. Capture expected storage errors in their tests. Focused RED and GREEN evidence is retained locally; complete candidate verification is recorded separately. Keep the supported fee-file format separate from the application version. Verify learned estimates survive restart and invalid files preserve existing history. Keep the automatic high-fee test independent of restored fee estimates.
Set testnet activation to block 432,100 and mainnet to 24,490,000. Each network uses its one existing height for all Thaw Day rule changes. Keep historical deployment heights and public override refusal unchanged. Pin the exact boundaries in unit tests and check the published schedules through isolated mainnet and testnet RPC nodes. Keep the existing regtest restart and reorg checks. Update operator instructions with estimated dates, upgrade windows, and coordinated postponement steps. The focused tests passed before integration. Complete verification of this combined candidate is recorded separately; public activation is still pending.
…let's script table What was wrong: block and mempool validation below Thaw Day read DigiDollar amounts from the in-memory script metadata registry before reading the chain. The wallet and the transaction builder fill that table, and it is keyed by output script alone, so an owner address that is used again keeps only the last amount. Change from a send returns to the address that held the spent token, so any wallet that has sent DigiDollar has such an address. A mainnet rc1 node holding a wallet that had minted $100 and later held $98 of change at the same address rejected block 23,869,549, the first DigiDollar mint block, with bad-dd-mint-amount while reindexing, marked every later block invalid and stopped following the chain. Nodes without that wallet accepted the block. Block validity depended on local wallet state. What changed: - ExtractDDAmount(script, amount) reads only the script's own data. The registry form takes an explicit allow_registry flag and is test-only. - Mint validation classifies outputs by structure at every height and never registers the reconstructed vault script. - Transfer and redemption input resolution, redemption change accounting, collateral release and vault-spend detection drop their registry fallbacks. Unresolvable data is rejected, which is what every node without a wallet entry already did since v9.26.4. - The remaining registry readers are marked test-only. - Tests: a new unit suite writes wrong amounts into the registry and checks that mint validation, vault detection and the amount reader answer from chain data, including the exact mainnet case. A new functional test mints, pays the mint address again, then reorgs and reindexes with the wallet loaded. Both fail before this change. Existing tests that fed amounts through the registry now serve the creating mint through the transaction lookup, and a redemption whose change amount was never serialized is expected to be rejected below Thaw Day on every node. Why this fix: consensus must be a function of the chain and the block alone. The Thaw Day heights and rules are unchanged. The existing chain is what nodes without the wallet table already accepted, so nothing on it changes. How it was tested: the new unit suite and functional test fail on the unchanged code and pass with it. The DigiDollar unit suites and Qt tests pass. A mainnet node holding the affected wallet accepted block 23,869,549 with this change after reconsiderblock.
…ug category The message was written once for every connected block while the chainstate was not ready, which produced an 8 GB log during one mainnet reindex.
rc2 replaces rc1, which could reject a valid DigiDollar mint block during a reindex on a node holding a DigiDollar wallet. The notes explain the defect, the repair, and how to recover a stuck rc1 node with reconsiderblock, and record the rc2 test results. The wallet image now reads v9.26.6rc2.
The private Thaw Day rehearsal (thawDay.sh, contrib/thawday/, and the guide) runs the same DigiDollar features before and after Thaw Day on an isolated local network with eight wallet nodes and real MuSig2 oracle signing, then reindexes a wallet-holding node and a fresh empty node. Commit it to the release branch with the rest of the v9.26.6rc2 work. Result. Run rc2-rehearsal-09 completed the whole harness with no failed check: final height 5,658, tip 0000073bc7...856c, 143 recorded checks, 0 failures. It crossed Thaw Day at lab height 5,000 and confirmed, before and after it, all ten lock-tier mints, transfers with exact balances, the early, partial and second-spend redemption rejections, whole-vault redemption, the extra burn, block H rule selection, the boundary reorg, the price-edge mint pauses, wallet backup and restore, Bob's reindex with its wallet loaded, and a fresh empty node syncing from scratch to the same block. The guide's execution table records this pass. It is the lab exercise only and does not replace the audit, public testnet activation and observation, the older-binary comparison, or the full mainnet history reindex. Harness fixes made while diagnosing the run (all harness, no product change): - After the mining node restarts, wait for a signed price mined after the restart before treating the candidate quote as ready. - Confirm the re-signed redemption through the ordinary miner; the getblocktemplate diagnostic passes the "digidollar-oracle" rule so it reflects what the miner builds. - Send the extra-burn control payment from Alice and keep it out of the DigiDollar ledger. - Below Thaw Day, assert exact circulating supply only on a node with the stats index; the chainstate makes it exact on every node at and after Thaw Day. - After a reindex, re-establish the spoke connections to the hub so block relay resumes. - Skip a full redemption that carries no DD change (no metadata, no token output) in the ledger decode. - Do not cap mining during the after-Thaw price edges. Docs. Record the lab pass in the release notes and say reindex, not replay.
Compare the stored timestamps and integer amounts instead of their display text. Keep the selected sort order when the transaction list refreshes. The regression test failed with the old comparison and passes with this change. Checked ascending and descending order on the testnet desktop in light and dark mode after a full clean rebuild. Validation: make check; rendered Qt tests; extended functional suite (with dependency-based skips); all 255 fuzz targets with the local corpus.
Write CSV amounts from the stored integer value using the existing exact amount formatter. Keep currency labels in the wallet and preserve CSV quoting, transaction IDs, and the existing columns. The regression test first failed on the currency suffix. It now exports positive and negative amounts and notes containing quotes and newlines. A fresh desktop testnet export contained 24 numeric amount values. Validation after a full clean build: make check, rendered Qt tests, extended functional suite (395 passed, 17 dependency-based skips), and all 255 fuzz targets with the local corpus.
Use the same computer date format as normal DigiByte history. Sort dates by their timestamps, keep Receive rows together while inserting them, and give longer dates enough space. Validation: failing regressions followed by a clean build, all unit tests, 395 extended functional passes with 17 environment or unsupported-network skips, all 255 fuzz targets, and rendered Qt tests in US, UK, and Australian locales. Desktop checks cover light and dark themes.
Show the first missing or invalid address or amount through the existing Send warning dialog. Focus the field and stop before requesting an unlock or preparing a transaction. Keep all address, amount and dust checks. Validation: failing regression followed by a clean build, all unit and Qt tests, 395 extended functional passes with 17 environment or unsupported-network skips, and all 255 fuzz targets. Desktop checks confirm readable popups in light and dark mode.
Show the node's existing mint status on Overview. Explain missing prices, price protection, missing history, and unavailable health checks in plain English. Give the missing oracle price priority on the Mint page. Keep the mint allowance checks unchanged. Clearing an amount warning does not hide a network pause. Test the legacy freeze, the next-block Thaw Day boundary, an expired quote, and a disconnected view. Validate with a clean build, unit tests, rendered Qt tests, the extended functional suite, all fuzz targets, and desktop checks in light and dark mode.
Use the wallet's existing mint state in Vault, Overview and Transactions. An expired, abandoned or conflicted attempt no longer looks like a redeemed vault or a transaction waiting to confirm. Failed attempts cannot offer a Redeem action or display a made-up health ratio. Keep the wallet records and transaction rules unchanged. Cover expired, abandoned, conflicted, confirmed and local attempts in the Qt regression. Validate with a clean build, all unit and rendered Qt tests, the extended functional suite, all fuzz targets, and desktop checks in both themes.
Do not count a local mint after its last allowed confirmation height. Read the unlock height and tier from the transaction so old attempts without a saved position record are handled too. Keep valid local transactions pending. Keep the existing behavior when the transaction is in the mempool, the wallet height is unknown, or the lock data cannot be read. Do not remove records, release coin locks, or change spendable balances or block validation. Test one-hour and ten-year expiry boundaries, a shorter chain, missing metadata, mempool state, and preservation of wallet records and locks. Validate with all unit tests, sequential minimal and rendered Qt tests, the extended functional suite, all fuzz targets, and the live testnet wallet's balances and vault history.
Use the existing DigiDollar green across its seven pages. Keep text, inputs, selected rows and validation messages readable in both themes. Add bold balance headings and colons to match the main wallet's layout. Remove extra dark-theme frame padding and keep the amount input in its grid so its warning has enough room at the normal window size. Use Qt's styled item delegate for the lock-period and transaction-filter menus so the popup obeys the same colors as its list. Keep numeric values, validation rules and transaction handling unchanged. Regression tests cover input contrast, headings, recent amounts, the redemption unit label, and actual selected-row and popup pixels. Check all seven tabs on the desktop in both themes after a clean rebuild. Validate with all unit, Qt, extended functional and fuzz tests.
Problem: Transaction-page styles also reached text editors inside its export dialog. In the dark theme, a new folder name could become white text on a white background. Change: Name the transaction search and amount fields, then restrict their styles to those fields. Give file-list text editors explicit dark colours. Remove unused rules for the old filter names. Checks: Rebuilt the resources and entered folder names in the ordinary and DigiDollar export dialogs in both Linux themes. Checked that the transaction filters retained their intended appearance.
Problem: The Send DD page could offer confirmation before discovering that the selected coins could not fund the requested transaction. Change: Run the existing transfer planner with the actual selected inputs before showing confirmation or asking for wallet unlock. Show its error immediately. Change the amount hint to say only that the amount is within the send limits. Tests: Exercise Send with an unusable selected input. Require the first dialog to explain the selection error rather than offer confirmation. The Qt suite passed this check.
Problem: A mint funded by many small DGB coins could merge them and then immediately spend the unconfirmed merges. The mint could exceed the existing limit on unconfirmed parent transactions after paying merge fees. Retrying could create more merges. Change: Share the merge helper between RPC and Qt. Merge only enough confirmed coins for the mint, then stop before signing or saving it. Return the merge transaction IDs and tell the user to wait for a block. Save pending merge state in the wallet so retries and restarts do not repeat the work. Keep that internal state out of transaction RPC replies. Keep IDs of accepted batches if a later batch fails. Release a known failed commit when possible and retain its cleanup state if the wallet file cannot be written. Keep existing fees, size and relay limits, and ordinary RPC funding from trusted unconfirmed change. Tests: Reproduced the original rejection before the fix. Both mint functional tests now pass, including repeated requests, restart, confirmation retry, ordinary change and partial batch failure. Qt tests cover confirmation and wallet database failure. A new RPC unit test passes 30 assertions; the wallet unit suite passes 21 cases and 380 assertions. Full final-release verification is recorded separately.
Problem: The About dialog's generic frame name picked up an unrelated balance-panel style. The empty space became too wide and squeezed the text into a narrow column. Link colours were also hard to read. Change: Give the logo spacer its own name and let the text column use the remaining width. Use the dialog's text colour for clickable links. Checks: Rebuilt and inspected the About dialog in both Linux themes. Saved screenshots show the text using the available width and readable links. The Qt suite also passed.
Problem: The rehearsal could mine its last allowed block before the oracle round finished. It then waited for a signed bundle in an already-mined block, which cannot change, and timed out. Change: Keep the last block available while its signing round is still running. Do not use the old round's status to hold an epoch-boundary block. Report an exhausted height limit immediately. Keep all checks on the actual mined bundle, its price, its signers and agreement between nodes. Tests: Reproduced the original timeout with failing tests. Seven isolated regression tests now pass, including the epoch boundary and wrong-price cases. Independent review confirmed the narrow correction. The complete private Thaw Day rehearsal will run again from this commit. No production node or consensus code changes.
Problem: The release notes did not yet describe the final wallet repairs or distinguish the final test results from earlier RC1 and RC2 runs. Change: Add 18 final change groups, each explaining what changed and why, for 125 groups across the release. State the required upgrade height, the coin-merge wait response, known limits and completed test results. Point both standard release-note locations to the combined notes. Update the Thaw Day guide with exact source identities, the successful final run, the earlier script failure and the limits of the rehearsal evidence. Use portable example paths rather than this computer's home directory. Checks: The production source passed 3,759 unit cases, all 11 Qt suites, 405 extended functional cases with 17 skips, all 256 fuzz targets, and the supporting library and utility tests. The private Thaw Day run at 86c8176 passed before/after operations, activation, branch replacement, price limits, wallet recovery, reindex and fresh sync. All nine nodes finished on the same block. Seven script regression tests also passed. Two existing unit fixture warnings and native-platform limits are stated. Local links and whitespace checks pass. No production code changes here.
| assert_equal(node.getrawmempool(), []) | ||
| self.restart_node(0) | ||
| node = self.nodes[0] | ||
| miner = node.get_wallet_rpc(self.default_wallet_name) |
| self.log.info("Failures before any merge preserve existing RPC error codes") | ||
| self.restart_node(0, extra_args=self.extra_args[0] + ["-walletbroadcast=0"]) | ||
| node = self.nodes[0] | ||
| miner = node.get_wallet_rpc(self.default_wallet_name) |
Problem: Mac CI reports 4.6% estimated memory savings and fails a test that requires 5%. The ordinary-map estimate uses a Linux allocator model, so this percentage is not a portable requirement. Change: check that the pool has storage for the inserted entries and uses fewer chunks than entries. Keep both memory estimates as diagnostic output. The allocator, block storage, and consensus code are unchanged. Validation: confirmed the original failure in all three native Mac CI runs. The test now checks pooling directly instead of relying on a platform-specific memory estimate. Native Mac and Linux CI will validate the updated test.
Problem: CodeQL resolves current functional tests to qa/rpc-tests/test_framework instead of test/functional/test_framework. Alert 21320 points directly to the old stop_node method, which lacks an argument supported by the current method. The same old framework also has a different setup_network signature. Change: exclude the retired qa/rpc-tests tree from analysis, alongside the already excluded historical test snapshot. Keep all active functional tests and all query suites enabled. Validation: inspected the alert reference and both method definitions, confirmed current build and CI use test/functional, and parsed the updated YAML. The next CodeQL run must confirm that the false errors are gone.
Shen
added a commit
to Shen/digibyte
that referenced
this pull request
Oct 1, 2026
Integrate DigiByte-Core#452 at 92330d9 with upstream behavior and release documentation taking precedence over the fork. Keep upstream DD-only preflight and detailed errors. Move the fork's concrete DGB funding checks into PlanFundedDigiDollarTransfer and adapt AUTO fallback and provider maintenance callers. Preserve the official selected-input Qt check before confirmation and both private metadata filters. Retain Paymaster operator styles alongside upstream dialogs. Keep official release notes intact and move fork additions into separate integration notes. Record the integration decisions and pending operator verification in the runbook. Validation: ten selected MSVC translation units compiled; seven official rehearsal tests passed; Python syntax, conflict, whitespace, CSS block and upstream-preservation checks passed. No integrated executables were linked. Rebuilt C++/Qt/functional tests remain pending, including the previously observed Qt light-theme regression.
The schedule test starts mainnet and testnet nodes at genesis with networking disabled. On smaller CI disks, they warn that a full chain will not fit, and the test fails when it checks stderr during shutdown. Set a 550 MiB prune budget for these two test nodes. Keep every height, restart, reorg, and startup-warning assertion. Production code and network rules are unchanged. Validation: reproduced the original warning and failure on a 22 GiB temporary filesystem. The full Thaw Day height test passes with the change on that same filesystem and on the normal disk, using the existing release binaries.
The Thaw Day node matrix mines without waiting for its connected followers, then jumps their mock clocks by 60 seconds. An unfinished download can expire during that jump and disconnect a follower. One Mac CI run failed with a disconnected node before the first matrix comparison. Wait for the four connected nodes to reach the mined tip before returning from mine(). Keep the fresh-sync node isolated at genesis. Keep all accounting, pruning, restart, and reorg checks and leave production timeouts unchanged. Validation: an isolated two-node reproduction records an in-flight block, then proves that a 60-second clock jump disconnects the peer with a download-timeout log. Delivering the block before the jump keeps the peer connected. The complete corrected matrix test passes five consecutive runs pinned to one CPU. The original Mac node log was unavailable, so its exact disconnect reason is not independently confirmed.
JaredTate
approved these changes
Oct 6, 2026
JaredTate
left a comment
There was a problem hiding this comment.
ACK. All tests pass, we are ready to merge.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR brings the published v9.26.6 release into
develop. The release contains RC1, RC2 and the final wallet fixes: 125 change groups. It was published on October 1, 2026.Release tag:
v9.26.6at92330d952625e20aef2ee40671a179ef03872ac1. The existing PR branch keeps its RC2 name to preserve this review.Four small CI corrections follow the release tag in this PR:
These four commits change tests and CI configuration only. Published tags, binaries, consensus rules and Thaw Day heights are unchanged. The current PR head is
b84a02b54563a5ea2aa79ecc7ad65057b2fc7c98.Final CI verification (October 2, 2026): All 13 checks pass. Both native Mac jobs and both native Linux jobs completed their builds, unit tests and configured functional suites successfully. CodeQL and quality checks also pass. The targeted local regressions pass, including five single-CPU Thaw Day node comparisons. See the PR run and the branch run.
The published release notes are reproduced below. Later v9.26.7 work is on a separate local branch and is not part of this PR.
DigiByte Core v9.26.6 release notes
Final v9.26.6 release
v9.26.6 includes RC1, RC2 and the final wallet improvements listed below.
The final changes improve minting from wallets with many small coins, explain
send errors, and make the wallet easier to read. They do not change RC2's
consensus rules, oracle requirements or Thaw Day heights. Consensus means
the rules nodes use to agree on valid blocks.
All full-node and mining operators must upgrade before mainnet block
24,490,000, including operators who do not use DigiDollar. Older software
can disagree about valid blocks after that height. Testnet26 activated Thaw
Day at block 432,100. Mainnet activation is controlled by its block
height, not a calendar date.
What to do
A normal upgrade from a working RC2 node does not require a reindex. Keep the
required DigiDollar block history. If the old node stopped on a rejected block,
use the reviewed recovery instructions for that failure.
Installing this release enables its wallet and display improvements immediately.
The scheduled mainnet rule changes begin at block 24,490,000. Minting still
requires an eligible price, sufficient collateral and the other existing checks.
Changes added after RC2
Each entry is one change group. Supporting tests count with their fix.
The version number, wallet version image and release-note edits are not extra fixes.
Minting and sending
Change: Large mints wait for coin-merge transactions to confirm before building the mint, and show the merge transaction IDs. Repeated requests reuse that pending status, including after restart.
Why: Spending several large, unconfirmed merges at once can exceed the existing transaction-chain limit. The wallet must explain the wait without recording a failed mint or starting unnecessary extra merges.
Change: The Qt mint form respects manually locked DGB coins and uses the wallet's normal spendable-coin checks.
Why: Coins the user has locked must stay out of automatic collateral selection.
Change: DigiDollar sends report the actual coin-selection error and check the selected inputs before asking for confirmation.
Why: Change below $1 needs a different amount or input selection. Waiting for confirmations will not fix that error. The $1 output minimum is unchanged.
Change: Oversized DGB sends explain that too many coins are needed and suggest a smaller send or combining small coins first.
Why: The existing transaction-size limit remains necessary, but users need a useful next step.
Change: A DigiDollar send that lacks fee funds shows the estimated fee in DGB.
Why: Users should not have to convert an internal unit or assume every send costs the same amount.
Wallet screens and CSV exports
Change: The Send DigiDollar address field says "Enter a DigiDollar address."
Why: Example text should not look like an address already entered by the user.
Change: DigiDollar paste and address-book icons have readable contrast, and Send and Clear buttons visibly respond to hovering and clicking.
Why: The controls should be recognizable and show when they are being used in both themes.
Change: DigiDollar transaction rows, filters and dropdowns use the DigiDollar green theme consistently.
Why: Mixed background and text colours made the page harder to read.
Change: Main Transactions CSV dates include hours, minutes and seconds without an unnecessary ".000" ending.
Why: Exports should contain clear, consistent dates. Dates shown inside the wallet still follow the computer's regional settings.
Change: The main Transactions page exports DigiDollar amounts as plain decimal numbers without a currency suffix.
Why: Spreadsheets need numeric cells for calculations. This completes the CSV amount repair started in RC2.
Change: Transaction exports suggest a dated filename and make the disabled Save button readable.
Why: Users should have a useful starting filename and understand when saving is unavailable.
Change: New folder names remain readable while editing them in the dark-theme export dialog.
Why: The old styling could put white text on a white background.
Change: The About window gives its text enough room, keeps links readable, and points to the current DigiByte website and source repository.
Why: Users need to find their version and the project's current information without a cramped text column.
RPC, logging and test tools
Change:
listdigidollaraddressesreturns saved labels, transaction counts and last-used times from the wallet.Why: These fields previously returned empty or zero values. An unknown address creation date remains empty rather than being guessed.
Change:
validateaddresshelp and wallet integration instructions direct DigiDollar users tovalidateddaddress.Why: DigiByte and DigiDollar use different address formats. The existing DigiDollar command checks DD, TD and RD addresses without changing ordinary DigiByte address validation.
Change: Expected nonmatching DigiDollar key checks appear only when DigiDollar debug logging is enabled.
Why: Routine wallet scanning should not fill the normal log with misleading messages.
Change: The isolated Thaw Day test builds the current release candidate by default and also accepts an exact commit or tag.
Why: Each rehearsal must exercise the intended candidate rather than an older, fixed commit.
Change: The Thaw Day test leaves its last permitted block available while oracle signatures finish.
Why: A block mined without a price bundle cannot gain one later. The test must wait before mining that block and still check the actual signed bundle afterward.
Integration notes and limits
When a mint needs coin merging,
mintdigidollarcan returnstatus: "consolidation_pending"andconsolidation_txids. This means thatno DigiDollar has been minted yet. Wait for those transactions to confirm,
then retry. Check any accompanying
errorif a later merge failed. The normalsuccessful mint response is unchanged. Coin merges are ordinary DGB
transactions and pay the normal network fees.
listdigidollaraddressescounts distinct DigiDollar transactions known to thewallet.
last_usedis the latest wallet transaction time, in UTC. These fieldsdescribe this wallet's records, not a complete public address history.
This release does not add a general "combine coins" button or DigiDollar
watch-only import support. An oracle pause remains a restriction, not permission
to bypass missing signatures or price checks. A reported Windows-only blank
progress popup was not reproduced in the Linux checks; no speculative change
was made for it.
Final verification
The Linux test runs checked the production source at
a96e6b10b6. The laterrehearsal correction changes only the test script and its regression tests;
the production source is identical.
The functional skips require older binaries, tracing support, special network
interfaces, or unsupported Signet features. Fuzz checks replayed the saved
test inputs; the two targets without saved inputs each generated new inputs
for ten seconds. This was a bounded test run, not an exhaustive search.
Linux visual checks covered all seven DigiDollar tabs, the changed controls
and export dialogs, and the About window in light and dark themes. Native
Windows and macOS checks are still needed on their release packages.
The private rehearsal used commit
86c8176902with the isolated lab patch.All nine nodes finished on the same block at height 5,686. The lab changes
its own network settings and activation height; it does not replace a full
mainnet history reindex or native release-package checks.
The RC1 and RC2 results below describe those earlier candidates. Release
packages must be built from the reviewed final tag and checked before
publication. These source tests do not verify packages that have not yet
been built.
Release package checks
These five packages were built with the same native Guix process used for RC2,
from tag v9.26.6, commit 92330d9.
b84a02b54563a5ea2aa79ecc7ad65057b2fc7c98, after four test and CI corrections. All 13 checks pass. These changes follow the published tag and leave production code and release packages unchanged. See the PR CI results.Windows and Mac packages are unsigned, as in RC2. Mac applications are ZIP files.
The attached
SHA256SUMSfile and the values below identify the five downloads.They are not digitally signed.
RC2 — second release candidate
RC2 adds the changes below to RC1. The code change list covers source through
943243613ce7f75492eae8b4a074859eeb5ba6d1. RC2 is a test release before thefinal v9.26.6 release. The source reference for the published RC2 packages is clarified on the
RC2 release page.
Full-node and mining operators must upgrade before mainnet block
24,490,000. Thaw Day changes the rules used to agree on valid blocks, even
for operators who do not use DigiDollar. Older software can disagree after
activation. Installing the update prepares the node; the block height starts
the scheduled rule changes.
Testnet26 has passed block 432,100 and Thaw Day activated there. RC2 is being
tested on the already-active testnet. Mainnet block 24,490,000 remains the
future production activation height. Calendar estimates in the preserved RC1
notes are historical. The RC2 repair that removes wallet state from DigiDollar
validation also applies when checking blocks below Thaw Day.
What the totals count
Each numbered entry counts one distinct change group. Related repairs are
grouped, and a repair's supporting tests are included with that repair. A
separate test tool or coverage expansion has its own entry. Version labels,
wallet version artwork and edits to these notes are not extra improvements.
These totals are not counts of security vulnerabilities or outside reports.
The categories describe the main purpose of each group, not its severity.
Corrective fixes since RC1
Change: DigiDollar block and mempool validation read amounts and vault identity from chain records independently of the wallet's local script table.
Why: Nodes checking the same transaction must reach the same result regardless of their wallet history.
Change: Header synchronization calculates mining work using the header's actual chain history, including competing branches.
Why: Valid headers must receive the work score required by the existing mining rules.
Change: Incoming block checks verify proof of work before consulting more expensive chain history.
Why: Invalid block submissions should be rejected without unnecessary history lookups.
Change: The DigiByte send form identifies a missing or invalid address, an invalid amount, or an amount too small to send.
Why: Clicking Send should explain the field that needs attention.
Change: DigiDollar transaction dates and amounts, position dates and receive-request dates sort by their underlying values.
Why: Formatted text can put dates and money in the wrong order.
Change: DigiDollar transaction CSV exports write amounts as plain decimal numbers.
Why: Spreadsheets and accounting tools need numeric amounts without a currency suffix.
Change: DigiDollar pages distinguish expired, abandoned and conflicted mint attempts from confirmed vaults and completed redemptions.
Why: An unsuccessful mint must not appear as collateral that was redeemed or can still be redeemed.
Change: The pending DigiDollar balance excludes local mint attempts whose confirmation window has expired.
Why: A mint that cannot confirm on the current chain should not inflate the pending balance.
Change: Redemption commands and estimates use the correct block boundary for the transaction's time lock.
Why: A vault must not be reported as redeemable one block before its redemption can enter the mempool.
Change: Redemption status finds the actual collateral output when an older mint places its outputs in a different order.
Why: An unconfirmed redemption must remain pending until it confirms, including when ordinary change precedes the collateral.
Change: Bounds the recent Dandelion transaction hashes remembered for each peer while keeping exact checks for retained entries.
Why: Long-running peer connections need predictable memory use without weakening transaction relay checks.
Change: Clears Dandelion peer routes before shutdown deletes peer connections.
Why: Shutdown must not leave transaction relay referring to a peer that has already been removed.
Usability and logging improvements since RC1
Change: DigiDollar dates use the computer's regional format, with columns sized to fit.
Why: Dates should follow the user's settings across the wallet.
Change: The DigiDollar overview and mint pages explain missing prices, unavailable checks and restrictions that pause minting.
Why: Users need to know why minting is unavailable and when they can check collateral and fees.
Change: DigiDollar controls, labels, dropdowns and status text follow the wallet's light and dark themes consistently.
Why: Both themes need readable text and recognizable controls.
Change: Repeated redemption requests distinguish a pending redemption, a redeemed vault and another inactive position.
Why: Users need the position's actual state before deciding whether to retry.
Change:
estimatecollateralincludes mint restrictions and their reason alongside its collateral figures.Why: A collateral estimate alone does not mean a mint can currently proceed.
Change: DigiDollar commands distinguish an unavailable next-block oracle quote from unavailable health state.
Why: The error should identify which information is missing.
Change:
senddigidollarhelp explains that the sending wallet needs spendable DGB for the transaction fee.Why: A DigiDollar balance cannot pay a DGB network fee.
Change: Repeated wallet reconciliation messages during synchronization require
-debug=digidollar.Why: Routine progress should not fill the normal log once per block.
Change: Routine compact-block header messages follow the network debug setting.
Why: Normal logs should stay quiet when network debugging is disabled.
Tests, tools and documentation since RC1
Change: Adds a repeatable, isolated Thaw Day rehearsal with build records and checks before, across and after activation.
Why: The same wallet, oracle and chain scenarios need to be repeatable on each candidate.
Change: Expands tests for DigiDollar transfer recovery after a mint is disconnected and later confirms again, including after restart.
Why: Tests must cover normal wallet rebroadcast and balance recovery as well as rejection while the mint is unconfirmed.
Change: Corrects the private security-reporting instructions.
Why: Sensitive reports need to reach the project's designated private channels.
Verification and known limits
The combined source passed 3,755 unit test cases and the rendered Qt test
suite. Of 421 scheduled extended functional-test entries, 404 passed and
17 were skipped. None failed. The skips cover unsupported Signet, unavailable
old release binaries, disabled USDT tracepoints and special test IP addresses.
All 256 fuzz targets passed under AddressSanitizer and UndefinedBehaviorSanitizer,
which check for memory errors and undefined behavior. That run replayed saved
inputs and generated inputs for the target without a saved corpus.
Focused shutdown tests also reproduced the stale-route failure before the fix
and passed under AddressSanitizer after the fix.
The isolated Thaw Day rehearsal built from commit
8ae095ae01b3bbdac13723db346c3970343ec544also passed. It repeated DigiDollarminting, sending, redemption and accounting before and after the exact activation
height. It also passed restart, backup restore, boundary rollback, competing-branch
reorg, full private reindex and empty-directory fresh-sync checks.
These results verify the source build used for testing. They do not certify the
final RC2 release binaries. The release build record must identify the final tag,
binary hashes, build options, completed checks, skips and unresolved findings.
An isolated rehearsal does not establish public-network agreement.
Large DigiByte sends from wallets with many small coins can still require
consolidation. RC2 does not add a guided or automatic consolidation flow for
that reported case. The abandoned-transaction icon has not been replaced.
These notes do not claim that every reported synchronization problem or
external wallet, pool or service issue has been resolved.
The scheduled Thaw Day rules, mining difficulty, block rewards and the $1
minimum DigiDollar output are unchanged from RC1. New minting status messages
report current conditions; a successful mint does not make a later warning
incorrect if those conditions change.
Before installing a published build, back up wallets and configuration, verify
the published checksums, and stop the old program normally. Keep the
required DigiDollar block history. Use the release's reviewed recovery
instructions if an older candidate stopped on a rejected block.
Report ordinary problems with the version, network, block height, expected
result and relevant logs with private information removed. Use
the private security-reporting instructions for sensitive
reports.
RC1 — preserved release notes
The following is the unchanged RC1 note from tag
v9.26.6rc1, commit390f71d5cb74bf519dc0510cc5d8e9c70fefa3cc. Its version, counts, dates,measurements and test results refer to RC1. The RC2 section above gives the
RC2 additions, combined count and verification limits.
DigiByte Core v9.26.6 release notes
Current version: v9.26.6rc1. This is the first release candidate: a test
build before the final release.
Summary
v9.26.6 includes 83 fixes and improvements. It improves wallet recovery,
DigiDollar (DD) sending and redemption, wallet displays, node stability, price
services, memory use and startup. The count also includes tests and documentation.
Node and mining operators must upgrade before mainnet block 24,490,000,
expected around November 1, 2026. This applies even if you only use DGB.
Thaw Day changes consensus: the rules nodes use to agree on valid blocks.
Older software may follow a different chain after the change.
We are testing Thaw Day on testnet first. The final mainnet release follows
the remaining tests and release review.
What you need to do
make sure the node has enough disk space.
and oracle keys too.
published checksums. Stop the old node normally and wait for it to exit first.
RC1 is for the test exercise; use the approved final build for the mainnet rollout.
Do not mistake a long scan for a stopped program.
Thaw Day height. Check any wallet or oracle service you operate.
Full nodes, miners, pools, exchanges, oracle services and wallet backends need
the update. If a provider runs your wallet or exchange service, check its
upgrade notice.
Thaw Day: testnet first, then mainnet
The block number starts the change. The date is an estimate. Faster or
slower block production can move that date. The old rules remain below the
height, including when old blocks are checked again.
Release files and instructions must be available at least 3 days before
testnet activation and 14 days before mainnet activation. Track block
progress during that time.
There is no miner vote or local public-network setting to change Thaw Day.
Postponing it requires a replacement build and coordinated upgrades before
the original height. Editing an announcement cannot postpone installed software.
The testnet exercise will check the switch itself, minting, transfers,
redemptions, oracle prices and agreement between independent nodes. Tests also
cover restarts and chain changes, where recent blocks are replaced by another
branch. Public testnet activation and observation have not yet finished.
To check your node's schedule:
The result shows the height and whether the rules apply to the current tip
or next block. The tip is the latest block on that node's chain.
Upgrade details that matter
Amounts sent by scripts
Four commands accept
amount_unit:senddigidollar,sendmanydigidollar,redeemdigidollarandgetredemptioninfo.The amount filters in
listdigidollarpositionsandlistdigidollaraddressesuse it too.25000, with no unitamount_unit="cents"amount_unit="dollars"Existing scripts using whole cents keep working. Scripts using decimals
must specify dollars. The new unit argument goes last in a positional call.
For example, this requests a $250.00 send:
mintdigidollarstill takes whole cents.The $1 minimum DD output is unchanged. The $100,000 request limit
applies to a single send, each sendmany recipient and a requested redemption.
It does not limit the extra DD the rules may require burning in an emergency
redemption. A redemption still closes the whole vault.
Minting and redemption after Thaw Day
A vault is DGB locked to back newly minted DigiDollars. Oracles provide
the signed DGB prices used by DigiDollar.
At Thaw Day, a new price check replaces the old mint freeze. It uses prices
already recorded in the chain. Transfers and redemptions stop using the old
volatility freeze, but their other requirements still apply.
New mints still need an accepted oracle price, enough collateral and a price
that passes the new check. Large price swings can still pause minting.
Health will count the original DD amounts attached to vaults that remain open.
DD still in circulation is a separate total. Extra DD burned during redemption
can make circulation smaller than the amount attached to open vaults.
This can lower health, keep emergency restrictions in place longer or require
more DD to redeem than the old calculation. Check the current estimate before
confirming. Thaw Day itself creates no tokens and changes no wallet balances.
Wallets and service integrations
receiving and change addresses. The wallet explains missing support early.
Recovery of a missing key record cannot replace a missing private key.
Amount ($DD). Position status can includeexpired_mint,abandoned_mintandconflicted_mint.open_vault_principalfrom circulating supply.selected_health_denominatoridentifies the total used for health.An unavailable total is not zero.
-debug=digidollarif your log tools need routine DD details.Errors and startup progress remain visible without it.
Disk space, startup and recovery
Pruning deletes older block files to save space. A pruned node must still keep
DigiDollar's required history. On mainnet, the retention floor remains
23,627,520. Required blocks and the data used to reverse them must stay.
That history can exceed a small prune target. The target is not a hard disk
limit, and this release does not add a warning for every overrun. Leave room
for growth and check actual disk use.
An ordinary upgrade with the required data does not need a full reindex.
A reindex rebuilds the node's chain databases from block history. A late
upgrade may need extra checks; missing files need restoration or download.
Repeated restarts cannot supply missing data.
If recovery fails, keep the error, logs, wallets and block files. Pause any
automatic restart loop while the cause is checked. After Thaw Day, downgrading
to old software is not a repair. If nodes disagree, compare block hashes at
the same height and coordinate recovery before resuming settlement.
Feather's RAM improvements work on installation. On Unix, the new database
file allowance may expose a low system open-file limit. Check that limit if
startup reports it or reduces connections.
All 83 fixes and improvements
Each entry states the change and the reason. Related repairs are grouped.
These are implemented changes, not a claim that every outside bug report is fixed.
Thaw Day and DigiDollar accounting
New block rules wait for Thaw Day. Status reporting and preparation are available before it.
Change: All new DigiDollar block rules start at one Thaw Day height on each network.
Why: Nodes need to change rules at the same point.
Change: Status shows the scheduled height and whether the current or next block uses the new rules.
Why: Operators can see when their node reaches Thaw Day.
Change: At Thaw Day, new mints use earlier block prices to check for large price swings.
Why: Nodes checking the same chain need the same minting reference.
Change: At Thaw Day, transfers and redemptions stop using the old volatility freeze.
Why: The minting price safeguard should not apply that freeze to these operations.
Change: At Thaw Day, checks use the prices, coins and history belonging to the block being checked.
Why: A restart or a different branch must not change the inputs to that block's checks.
Change: At Thaw Day, health counts the original DD amounts attached to vaults still open.
Why: The system needs a consistent measure of what those vaults back.
Change: Vault totals are saved with chain data and updated as blocks are added or reversed.
Why: Accounting must stay with the right chain through restarts and interrupted saves.
Change: At Thaw Day, validation and recovery give each vault the same transaction-based identity.
Why: Both paths must find the same vault.
Change: Recovery checks saved vault totals and unchecked Thaw Day history, and rebuilds totals from available records when needed.
Why: Late upgrades and interrupted recovery must finish their checks before using the results.
Change: Status separates DD still in circulation from the amounts attached to open vaults.
Why: Burning extra tokens can make these two totals differ.
Change: From Thaw Day, saved circulating-supply totals are checked against chain records and repaired when needed.
Why: An incorrect saved total should not keep carrying forward.
Change: Coin scans use a consistent order and read older accepted vault records consistently.
Why: Recent changes saved at different times must still give the same accounting totals.
Node crashes, hangs and transaction sharing
Dandelion is DigiByte's system for passing transactions between nodes.
Change: Fixes a Dandelion crash when recent blocks are replaced by another chain branch.
Why: Pending transaction records must remain usable during a chain change.
Change: Fixes hangs during transaction-sharing checks, peer disconnections and incoming announcements.
Why: Tasks running at the same time must not get stuck waiting for each other.
Change: Protects shared transaction records when the usual Dandelion relay peer is unavailable.
Why: The fallback send path must handle those records safely too.
Change: After loading a saved chain state, the relay checks pending transactions against that chain.
Why: The relay must follow the chain the node is using.
Change: Fixes conflicting wallet and chain locks during wallet loading, imports, rescans and DigiDollar checks.
Why: Wallet work and chain work must not block each other indefinitely.
Wallet recovery, sending and redemption
Change: Saves a mint's owner key and recovery records before sending the transaction.
Why: The recovery information must be saved before the mint can reach the network.
Change: Rebuilds a missing vault-key record from a matching key already in the wallet.
Why: A missing record should not stop redemption when the correct key still exists.
Change: Refuses to replace a vault's saved owner key with a different key.
Why: Existing vault ownership records must stay intact.
Change: Reports an error if the key for a new DigiDollar address cannot be saved.
Why: The wallet should save the required key before offering the address.
Change: Releases eligible coins reserved by failed, abandoned or expired mints, including after restart.
Why: Unsuccessful mints should not leave spendable DGB reserved forever.
Change: Keeps mint keys and recovery history during cleanup and checks whether the mint can still confirm.
Why: A later confirmation or chain change can make that history necessary again.
Change: Labels expired, abandoned and conflicted mints separately from completed redemptions.
Why: Users need to distinguish a failed mint from a closed vault.
Change: Saves affected transaction states together when abandoning a transaction, and reports failed saves.
Why: An incomplete save must not look successful or release coins incorrectly.
Change: Coordinates simultaneous mint and redemption requests so they do not select the same coins.
Why: One request should not conflict with another before either has finished.
Change: Calculates redemption fees from the transaction being built and selects more fee coins when needed.
Why: Many small DGB coins can make a transaction larger than a fixed estimate.
Change: Explains when small DGB coins cost more in fees than they can contribute.
Why: Users need to know when to combine small coins instead of retrying.
Change: Stops a mint or send if required DGB change has no usable destination.
Why: Leftover funds must not go to an address invented by the builder.
Change: Checks the redemption address and keeps leftover fee money in the sending wallet.
Why: Collateral may go to a chosen external address; fee change should stay in the wallet.
Change: Adds explicit cents or dollars to four amount commands and two filters, with checks for invalid amounts.
Why: A decimal point must not silently change the amount being requested.
Change: Rejects sends, requested redemptions and redemption estimates above $100,000; sendmany keeps its per-recipient cap.
Why: The limit should be checked early and match between estimates and submitted requests.
Change: Prevents large amounts from overflowing wallet totals, displayed collateral ratios and collateral diagnostic calculations.
Why: Overflow can turn a large number into a misleading small or negative number.
Change: Explains missing minting support before confirmation or passphrase prompts.
Why: Users should know their wallet cannot mint before approving the operation.
Change: Eight more DigiDollar wallet commands wait for the wallet to process the latest block.
Why: A newly confirmed balance or transaction should not be missed.
Change: Mint and redemption estimates follow the next block's rules and explain unavailable or restricted conditions.
Why: The estimate should use the same rules as the transaction builder.
Change: Loads compatible saved fee estimates correctly after restart.
Why: The node should keep the useful fee history it already learned.
Desktop wallet displays and buttons
Change: The Redeem button on a locked wallet opens the passphrase prompt.
Why: An owner needs to unlock the wallet to redeem; wallets without private keys still cannot sign.
Change: Shows redemption results and mint refusals in dialogs.
Why: Important messages must be visible even without desktop notifications.
Change: Redemption success messages show the transaction ID and explain that collateral returns after confirmation.
Why: Sending a transaction is different from confirming it.
Change: Shows wallet-created mints with separate rows for DD created, DGB locked and the network fee.
Why: A mint should not look like money sent out and back, or count its fee as collateral.
Change: Shows the DGB fee for a DigiDollar transfer on its own row.
Why: A DGB fee should not disappear into a dollar amount.
Change: Gives DGB and DigiDollar separate columns in transaction tables and CSV exports.
Why: Each currency needs its own value for sorting and exporting.
Change: Uses the correct currency for copied amounts, overview entries and notifications.
Why: A DigiDollar payment should not appear as zero DGB.
Change: Keeps DigiDollar rows visible when the DGB minimum-amount filter is used.
Why: A filter for DGB amounts should not hide dollar transactions.
Change: Restores saved column widths after loading the table and keeps the DD column visible.
Why: Opening the wallet should preserve the layout and show both currencies.
Change: Transaction details show DD amounts, vault information, lock periods and the actual mint collateral, even with reordered outputs.
Why: Users need the actual transaction details instead of misleading zero amounts.
Change: Gives returned DD its own row, labelled “DigiDollar change returned,” with an explanation.
Why: Extra selected DD comes back as change; the vault still closes in full.
Change: Keeps showing the confirmation count after a DigiDollar transaction is confirmed.
Why: The count remains useful after the first few confirmations.
Change: Keeps amounts typed above the send limit and explains why they cannot be sent.
Why: Dropping the final digit could leave a smaller amount than intended.
Change: Allows full DigiDollar addresses to be typed and corrected in the send form.
Why: The old partial-address cutoff could prevent entry of a valid address.
Oracle price services
Change: Fixes an alternate way of combining oracle public keys and keeps cached results tied to the right network settings.
Why: Price verification must use the intended keys and settings.
Change: Starts oracle services before other tasks use them and waits for those tasks before destroying the services.
Why: Background work must not use a service that is not ready or has already stopped.
Change: Retries stored public signing messages when the first send had no connected peer.
Why: Signing should recover when a connection becomes available.
Change: Protects oracle settings and the current signing period from conflicting reads and changes.
Why: Tasks running together must not read settings while another task changes them.
Change: Shows oracle operator names from the selected network's list.
Why: Operators should be easy to recognize without changing their keys or signing rules.
RAM and disk use
The block index is the node's directory of known blocks. A header is a block's short summary.
Change: Removes eight mining lookup pointers from each block's memory record.
Why: Finding earlier blocks through existing links saves permanent RAM.
Change: Reads less-used saved block details from disk and keeps a limited set of recent reads in RAM.
Why: Every block no longer needs those details in memory all the time.
Change: Stores mining work scores in less space, with an exact full-size value when needed.
Why: Saving RAM must not round the score used to choose a chain.
Change: Gives block records space in shared memory chunks and removes unnecessary lookup bookkeeping.
Why: Millions of separate allocations waste space.
Change: Reads needed parts of database files while still checking for incomplete or damaged data.
Why: The node can avoid whole-file memory mappings without dropping those checks.
Change: Reserves open-file capacity for databases before assigning it to network connections.
Why: Database and network work need to share the system's file limit.
Change: Uses a smaller sorted copy of changed coins during accounting scans.
Why: The scan needs a stable copy, but not the previous extra lookup table.
Change: Keeps unsaved headers in RAM and saves block and reversal data before recording their disk locations.
Why: A failed save must not lose pending data or point to an unfinished file write.
Change: Handles missing or unreadable local block headers as storage errors.
Why: A local disk failure must not be blamed on another node's block.
Startup, recovery and mining
Change: Loads the block directory without first reading it only to count its entries.
Why: Startup can begin loading straight away and report the count as it goes.
Change: Reads the last saved block before building lists of possible chain ends.
Why: Startup avoids making a large list it would immediately discard.
Change: Avoids repeated warning calculations for old periods that cannot trigger the warning.
Why: Startup does less work while keeping checks at the boundary and afterward.
Change: Reuses processed oracle price records and avoids repeating completed startup work.
Why: The same records should not need repeated parsing and setup.
Change: Shows reconstruction progress, allows cancellation and keeps incomplete results marked as not ready.
Why: Users need to see progress without mistaking a partial scan for a finished one.
Change: Stops startup with specific recovery information when required history cannot be read.
Why: Repeated restarts cannot replace missing block or reversal data.
Change: Keeps the required DigiDollar history through chain changes, including when no blocks can yet be pruned.
Why: Deleting old files must not remove records still needed to check transactions.
Change: Prepares starting Thaw Day totals when the preceding block is added, rather than for every mining request.
Why: Miners should not repeatedly scan all coins while asking for work.
Logs, tests and instructions
Change: Moves routine DigiDollar, oracle and wallet messages into debug logs and removes three repeated transaction messages.
Why: Normal logs should stay readable while retaining errors and startup progress.
Change: Stops reporting a false key-write error when re-saving the same key during a payment to the same wallet.
Why: A successful payment should not look like a failed save.
Change: Documents the DD fields returned by raw-transaction commands so their result checks also work.
Why: Command help and automated checks need to match the actual output.
Change: Lets source-reading tests find the checkout from a different working directory.
Why: The directory used to launch a test should not cause a false failure.
Change: Corrects test setup for pruning, low-numbered ports, fees, script rules and Thaw Day.
Why: Tests must use the intended network rules and data.
Change: Captures and checks errors from tests that deliberately cause storage failures.
Why: Successful error tests should not print unexplained fatal-error messages.
Change: Adds checks for activation, accounting, extra burns, restarts, chain changes, wallet recovery, oracle retries and memory use.
Why: These tests help catch future changes that break the repairs.
Change: Fixes the supplied configuration example and refreshes command help and manuals.
Why: The example must load correctly and describe the available settings.
Change: Updates node, wallet, exchange and oracle instructions for upgrades, recovery, amounts and accounting.
Why: Operators need instructions for the behavior added in this release.
Change: Adds setup steps for nodes sharing a router and for block-filter services used by lightweight wallets.
Why: Correct ports and service settings help those setups work; this does not claim a mobile-wallet code fix.
Tests completed and work still ahead
These are the recorded results for source commit
d2097819f260f4d82409643fe9f7263cdd7e3eaa:Unit tests check pieces of the program. Functional tests run nodes and check
how they behave. Fuzz tests try many inputs to find unexpected behavior.
A skipped test is not a pass.
One RC1 desktop run settled at about 3.65–3.67 GiB of RAM and started in
108 seconds. These figures describe that workload. They do not predict
startup on every computer or the cost of the future Thaw Day accounting scan.
Before the final mainnet release, complete the full mainnet history replay,
public testnet activation and observation, remaining platform checks and final
release review.
Some reports about mobile wallets, pools and outside services still need those
projects' investigation. Mining difficulty, block rewards and the $1 DD output
minimum are unchanged by this release.
Reporting a problem
Include the version, network, block height and hash, what you expected, what
happened and relevant log lines. Remove private information from logs first.
Report security-sensitive details through the project's private security
channel, rather than a public bug report.