From c6504276dca3946a2d8973804f89b5875f9f533f Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 21 Feb 2026 21:31:59 +0000 Subject: [PATCH] fix(chain): skip overlap block in P2P sync chain entries RESPONSE_CHAIN_ENTRY includes the fork-point block as its first entry. The sync loop now skips blocks already stored to avoid height validation failures on subsequent chain iterations. Co-Authored-By: Charon --- chain/p2psync.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/chain/p2psync.go b/chain/p2psync.go index a6cbde4..72cb8a8 100644 --- a/chain/p2psync.go +++ b/chain/p2psync.go @@ -78,8 +78,20 @@ func (c *Chain) P2PSync(ctx context.Context, conn P2PConnection, opts SyncOption log.Printf("p2p sync: chain entry from height %d, %d block IDs", startHeight, len(blockIDs)) + // The daemon returns the fork-point block as the first entry. + // Skip blocks we already have. + skip := 0 + if startHeight < localHeight { + skip = int(localHeight - startHeight) + if skip >= len(blockIDs) { + continue // all IDs are blocks we already have + } + } + fetchIDs := blockIDs[skip:] + fetchStart := startHeight + uint64(skip) + // Fetch blocks in batches. - for i := 0; i < len(blockIDs); i += p2pBatchSize { + for i := 0; i < len(fetchIDs); i += p2pBatchSize { select { case <-ctx.Done(): return ctx.Err() @@ -87,17 +99,17 @@ func (c *Chain) P2PSync(ctx context.Context, conn P2PConnection, opts SyncOption } end := i + p2pBatchSize - if end > len(blockIDs) { - end = len(blockIDs) + if end > len(fetchIDs) { + end = len(fetchIDs) } - batch := blockIDs[i:end] + batch := fetchIDs[i:end] entries, err := conn.RequestObjects(batch) if err != nil { return fmt.Errorf("p2p sync: request objects: %w", err) } - currentHeight := startHeight + uint64(i) + currentHeight := fetchStart + uint64(i) for j, entry := range entries { blockHeight := currentHeight + uint64(j) if blockHeight > 0 && blockHeight%100 == 0 {