Skip to content

feat(batcher): per-batcher fixed-cadence flushing (SetTickInterval) + go-batcher v2.0.3 bump#1017

Merged
freemans13 merged 3 commits into
bsv-blockchain:mainfrom
freemans13:stu/bump-go-batcher-v2.0.3
Jun 2, 2026
Merged

feat(batcher): per-batcher fixed-cadence flushing (SetTickInterval) + go-batcher v2.0.3 bump#1017
freemans13 merged 3 commits into
bsv-blockchain:mainfrom
freemans13:stu/bump-go-batcher-v2.0.3

Conversation

@freemans13

@freemans13 freemans13 commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two related, separable commits — a dependency bump and the feature it unlocks:

  1. chore(deps) — bump github.com/bsv-blockchain/go-batcher/v2 v2.0.0v2.0.3 (latest), plus the transitive minimums v2.0.3 requires (go-sdk, go-tx-map, go-bt, otel otel submodules →v1.44.0, golang.org/x/*).
  2. feat(batcher) — wires v2.0.3's new SetTickInterval (fixed-cadence batch flushing) across every go-batcher instance on the tx-validator path, exposed via per-batcher settings, all defaulting to 0 (disabled) so behaviour is unchanged until explicitly tuned.

New settings (10, all int milliseconds, default 0 = disabled)

key batcher
utxostore_storeBatcherTickerIntervalMillis aerospike store / sql create
utxostore_getBatcherTickerIntervalMillis aerospike + sql get
utxostore_spendBatcherTickerIntervalMillis aerospike + sql spend
utxostore_outpointBatcherTickerIntervalMillis aerospike outpoint (decorate)
utxostore_incrementBatcherTickerIntervalMillis aerospike increment
utxostore_setDAHBatcherTickerIntervalMillis aerospike setDAH
utxostore_lockedBatcherTickerIntervalMillis aerospike locked / sql unlock
blockassembly_sendBatchTickerIntervalMillis block-assembly send
validator_sendBatchTickerIntervalMillis validator gRPC client
validator_txmeta_kafka_batchTickerIntervalMillis validator txmeta-Kafka

When > 0, the batcher flushes every N ms regardless of fill (empty ticks skipped); the size cap still forces an early flush.

Behavioural notes

  • Drain wins on conflict. Tick mode is mutually exclusive with drain mode in go-batcher. SetTickInterval is applied after SetDrainMode at every call site, so go-batcher's own guard no-ops the tick (with a warning) when drain is enabled.
  • validator/Client.go batcher field: value → pointer. v2.0.3's Batcher embeds a sync.Pool, so the prior batcher = *NewWithPool(...) value-copy would trip go vet copylocks and would silently drop the ticker state (the worker runs on the original instance). Usages (TriggerBatcher, ValidateWithOptions) are guarded by the same batchSize check as construction, so the now-nilable pointer is never dereferenced when batching is disabled.
  • otel aligned to v1.44.0: all direct otel deps (otel, otel/trace, otel/metric, otel/sdk, otltrace, otltracehttp) are at v1.44.0 (the go-batcher bump raised some; a follow-up commit aligned the rest). Indirect metric exporters (otlpmetric*) stay at their current versions — not on the trace path.

Test plan

  • go build ./... — success
  • go vet on all changed packages (incl. -tags aerospike test compile) — no issues
  • golangci-lint run --new-from-rev=HEAD — no issues
  • settings: TestBatcherTickInterval_LoaderReadsAllKeys (asserts each of the 10 keys' non-zero override propagates, guarding the "tagged but unread" bug) + full package (157)
  • validator + blockassembly: 978 passed
  • sql store: 234 passed

Picks up SetTickInterval (fixed-cadence batch flushing) and the
transitive dependency minimums required by go-batcher v2.0.3
(go-sdk, go-tx-map, go-bt, otel 1.44, golang.org/x/*). No API
breakage; build and go vet pass across all packages.
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

Status: Complete


Current Review:

No issues found. This PR is well-structured and maintains backward compatibility.

Summary:

This PR cleanly wires go-batcher v2.0.3's new SetTickInterval feature across all validator-path batchers, adds 10 new settings (all default 0/disabled), and includes a comprehensive test to guard against silent config misreads.

Key Strengths:

  1. Backward Compatible: All new settings default to 0 (disabled), ensuring no behavior change unless explicitly configured
  2. Drain-Wins Semantics: SetTickInterval correctly applied after SetDrainMode, with go-batcher enforcing mutual exclusion via a no-op + warning
  3. Pointer Fix: validator/Client.go batcher changed from value to pointer to prevent sync.Pool copy issues and ticker state loss (services/validator/Client.go:80)
  4. Test Coverage: settings/batcher_tickinterval_test.go verifies all 10 keys are actually read by the loader
  5. Consistent Pattern: Same setup pattern used across all sites (aerospike, SQL, blockassembly, validator)
  6. Dependency Hygiene: Transitive dep bumps (go-sdk, go-tx-map, go-bt, otel→v1.44.0) are the minimal set required by go-batcher v2.0.3

Test Plan (per PR description):

  • ✅ go build ./...
  • ✅ go vet (including -tags aerospike)
  • ✅ golangci-lint run --new-from-rev=HEAD
  • ✅ settings: 157 tests (including the new guard test)
  • ✅ validator + blockassembly: 978 tests
  • ✅ sql store: 234 tests

No changes recommended.

@oskarszoon oskarszoon self-requested a review June 2, 2026 10:20
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Benchmark Comparison Report

Baseline: main (unknown)

Current: PR-1017 (92462b8)

Summary

  • Regressions: 0
  • Improvements: 0
  • Unchanged: 144
  • Significance level: p < 0.05
All benchmark results (sec/op)
Benchmark Baseline Current Change p-value
_NewBlockFromBytes-4 1.756µ 1.790µ ~ 0.100
SplitSyncedParentMap_SetIfNotExists/256_buckets-4 62.23n 61.86n ~ 0.400
SplitSyncedParentMap_SetIfNotExists/16_buckets-4 61.72n 62.07n ~ 0.700
SplitSyncedParentMap_SetIfNotExists/1_bucket-4 61.76n 61.98n ~ 0.200
SplitSyncedParentMap_ConcurrentSetIfNotExists/256_buckets... 30.82n 37.40n ~ 0.100
SplitSyncedParentMap_ConcurrentSetIfNotExists/16_buckets_... 53.04n 54.31n ~ 0.100
SplitSyncedParentMap_ConcurrentSetIfNotExists/1_bucket_pa... 114.9n 115.5n ~ 0.400
MiningCandidate_Stringify_Short-4 263.8n 263.0n ~ 0.800
MiningCandidate_Stringify_Long-4 1.927µ 1.898µ ~ 0.100
MiningSolution_Stringify-4 982.4n 989.5n ~ 0.200
BlockInfo_MarshalJSON-4 1.821µ 1.812µ ~ 0.200
NewFromBytes-4 129.4n 157.0n ~ 0.700
AddTxBatchColumnar_Validation-4 2.510µ 2.469µ ~ 0.400
OffsetValidationLoop-4 641.3n 637.1n ~ 0.400
Mine_EasyDifficulty-4 61.81µ 61.17µ ~ 0.700
Mine_WithAddress-4 7.373µ 6.951µ ~ 0.200
DirectSubtreeAdd/4_per_subtree-4 57.07n 60.81n ~ 0.400
DirectSubtreeAdd/64_per_subtree-4 30.70n 29.58n ~ 0.100
DirectSubtreeAdd/256_per_subtree-4 30.04n 28.54n ~ 0.100
DirectSubtreeAdd/1024_per_subtree-4 28.62n 27.70n ~ 0.100
DirectSubtreeAdd/2048_per_subtree-4 28.11n 27.06n ~ 0.100
SubtreeProcessorAdd/4_per_subtree-4 279.0n 278.2n ~ 1.000
SubtreeProcessorAdd/64_per_subtree-4 281.4n 274.5n ~ 0.200
SubtreeProcessorAdd/256_per_subtree-4 281.8n 277.9n ~ 0.700
SubtreeProcessorAdd/1024_per_subtree-4 268.0n 266.2n ~ 0.400
SubtreeProcessorAdd/2048_per_subtree-4 266.4n 266.3n ~ 0.700
SubtreeProcessorRotate/4_per_subtree-4 275.6n 268.8n ~ 0.100
SubtreeProcessorRotate/64_per_subtree-4 277.4n 273.3n ~ 0.200
SubtreeProcessorRotate/256_per_subtree-4 275.5n 272.7n ~ 0.100
SubtreeProcessorRotate/1024_per_subtree-4 283.2n 270.7n ~ 0.100
SubtreeNodeAddOnly/4_per_subtree-4 54.03n 53.62n ~ 0.700
SubtreeNodeAddOnly/64_per_subtree-4 34.01n 34.09n ~ 0.400
SubtreeNodeAddOnly/256_per_subtree-4 32.93n 33.09n ~ 0.200
SubtreeNodeAddOnly/1024_per_subtree-4 32.40n 32.51n ~ 0.400
SubtreeCreationOnly/4_per_subtree-4 111.9n 111.7n ~ 1.000
SubtreeCreationOnly/64_per_subtree-4 390.6n 386.9n ~ 0.100
SubtreeCreationOnly/256_per_subtree-4 1.314µ 1.315µ ~ 0.700
SubtreeCreationOnly/1024_per_subtree-4 4.341µ 4.386µ ~ 0.200
SubtreeCreationOnly/2048_per_subtree-4 7.799µ 7.838µ ~ 0.700
SubtreeProcessorOverheadBreakdown/64_per_subtree-4 274.4n 268.4n ~ 0.100
SubtreeProcessorOverheadBreakdown/1024_per_subtree-4 273.2n 270.7n ~ 0.200
ParallelGetAndSetIfNotExists/1k_nodes-4 2.216m 2.166m ~ 0.100
ParallelGetAndSetIfNotExists/10k_nodes-4 5.380m 5.250m ~ 0.100
ParallelGetAndSetIfNotExists/50k_nodes-4 7.296m 6.955m ~ 0.100
ParallelGetAndSetIfNotExists/100k_nodes-4 9.823m 9.555m ~ 0.100
SequentialGetAndSetIfNotExists/1k_nodes-4 1.938m 1.925m ~ 0.700
SequentialGetAndSetIfNotExists/10k_nodes-4 4.259m 4.285m ~ 0.100
SequentialGetAndSetIfNotExists/50k_nodes-4 11.97m 12.24m ~ 0.100
SequentialGetAndSetIfNotExists/100k_nodes-4 21.39m 22.34m ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/1k_nodes-4 2.207m 2.207m ~ 0.700
ProcessOwnBlockSubtreeNodesParallel/10k_nodes-4 8.112m 8.077m ~ 0.400
ProcessOwnBlockSubtreeNodesParallel/100k_nodes-4 12.72m 12.56m ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/1k_nodes-4 1.992m 1.938m ~ 0.200
ProcessOwnBlockSubtreeNodesSequential/10k_nodes-4 7.294m 7.350m ~ 0.700
ProcessOwnBlockSubtreeNodesSequential/100k_nodes-4 39.81m 39.59m ~ 0.400
DiskTxMap_SetIfNotExists-4 3.547µ 3.632µ ~ 0.100
DiskTxMap_SetIfNotExists_Parallel-4 3.457µ 3.261µ ~ 0.100
DiskTxMap_ExistenceOnly-4 322.4n 318.1n ~ 0.100
Queue-4 190.7n 188.3n ~ 0.100
AtomicPointer-4 4.653n 4.696n ~ 0.700
ReorgOptimizations/DedupFilterPipeline/Old/10K-4 907.3µ 895.5µ ~ 0.100
ReorgOptimizations/DedupFilterPipeline/New/10K-4 792.5µ 802.6µ ~ 0.100
ReorgOptimizations/AllMarkFalse/Old/10K-4 107.0µ 115.0µ ~ 1.000
ReorgOptimizations/AllMarkFalse/New/10K-4 62.56µ 63.62µ ~ 0.100
ReorgOptimizations/HashSlicePool/Old/10K-4 56.86µ 55.56µ ~ 0.200
ReorgOptimizations/HashSlicePool/New/10K-4 10.70µ 12.16µ ~ 0.100
ReorgOptimizations/NodeFlags/Old/10K-4 4.706µ 4.718µ ~ 0.600
ReorgOptimizations/NodeFlags/New/10K-4 1.694µ 1.599µ ~ 0.200
ReorgOptimizations/DedupFilterPipeline/Old/100K-4 9.919m 9.380m ~ 0.100
ReorgOptimizations/DedupFilterPipeline/New/100K-4 9.763m 9.889m ~ 0.100
ReorgOptimizations/AllMarkFalse/Old/100K-4 1.173m 1.177m ~ 1.000
ReorgOptimizations/AllMarkFalse/New/100K-4 687.0µ 689.3µ ~ 0.400
ReorgOptimizations/HashSlicePool/Old/100K-4 580.7µ 574.5µ ~ 1.000
ReorgOptimizations/HashSlicePool/New/100K-4 309.2µ 313.7µ ~ 1.000
ReorgOptimizations/NodeFlags/Old/100K-4 51.18µ 47.82µ ~ 0.100
ReorgOptimizations/NodeFlags/New/100K-4 16.40µ 16.42µ ~ 1.000
TxMapSetIfNotExists-4 52.87n 53.04n ~ 0.400
TxMapSetIfNotExistsDuplicate-4 40.16n 40.73n ~ 0.100
ChannelSendReceive-4 642.6n 629.5n ~ 0.100
BlockAssembler_AddTx-4 0.02283n 0.02395n ~ 0.700
AddNode-4 9.254 9.562 ~ 0.400
AddNodeWithMap-4 9.383 10.361 ~ 0.700
CalcBlockWork-4 528.4n 504.8n ~ 0.700
CalculateWork-4 687.4n 694.4n ~ 0.100
BuildBlockLocatorString_Helpers/Size_10-4 1.413µ 1.388µ ~ 0.200
BuildBlockLocatorString_Helpers/Size_100-4 15.92µ 13.32µ ~ 0.100
BuildBlockLocatorString_Helpers/Size_1000-4 131.4µ 131.0µ ~ 0.700
CatchupWithHeaderCache-4 104.7m 104.8m ~ 0.700
_BufferPoolAllocation/16KB-4 4.301µ 3.881µ ~ 0.400
_BufferPoolAllocation/32KB-4 10.013µ 8.717µ ~ 0.400
_BufferPoolAllocation/64KB-4 19.37µ 16.75µ ~ 0.100
_BufferPoolAllocation/128KB-4 33.42µ 34.49µ ~ 0.100
_BufferPoolAllocation/512KB-4 128.4µ 118.8µ ~ 0.400
_BufferPoolConcurrent/32KB-4 18.86µ 19.52µ ~ 1.000
_BufferPoolConcurrent/64KB-4 30.08µ 30.41µ ~ 0.700
_BufferPoolConcurrent/512KB-4 144.4µ 143.2µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/16KB-4 632.0µ 625.4µ ~ 1.000
_SubtreeDeserializationWithBufferSizes/32KB-4 626.4µ 609.9µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/64KB-4 627.9µ 640.2µ ~ 0.700
_SubtreeDeserializationWithBufferSizes/128KB-4 616.9µ 618.3µ ~ 0.700
_SubtreeDeserializationWithBufferSizes/512KB-4 643.8µ 609.5µ ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/16KB-4 36.92m 36.65m ~ 0.700
_SubtreeDataDeserializationWithBufferSizes/32KB-4 36.37m 36.71m ~ 0.700
_SubtreeDataDeserializationWithBufferSizes/64KB-4 36.51m 36.53m ~ 0.700
_SubtreeDataDeserializationWithBufferSizes/128KB-4 36.56m 36.70m ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/512KB-4 36.31m 36.17m ~ 0.100
_PooledVsNonPooled/Pooled-4 737.4n 737.4n ~ 0.800
_PooledVsNonPooled/NonPooled-4 7.807µ 7.770µ ~ 1.000
_MemoryFootprint/Current_512KB_32concurrent-4 6.451µ 6.713µ ~ 0.100
_MemoryFootprint/Proposed_32KB_32concurrent-4 9.428µ 9.355µ ~ 0.700
_MemoryFootprint/Alternative_64KB_32concurrent-4 8.715µ 9.057µ ~ 0.100
SubtreeSizes/10k_tx_4_per_subtree-4 1.356m 1.360m ~ 0.700
SubtreeSizes/10k_tx_16_per_subtree-4 321.6µ 320.0µ ~ 0.700
SubtreeSizes/10k_tx_64_per_subtree-4 77.44µ 76.79µ ~ 0.700
SubtreeSizes/10k_tx_256_per_subtree-4 19.40µ 19.03µ ~ 0.100
SubtreeSizes/10k_tx_512_per_subtree-4 9.508µ 9.431µ ~ 0.200
SubtreeSizes/10k_tx_1024_per_subtree-4 4.686µ 4.734µ ~ 1.000
SubtreeSizes/10k_tx_2k_per_subtree-4 2.354µ 2.319µ ~ 0.200
BlockSizeScaling/10k_tx_64_per_subtree-4 73.35µ 74.11µ ~ 0.200
BlockSizeScaling/10k_tx_256_per_subtree-4 18.63µ 18.62µ ~ 1.000
BlockSizeScaling/10k_tx_1024_per_subtree-4 4.653µ 4.631µ ~ 0.700
BlockSizeScaling/50k_tx_64_per_subtree-4 387.3µ 390.6µ ~ 0.200
BlockSizeScaling/50k_tx_256_per_subtree-4 94.05µ 92.32µ ~ 0.100
BlockSizeScaling/50k_tx_1024_per_subtree-4 23.08µ 23.06µ ~ 0.700
SubtreeAllocations/small_subtrees_exists_check-4 157.4µ 157.2µ ~ 0.400
SubtreeAllocations/small_subtrees_data_fetch-4 162.7µ 161.5µ ~ 0.400
SubtreeAllocations/small_subtrees_full_validation-4 324.3µ 324.9µ ~ 1.000
SubtreeAllocations/medium_subtrees_exists_check-4 9.415µ 9.250µ ~ 0.100
SubtreeAllocations/medium_subtrees_data_fetch-4 9.612µ 9.537µ ~ 1.000
SubtreeAllocations/medium_subtrees_full_validation-4 18.70µ 18.65µ ~ 0.400
SubtreeAllocations/large_subtrees_exists_check-4 2.220µ 2.222µ ~ 1.000
SubtreeAllocations/large_subtrees_data_fetch-4 2.335µ 2.327µ ~ 0.700
SubtreeAllocations/large_subtrees_full_validation-4 4.707µ 4.679µ ~ 0.200
_prepareTxsPerLevel-4 401.8m 401.7m ~ 0.700
_prepareTxsPerLevelOrdered-4 3.575m 3.645m ~ 0.700
_prepareTxsPerLevel_Comparison/Original-4 399.2m 399.4m ~ 1.000
_prepareTxsPerLevel_Comparison/Optimized-4 3.661m 3.665m ~ 1.000
StoreBlock_Sequential/BelowCSVHeight-4 336.1µ 343.3µ ~ 0.200
StoreBlock_Sequential/AboveCSVHeight-4 339.3µ 338.6µ ~ 0.700
GetUtxoHashes-4 281.2n 285.7n ~ 0.700
GetUtxoHashes_ManyOutputs-4 46.08µ 46.23µ ~ 0.700
_NewMetaDataFromBytes-4 213.4n 213.9n ~ 0.700
_Bytes-4 399.5n 398.3n ~ 1.000
_MetaBytes-4 137.4n 139.2n ~ 0.100

Threshold: >10% with p < 0.05 | Generated: 2026-06-02 12:41 UTC

…n the validator path

Wires go-batcher v2.0.3's new SetTickInterval into every batcher the tx
validator path touches: the UTXO-store batchers (aerospike store/get/spend/
outpoint/increment/setDAH/locked and the sql spend/get/create/unlock), the
blockassembly send batcher, and the validator txmeta-kafka and gRPC client
batchers.

Each batcher gets a per-batcher <name>TickerIntervalMillis setting, defaulting
to 0 (disabled) so behaviour is unchanged until tuned. Tick mode is mutually
exclusive with drain mode; SetTickInterval is applied after SetDrainMode so
go-batcher's own guard makes drain win (no-op + warning) on conflict.

The validator gRPC client's batcher field becomes a pointer: the v2.0.3 Batcher
carries a sync.Pool, so the prior value-copy would trip go vet copylocks and
would not let SetTickInterval reach the worker's instance.
@freemans13 freemans13 self-assigned this Jun 2, 2026
@freemans13 freemans13 requested review from liam and ordishs June 2, 2026 11:27
@ordishs

ordishs commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Code Review

Overview

The title and body describe a pure dependency bump ("Only go.mod and go.sum change. No source changes required"). The PR actually contains two commits:

  1. 63cb39208 — the go-batcher v2.0.0 → v2.0.3 bump (+ transitive bumps)
  2. b258dcc1aa feature: wires the new SetTickInterval (fixed-cadence batch flushing) API across the validator client, validator txmeta-Kafka batcher, block-assembly client, the Aerospike UTXO store (7 batchers), and the SQL UTXO store (4 batchers), adding 10 new tunable settings + a test.

So this is a feat, not a chore(deps), touching 10 source/test files. The code itself is solid — but the metadata is the headline issue.

🔴 Primary issue — inaccurate title & description

  • The body states "No source changes required — the only API change in go-batcher was additive." A reviewer skimming this will under-scrutinize a behavioural change to hot-path batching in the validator and UTXO store.
  • The feature won't surface in changelog/release notes generated from the chore(deps) prefix.
  • Recommendation: either retitle to feat(batcher): per-batcher fixed-cadence flushing (SetTickInterval) and document the 10 new settings in the body, or split the feature commit into its own PR stacked on the bump. They are genuinely separable.

✅ Correctness (verified locally — build/vet/test clean)

  • Value → pointer batcher in validator/Client.go — correct and necessary. The v2.0.3 Batcher embeds a sync.Pool, so the old batcher = *batcher.NewWithPool(...) value-copy would both trip go vet copylocks and silently drop the ticker state. Both consumers (TriggerBatcher, ValidateWithOptions) are guarded by batchSize checks matching the construction guard, so the now-nilable pointer is never dereferenced when batching is disabled. go vet is clean.
  • Drain vs. tick orderingSetTickInterval is applied after SetDrainMode in every site, so go-batcher's "drain wins" guard sees final state and no-ops the tick under drain. Well commented.
  • Defaults — every new key defaults to 0 (disabled); behaviour is unchanged until explicitly tuned.
  • Build of all changed packages: OK. TestBatcherTickInterval_LoaderReadsAllKeys: passes.

✅ Test quality

settings/batcher_tickinterval_test.go is a genuinely good test: it guards against the "field has a key: tag but NewSettings() never reads it" bug by asserting a non-zero override propagates, not merely that the default is 0 (which would pass spuriously, since default == Go zero). All 10 keys covered, with cleanup.

🟡 Minor notes

  • Mixed otel versions: go.opentelemetry.io/otel and .../trace go to v1.44.0, but .../sdk and the otlptrace exporters stay at v1.43.0. Compiles (Go takes the max), but a partial otel bump is slightly unusual — worth confirming it's intentional.
  • SQL store knob asymmetry: in sql.go, drain comes from the global BatcherDrainMode while the new tick interval comes from per-batcher UtxoStore.*TickerIntervalMillis. Not a bug (the longdesc notes it), just an inconsistency in granularity.
  • Boilerplate: the if ms := ...; ms > 0 { b.SetTickInterval(...) } block repeats ~13 times. A tiny helper would tighten it, but the current form is clear and each batcher is distinct — acceptable.
  • Test global state: the test mutates the process-wide gocore.Config() singleton; the leading default-value assertions assume no other test left those keys dirty. Fine in practice (no t.Parallel), just a latent fragility.

Verdict

Well-engineered, defaulted-off, tested, and verified to build/vet/test clean. The one thing that should block merge as-is is the misleading title and description — a behavioural feature on hot paths is presented as a no-op dependency bump. Fix the metadata (or split the commits) and this is good to go.

@freemans13 freemans13 changed the title chore(deps): bump go-batcher from v2.0.0 to v2.0.3 feat(batcher): per-batcher fixed-cadence flushing (SetTickInterval) + go-batcher v2.0.3 bump Jun 2, 2026
The go-batcher v2.0.3 bump pulled otel/otel/trace/otel/metric to v1.44.0 but
left otel/sdk and the otltrace exporters at v1.43.0 (Go MVS only raised what was
strictly required). Align the remaining direct otel deps (sdk, otltrace,
otltracehttp) to v1.44.0 so the otel surface is uniform; this also raises grpc
and genproto to the versions otltracehttp v1.44.0 requires. Indirect metric
exporters stay at their current versions (not used on the trace path).
@sonarqubecloud

sonarqubecloud Bot commented Jun 2, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
52.2% Coverage on New Code (required ≥ 80%)
5.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@ordishs

ordishs commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Re-review (head 93ac463b2)

Both concerns from the previous review are addressed. Re-verified locally at the updated head.

✅ Resolved

  • Primary issue — metadata. Title is now feat(batcher): per-batcher fixed-cadence flushing (SetTickInterval) + go-batcher v2.0.3 bump, and the body now documents both commits, the 10 new settings (with a key→batcher table), the drain-wins behaviour, the value→pointer rationale, and the otel alignment. The feature is no longer hidden behind a chore(deps) label. 👍
  • Mixed otel versions. New commit 93ac463b2 aligns otel/sdk, otltrace, otltracehttp, and sdk/metric to v1.44.0, so the trace surface is now uniform. This correctly pulls the transitive minimums it requires (grpc 1.80.0→1.81.1, grpc-gateway 2.28→2.29, genproto).

Verification at 93ac463b2

  • go build ./... — OK
  • go vet on validator / blockassembly / sql / settings, plus -tags aerospike on the aerospike store — clean
  • go mod verify — all modules verified; go mod tidy — no diff
  • settings.TestBatcherTickInterval_LoaderReadsAllKeys — passes

(Did not re-run the full validator/sql suites locally — the feature code is unchanged from the prior review, which I verified for correctness; the only delta in this push is the otel go.mod/go.sum alignment.)

🟡 Residual (all non-blocking, unchanged from before)

  • otlptrace/otlptracegrpc remains at v1.42.0 (indirect) while the rest of the trace surface is v1.44.0. It's the gRPC trace exporter, which this repo doesn't use (it's on otltracehttp), so this is cosmetic — but if "uniform otel surface" is the goal, it's the one straggler.
  • SQL store still reads drain from the global BatcherDrainMode but tick from per-batcher UtxoStore.*TickerIntervalMillis — documented, intentional granularity difference.
  • The if ms := ...; ms > 0 { SetTickInterval(...) } boilerplate (~13×) and the test's mutation of the global gocore.Config() singleton — both fine as-is.

Verdict

LGTM. The blocking metadata issue is fixed and the otel surface is tidied. Ship it.

@ordishs ordishs left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving. Both prior-review concerns addressed: the PR is now correctly labeled feat with the feature, 10 new settings, and behavioural notes fully documented, and the otel trace surface is aligned to v1.44.0. Re-verified at head 93ac463 — build, vet (incl. -tags aerospike), go mod verify/tidy, and the settings loader test all clean. The new tick settings default to 0 (disabled), so behaviour is unchanged until tuned. LGTM.

@freemans13 freemans13 merged commit bbb7063 into bsv-blockchain:main Jun 2, 2026
34 checks passed
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.

3 participants