Skip to content

fix(sync): sync distant P2P data heads by range - #3421

Merged
tac0turtle merged 2 commits into
evstack:mainfrom
jgimeno:jgimeno/fix-p2p-data-range-sync
Aug 5, 2026
Merged

fix(sync): sync distant P2P data heads by range#3421
tac0turtle merged 2 commits into
evstack:mainfrom
jgimeno:jgimeno/fix-p2p-data-range-sync

Conversation

@jgimeno

@jgimeno jgimeno commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Overview

Fix P2P data head verification so non-adjacent heads are accepted as provisional sync targets instead of triggering repeated bifurcation requests.

P2PData.Verify previously compared the trusted data hash with LastDataHash for every candidate. That linkage is only meaningful for adjacent heights: a distant head points to its immediate predecessor, not the node's current local head. As a result, distant heads soft-failed verification and go-header fetched intermediate heights repeatedly before starting normal range sync (258 GetByHeight calls when catching up from height 1 to 64 in the regression).

The verification now checks data-hash linkage only for adjacent heights. Non-adjacent heads can become provisional sync targets, after which the downloaded range is verified link by link. Adjacent candidates with an invalid LastDataHash are still rejected.

Validation

  • go test ./... -count=1
  • go test ./pkg/sync -run TestDataSyncerDistantHeadUsesRangeSync -count=50
  • go test -race ./pkg/sync -run TestDataSyncerDistantHeadUsesRangeSync -count=1
  • go test ./types -run TestP2PDataVerifyAdjacentHeads -count=50
  • go vet ./types ./pkg/sync
  • git diff --check

Summary by CodeRabbit

  • Bug Fixes
    • Improved synchronization for distant chain heads by using efficient range fetching instead of repeatedly retrieving intermediate blocks.
    • Updated peer-to-peer data verification to validate only immediately adjacent chain heights, improving handling of non-adjacent data.
    • Strengthened verification of adjacent blocks, including predecessor hash validation.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 271a0863-e892-40ce-885a-39518e0ee0cd

📥 Commits

Reviewing files that changed from the base of the PR and between b573584 and 4eb656b.

📒 Files selected for processing (1)
  • pkg/sync/sync_service_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/sync/sync_service_test.go

📝 Walkthrough

Walkthrough

P2PData.Verify now checks underlying data only for adjacent heights. New tests validate adjacent verification and confirm that distant-head synchronization uses range fetching.

Changes

Synchronization verification

Layer / File(s) Summary
Adjacent P2P verification
types/p2p_envelope.go, types/p2p_envelope_test.go
P2PData.Verify skips hash verification for non-adjacent heights. Tests cover valid adjacent data and invalid predecessor hashes.
Distant-head range synchronization
pkg/sync/sync_service_test.go
Test utilities count single-height and range fetches. The end-to-end test verifies catch-up across a 64-block chain with range retrieval.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary change: fixing synchronization of distant P2P data heads through range sync.
Description check ✅ Passed The description includes the required Overview section and explains the context, cause, solution, rationale, and validation steps.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jgimeno
jgimeno marked this pull request as ready for review August 5, 2026 08:50

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/sync/sync_service_test.go`:
- Around line 105-112: Move the getter.getByHeightCalls.Load() assertion below
the require.Eventually catch-up completion check in the sync test, while
preserving its existing limit and message. Keep the final height and range-call
assertions unchanged.

In `@types/p2p_envelope.go`:
- Around line 114-115: Update the height adjacency check in the surrounding
envelope validation logic to avoid incrementing p.Height(), which can wrap at
math.MaxUint64. Compare the trusted and untrusted heights using subtraction or
an equivalent overflow-safe condition, preserving adjacent-height hash
validation while treating overflow and non-adjacent candidates as the documented
non-adjacent path.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1442f16e-c5ec-45bd-bb95-05ae5213589b

📥 Commits

Reviewing files that changed from the base of the PR and between c27a9fd and b573584.

📒 Files selected for processing (3)
  • pkg/sync/sync_service_test.go
  • types/p2p_envelope.go
  • types/p2p_envelope_test.go

Comment thread pkg/sync/sync_service_test.go
Comment thread types/p2p_envelope.go
Comment on lines +114 to +115
if p.Height()+1 != untrusted.Height() {
return nil

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Prevent height wraparound in the adjacency check.

p.Height()+1 wraps from math.MaxUint64 to zero. A candidate at height zero then takes the adjacent hash-validation path. This contradicts the documented non-adjacent behavior and can reject that provisional candidate based on LastDataHash.

Compare heights without incrementing the trusted height.

Proposed fix
-	if p.Height()+1 != untrusted.Height() {
+	if untrusted.Height() <= p.Height() || untrusted.Height()-p.Height() != 1 {
 		return nil
 	}

As per coding guidelines, “Prevent integer overflows … during validation.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if p.Height()+1 != untrusted.Height() {
return nil
if untrusted.Height() <= p.Height() || untrusted.Height()-p.Height() != 1 {
return nil
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@types/p2p_envelope.go` around lines 114 - 115, Update the height adjacency
check in the surrounding envelope validation logic to avoid incrementing
p.Height(), which can wrap at math.MaxUint64. Compare the trusted and untrusted
heights using subtraction or an equivalent overflow-safe condition, preserving
adjacent-height hash validation while treating overflow and non-adjacent
candidates as the documented non-adjacent path.

Source: Coding guidelines

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.47%. Comparing base (c27a9fd) to head (4eb656b).

Files with missing lines Patch % Lines
types/p2p_envelope.go 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3421      +/-   ##
==========================================
+ Coverage   62.37%   62.47%   +0.10%     
==========================================
  Files         121      121              
  Lines       13467    13469       +2     
==========================================
+ Hits         8400     8415      +15     
+ Misses       4127     4113      -14     
- Partials      940      941       +1     
Flag Coverage Δ
combined 62.47% <0.00%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

interesting fix, its odd this was hit in production.

@tac0turtle
tac0turtle merged commit d47195a into evstack:main Aug 5, 2026
22 of 25 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.

2 participants