Skip to content

chore(deps): upgrade aerospike-client-go/v8 to v8.7.0, drop v8.2.0 replace#805

Draft
oskarszoon wants to merge 1 commit intobsv-blockchain:mainfrom
oskarszoon:chore/upgrade-aerospike-v8.7.0
Draft

chore(deps): upgrade aerospike-client-go/v8 to v8.7.0, drop v8.2.0 replace#805
oskarszoon wants to merge 1 commit intobsv-blockchain:mainfrom
oskarszoon:chore/upgrade-aerospike-v8.7.0

Conversation

@oskarszoon
Copy link
Copy Markdown
Contributor

Summary

  • Upgrade github.com/aerospike/aerospike-client-go/v8 from v8.4.2 (with replace ... => v8.2.0) to v8.7.0 as a direct require, no replace.
  • Pulls in the panic fixes from v8.6.0 (DynConfig nil-deref, BatchDelete / BatchGet / BatchOperate goroutine panics) and the metrics-hot-path performance work tagged as CLIENT-3968.
  • Aligns the binary actually shipped (v0.15.0-beta-3 stack traces show v8.4.2 paths despite the source-side replace) with the version declared in go.mod.

Why drop the replace

The replace was added in #301 (Dec 2025) to side-step the v8.3+ perf regression tracked upstream as aerospike/aerospike-client-go#565. Upstream issue is still listed as OPEN, but v8.6.0 release notes call out Changes to improve performance regression with detailed metrics in hot path. [CLIENT-3968]. v8.7.0 inherits that change.

Benchmarks (suggestive, not confirmatory)

n=3, M3 Max laptop, testcontainers Aerospike, go test -bench BenchmarkSetMinedMulti -count=3 ./stores/utxo/aerospike/.

metric geomean delta v8.7.0 vs v8.2.0 per-row significance
sec/op +14.01% none (p ≥ 0.1, n=3)
B/op −6.95% none
allocs/op −11.34% none

Direction suggests CLIENT-3968 reduced allocations but didn't fully claw back the CPU cost from #565. Needs a steadier runner and n ≥ 10 before treating as a real regression. Tracked as a follow-up.

Out of scope

  • The upstream Cluster.tend(*Guard).InitDoVal(nil, ...) panic seen on bsva-ovh-teranode-ttn-eu-4 is unchanged in v8.7.0 (cluster.go and refreshPartitions are byte-identical to v8.4.2). I'll file an upstream issue with the stack trace separately.
  • Block-assembly tip-reconciliation on startup (the reason a v8.4.2 panic produced a 20-block-stuck node instead of self-healing) is being handled in a separate branch.

Test plan

  • go mod tidy — clean
  • go build ./... — green
  • go test -short -race ./stores/utxo/aerospike/... — 446 pass
  • go test -short -tags testtxmetacache ./services/blockassembly/... — 989 pass (1 unrelated flake passes alone)
  • go vet ./... — only pre-existing test/utils issues
  • Re-bench with n ≥ 10 on dedicated runner once available
  • Smoke-deploy on TTN node, watch tend()/refreshPartitions for ≥ 24h before un-drafting

… replace

The repo previously pinned the Aerospike Go client to v8.2.0 via a `replace`
directive (PR bsv-blockchain#301) to avoid a performance regression introduced in v8.3 by
detailed metrics in the hot path (upstream issue
aerospike/aerospike-client-go#565).

v8.6.0 release notes claim "Changes to improve performance regression with
detailed metrics in hot path. [CLIENT-3968]". v8.7.0 is the latest minor and
also pulls in several panic-in-goroutine fixes shipped in v8.6.0
(DynConfig.logUpdate nil-deref, BatchDelete/BatchGet/BatchOperate panics).

Production binaries shipped under tag v0.15.0-beta-3 show v8.4.2 stack-trace
paths despite the source-side replace, so the build pipeline appears not to
honour it. Aligning the direct require with the latest version eliminates the
ambiguity and gives us the upstream fixes either way.

A local n=3 benchmark of `BenchmarkSetMinedMulti` (M3 Max + testcontainers)
shows v8.7.0 vs v8.2.0 geomean: sec/op +14%, B/op -7%, allocs/op -11%. With
n=3 no per-row p<0.05; treated as suggestive, not confirmatory. Re-bench under
load on a steady runner before relying on the perf direction. The upstream
issue bsv-blockchain#565 is still listed as OPEN, so the regression status warrants
follow-up upstream regardless of changelog wording.

The unrelated `Cluster.tend` -> `(*Guard).InitDoVal(nil, ...)` panic seen on
`bsva-ovh-teranode-ttn-eu-4` is unchanged in v8.7.0 (cluster.go and
refreshPartitions are byte-identical to v8.4.2). That upstream bug will be
filed separately.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

Benchmark Comparison Report

Baseline: main (unknown)

Current: PR-805 (5c0a006)

Summary

  • Regressions: 0
  • Improvements: 0
  • Unchanged: 142
  • Significance level: p < 0.05
All benchmark results (sec/op)
Benchmark Baseline Current Change p-value
_NewBlockFromBytes-4 1.575µ 1.567µ ~ 1.000
SplitSyncedParentMap_SetIfNotExists/256_buckets-4 71.15n 71.23n ~ 0.400
SplitSyncedParentMap_SetIfNotExists/16_buckets-4 71.04n 71.20n ~ 0.500
SplitSyncedParentMap_SetIfNotExists/1_bucket-4 70.91n 71.17n ~ 0.300
SplitSyncedParentMap_ConcurrentSetIfNotExists/256_buckets... 32.75n 33.32n ~ 0.100
SplitSyncedParentMap_ConcurrentSetIfNotExists/16_buckets_... 56.24n 55.09n ~ 0.100
SplitSyncedParentMap_ConcurrentSetIfNotExists/1_bucket_pa... 127.3n 133.2n ~ 0.100
MiningCandidate_Stringify_Short-4 218.3n 223.0n ~ 0.100
MiningCandidate_Stringify_Long-4 1.641µ 1.654µ ~ 0.200
MiningSolution_Stringify-4 853.2n 849.4n ~ 0.400
BlockInfo_MarshalJSON-4 1.725µ 1.730µ ~ 1.000
NewFromBytes-4 156.3n 146.5n ~ 1.000
Mine_EasyDifficulty-4 67.33µ 67.26µ ~ 1.000
Mine_WithAddress-4 7.239µ 7.031µ ~ 0.100
BlockAssembler_AddTx-4 0.02753n 0.02914n ~ 1.000
AddNode-4 12.40 11.68 ~ 0.100
AddNodeWithMap-4 12.12 11.81 ~ 0.400
DirectSubtreeAdd/4_per_subtree-4 64.59n 60.35n ~ 0.100
DirectSubtreeAdd/64_per_subtree-4 32.14n 29.24n ~ 0.100
DirectSubtreeAdd/256_per_subtree-4 30.69n 27.36n ~ 0.100
DirectSubtreeAdd/1024_per_subtree-4 29.33n 26.35n ~ 0.100
DirectSubtreeAdd/2048_per_subtree-4 28.89n 26.04n ~ 0.100
SubtreeProcessorAdd/4_per_subtree-4 279.4n 275.7n ~ 0.100
SubtreeProcessorAdd/64_per_subtree-4 275.5n 275.4n ~ 1.000
SubtreeProcessorAdd/256_per_subtree-4 276.3n 275.5n ~ 1.000
SubtreeProcessorAdd/1024_per_subtree-4 266.7n 266.2n ~ 0.500
SubtreeProcessorAdd/2048_per_subtree-4 270.3n 264.6n ~ 0.100
SubtreeProcessorRotate/4_per_subtree-4 275.7n 273.0n ~ 0.400
SubtreeProcessorRotate/64_per_subtree-4 270.2n 270.0n ~ 1.000
SubtreeProcessorRotate/256_per_subtree-4 270.1n 272.5n ~ 0.100
SubtreeProcessorRotate/1024_per_subtree-4 268.8n 268.7n ~ 1.000
SubtreeNodeAddOnly/4_per_subtree-4 54.44n 54.66n ~ 1.000
SubtreeNodeAddOnly/64_per_subtree-4 34.41n 34.32n ~ 1.000
SubtreeNodeAddOnly/256_per_subtree-4 33.56n 33.52n ~ 0.400
SubtreeNodeAddOnly/1024_per_subtree-4 32.89n 32.87n ~ 0.800
SubtreeCreationOnly/4_per_subtree-4 113.3n 113.0n ~ 1.000
SubtreeCreationOnly/64_per_subtree-4 396.5n 409.6n ~ 0.700
SubtreeCreationOnly/256_per_subtree-4 1.331µ 1.361µ ~ 0.400
SubtreeCreationOnly/1024_per_subtree-4 4.414µ 4.386µ ~ 0.400
SubtreeCreationOnly/2048_per_subtree-4 8.095µ 8.238µ ~ 0.100
SubtreeProcessorOverheadBreakdown/64_per_subtree-4 269.7n 271.1n ~ 1.000
SubtreeProcessorOverheadBreakdown/1024_per_subtree-4 269.9n 272.7n ~ 0.100
ParallelGetAndSetIfNotExists/1k_nodes-4 587.0µ 798.7µ ~ 0.100
ParallelGetAndSetIfNotExists/10k_nodes-4 1.357m 1.576m ~ 0.100
ParallelGetAndSetIfNotExists/50k_nodes-4 6.720m 6.624m ~ 0.700
ParallelGetAndSetIfNotExists/100k_nodes-4 13.37m 13.31m ~ 0.100
SequentialGetAndSetIfNotExists/1k_nodes-4 665.1µ 665.4µ ~ 1.000
SequentialGetAndSetIfNotExists/10k_nodes-4 2.777m 2.781m ~ 0.700
SequentialGetAndSetIfNotExists/50k_nodes-4 10.37m 10.41m ~ 0.400
SequentialGetAndSetIfNotExists/100k_nodes-4 20.14m 19.91m ~ 0.400
ProcessOwnBlockSubtreeNodesParallel/1k_nodes-4 638.6µ 636.6µ ~ 1.000
ProcessOwnBlockSubtreeNodesParallel/10k_nodes-4 4.248m 4.244m ~ 0.400
ProcessOwnBlockSubtreeNodesParallel/100k_nodes-4 16.64m 16.56m ~ 0.400
ProcessOwnBlockSubtreeNodesSequential/1k_nodes-4 717.2µ 706.9µ ~ 0.400
ProcessOwnBlockSubtreeNodesSequential/10k_nodes-4 5.752m 5.869m ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/100k_nodes-4 37.47m 37.83m ~ 0.700
DiskTxMap_SetIfNotExists-4 3.702µ 3.704µ ~ 0.700
DiskTxMap_SetIfNotExists_Parallel-4 3.562µ 3.496µ ~ 0.400
DiskTxMap_ExistenceOnly-4 326.6n 317.5n ~ 0.100
Queue-4 195.7n 195.3n ~ 0.600
AtomicPointer-4 4.783n 4.508n ~ 0.200
ReorgOptimizations/DedupFilterPipeline/Old/10K-4 891.0µ 857.9µ ~ 0.100
ReorgOptimizations/DedupFilterPipeline/New/10K-4 854.6µ 833.7µ ~ 0.100
ReorgOptimizations/AllMarkFalse/Old/10K-4 118.3µ 115.2µ ~ 0.200
ReorgOptimizations/AllMarkFalse/New/10K-4 62.28µ 62.32µ ~ 1.000
ReorgOptimizations/HashSlicePool/Old/10K-4 67.68µ 61.56µ ~ 0.200
ReorgOptimizations/HashSlicePool/New/10K-4 12.05µ 11.83µ ~ 0.200
ReorgOptimizations/NodeFlags/Old/10K-4 6.014µ 5.631µ ~ 0.400
ReorgOptimizations/NodeFlags/New/10K-4 2.057µ 2.028µ ~ 0.200
ReorgOptimizations/DedupFilterPipeline/Old/100K-4 11.41m 10.58m ~ 0.400
ReorgOptimizations/DedupFilterPipeline/New/100K-4 10.26m 10.38m ~ 0.200
ReorgOptimizations/AllMarkFalse/Old/100K-4 1.213m 1.177m ~ 0.100
ReorgOptimizations/AllMarkFalse/New/100K-4 684.7µ 688.6µ ~ 0.400
ReorgOptimizations/HashSlicePool/Old/100K-4 718.8µ 700.8µ ~ 0.700
ReorgOptimizations/HashSlicePool/New/100K-4 319.3µ 299.1µ ~ 0.400
ReorgOptimizations/NodeFlags/Old/100K-4 57.46µ 56.52µ ~ 1.000
ReorgOptimizations/NodeFlags/New/100K-4 19.93µ 20.21µ ~ 0.400
TxMapSetIfNotExists-4 52.70n 52.78n ~ 0.400
TxMapSetIfNotExistsDuplicate-4 38.30n 38.03n ~ 0.100
ChannelSendReceive-4 643.3n 616.5n ~ 0.100
CalcBlockWork-4 496.6n 501.3n ~ 0.100
CalculateWork-4 676.2n 746.5n ~ 0.700
BuildBlockLocatorString_Helpers/Size_10-4 1.029µ 1.047µ ~ 0.700
BuildBlockLocatorString_Helpers/Size_100-4 9.756µ 9.987µ ~ 0.100
BuildBlockLocatorString_Helpers/Size_1000-4 117.39µ 99.24µ ~ 0.100
CatchupWithHeaderCache-4 103.6m 103.7m ~ 1.000
_prepareTxsPerLevel-4 446.8m 435.8m ~ 1.000
_prepareTxsPerLevelOrdered-4 4.045m 4.122m ~ 0.700
_prepareTxsPerLevel_Comparison/Original-4 465.5m 441.7m ~ 0.100
_prepareTxsPerLevel_Comparison/Optimized-4 3.981m 4.050m ~ 0.700
SubtreeSizes/10k_tx_4_per_subtree-4 1.415m 1.333m ~ 0.700
SubtreeSizes/10k_tx_16_per_subtree-4 340.8µ 319.5µ ~ 0.100
SubtreeSizes/10k_tx_64_per_subtree-4 79.45µ 76.99µ ~ 0.100
SubtreeSizes/10k_tx_256_per_subtree-4 19.57µ 18.89µ ~ 0.100
SubtreeSizes/10k_tx_512_per_subtree-4 9.774µ 9.447µ ~ 0.100
SubtreeSizes/10k_tx_1024_per_subtree-4 4.876µ 4.639µ ~ 0.100
SubtreeSizes/10k_tx_2k_per_subtree-4 2.401µ 2.314µ ~ 0.100
BlockSizeScaling/10k_tx_64_per_subtree-4 76.55µ 74.04µ ~ 0.100
BlockSizeScaling/10k_tx_256_per_subtree-4 19.42µ 18.80µ ~ 0.100
BlockSizeScaling/10k_tx_1024_per_subtree-4 4.782µ 4.715µ ~ 0.100
BlockSizeScaling/50k_tx_64_per_subtree-4 404.2µ 384.0µ ~ 0.100
BlockSizeScaling/50k_tx_256_per_subtree-4 95.83µ 93.00µ ~ 0.100
BlockSizeScaling/50k_tx_1024_per_subtree-4 23.74µ 22.91µ ~ 0.100
SubtreeAllocations/small_subtrees_exists_check-4 164.9µ 154.9µ ~ 0.100
SubtreeAllocations/small_subtrees_data_fetch-4 172.4µ 164.5µ ~ 0.100
SubtreeAllocations/small_subtrees_full_validation-4 337.1µ 317.9µ ~ 0.100
SubtreeAllocations/medium_subtrees_exists_check-4 9.592µ 9.117µ ~ 0.100
SubtreeAllocations/medium_subtrees_data_fetch-4 10.269µ 9.452µ ~ 0.100
SubtreeAllocations/medium_subtrees_full_validation-4 19.60µ 18.70µ ~ 0.100
SubtreeAllocations/large_subtrees_exists_check-4 2.314µ 2.192µ ~ 0.100
SubtreeAllocations/large_subtrees_data_fetch-4 2.502µ 2.309µ ~ 0.100
SubtreeAllocations/large_subtrees_full_validation-4 4.909µ 4.646µ ~ 0.100
_BufferPoolAllocation/16KB-4 2.668µ 2.668µ ~ 0.800
_BufferPoolAllocation/32KB-4 7.795µ 6.762µ ~ 0.400
_BufferPoolAllocation/64KB-4 14.58µ 14.15µ ~ 0.100
_BufferPoolAllocation/128KB-4 24.04µ 23.61µ ~ 0.400
_BufferPoolAllocation/512KB-4 97.28µ 95.59µ ~ 0.400
_BufferPoolConcurrent/32KB-4 15.38µ 13.65µ ~ 0.100
_BufferPoolConcurrent/64KB-4 23.70µ 21.52µ ~ 0.100
_BufferPoolConcurrent/512KB-4 119.8µ 119.6µ ~ 1.000
_SubtreeDeserializationWithBufferSizes/16KB-4 525.7µ 527.3µ ~ 1.000
_SubtreeDeserializationWithBufferSizes/32KB-4 539.0µ 530.9µ ~ 0.700
_SubtreeDeserializationWithBufferSizes/64KB-4 542.6µ 523.8µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/128KB-4 541.1µ 520.8µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/512KB-4 551.4µ 536.0µ ~ 0.700
_SubtreeDataDeserializationWithBufferSizes/16KB-4 29.70m 29.92m ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/32KB-4 30.13m 29.32m ~ 0.200
_SubtreeDataDeserializationWithBufferSizes/64KB-4 31.28m 29.72m ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/128KB-4 30.91m 29.49m ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/512KB-4 30.25m 28.99m ~ 0.100
_PooledVsNonPooled/Pooled-4 705.0n 703.6n ~ 0.700
_PooledVsNonPooled/NonPooled-4 5.244µ 5.160µ ~ 1.000
_MemoryFootprint/Current_512KB_32concurrent-4 6.354µ 5.928µ ~ 0.100
_MemoryFootprint/Proposed_32KB_32concurrent-4 8.161µ 8.095µ ~ 1.000
_MemoryFootprint/Alternative_64KB_32concurrent-4 7.541µ 7.496µ ~ 0.400
StoreBlock_Sequential/BelowCSVHeight-4 334.1µ 334.1µ ~ 1.000
StoreBlock_Sequential/AboveCSVHeight-4 326.9µ 330.3µ ~ 1.000
GetUtxoHashes-4 257.5n 259.3n ~ 0.700
GetUtxoHashes_ManyOutputs-4 47.70µ 42.95µ ~ 0.200
_NewMetaDataFromBytes-4 237.5n 238.7n ~ 0.100
_Bytes-4 630.3n 620.7n ~ 0.700
_MetaBytes-4 564.1n 564.4n ~ 1.000

Threshold: >10% with p < 0.05 | Generated: 2026-05-04 13:19 UTC

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.

1 participant