Skip to content

Test fix data race#639

Closed
sugh01 wants to merge 4 commits into
bsv-blockchain:mainfrom
sugh01:test-fix-data-race
Closed

Test fix data race#639
sugh01 wants to merge 4 commits into
bsv-blockchain:mainfrom
sugh01:test-fix-data-race

Conversation

@sugh01

@sugh01 sugh01 commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@github-actions

github-actions Bot commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

Status: Complete


This PR addresses data race issues in SubtreeProcessor tests and adds comprehensive settings propagation tests across blockassembly and blockvalidation packages.

Key changes:

  1. Data race fix in SubtreeProcessor tests: Replaced racy polling patterns (txCount.Load() < n loops and arbitrary time.Sleep calls) with require.Eventually that properly synchronizes through GetCurrentLength(), which establishes happens-before edges via channel communication
  2. New settings tests: Added extensive test coverage for settings propagation in blockassembly and blockvalidation, verifying configuration values flow correctly to service objects

No issues found - changes follow sound concurrency patterns and improve test reliability.

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Comparison Report

Baseline: main (unknown)

Current: PR-639 (a5c02c8)

Summary

  • Regressions: 0
  • Improvements: 0
  • Unchanged: 151
  • Significance level: p < 0.05
All benchmark results (sec/op)
Benchmark Baseline Current Change p-value
_NewBlockFromBytes-4 1.587µ 1.410µ ~ 0.100
SplitSyncedParentMap_SetIfNotExists/256_buckets-4 61.62n 61.49n ~ 0.100
SplitSyncedParentMap_SetIfNotExists/16_buckets-4 61.63n 61.79n ~ 0.800
SplitSyncedParentMap_SetIfNotExists/1_bucket-4 61.64n 61.72n ~ 0.200
SplitSyncedParentMap_ConcurrentSetIfNotExists/256_buckets... 35.16n 40.31n ~ 0.200
SplitSyncedParentMap_ConcurrentSetIfNotExists/16_buckets_... 60.60n 53.66n ~ 0.200
SplitSyncedParentMap_ConcurrentSetIfNotExists/1_bucket_pa... 128.8n 111.3n ~ 0.200
MiningCandidate_Stringify_Short-4 262.9n 261.7n ~ 1.000
MiningCandidate_Stringify_Long-4 1.883µ 1.945µ ~ 0.100
MiningSolution_Stringify-4 955.8n 980.6n ~ 0.700
BlockInfo_MarshalJSON-4 1.809µ 1.820µ ~ 0.400
NewFromBytes-4 141.6n 127.4n ~ 0.100
Mine_EasyDifficulty-4 57.90µ 57.70µ ~ 0.200
Mine_WithAddress-4 4.633µ 4.940µ ~ 0.400
BlockAssembler_AddTx-4 0.02879n 0.02746n ~ 0.400
AddNode-4 10.73 10.83 ~ 0.700
AddNodeWithMap-4 10.86 10.71 ~ 0.700
DirectSubtreeAdd/4_per_subtree-4 62.63n 69.66n ~ 0.200
DirectSubtreeAdd/64_per_subtree-4 30.73n 31.81n ~ 0.200
DirectSubtreeAdd/256_per_subtree-4 29.35n 30.34n ~ 0.100
DirectSubtreeAdd/1024_per_subtree-4 28.35n 29.05n ~ 0.100
DirectSubtreeAdd/2048_per_subtree-4 27.96n 28.58n ~ 0.100
SubtreeProcessorAdd/4_per_subtree-4 309.6n 312.6n ~ 0.200
SubtreeProcessorAdd/64_per_subtree-4 302.7n 311.5n ~ 0.100
SubtreeProcessorAdd/256_per_subtree-4 303.1n 310.9n ~ 0.100
SubtreeProcessorAdd/1024_per_subtree-4 301.2n 310.2n ~ 0.100
SubtreeProcessorAdd/2048_per_subtree-4 300.3n 305.9n ~ 0.100
SubtreeProcessorRotate/4_per_subtree-4 305.6n 328.9n ~ 0.100
SubtreeProcessorRotate/64_per_subtree-4 301.6n 311.7n ~ 0.100
SubtreeProcessorRotate/256_per_subtree-4 304.3n 314.8n ~ 0.100
SubtreeProcessorRotate/1024_per_subtree-4 306.8n 308.7n ~ 0.700
SubtreeNodeAddOnly/4_per_subtree-4 65.35n 66.21n ~ 0.200
SubtreeNodeAddOnly/64_per_subtree-4 39.62n 39.82n ~ 0.400
SubtreeNodeAddOnly/256_per_subtree-4 38.12n 38.30n ~ 0.400
SubtreeNodeAddOnly/1024_per_subtree-4 37.93n 37.14n ~ 0.700
SubtreeCreationOnly/4_per_subtree-4 142.5n 148.8n ~ 0.100
SubtreeCreationOnly/64_per_subtree-4 623.5n 652.3n ~ 0.100
SubtreeCreationOnly/256_per_subtree-4 2.151µ 2.261µ ~ 0.100
SubtreeCreationOnly/1024_per_subtree-4 7.772µ 8.236µ ~ 0.100
SubtreeCreationOnly/2048_per_subtree-4 14.63µ 15.68µ ~ 0.100
SubtreeProcessorOverheadBreakdown/64_per_subtree-4 300.9n 311.4n ~ 0.100
SubtreeProcessorOverheadBreakdown/1024_per_subtree-4 302.2n 309.8n ~ 0.500
ParallelGetAndSetIfNotExists/1k_nodes-4 955.2µ 973.5µ ~ 0.200
ParallelGetAndSetIfNotExists/10k_nodes-4 1.916m 1.974m ~ 0.100
ParallelGetAndSetIfNotExists/50k_nodes-4 8.300m 8.495m ~ 0.100
ParallelGetAndSetIfNotExists/100k_nodes-4 16.27m 16.61m ~ 0.100
SequentialGetAndSetIfNotExists/1k_nodes-4 773.5µ 792.6µ ~ 0.100
SequentialGetAndSetIfNotExists/10k_nodes-4 3.025m 3.227m ~ 0.100
SequentialGetAndSetIfNotExists/50k_nodes-4 10.93m 11.27m ~ 0.100
SequentialGetAndSetIfNotExists/100k_nodes-4 21.00m 21.60m ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/1k_nodes-4 991.1µ 1046.7µ ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/10k_nodes-4 4.665m 4.867m ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/100k_nodes-4 19.30m 19.79m ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/1k_nodes-4 813.7µ 824.9µ ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/10k_nodes-4 6.080m 6.879m ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/100k_nodes-4 40.60m 44.16m ~ 0.100
DiskTxMap_SetIfNotExists-4 3.853µ 3.758µ ~ 1.000
DiskTxMap_SetIfNotExists_Parallel-4 3.569µ 3.640µ ~ 0.100
DiskTxMap_ExistenceOnly-4 334.3n 333.9n ~ 1.000
Queue-4 197.7n 195.0n ~ 0.100
AtomicPointer-4 4.415n 4.646n ~ 0.100
ReorgOptimizations/DedupFilterPipeline/Old/10K-4 962.5µ 872.3µ ~ 0.100
ReorgOptimizations/DedupFilterPipeline/New/10K-4 894.8µ 837.9µ ~ 0.100
ReorgOptimizations/AllMarkFalse/Old/10K-4 130.7µ 112.3µ ~ 0.100
ReorgOptimizations/AllMarkFalse/New/10K-4 63.00µ 62.71µ ~ 0.400
ReorgOptimizations/HashSlicePool/Old/10K-4 81.46µ 66.28µ ~ 0.100
ReorgOptimizations/HashSlicePool/New/10K-4 11.59µ 10.89µ ~ 0.100
ReorgOptimizations/NodeFlags/Old/10K-4 6.780µ 5.607µ ~ 0.100
ReorgOptimizations/NodeFlags/New/10K-4 2.805µ 1.862µ ~ 0.100
ReorgOptimizations/DedupFilterPipeline/Old/100K-4 12.19m 10.27m ~ 0.100
ReorgOptimizations/DedupFilterPipeline/New/100K-4 11.14m 11.03m ~ 0.700
ReorgOptimizations/AllMarkFalse/Old/100K-4 1.300m 1.167m ~ 0.100
ReorgOptimizations/AllMarkFalse/New/100K-4 690.8µ 683.9µ ~ 0.400
ReorgOptimizations/HashSlicePool/Old/100K-4 638.0µ 732.2µ ~ 0.100
ReorgOptimizations/HashSlicePool/New/100K-4 315.5µ 317.9µ ~ 0.400
ReorgOptimizations/NodeFlags/Old/100K-4 59.68µ 57.06µ ~ 0.100
ReorgOptimizations/NodeFlags/New/100K-4 20.92µ 20.25µ ~ 0.100
TxMapSetIfNotExists-4 53.36n 52.88n ~ 0.200
TxMapSetIfNotExistsDuplicate-4 48.52n 37.62n ~ 0.200
ChannelSendReceive-4 645.4n 619.8n ~ 0.100
CalcBlockWork-4 502.5n 497.7n ~ 0.700
CalculateWork-4 679.8n 684.5n ~ 0.100
BuildBlockLocatorString_Helpers/Size_10-4 1.299µ 1.292µ ~ 0.700
BuildBlockLocatorString_Helpers/Size_100-4 15.08µ 14.93µ ~ 1.000
BuildBlockLocatorString_Helpers/Size_1000-4 122.1µ 122.4µ ~ 0.200
CatchupWithHeaderCache-4 104.3m 104.5m ~ 0.700
_BufferPoolAllocation/16KB-4 4.672µ 3.202µ ~ 0.100
_BufferPoolAllocation/32KB-4 7.782µ 8.728µ ~ 0.400
_BufferPoolAllocation/64KB-4 16.03µ 15.36µ ~ 0.100
_BufferPoolAllocation/128KB-4 31.53µ 31.93µ ~ 0.200
_BufferPoolAllocation/512KB-4 115.4µ 105.7µ ~ 0.100
_BufferPoolConcurrent/32KB-4 18.21µ 18.92µ ~ 0.100
_BufferPoolConcurrent/64KB-4 27.57µ 29.80µ ~ 0.100
_BufferPoolConcurrent/512KB-4 139.5µ 145.8µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/16KB-4 626.5µ 632.4µ ~ 1.000
_SubtreeDeserializationWithBufferSizes/32KB-4 620.8µ 611.4µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/64KB-4 616.7µ 609.6µ ~ 0.200
_SubtreeDeserializationWithBufferSizes/128KB-4 611.0µ 609.2µ ~ 0.700
_SubtreeDeserializationWithBufferSizes/512KB-4 638.3µ 620.9µ ~ 0.400
_SubtreeDataDeserializationWithBufferSizes/16KB-4 35.35m 35.65m ~ 0.400
_SubtreeDataDeserializationWithBufferSizes/32KB-4 35.00m 35.44m ~ 0.400
_SubtreeDataDeserializationWithBufferSizes/64KB-4 35.75m 35.48m ~ 0.400
_SubtreeDataDeserializationWithBufferSizes/128KB-4 35.21m 35.49m ~ 0.700
_SubtreeDataDeserializationWithBufferSizes/512KB-4 34.98m 35.35m ~ 0.400
_PooledVsNonPooled/Pooled-4 733.0n 735.9n ~ 0.100
_PooledVsNonPooled/NonPooled-4 6.922µ 7.340µ ~ 0.700
_MemoryFootprint/Current_512KB_32concurrent-4 6.473µ 7.119µ ~ 0.100
_MemoryFootprint/Proposed_32KB_32concurrent-4 8.753µ 10.728µ ~ 0.100
_MemoryFootprint/Alternative_64KB_32concurrent-4 8.578µ 10.238µ ~ 0.100
_prepareTxsPerLevel-4 408.5m 408.2m ~ 1.000
_prepareTxsPerLevelOrdered-4 3.659m 3.520m ~ 0.100
_prepareTxsPerLevel_Comparison/Original-4 419.7m 410.1m ~ 0.100
_prepareTxsPerLevel_Comparison/Optimized-4 3.764m 3.629m ~ 0.100
SubtreeProcessor/100_tx_64_per_subtree-4 83.51m 81.41m ~ 0.700
SubtreeProcessor/500_tx_64_per_subtree-4 390.7m 386.8m ~ 0.400
SubtreeProcessor/500_tx_256_per_subtree-4 404.5m 407.5m ~ 0.400
SubtreeProcessor/1k_tx_64_per_subtree-4 783.2m 783.3m ~ 0.700
SubtreeProcessor/1k_tx_256_per_subtree-4 794.8m 806.5m ~ 0.200
StreamingProcessorPhases/FilterValidated/100_tx-4 2.799m 2.847m ~ 0.100
StreamingProcessorPhases/ClassifyProcess/100_tx-4 245.9µ 245.6µ ~ 1.000
StreamingProcessorPhases/FilterValidated/500_tx-4 13.90m 14.01m ~ 0.100
StreamingProcessorPhases/ClassifyProcess/500_tx-4 615.4µ 612.5µ ~ 0.700
StreamingProcessorPhases/FilterValidated/1k_tx-4 27.58m 27.94m ~ 0.100
StreamingProcessorPhases/ClassifyProcess/1k_tx-4 1.078m 1.073m ~ 0.400
SubtreeSizes/10k_tx_4_per_subtree-4 1.396m 1.390m ~ 1.000
SubtreeSizes/10k_tx_16_per_subtree-4 330.8µ 337.4µ ~ 0.700
SubtreeSizes/10k_tx_64_per_subtree-4 78.58µ 77.69µ ~ 0.700
SubtreeSizes/10k_tx_256_per_subtree-4 19.55µ 19.77µ ~ 0.200
SubtreeSizes/10k_tx_512_per_subtree-4 9.748µ 9.742µ ~ 1.000
SubtreeSizes/10k_tx_1024_per_subtree-4 4.841µ 4.750µ ~ 0.100
SubtreeSizes/10k_tx_2k_per_subtree-4 2.422µ 2.419µ ~ 0.800
BlockSizeScaling/10k_tx_64_per_subtree-4 75.62µ 76.26µ ~ 0.700
BlockSizeScaling/10k_tx_256_per_subtree-4 19.29µ 19.31µ ~ 1.000
BlockSizeScaling/10k_tx_1024_per_subtree-4 4.775µ 4.766µ ~ 1.000
BlockSizeScaling/50k_tx_64_per_subtree-4 406.9µ 399.8µ ~ 0.400
BlockSizeScaling/50k_tx_256_per_subtree-4 95.14µ 95.86µ ~ 0.400
BlockSizeScaling/50k_tx_1024_per_subtree-4 23.63µ 23.66µ ~ 0.400
SubtreeAllocations/small_subtrees_exists_check-4 159.8µ 160.2µ ~ 0.700
SubtreeAllocations/small_subtrees_data_fetch-4 168.6µ 167.0µ ~ 1.000
SubtreeAllocations/small_subtrees_full_validation-4 330.6µ 332.0µ ~ 0.100
SubtreeAllocations/medium_subtrees_exists_check-4 9.473µ 9.459µ ~ 0.700
SubtreeAllocations/medium_subtrees_data_fetch-4 9.737µ 9.843µ ~ 0.400
SubtreeAllocations/medium_subtrees_full_validation-4 19.14µ 19.42µ ~ 0.200
SubtreeAllocations/large_subtrees_exists_check-4 2.255µ 2.271µ ~ 0.400
SubtreeAllocations/large_subtrees_data_fetch-4 2.371µ 2.386µ ~ 0.700
SubtreeAllocations/large_subtrees_full_validation-4 4.816µ 4.850µ ~ 0.400
GetUtxoHashes-4 259.3n 257.0n ~ 0.700
GetUtxoHashes_ManyOutputs-4 46.00µ 45.73µ ~ 1.000
_NewMetaDataFromBytes-4 240.3n 238.5n ~ 0.300
_Bytes-4 626.8n 632.2n ~ 0.700
_MetaBytes-4 576.9n 572.4n ~ 0.700

Threshold: >10% with p < 0.05 | Generated: 2026-03-30 12:20 UTC

@oskarszoon oskarszoon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race fix itself is correct (currentSubtree.Load().Length() → synchronized GetCurrentLength(), busy-wait/sleep → require.Eventually). Two issues block merge:

  • 1474 of the 1508 added lines are the same settings-test files as PR #615. If #615 merges first this branch will need a rebase to drop them; if this merges first #615 needs the same. Worth rebasing to strip the settings-test cargo from this PR so it's the race fix only.
  • This PR's SubtreeProcessor_test.go changes are identical to PR #641. Exactly one should land — please coordinate with #641 author to either close one or rebase so the diffs don't compete.

@sugh01 sugh01 closed this May 22, 2026
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