Skip to content

Fix array bounds bug in multi-algo block index tracking#369

Merged
JaredTate merged 1 commit intofeature/digidollar-v1from
copilot/analyze-performance-issues
Feb 14, 2026
Merged

Fix array bounds bug in multi-algo block index tracking#369
JaredTate merged 1 commit intofeature/digidollar-v1from
copilot/analyze-performance-issues

Conversation

Copy link

Copilot AI commented Feb 3, 2026

GetAlgo() can return ALGO_UNKNOWN (-1) for blocks with unrecognized version bits. This value was used directly as an array index for lastAlgoBlocks[], causing undefined behavior.

Changes

  • src/node/blockstorage.cpp: Add bounds check before lastAlgoBlocks[algo] assignment in AddToBlockIndex() and LoadBlockIndexDB()
  • src/pow.cpp: Add bounds check in GetLastBlockIndexForAlgoFast(), fall back to slow iteration if algo is out of bounds

Pattern

The CBlockIndex constructor in chain.cpp already had correct bounds checking:

int rawAlgo = block.GetAlgo();
if (rawAlgo >= 0 && rawAlgo < NUM_ALGOS_IMPL) {
    lastAlgoBlocks[rawAlgo] = this;
}

The fixed code in blockstorage.cpp now follows the same pattern:

int algo = pindexNew->GetAlgo();
if (algo >= 0 && algo < NUM_ALGOS_IMPL) {
    pindexNew->lastAlgoBlocks[algo] = pindexNew;
}
Original prompt You are an expert software quality engineer with extensive experience in: - C++ systems programming and debugging - Bitcoin Core and cryptocurrency node development - Distributed systems and consensus protocols - Test-driven development and code review - Performance analysis and optimization - Cross-platform compatibility (Linux, macOS, Windows)

You have a track record of finding subtle bugs that evade traditional testing—the kind of issues that manifest under specific conditions, at scale, or after extended operation. You understand that in cryptocurrency systems, even non-security bugs can have severe operational consequences: chain stalls, sync failures, wallet corruption, or degraded user experience.

Your approach is methodical and thorough. You don't just find bugs—you understand their root causes and can articulate clear reproduction steps and fixes.

<repository_context>
You are analyzing the DigiByte Core repository (https://github.com/DigiByte-Core/digibyte).

Key technical characteristics:

  • Derived from Bitcoin Core with ongoing upstream merges
  • C++17 codebase with extensive use of templates and RAII
  • Multi-threaded architecture with complex synchronization
  • Platform: Linux, macOS, Windows, ARM support
  • Build system: Autotools and CMake
  • Dependencies: Boost, libevent, LevelDB, BerkeleyDB, OpenSSL/libsecp256k1
  • Test framework: Boost.Test (unit), Python (functional)

DigiByte-specific components:

  • Multi-algorithm mining (SHA256, Scrypt, Groestl, Skein, Qubit)
  • DigiShield/MultiShield difficulty adjustment
  • Faster block times (15 seconds vs Bitcoin's 10 minutes)
  • DigiAssets tokenization layer
  • Digi-ID authentication

The faster block times and multi-algorithm nature mean certain classes of bugs (race conditions, timing issues) may be more likely to manifest than in Bitcoin Core.
</repository_context>

Perform a comprehensive bug analysis of the provided code. Identify defects that could cause: - Incorrect program behavior - Crashes or undefined behavior - Data corruption or loss - Performance degradation - Synchronization failures - Compatibility issues

Focus on finding REAL bugs with clear reproduction paths, not theoretical issues or style preferences. Each bug report should be actionable by a developer.

<bug_categories>
Systematically analyze for these bug classes:

Code that does not correctly implement its intended behavior - Off-by-one errors in loops and array access - Incorrect operator precedence - Wrong comparison operators (< vs <=, == vs !=) - Inverted conditionals - Missing break statements - Incorrect state machine transitions - Algorithmic errors in calculations - Copy-paste errors with unreplaced variables - Incorrect fee calculations - Wrong block height comparisons - Consensus rule implementation errors - Reward calculation mistakes - Difficulty calculation bugs Edge cases not properly handled - Empty container handling - Zero/null value edge cases - Maximum value overflow - Minimum value underflow - First/last element handling - Single-element collections - Boundary crossing in ranges - Genesis block edge cases - Block 0 special handling - MAX_MONEY boundary - Timestamp boundary conditions - Difficulty adjustment at activation heights Multi-threading and synchronization issues - Race conditions (TOCTOU) - Deadlocks and priority inversion - Missing or incorrect lock acquisition - Lock ordering violations - Condition variable misuse - Atomic operation errors - Thread-unsafe initialization - Stale data reads - cs_main lock violations - Mempool/wallet synchronization - Block validation threading - Peer connection races - Signal handler issues Memory, file handle, and resource handling errors - Memory leaks - File descriptor leaks - Double-free errors - Use-after-free - Uninitialized variables - Resource exhaustion - Missing cleanup in error paths - RAII violations Improper handling of error conditions - Unchecked return values - Swallowed exceptions - Incorrect error propagation - Missing error recovery - Error message information leaks - Assertion failures in production - Exception safety violations - Validation state handling - Block/transaction rejection handling - Network error recovery - Wallet error handling - RPC error responses Type-related errors and con...

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Analyze performance issues in DigiByte Core Fix array bounds bug in multi-algo block index tracking Feb 3, 2026
Copilot AI requested a review from gto90 February 3, 2026 02:14
@JaredTate JaredTate force-pushed the feature/digidollar-v1 branch 18 times, most recently from 5a12092 to 28f0165 Compare February 10, 2026 03:29
@DigiSwarm
Copy link

Reviewed and merged manually into feature/digidollar-v1 (commit e57a353cc8).

What was applied (DGB-BUG-011):

All three array bounds fixes:

  1. blockstorage.cpp AddToBlockIndex() — Check algo >= 0 && algo < NUM_ALGOS_IMPL before lastAlgoBlocks[algo] = pindexNew
  2. blockstorage.cpp LoadBlockIndex() — Same bounds check for the block loading path
  3. pow.cpp GetLastBlockIndexForAlgoFast() — Falls back to slow GetLastBlockIndexForAlgo() when algo is out of bounds

GetAlgo() can return ALGO_UNKNOWN (-1) for unrecognized block versions. Using -1 as an array index is undefined behavior and could crash the node during initial block download or reorg processing.

What was NOT applied:

  • ADDITIONAL_BUGS_FOUND.md report — docs-only, not needed on the branch

Verification:

  • All 1740 unit tests pass ✅
  • Full build clean ✅

Closing as manually merged. This is core DigiByte (not DD-specific) and a legit defensive fix.

@DigiSwarm DigiSwarm closed this Feb 13, 2026
@DigiSwarm DigiSwarm reopened this Feb 13, 2026
JaredTate added a commit that referenced this pull request Feb 13, 2026
…king (DGB-BUG-011)

Applied array bounds fixes from copilot/fix-openssl-build-error for GetAlgo() returning
ALGO_UNKNOWN (-1) used as array index in blockstorage.cpp (2 sites) and pow.cpp.
Build system OpenSSL changes from PR branch were not applicable.

Co-authored-by: Copilot <copilot@users.noreply.github.com>
@gto90 gto90 added the bug Something isn't working label Feb 14, 2026
…ploitable - defense verified

Attempted 6 attack vectors for same-block DD transaction chains:
  a) Same-block mint+redeem: BLOCKED by CLTV timelock (ctx.nHeight < nLockTime)
  b) Zero lock period mint: BLOCKED by lockPeriod <= 0 check
  c) Same-block transfer via txLookup: WORKS correctly (block on disk, valid chain)
  d) Inflated DD via same-block: BLOCKED by conservation (inputDD != outputDD)
  e) Negative lock period mint: BLOCKED by lockPeriod <= 0 and tier mismatch
  f) Exact lockHeight boundary: CORRECT >= semantics (lockHeight passes, lockHeight-1 rejected)

Key defenses verified:
- CLTV in Tapscript enforced by CheckInputScripts (minimum 1 block lock)
- NUMS internal key prevents key-path bypass of CLTV
- lockPeriod > 0 enforced in ValidateMintTransaction
- ValidateNormalRedemptionConditions checks ctx.nHeight >= tx.nLockTime
- Standard UTXO model prevents double-spending within blocks
- txLookup correctly reads current block from disk for same-block chains
- Conservation checks work independently per transaction

All 1784 unit tests pass.
@JaredTate JaredTate force-pushed the copilot/analyze-performance-issues branch from e620d1a to e2d084a Compare February 14, 2026 03:53
@JaredTate JaredTate merged commit e2d084a into feature/digidollar-v1 Feb 14, 2026
@gto90 gto90 deleted the copilot/analyze-performance-issues branch February 14, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants