Skip to content

Test/longest chain double spend v2#386

Open
sugh01 wants to merge 9 commits intobsv-blockchain:mainfrom
sugh01:test/longest-chain-double-spend-v2
Open

Test/longest chain double spend v2#386
sugh01 wants to merge 9 commits intobsv-blockchain:mainfrom
sugh01:test/longest-chain-double-spend-v2

Conversation

@sugh01
Copy link
Collaborator

@sugh01 sugh01 commented Jan 13, 2026

No description provided.

sugh01 and others added 9 commits November 10, 2025 16:45
…ing reorg

During blockchain reorganizations in SubtreeProcessor.reorgBlocks(), conflicting
transactions that lost to newly-mined transactions were being removed from block
assembly but never marked as NOT on longest chain in the UTXO store, leaving them
with UnminedSince = 0.

Changes:
- Modified moveForwardBlock() to return losingTxHashesMap alongside transactionMap
- Updated reorgBlocks() with two-pass processing:
  * Pass 1: Collect winning and losing transactions from all moveForward blocks
  * Pass 2: Filter and mark transactions appropriately, removing losers from winners
- Fixed test scenario in testLongestChainWithDoubleSpendTransaction to ensure
  parentTx2 is mined in both forks, making tx3 valid on both chains
- Removed impossible test scenario where tx3 would be mined after tx2 already
  consumed the same UTXO

This ensures proper UTXO state tracking during chain reorganizations and fixes
failures in the longest_chain test suite, particularly on Aerospike backend.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <[email protected]>
fix: Mark losing conflicting transactions as NOT on longest chain during reorg
@github-actions
Copy link
Contributor

github-actions bot commented Jan 13, 2026

🤖 Claude Code Review

Status: Complete

Review Summary:

This PR implements fixes for tracking losing conflicting transactions during blockchain reorgs and adds comprehensive test coverage.

Issues Found: None

Key Changes:

  1. reorgBlocks() two-pass logic: Correctly identifies and marks losing conflicting transactions as NOT on longest chain
  2. moveForwardBlock() signature: Now returns both transactionMap and losingTxHashesMap
  3. Test fixes: Corrected assertion message in VerifyNotOnLongestChainInUtxoStore()
  4. Test enhancements: Increased timeouts, added new test scenarios for fork handling
  5. Early optimization: WaitForBlockStateChange() now returns early if block is already current

The approach is sound - the two-pass processing ensures transactions that win in ANY moveForward block are properly excluded from the losing list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants