Skip to content

fix(legacy): fetch blocks from the asset service with the trusted HTTP client (stacked on #1675) - #1677

Open
ordishs wants to merge 8 commits into
bsv-blockchain:mainfrom
ordishs:feat/svp2p-legacy-trusted-fetch
Open

fix(legacy): fetch blocks from the asset service with the trusted HTTP client (stacked on #1675)#1677
ordishs wants to merge 8 commits into
bsv-blockchain:mainfrom
ordishs:feat/svp2p-legacy-trusted-fetch

Conversation

@ordishs

@ordishs ordishs commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stacked on #1675 — only the last commit (f41c103da) is new; the rest is the svp2p service branch.

asset_httpAddress is an operator-configured URL whose default is http://localhost. The legacy service reads blocks from it through the shared peer-facing HTTP client, whose SSRF dial policy blocks loopback — so a single-process node cannot serve a block over legacy P2P. This switches that one call to util.DoTrustedHTTPRequestBodyReader (introduced in #1675), which keeps the scheme validation and redirect bound but skips the peer-address policy. Do not route peer-derived URLs through it.

One line changed in services/legacy/peer_server.go.

The TTL cleaner reads the height on its own goroutine while services write it
from a blockchain subscription; the svp2p parity harness reports the race on
CI.
The legacy_* keys the service reads (with legacy_config_* fallbacks for keys
the legacy service reads reflectively), the SubscriberSVP2P source name and
its RPC gate, the trusted-fetch helper for operator-configured URLs, and the
in-memory Kafka additions the service tests use.
Port of SVNode net.cpp/net_processing.cpp semantics: transport (association
streams, extended >4 GiB frames), protocol (handshake, addrman, headers-first
sync, multi-peer block download, serving, BIP152 compact block receive),
bridge to the Teranode pipeline, scripted-peer test harness and a legacy/svp2p
parity harness. Ported rules cite the C++ source line.
Off by default: starts only with -svp2p=1 or startSvp2p=true, and the daemon
refuses to run it together with the legacy service (shared ports and
settings).
@ordishs ordishs added the svp2p Legacy P2P bridge rewrite (services/svp2p) label Aug 31, 2026
@socket-security

socket-security Bot commented Aug 31, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedgolang/​github.com/​bsv-blockchain/​go-wire@​v1.2.11 ⏵ v1.2.1387 +1100100100100

View full report

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

🤖 Claude Code Review

Status: Complete

This PR is stacked on #1675; only the final commit (411b1db7) is new — a one-line change in services/legacy/peer_server.go. The svp2p service (the bulk of the +72k diff / 190 files) belongs to #1675 and is reviewed there.

Current Review:

  • No issues found.

The change swaps util.DoHTTPRequestBodyReaderutil.DoTrustedHTTPRequestBodyReader when the legacy service fetches a block from its own asset service to serve a getdata. This is sound:

  • The URL host/scheme come from asset_httpAddress (operator config via s.settings.Asset.HTTPAddress), not from the peer. The only peer-influenced segment is hash.String(), a fixed 64-char hex path element — no host/scheme injection.
  • DoTrustedHTTPRequestBodyReader still runs ValidateURL (scheme check) and keeps the redirect bound; it only drops the loopback/link-local dial policy, which is exactly what's needed so a single-process node (default http://localhost) can serve blocks.
  • Matches the documented contract on trustedHTTPClient, which explicitly names the legacy service as an intended caller.

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Benchmark Comparison Report

Baseline: main (unknown)

Current: PR-1677 (0d6bb13)

Summary

  • Regressions: 0
  • Improvements: 0
  • Unchanged: 139
  • Significance level: p < 0.05
All benchmark results (sec/op)
Benchmark Baseline Current Change p-value
_NewBlockFromBytes-4 1.747µ 1.724µ ~ 0.100
Block_ValidOrderAndBlessed_DiskVsMemory/leaves=1024/memory-4 12.82m 12.83m ~ 1.000
Block_ValidOrderAndBlessed_DiskVsMemory/leaves=1024/disk_1-4 12.26m 12.39m ~ 0.400
Block_ValidOrderAndBlessed_DiskVsMemory/leaves=1024/disk_2-4 12.55m 12.64m ~ 0.400
Block_ValidOrderAndBlessed_DiskVsMemory/leaves=16384/memo... 30.87m 31.48m ~ 1.000
Block_ValidOrderAndBlessed_DiskVsMemory/leaves=16384/disk... 36.77m 36.80m ~ 1.000
Block_ValidOrderAndBlessed_DiskVsMemory/leaves=16384/disk... 36.46m 36.87m ~ 0.400
SplitSyncedParentMap_SetIfNotExists/256_buckets-4 59.27n 59.25n ~ 0.800
SplitSyncedParentMap_SetIfNotExists/16_buckets-4 59.24n 59.25n ~ 1.000
SplitSyncedParentMap_SetIfNotExists/1_bucket-4 62.42n 59.19n ~ 0.700
SplitSyncedParentMap_ConcurrentSetIfNotExists/256_buckets... 34.98n 33.62n ~ 0.700
SplitSyncedParentMap_ConcurrentSetIfNotExists/16_buckets_... 63.47n 59.74n ~ 0.200
SplitSyncedParentMap_ConcurrentSetIfNotExists/1_bucket_pa... 150.7n 146.1n ~ 0.200
MiningCandidate_Stringify_Short-4 232.1n 231.1n ~ 0.400
MiningCandidate_Stringify_Long-4 1.572µ 1.561µ ~ 0.400
MiningSolution_Stringify-4 796.2n 790.1n ~ 0.700
BlockInfo_MarshalJSON-4 1.655µ 1.643µ ~ 0.400
NewFromBytes-4 129.5n 128.5n ~ 0.600
AddTxBatchColumnar_Validation-4 2.025µ 2.021µ ~ 0.700
OffsetValidationLoop-4 642.3n 641.8n ~ 1.000
Mine_EasyDifficulty-4 61.06µ 62.28µ ~ 0.200
Mine_WithAddress-4 7.195µ 7.253µ ~ 0.200
DirectSubtreeAdd/4_per_subtree-4 63.77n 59.08n ~ 0.100
DirectSubtreeAdd/64_per_subtree-4 30.29n 30.87n ~ 0.200
DirectSubtreeAdd/256_per_subtree-4 29.78n 29.35n ~ 0.200
DirectSubtreeAdd/1024_per_subtree-4 28.24n 28.21n ~ 1.000
DirectSubtreeAdd/2048_per_subtree-4 27.86n 27.65n ~ 0.100
SubtreeProcessorAdd/4_per_subtree-4 239.4n 242.7n ~ 1.000
SubtreeProcessorAdd/64_per_subtree-4 240.2n 234.9n ~ 0.200
SubtreeProcessorAdd/256_per_subtree-4 239.8n 239.1n ~ 1.000
SubtreeProcessorAdd/1024_per_subtree-4 229.2n 232.2n ~ 0.200
SubtreeProcessorAdd/2048_per_subtree-4 231.2n 233.1n ~ 0.400
SubtreeProcessorRotate/4_per_subtree-4 233.5n 232.8n ~ 1.000
SubtreeProcessorRotate/64_per_subtree-4 231.4n 232.3n ~ 1.000
SubtreeProcessorRotate/256_per_subtree-4 232.7n 232.8n ~ 1.000
SubtreeProcessorRotate/1024_per_subtree-4 231.8n 237.0n ~ 0.100
SubtreeNodeAddOnly/4_per_subtree-4 54.92n 59.85n ~ 0.100
SubtreeNodeAddOnly/64_per_subtree-4 34.36n 35.01n ~ 0.100
SubtreeNodeAddOnly/256_per_subtree-4 33.43n 33.70n ~ 0.100
SubtreeNodeAddOnly/1024_per_subtree-4 32.95n 33.39n ~ 0.400
SubtreeCreationOnly/4_per_subtree-4 120.0n 144.2n ~ 0.100
SubtreeCreationOnly/64_per_subtree-4 424.2n 415.4n ~ 0.700
SubtreeCreationOnly/256_per_subtree-4 1.334µ 1.404µ ~ 0.100
SubtreeCreationOnly/1024_per_subtree-4 4.415µ 5.048µ ~ 0.100
SubtreeCreationOnly/2048_per_subtree-4 7.891µ 8.811µ ~ 0.100
SubtreeProcessorOverheadBreakdown/64_per_subtree-4 232.1n 230.9n ~ 0.600
SubtreeProcessorOverheadBreakdown/1024_per_subtree-4 232.8n 232.3n ~ 1.000
ParallelGetAndSetIfNotExists/1k_nodes-4 10.35m 14.02m ~ 0.100
ParallelGetAndSetIfNotExists/10k_nodes-4 13.68m 16.57m ~ 0.100
ParallelGetAndSetIfNotExists/50k_nodes-4 17.60m 17.70m ~ 1.000
ParallelGetAndSetIfNotExists/100k_nodes-4 19.84m 19.61m ~ 1.000
SequentialGetAndSetIfNotExists/1k_nodes-4 11.11m 13.40m ~ 0.100
SequentialGetAndSetIfNotExists/10k_nodes-4 17.13m 19.79m ~ 0.700
SequentialGetAndSetIfNotExists/50k_nodes-4 31.34m 28.22m ~ 0.100
SequentialGetAndSetIfNotExists/100k_nodes-4 41.01m 40.62m ~ 0.700
ProcessOwnBlockSubtreeNodesParallel/1k_nodes-4 13.20m 11.21m ~ 0.700
ProcessOwnBlockSubtreeNodesParallel/10k_nodes-4 15.62m 15.99m ~ 0.100
ProcessOwnBlockSubtreeNodesParallel/100k_nodes-4 22.23m 23.52m ~ 0.400
ProcessOwnBlockSubtreeNodesSequential/1k_nodes-4 10.78m 12.98m ~ 0.700
ProcessOwnBlockSubtreeNodesSequential/10k_nodes-4 17.78m 16.92m ~ 0.400
ProcessOwnBlockSubtreeNodesSequential/100k_nodes-4 57.81m 59.35m ~ 1.000
DiskTxMap_SetIfNotExists-4 3.964µ 3.770µ ~ 0.100
DiskTxMap_SetIfNotExists_Parallel-4 3.847µ 3.645µ ~ 0.100
DiskTxMap_ExistenceOnly-4 404.1n 328.7n ~ 0.100
Queue-4 192.2n 186.4n ~ 0.100
AtomicPointer-4 3.258n 3.239n ~ 0.700
TxMapSetIfNotExists-4 49.92n 49.47n ~ 0.700
TxMapSetIfNotExistsDuplicate-4 41.67n 41.61n ~ 0.600
ChannelSendReceive-4 562.7n 575.6n ~ 0.400
BlockAssembler_AddTx-4 0.02001n 0.02332n ~ 0.700
AddNode-4 10.37 10.57 ~ 0.700
AddNodeWithMap-4 11.30 11.08 ~ 0.400
CalcBlockWork-4 468.2n 469.2n ~ 1.000
CalculateWork-4 635.5n 626.9n ~ 0.400
CheckOldBlockIDs/on-chain-prefetch/1000-4 61.23µ 60.56µ ~ 0.400
CheckOldBlockIDs/in-memory-chain-check/1000-4 1.449m 1.454m ~ 1.000
CheckOldBlockIDs/on-chain-prefetch/10000-4 460.8µ 453.2µ ~ 0.100
CheckOldBlockIDs/in-memory-chain-check/10000-4 2.092m 2.108m ~ 0.700
BuildBlockLocatorString_Helpers/Size_10-4 1.348µ 1.349µ ~ 0.700
BuildBlockLocatorString_Helpers/Size_100-4 12.87µ 12.88µ ~ 1.000
BuildBlockLocatorString_Helpers/Size_1000-4 127.5µ 127.3µ ~ 1.000
CatchupWithHeaderCache-4 106.4m 106.5m ~ 0.200
_BufferPoolAllocation/16KB-4 4.818µ 4.906µ ~ 0.200
_BufferPoolAllocation/32KB-4 10.379µ 9.483µ ~ 0.700
_BufferPoolAllocation/64KB-4 24.61µ 26.72µ ~ 0.700
_BufferPoolAllocation/128KB-4 39.25µ 39.49µ ~ 1.000
_BufferPoolAllocation/512KB-4 131.6µ 139.3µ ~ 0.700
_BufferPoolConcurrent/32KB-4 25.49µ 24.57µ ~ 0.700
_BufferPoolConcurrent/64KB-4 39.93µ 39.54µ ~ 1.000
_BufferPoolConcurrent/512KB-4 188.1µ 182.8µ ~ 0.400
_SubtreeDeserializationWithBufferSizes/16KB-4 824.1µ 823.5µ ~ 1.000
_SubtreeDeserializationWithBufferSizes/32KB-4 796.4µ 811.3µ ~ 0.700
_SubtreeDeserializationWithBufferSizes/64KB-4 762.8µ 815.1µ ~ 0.200
_SubtreeDeserializationWithBufferSizes/128KB-4 762.4µ 737.6µ ~ 0.200
_SubtreeDeserializationWithBufferSizes/512KB-4 760.2µ 767.9µ ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/16KB-4 42.11m 42.20m ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/32KB-4 42.40m 41.67m ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/64KB-4 41.25m 42.07m ~ 0.100
_SubtreeDataDeserializationWithBufferSizes/128KB-4 43.83m 43.13m ~ 1.000
_SubtreeDataDeserializationWithBufferSizes/512KB-4 45.08m 42.81m ~ 0.200
_PooledVsNonPooled/Pooled-4 876.6n 903.3n ~ 0.200
_PooledVsNonPooled/NonPooled-4 9.341µ 10.738µ ~ 0.100
_MemoryFootprint/Current_512KB_32concurrent-4 7.900µ 8.680µ ~ 0.100
_MemoryFootprint/Proposed_32KB_32concurrent-4 12.01µ 11.30µ ~ 0.100
_MemoryFootprint/Alternative_64KB_32concurrent-4 11.41µ 10.85µ ~ 0.100
_prepareTxsPerLevel-4 398.2m 401.8m ~ 1.000
_prepareTxsPerLevelOrdered-4 3.683m 3.752m ~ 0.700
_prepareTxsPerLevel_Comparison/Original-4 402.7m 398.7m ~ 0.200
_prepareTxsPerLevel_Comparison/Optimized-4 3.812m 3.970m ~ 0.100
SubtreeSizes/10k_tx_4_per_subtree-4 1.279m 1.277m ~ 1.000
SubtreeSizes/10k_tx_16_per_subtree-4 302.7µ 301.7µ ~ 0.400
SubtreeSizes/10k_tx_64_per_subtree-4 74.77µ 72.21µ ~ 0.100
SubtreeSizes/10k_tx_256_per_subtree-4 18.18µ 18.18µ ~ 0.700
SubtreeSizes/10k_tx_512_per_subtree-4 9.044µ 8.907µ ~ 0.200
SubtreeSizes/10k_tx_1024_per_subtree-4 4.489µ 4.457µ ~ 1.000
SubtreeSizes/10k_tx_2k_per_subtree-4 2.243µ 2.218µ ~ 0.700
BlockSizeScaling/10k_tx_64_per_subtree-4 71.11µ 72.45µ ~ 0.200
BlockSizeScaling/10k_tx_256_per_subtree-4 18.26µ 18.01µ ~ 0.100
BlockSizeScaling/10k_tx_1024_per_subtree-4 4.569µ 4.476µ ~ 0.100
BlockSizeScaling/50k_tx_64_per_subtree-4 361.1µ 362.2µ ~ 0.400
BlockSizeScaling/50k_tx_256_per_subtree-4 90.24µ 88.78µ ~ 0.200
BlockSizeScaling/50k_tx_1024_per_subtree-4 22.23µ 22.38µ ~ 1.000
SubtreeAllocations/small_subtrees_exists_check-4 149.1µ 147.6µ ~ 0.700
SubtreeAllocations/small_subtrees_data_fetch-4 157.2µ 153.4µ ~ 0.400
SubtreeAllocations/small_subtrees_full_validation-4 301.8µ 305.2µ ~ 0.200
SubtreeAllocations/medium_subtrees_exists_check-4 9.197µ 9.022µ ~ 0.100
SubtreeAllocations/medium_subtrees_data_fetch-4 9.466µ 9.342µ ~ 0.100
SubtreeAllocations/medium_subtrees_full_validation-4 18.49µ 18.25µ ~ 0.400
SubtreeAllocations/large_subtrees_exists_check-4 2.235µ 2.176µ ~ 0.100
SubtreeAllocations/large_subtrees_data_fetch-4 2.380µ 2.298µ ~ 0.100
SubtreeAllocations/large_subtrees_full_validation-4 4.542µ 4.630µ ~ 0.200
StoreBlock_Sequential/BelowCSVHeight-4 350.7µ 349.0µ ~ 1.000
StoreBlock_Sequential/AboveCSVHeight-4 340.9µ 344.4µ ~ 1.000
GetUtxoHashes-4 171.9n 172.4n ~ 1.000
GetUtxoHashes_ManyOutputs-4 30.41µ 26.60µ ~ 0.100
MetaBytes-4 47.44n 45.38n ~ 0.400
_NewMetaDataFromBytes-4 147.4n 139.0n ~ 0.100
_Bytes-4 216.0n 211.2n ~ 0.200
_MetaBytes-4 72.68n 70.11n ~ 0.700

Threshold: >10% with p < 0.05 | Generated: 2026-09-01 10:54 UTC

The root .gitignore excludes *.bin, so the four real-block fixtures the bridge
tests read never reached the branch; CI fails with 'no such file or
directory' while local runs pass on the untracked copies.
…P client

asset_httpAddress is operator-configured, and its default is localhost; the
peer-facing SSRF dial policy on the shared HTTP client made a single-process
node unable to serve a block. Uses the trusted client introduced for svp2p.
@ordishs
ordishs force-pushed the feat/svp2p-legacy-trusted-fetch branch from f41c103 to 411b1db Compare September 1, 2026 10:38
@sonarqubecloud

sonarqubecloud Bot commented Sep 1, 2026

Copy link
Copy Markdown

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

Labels

svp2p Legacy P2P bridge rewrite (services/svp2p)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant