Skip to content

MvP-4597 Upgrade bdk 1.2.4#839

Merged
ctnguyen merged 3 commits into
bsv-blockchain:mainfrom
ctnguyen:Feature/MvP-4597_update_bdk
May 18, 2026
Merged

MvP-4597 Upgrade bdk 1.2.4#839
ctnguyen merged 3 commits into
bsv-blockchain:mainfrom
ctnguyen:Feature/MvP-4597_update_bdk

Conversation

@ctnguyen

@ctnguyen ctnguyen commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Upgrades the embedded gobdk module from v1.2.3v1.2.4 and adapts Teranode's validator service to the renamed/restructured BDK API. Several validator checks (sigops counting, duplicate-input detection, coinbase handling, standardness gating) move from Teranode into BDK; the consumer surface shrinks accordingly. New build-tag-gated integration test scaffolding lets the consensus suite run with or without BDK.

What flowed in from BDK 1.2.3 → 1.2.4

Upstream commits between module/gobdk/v1.2.3 and module/gobdk/v1.2.4:

  • 5faf041 Reimplement validate batch instead of verify batch
  • 5773757 Rename CheckTransactionValidateTransaction
  • 7fee083 MvP-4597 Document skipping points
  • 6a7bd48 MvP-4615 Input value range and in-out value balance checks
  • 70f03b6 MvP-4614 Fix sigop count for p2sh flag gating
  • 22603d7 MvP-4613 Enforce Post-Genesis sigops policy limit
  • 2c8231a MvP-4612 MEMPOOL_HEIGHT untyped error in GetProtocolEra
  • a1f9744 MvP-4606 Fix standardness check gate
  • f939aa3 MvP-4605 Off-by-one era height in the policy path
  • f36dfd5 MvP-4604 Check duplicate inputs
  • 130274d MvP-4603 Add coinbase transaction handling
  • 8c39fcb MvP-4602 Fix missing CheckTransactionCommon checks

Changes on the Teranode side

Validator (services/validator/)

  • ScriptVerifierGoBDK.go: adapts to the CheckTransactionValidateTransaction rename; reworks the batch path to BDK 1.2.4's validate batch semantics; pre-subtracts 1 from block height for policy-mode calls to match BDK's consensus=false uses blockHeight+1 era convention.
  • TxValidator.go: ~250-line reduction. Sigops counting, duplicate-input detection, coinbase handling, and standardness gating now come from BDK rather than being duplicated in Teranode.
  • Validator.go: pipeline wiring adjusted for the renamed/restructured BDK entry points.
  • New ScriptVerifierGoBDK_test.go (+186) covering the renamed API, error-classification mapping, and batch path.

Settings (settings/)

  • policy_settings.go / settings.go: new tunables surfaced for the BDK 1.2.4 policy controls (post-Genesis sigops limit, etc.).

Integration tests (test/consensus/)

  • validator_integration.go trimmed of the duplicated checks now living in BDK.
  • New validator_integration_bdk.go (//go:build bdk) and validator_integration_nobdk.go (//go:build !bdk) split — same interface, two backends, so the consensus suite stays runnable without the BDK build dependency.

Docs

  • docs/references/services/validator_reference.md and docs/topics/services/validator.md updated to reflect the renamed BDK entry points and the shrunk Teranode validator surface.

Behaviour / consensus notes

  • Error classification: BDK's DoS-score classification (core/doserror.hpp) is now the source of truth for whether a reject is policy vs invalid. Teranode's mapping in ScriptVerifierGoBDK.go follows BDK's classification; one disagreement remains and will be adjusted in a follow-up commit on this PR (DOS_ERR_NOT_FREE_CONSOLIDATION — DoS=0, should map to ErrTxPolicy).
  • No consensus-rule changes on Teranode's side beyond what BDK 1.2.4 introduces upstream. The checks that were duplicated in Teranode are removed; the BDK-side implementations are what now governs them.
  • Standardness gate (MvP-4606) and off-by-one era height (MvP-4605) fixes from BDK are pulled in automatically; no Teranode-side migration needed but worth flagging for testnet operators.

Migration / config

  • No DB migration.
  • New policy-setting fields (see settings/policy_settings.go diff) — defaults preserved by NewPolicySettings(); operators with custom settings should re-validate against the new BDK-side limits.

Test plan

  • go test -tags=bdk ./services/validator/...
  • go test ./services/validator/... (nobdk path)
  • go test -tags=bdk ./test/consensus/...
  • Manual: run testnet node against BDK 1.2.4, confirm no regression in policy-reject classification for standard txns.

Linked issue

MvP-4597

@github-actions

github-actions Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

Status: Complete


Summary

This PR successfully upgrades the embedded gobdk module from v1.2.3 to v1.2.4, adapting Teranodes validator to BDKs refactored API. The changes are well-structured, reducing code duplication by moving validation logic into BDK.

No issues found - the changes are clean, well-documented, and correctly implement the BDK 1.2.4 integration.

Key Changes Verified

API Rename: CheckTransaction → ValidateTransaction correctly applied throughout
Policy Settings: New BDK policy controls properly surfaced (MaxTxSizePolicy, MaxSigOpsPostGenesisPolicy, DataCarrier, PermitBareMultisig)
Error Classification: DoS-score mapping updated with BDKs classification, including proper policy vs invalid error handling
Block Height Adjustment: Policy-mode calls correctly subtract 1 from block height to match BDKs era convention
Documentation: All documentation accurately reflects the new BDK-centric validation architecture
Code Reduction: ~250-line reduction in TxValidator.go as duplicate checks moved to BDK
Test Coverage: New tests added for renamed API and error classification

Architecture Impact

The validator surface has shrunk appropriately - Teranode now keeps only the checks that need node context (coinbase routing, MaxCoinsViewCacheSize, fee policy, consolidation exemption), while BDK handles transaction structure, value, standardness, sigops, and scripts. This is the correct separation of concerns.


Review completed following AGENTS.md guidelines - static analysis only, no code execution.

@github-actions

github-actions Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

Benchmark Comparison Report

Baseline: main (unknown)

Current: PR-839 (27eab78)

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.550µ 1.548µ ~ 0.800
SplitSyncedParentMap_SetIfNotExists/256_buckets-4 71.13n 71.22n ~ 1.000
SplitSyncedParentMap_SetIfNotExists/16_buckets-4 71.03n 71.15n ~ 0.700
SplitSyncedParentMap_SetIfNotExists/1_bucket-4 71.03n 71.01n ~ 1.000
SplitSyncedParentMap_ConcurrentSetIfNotExists/256_buckets... 31.40n 32.18n ~ 0.100
SplitSyncedParentMap_ConcurrentSetIfNotExists/16_buckets_... 53.14n 55.10n ~ 0.100
SplitSyncedParentMap_ConcurrentSetIfNotExists/1_bucket_pa... 125.3n 132.5n ~ 0.100
MiningCandidate_Stringify_Short-4 223.3n 222.7n ~ 0.700
MiningCandidate_Stringify_Long-4 1.618µ 1.599µ ~ 0.100
MiningSolution_Stringify-4 842.8n 836.8n ~ 0.100
BlockInfo_MarshalJSON-4 1.706µ 1.715µ ~ 0.400
NewFromBytes-4 123.2n 123.1n ~ 0.800
Mine_EasyDifficulty-4 60.79µ 61.08µ ~ 0.700
Mine_WithAddress-4 7.302µ 6.841µ ~ 0.700
BlockAssembler_AddTx-4 0.02840n 0.02860n ~ 1.000
AddNode-4 10.03 10.78 ~ 0.200
AddNodeWithMap-4 10.91 10.46 ~ 0.700
DirectSubtreeAdd/4_per_subtree-4 57.82n 58.16n ~ 1.000
DirectSubtreeAdd/64_per_subtree-4 29.32n 29.54n ~ 1.000
DirectSubtreeAdd/256_per_subtree-4 27.89n 27.79n ~ 0.200
DirectSubtreeAdd/1024_per_subtree-4 26.58n 26.41n ~ 0.100
DirectSubtreeAdd/2048_per_subtree-4 26.12n 25.92n ~ 0.100
SubtreeProcessorAdd/4_per_subtree-4 282.5n 284.6n ~ 0.400
SubtreeProcessorAdd/64_per_subtree-4 275.7n 282.7n ~ 0.200
SubtreeProcessorAdd/256_per_subtree-4 275.8n 281.2n ~ 0.100
SubtreeProcessorAdd/1024_per_subtree-4 268.4n 272.6n ~ 0.100
SubtreeProcessorAdd/2048_per_subtree-4 268.6n 273.7n ~ 0.100
SubtreeProcessorRotate/4_per_subtree-4 272.5n 273.3n ~ 0.300
SubtreeProcessorRotate/64_per_subtree-4 270.6n 270.7n ~ 1.000
SubtreeProcessorRotate/256_per_subtree-4 269.5n 271.5n ~ 0.100
SubtreeProcessorRotate/1024_per_subtree-4 270.8n 269.9n ~ 0.500
SubtreeNodeAddOnly/4_per_subtree-4 55.25n 55.10n ~ 0.200
SubtreeNodeAddOnly/64_per_subtree-4 36.11n 36.02n ~ 0.400
SubtreeNodeAddOnly/256_per_subtree-4 35.23n 34.96n ~ 0.100
SubtreeNodeAddOnly/1024_per_subtree-4 34.51n 34.53n ~ 0.500
SubtreeCreationOnly/4_per_subtree-4 111.3n 111.0n ~ 0.400
SubtreeCreationOnly/64_per_subtree-4 353.1n 349.0n ~ 0.100
SubtreeCreationOnly/256_per_subtree-4 1.227µ 1.229µ ~ 0.600
SubtreeCreationOnly/1024_per_subtree-4 3.781µ 3.739µ ~ 0.100
SubtreeCreationOnly/2048_per_subtree-4 6.857µ 6.714µ ~ 0.100
SubtreeProcessorOverheadBreakdown/64_per_subtree-4 272.6n 271.4n ~ 1.000
SubtreeProcessorOverheadBreakdown/1024_per_subtree-4 270.0n 271.8n ~ 0.100
ParallelGetAndSetIfNotExists/1k_nodes-4 554.8µ 549.9µ ~ 0.700
ParallelGetAndSetIfNotExists/10k_nodes-4 1.329m 1.348m ~ 0.700
ParallelGetAndSetIfNotExists/50k_nodes-4 6.594m 6.632m ~ 1.000
ParallelGetAndSetIfNotExists/100k_nodes-4 13.20m 13.47m ~ 0.100
SequentialGetAndSetIfNotExists/1k_nodes-4 635.9µ 625.0µ ~ 0.200
SequentialGetAndSetIfNotExists/10k_nodes-4 2.917m 2.937m ~ 1.000
SequentialGetAndSetIfNotExists/50k_nodes-4 11.32m 11.23m ~ 0.700
SequentialGetAndSetIfNotExists/100k_nodes-4 22.60m 21.34m ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/1k_nodes-4 593.7µ 597.6µ ~ 0.700
ProcessOwnBlockSubtreeNodesParallel/10k_nodes-4 4.624m 4.643m ~ 0.400
ProcessOwnBlockSubtreeNodesParallel/100k_nodes-4 16.96m 16.76m ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/1k_nodes-4 691.8µ 661.9µ ~ 0.100
ProcessOwnBlockSubtreeNodesSequential/10k_nodes-4 6.412m 6.496m ~ 0.700
ProcessOwnBlockSubtreeNodesSequential/100k_nodes-4 39.94m 40.77m ~ 0.100
DiskTxMap_SetIfNotExists-4 3.683µ 3.803µ ~ 0.300
DiskTxMap_SetIfNotExists_Parallel-4 3.654µ 3.575µ ~ 0.400
DiskTxMap_ExistenceOnly-4 311.5n 317.5n ~ 0.700
Queue-4 185.7n 184.1n ~ 0.400
AtomicPointer-4 3.308n 3.670n ~ 0.100
ReorgOptimizations/DedupFilterPipeline/Old/10K-4 797.2µ 796.2µ ~ 0.400
ReorgOptimizations/DedupFilterPipeline/New/10K-4 761.7µ 763.1µ ~ 0.400
ReorgOptimizations/AllMarkFalse/Old/10K-4 103.2µ 101.8µ ~ 0.100
ReorgOptimizations/AllMarkFalse/New/10K-4 64.04µ 64.23µ ~ 0.100
ReorgOptimizations/HashSlicePool/Old/10K-4 51.86µ 50.43µ ~ 0.700
ReorgOptimizations/HashSlicePool/New/10K-4 11.58µ 11.29µ ~ 0.200
ReorgOptimizations/NodeFlags/Old/10K-4 4.485µ 4.480µ ~ 1.000
ReorgOptimizations/NodeFlags/New/10K-4 1.559µ 1.542µ ~ 0.200
ReorgOptimizations/DedupFilterPipeline/Old/100K-4 9.415m 9.856m ~ 0.200
ReorgOptimizations/DedupFilterPipeline/New/100K-4 10.071m 9.522m ~ 0.700
ReorgOptimizations/AllMarkFalse/Old/100K-4 1.074m 1.075m ~ 1.000
ReorgOptimizations/AllMarkFalse/New/100K-4 703.7µ 706.2µ ~ 0.400
ReorgOptimizations/HashSlicePool/Old/100K-4 487.9µ 478.9µ ~ 0.700
ReorgOptimizations/HashSlicePool/New/100K-4 194.5µ 194.6µ ~ 1.000
ReorgOptimizations/NodeFlags/Old/100K-4 48.45µ 48.65µ ~ 0.400
ReorgOptimizations/NodeFlags/New/100K-4 16.67µ 17.02µ ~ 0.100
TxMapSetIfNotExists-4 47.12n 46.91n ~ 0.400
TxMapSetIfNotExistsDuplicate-4 39.16n 38.70n ~ 0.100
ChannelSendReceive-4 574.1n 607.2n ~ 0.100
CalcBlockWork-4 492.5n 501.7n ~ 0.100
CalculateWork-4 671.8n 676.2n ~ 0.700
BuildBlockLocatorString_Helpers/Size_10-4 1.292µ 1.342µ ~ 0.100
BuildBlockLocatorString_Helpers/Size_100-4 12.36µ 12.95µ ~ 0.100
BuildBlockLocatorString_Helpers/Size_1000-4 148.5µ 159.8µ ~ 0.700
CatchupWithHeaderCache-4 104.3m 104.3m ~ 0.200
SubtreeSizes/10k_tx_4_per_subtree-4 1.318m 1.360m ~ 0.700
SubtreeSizes/10k_tx_16_per_subtree-4 312.7µ 314.8µ ~ 1.000
SubtreeSizes/10k_tx_64_per_subtree-4 74.42µ 75.81µ ~ 0.100
SubtreeSizes/10k_tx_256_per_subtree-4 18.81µ 19.21µ ~ 0.400
SubtreeSizes/10k_tx_512_per_subtree-4 9.232µ 9.463µ ~ 0.100
SubtreeSizes/10k_tx_1024_per_subtree-4 4.560µ 4.677µ ~ 0.100
SubtreeSizes/10k_tx_2k_per_subtree-4 2.309µ 2.336µ ~ 0.200
BlockSizeScaling/10k_tx_64_per_subtree-4 73.12µ 74.72µ ~ 0.100
BlockSizeScaling/10k_tx_256_per_subtree-4 18.73µ 19.05µ ~ 0.400
BlockSizeScaling/10k_tx_1024_per_subtree-4 4.588µ 4.649µ ~ 0.700
BlockSizeScaling/50k_tx_64_per_subtree-4 384.9µ 395.1µ ~ 0.200
BlockSizeScaling/50k_tx_256_per_subtree-4 91.99µ 94.96µ ~ 0.100
BlockSizeScaling/50k_tx_1024_per_subtree-4 22.99µ 23.50µ ~ 0.100
SubtreeAllocations/small_subtrees_exists_check-4 160.5µ 155.5µ ~ 0.100
SubtreeAllocations/small_subtrees_data_fetch-4 161.7µ 167.1µ ~ 0.100
SubtreeAllocations/small_subtrees_full_validation-4 320.1µ 328.7µ ~ 0.100
SubtreeAllocations/medium_subtrees_exists_check-4 9.352µ 9.323µ ~ 0.700
SubtreeAllocations/medium_subtrees_data_fetch-4 9.480µ 9.797µ ~ 0.100
SubtreeAllocations/medium_subtrees_full_validation-4 18.63µ 19.09µ ~ 0.100
SubtreeAllocations/large_subtrees_exists_check-4 2.207µ 2.229µ ~ 0.400
SubtreeAllocations/large_subtrees_data_fetch-4 2.327µ 2.385µ ~ 0.100
SubtreeAllocations/large_subtrees_full_validation-4 4.662µ 4.791µ ~ 0.100
_BufferPoolAllocation/16KB-4 3.227µ 3.652µ ~ 0.100
_BufferPoolAllocation/32KB-4 8.007µ 9.308µ ~ 0.400
_BufferPoolAllocation/64KB-4 15.57µ 17.67µ ~ 0.200
_BufferPoolAllocation/128KB-4 31.67µ 36.97µ ~ 0.100
_BufferPoolAllocation/512KB-4 103.1µ 104.8µ ~ 0.700
_BufferPoolConcurrent/32KB-4 15.63µ 18.29µ ~ 0.100
_BufferPoolConcurrent/64KB-4 24.96µ 28.43µ ~ 0.100
_BufferPoolConcurrent/512KB-4 131.0µ 140.4µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/16KB-4 587.6µ 645.4µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/32KB-4 588.5µ 636.1µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/64KB-4 580.8µ 631.4µ ~ 0.100
_SubtreeDeserializationWithBufferSizes/128KB-4 583.4µ 585.0µ ~ 0.700
_SubtreeDeserializationWithBufferSizes/512KB-4 580.9µ 601.5µ ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/16KB-4 36.37m 35.86m ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/32KB-4 36.51m 36.02m ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/64KB-4 35.99m 35.86m ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/128KB-4 36.39m 36.30m ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/512KB-4 36.64m 35.67m ~ 0.700
_PooledVsNonPooled/Pooled-4 833.5n 832.7n ~ 1.000
_PooledVsNonPooled/NonPooled-4 5.988µ 7.871µ ~ 0.100
_MemoryFootprint/Current_512KB_32concurrent-4 6.742µ 6.646µ ~ 0.400
_MemoryFootprint/Proposed_32KB_32concurrent-4 8.758µ 9.221µ ~ 0.100
_MemoryFootprint/Alternative_64KB_32concurrent-4 8.709µ 8.823µ ~ 0.400
_prepareTxsPerLevel-4 405.6m 398.8m ~ 0.400
_prepareTxsPerLevelOrdered-4 3.701m 3.746m ~ 0.700
_prepareTxsPerLevel_Comparison/Original-4 414.3m 399.1m ~ 0.200
_prepareTxsPerLevel_Comparison/Optimized-4 3.797m 3.820m ~ 1.000
StoreBlock_Sequential/BelowCSVHeight-4 251.2µ 250.6µ ~ 1.000
StoreBlock_Sequential/AboveCSVHeight-4 250.3µ 251.6µ ~ 1.000
GetUtxoHashes-4 272.4n 271.7n ~ 1.000
GetUtxoHashes_ManyOutputs-4 46.16µ 45.79µ ~ 0.700
_NewMetaDataFromBytes-4 232.3n 229.1n ~ 0.100
_Bytes-4 610.9n 602.8n ~ 0.100
_MetaBytes-4 555.2n 558.2n ~ 1.000

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

@ctnguyen ctnguyen force-pushed the Feature/MvP-4597_update_bdk branch from a719f3c to f0e134d Compare May 11, 2026 06:59

@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.

Thanks for the upgrade. Two real fixes wanted before merge, plus a handful of nits.

Must-fix

1. DoS misclassification — DOS_ERR_NOT_FREE_CONSOLIDATIONErrTxInvalid (should be ErrTxPolicy)

BDK's core/doserror.hpp lists DOS_ERR_NOT_FREE_CONSOLIDATION with DoS=0, i.e. policy. The mapping in services/validator/ScriptVerifierGoBDK.go classifies it as ErrTxInvalid, and the new test at services/validator/ScriptVerifierGoBDK_test.go:207 encodes that. If a peer relays a non-free-consolidation tx, the node will treat it as invalid and ban — that's a peer-banning consequence for a policy reject. Re-map to ErrTxPolicy (and update the test to match).

2. TestCheckP2SHOutput is a no-op stub (services/validator/TxValidator_test.go:661-676)

The body is now _ = txValidator; _ = txP2SH — no assertions. P2SH-output coverage on the Teranode side drops to zero with this PR. Either restore the assertions against the BDK path, or delete the test if the check now lives entirely in BDK and is covered upstream.

Nits

  • Test_ScriptVerificationGoBDK uses zero-defaulted settings.NewPolicySettings(), but TestMaxTxSizePolicy carries a comment saying "BDK rejects values below 99999". One of the two is wrong — either the test will be rejected at construction, or the comment is stale.
  • bdkBlockHeight pre-subtracts 1 in policy mode (services/validator/ScriptVerifierGoBDK.go:166-176). Semantically correct vs BDK 1.2.4's consensus=false uses blockHeight+1 era convention, but the rationale isn't obvious at the call site — please add a one-line comment.
  • Deleted constants MaxBlockSize, MaxTxSizeConsensus*, MaxTxSigopsCountPolicyAfterGenesis — grep is clean, but please confirm block-validation still has an effective bound from the BDK side (just a sanity-check).
  • NewPolicySettings() still returns zero defaults with // TODO set defaults (settings/policy_settings.go:35-39). This PR widens the consumer surface; would be a good moment to either tackle the TODO or document why zero is the right default.
  • Stale pushDataCheck reference in docs/references/services/validator_reference.md:230 — pre-existing, but the PR touches the file, easy to fix in-flight.

Happy to re-approve once the two must-fix items are in.

@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.

Thanks for the quick turnaround. Both must-fix items resolved cleanly in a3b46755:

  • MF1 (DOS_ERR_NOT_FREE_CONSOLIDATIONErrTxPolicy) — mapping moved into the policy-codes case at ScriptVerifierGoBDK.go:214; test at ScriptVerifierGoBDK_test.go:205 flipped to wantPolicy: true. Locked in across both consensus modes.
  • MF2 (TestCheckP2SHOutput) — restored with stronger assertions than the original. NotErrorIs(err, ErrTxPolicy) pins this as a consensus rejection (which it is post-Genesis), and SkipPolicyChecks: true ensures the test doesn't accidentally pass via the policy bypass. Nice fix.

Also liked the 9b3f80f8 cleanup txvalidator interface commit — dropping the GoBT/GoSDK alternates and the two-phase API simplifies the validator surface considerably.

Approving. A few housekeeping items still open from the original review, none gating — fold into a follow-up commit whenever or carry as separate issues:

  • bdkBlockHeight pre-subtract at ScriptVerifierGoBDK.go:162-172 could use a one-line comment explaining BDK 1.2.4's consensus=false → blockHeight+1 era convention so the next reader doesn't suspect an off-by-one.
  • NewPolicySettings() still returns zero-defaults with // TODO set defaults. Test usage proves BDK treats zero as unlimited, so not broken — but consider renaming to EmptyPolicySettings() or populating from struct tags.
  • docs/references/services/validator_reference.md:209 still lists pushDataCheck(tx *bt.Tx) which doesn't exist anywhere in the package.

One operational note worth flagging before prod rollout: bumping to 1.2.4 doesn't fix the testnet 245k-OP_2DUP+OP_CHECKSIGVERIFY hang — that's BDK PR #41, expected in v1.2.5. The go.mod warning comment about #41 was removed in the fix commit; worth a one-line note in the PR description (or an updated go.mod comment) so the next reader understands why the pin moved without #41 having landed. Existing alert regexes matching _Cfunc_ScriptEngine_VerifyScript will also need to be widened to match _Cfunc_TxValidator_ValidateTransaction post-upgrade, since the symbol moved.

@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 — the architectural shift (Teranode → BDK for tx structure/sigops/standardness/output checks) is a clear improvement, and the bdkValidator interface gives clean test injection. Strong coverage in the new boundary tests (TestBDKBlockHeight, TestScriptVerifierGoBDKMapDoSErrors, TestScriptVerifierGoBDKMapScriptErrors).

A few minor cleanups worth addressing in this PR or a follow-up:

Worth a second look before merge:

  1. Behavioural change in TestTx5f37c7a38b5e0bc177a4c353481f30c6de1bc46db534019846d7bc829f58254a (services/validator/TxValidator_test.go:743) — historical tx now rejected with ErrTxInvalid under consensus mode. Test expectation flipped without a comment explaining which BDK 1.2.4 check newly rejects it (MvP-4615 input value range?). One-line comment would help future debugging.

  2. bdkBlockHeight rejects blockHeight=0 in policy mode (ScriptVerifierGoBDK.go:141). Correct in principle, but a new failure mode — worth confirming no mempool/test path hits this.

Non-blocking polish:

  1. Opaque "T14 parity decision" comment in TxValidator.checkInputs — future maintainers won't know what T14 references. Link the tracking issue or restate as "SVNode parity, tracked in MvP-XXXX".

  2. Dead params in checkInputs — after the dedup logic was removed, blockHeight and validationOptions are unused (the _ = blockHeight comment claiming "required by the interface" is no longer true). Either drop the params or inline the ~15 remaining lines into ValidateTransaction.

  3. BenchmarkConsolidationValidationImpact (TxValidator_benchmark_test.go:135) leaves tv.bdk nil after removing interpreter:. Works today since only checkFees/isConsolidationTx are called, but it's a footgun — set bdk: noopBDKValidator{} for safety.

  4. TestMaxTxSigopsCountsPolicy skipped "until a focused BDK ValidateTransaction sigops-policy fixture is added" — given MvP-4613 is a headline behaviour in this PR, please track that fixture in an issue rather than leaving the skip dangling.

  5. Direct txValidator.bdk = noopBDKValidator{} mutation in Test_MinFeePolicy and Validator_test.go is awkward — consider a WithBDKValidator(...) option on NewTxValidator if this injection becomes recurring.

  6. PR description states DOS_ERR_NOT_FREE_CONSOLIDATION mapping is a "follow-up" item, but the code already maps it to ErrTxPolicy (ScriptVerifierGoBDK.go:165). Either the description is stale or there's a different disagreement still to resolve — please clarify.

  7. Stale namingScriptVerifierGoBDK.go / scriptVerifierGoBDK no longer "verify scripts"; they adapt to BDK's full transaction validator. Reasonable to defer for diff minimality, but worth a follow-up rename.

  8. Please tick the test-plan checkboxes (-tags=bdk and nobdk paths, test/consensus) before merge so reviewers can confirm verification ran.

@ctnguyen ctnguyen force-pushed the Feature/MvP-4597_update_bdk branch from a3b4675 to cd0f09e Compare May 18, 2026 05:59
@sonarqubecloud

Copy link
Copy Markdown

@ctnguyen ctnguyen merged commit b61c1f8 into bsv-blockchain:main May 18, 2026
27 of 28 checks passed
@ctnguyen ctnguyen deleted the Feature/MvP-4597_update_bdk branch May 18, 2026 08:50
icellan added a commit that referenced this pull request May 18, 2026
Conflict: go.mod — main bumped gobdk to v1.2.5-... in #839. Took main's
newer version and dropped the obsolete "DO NOT bump to v1.2.4" comment,
since PR #41 has now merged. The PR's BSV aerospike-client fork line
was preserved alongside.
icellan added a commit that referenced this pull request May 26, 2026
Adopt main's BDK-only validator architecture (MvP-4597, #839):

- Delete ScriptVerifierGoBT.go and ScriptVerifierGoSDK.go (removed on
  main)
- Take main's TxValidator.go (no interpreter registry, BDK direct)
- Take main's ScriptVerifierGoBDK.go (BDK 1.2.5 API)
- Take main's go.mod versions (BDK 1.2.5, go-bt 2.6.3,
  go-chaincfg 1.5.8, go-sdk 1.2.23, go-subtree 1.4.1, plus
  ginkgo/gomega/rapid additions)
- Drop ValidateTransactionScriptsBatch / VerifyScriptBatch plumbing
  and the validator_scriptBatchThreads setting; no callers and the
  API on BDK 1.2.5 differs (NewValidateBatch / ValidateBatch, no
  per-call thread count). Batch verification can be reintroduced in a
  follow-up if and when a consumer is added.
- Remove TestMaxScriptNumLengthPolicy skip; the test passes against
  BDK 1.2.5.
- Keep both PR 655's docker-build / docker-build-purego targets and
  main's network-chaos-test target in the Makefile.
- Keep PR 655's Dockerfile.purego, CI purego build, and
  daemon/test_daemon !prod build tags as-is.

Validator and settings packages build and test clean against the
merged tree.
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