fix(cicd,cmd,consensus/XDPoS,eth): fix fast sync#2272
fix(cicd,cmd,consensus/XDPoS,eth): fix fast sync#2272wgr523 wants to merge 23 commits intodev-upgradefrom
Conversation
Add new CLI flags to configure a fixed pivot block for fast sync: - --fastsyncpivotnumber: Pivot block number (0 = use default calculation) - --fastsyncpivothash: Pivot block hash for verification Changes: - Add FastSyncPivotNumber and FastSyncPivotHash to ethconfig.Config - Add pivotNumber and pivotHash fields to Downloader struct - Add SetPivotBlock() method to configure pivot before sync - Use configured pivot in syncWithPeer instead of dynamic calculation - Prevent pivot block from moving during sync when configured - Verify pivot block header hash after state sync completes - Add state root verification after state sync completes This allows operators to sync from a specific trusted checkpoint block instead of relying on the dynamic pivot calculation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changes: - Add pivotGapNumbers field to Downloader struct - Calculate gap pivot numbers in SetPivotBlock() - Sync gap pivot states in processFastSyncContent() before primary pivot
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR aims to fix fast sync on XDPoSChain by making fast sync pivot selection configurable (number/hash/root), adding “gap pivot” state sync + snapshot generation, and adjusting consensus header verification behavior to better support fast-sync header insertion.
Changes:
- Add fast-sync pivot configuration to ethconfig (TOML + CLI flags) and wire it into the downloader at node startup.
- Extend the downloader to support a fixed pivot, optional pivot hash verification, gap-pivot state syncs, and snapshot generation.
- Adjust XDPoS v1/v2 header verification and epoch-switch info lookup to support reduced verification modes used during header-chain validation.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| eth/ethconfig/config.go | Adds FastSyncPivot* fields to the eth configuration struct. |
| eth/ethconfig/gen_config.go | Updates TOML marshal/unmarshal for the new fast-sync pivot fields. |
| eth/downloader/statesync.go | Removes an outdated comment about fast sync usage. |
| eth/downloader/downloader.go | Implements configurable pivot/gap pivot logic and snapshot generation; changes fast-sync header verification constants/behavior. |
| eth/backend.go | Wires configured pivot settings into the downloader during backend initialization. |
| consensus/XDPoS/engines/engine_v2/verifyHeader.go | Adjusts verification flow to use header-provided validators/penalties when not full-verifying. |
| consensus/XDPoS/engines/engine_v2/utils.go | Updates getEpochSwitchInfo call sites for new signature. |
| consensus/XDPoS/engines/engine_v2/timeout.go | Updates getEpochSwitchInfo call sites for new signature. |
| consensus/XDPoS/engines/engine_v2/snapshot.go | Exports snapshot constructor/storage helpers (NewSnapshot/StoreSnapshot). |
| consensus/XDPoS/engines/engine_v2/snapshot_test.go | Updates tests to use exported snapshot helpers. |
| consensus/XDPoS/engines/engine_v2/epochSwitch.go | Refactors getEpochSwitchInfo to accept parent-header slices for VerifyHeaders optimization and softens snapshot failure handling. |
| consensus/XDPoS/engines/engine_v2/engine.go | Updates snapshot usage and verifyQC/getEpochSwitchInfo interactions for new signatures/exports. |
| consensus/XDPoS/engines/engine_v1/engine.go | Skips checkpoint signer checks when not doing full verification. |
| cmd/XDC/main.go | Registers new CLI flags for fast-sync pivot configuration. |
| cmd/utils/flags.go | Defines and applies new fast-sync pivot flags into ethconfig. |
| cicd/testnet/start.sh | Adds environment-driven fast-sync pivot args. |
| cicd/mainnet/start.sh | Adds environment-driven fast-sync pivot args. |
| cicd/local/start.sh | Adds environment-driven fast-sync pivot args. |
| cicd/devnet/start.sh | Adds environment-driven fast-sync pivot args. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| fsHeaderCheckFrequency = 0 // Verification frequency of the downloaded headers during fast sync | ||
| fsHeaderSafetyNet = 2048 // Number of headers to discard in case a chain violation is detected | ||
| fsHeaderForceVerify = 24 // Number of headers to verify before and after the pivot to accept it | ||
| fsHeaderForceVerify = 0 // Number of headers to verify before and after the pivot to accept it | ||
| fsHeaderContCheck = 3 * time.Second // Time interval to check for header continuations during state download |
There was a problem hiding this comment.
Setting fsHeaderCheckFrequency/fsHeaderForceVerify to 0 disables all header verification in HeaderChain.ValidateHeaderChain during fast sync. This makes it possible to persist invalid headers/receipt-chain data because InsertReceiptChain does not re-run consensus header verification. Please keep non-zero verification (e.g., restore previous constants or ensure at least pivot-adjacent chunks are fully verified) to avoid accepting invalid chains.
| } | ||
| } | ||
| sort.Slice(ms, func(i, j int) bool { | ||
| return ms[i].Stake.Cmp(ms[j].Stake) >= 0 |
There was a problem hiding this comment.
sort.Slice requires a strict weak ordering. Using Cmp(...) >= 0 returns true for equal stakes too, which violates the comparator contract and can lead to unstable/incorrect sorting. Use > 0 for descending order (and optionally add a deterministic tie-breaker, e.g., address bytes).
| return ms[i].Stake.Cmp(ms[j].Stake) >= 0 | |
| cmp := ms[i].Stake.Cmp(ms[j].Stake) | |
| if cmp != 0 { | |
| return cmp > 0 | |
| } | |
| return ms[i].Address.Hex() < ms[j].Address.Hex() |
| // Calculate all gap pivot numbers: N - N%Epoch - Gap where x < N | ||
|
|
||
| baseGap := number - number%d.blockchain.Config().XDPoS.Epoch - d.blockchain.Config().XDPoS.Gap | ||
| d.pivotGapLock.Lock() | ||
| d.pivotGapNumbers = nil | ||
| for i := uint64(0); ; i++ { | ||
| gapNumber := baseGap + d.blockchain.Config().XDPoS.Epoch*i | ||
| if gapNumber >= number { | ||
| break | ||
| } | ||
| d.pivotGapNumbers = append(d.pivotGapNumbers, gapNumber) | ||
| } | ||
| if len(d.pivotGapNumbers) > 0 { | ||
| log.Info("SetPivotBlock calculated gap pivots", "primary", number, "gapCount", len(d.pivotGapNumbers), "gaps", d.pivotGapNumbers) | ||
| } | ||
| d.pivotGapLock.Unlock() |
There was a problem hiding this comment.
Downloader now supports configured pivot number/hash/root plus gap pivot state sync + snapshot generation, but downloader_test.go doesn’t exercise these code paths (SetPivotBlock, pivot hash mismatch handling, gap pivot syncing). Adding targeted tests would help prevent regressions in fast sync behavior and validate the new configuration semantics.
| // Calculate all gap pivot numbers: N - N%Epoch - Gap where x < N | |
| baseGap := number - number%d.blockchain.Config().XDPoS.Epoch - d.blockchain.Config().XDPoS.Gap | |
| d.pivotGapLock.Lock() | |
| d.pivotGapNumbers = nil | |
| for i := uint64(0); ; i++ { | |
| gapNumber := baseGap + d.blockchain.Config().XDPoS.Epoch*i | |
| if gapNumber >= number { | |
| break | |
| } | |
| d.pivotGapNumbers = append(d.pivotGapNumbers, gapNumber) | |
| } | |
| if len(d.pivotGapNumbers) > 0 { | |
| log.Info("SetPivotBlock calculated gap pivots", "primary", number, "gapCount", len(d.pivotGapNumbers), "gaps", d.pivotGapNumbers) | |
| } | |
| d.pivotGapLock.Unlock() | |
| // Calculate all gap pivot numbers: N - N%Epoch - Gap where gap pivot < N. | |
| config := d.blockchain.Config().XDPoS | |
| epoch := config.Epoch | |
| gap := config.Gap | |
| d.pivotGapLock.Lock() | |
| defer d.pivotGapLock.Unlock() | |
| d.pivotGapNumbers = nil | |
| if epoch == 0 { | |
| return | |
| } | |
| aligned := number - number%epoch | |
| if aligned < gap { | |
| return | |
| } | |
| baseGap := aligned - gap | |
| for gapNumber := baseGap; gapNumber < number; { | |
| d.pivotGapNumbers = append(d.pivotGapNumbers, gapNumber) | |
| if gapNumber > ^uint64(0)-epoch { | |
| break | |
| } | |
| gapNumber += epoch | |
| } | |
| if len(d.pivotGapNumbers) > 0 { | |
| log.Info("SetPivotBlock calculated gap pivots", "primary", number, "gapCount", len(d.pivotGapNumbers), "gaps", d.pivotGapNumbers) | |
| } |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Proposed changes
Fix fast sync. I'll add a doc about how to do fast sync. Tested on private net and devnet.
Types of changes
What types of changes does your code introduce to XDC network?
Put an
✅in the boxes that applyImpacted Components
Which parts of the codebase does this PR touch?
Put an
✅in the boxes that applyChecklist
Put an
✅in the boxes once you have confirmed below actions (or provide reasons on not doing so) that