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 <charon@lethean.io>
This commit is contained in:
Claude 2026-02-21 21:31:59 +00:00
parent 8caf157b1c
commit c6504276dc
No known key found for this signature in database
GPG key ID: AF404715446AEB41

View file

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