Skip to content

Commit d9c850c

Browse files
chainimport: process divergence headers region
1 parent 938f2cd commit d9c850c

File tree

2 files changed

+931
-3
lines changed

2 files changed

+931
-3
lines changed

chainimport/headers_import.go

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,16 @@ func (h *headersImport) Import(ctx context.Context) (*ImportResult, error) {
266266
result.StartHeight = regions.importStartHeight
267267
result.EndHeight = regions.importEndHeight
268268

269-
// TODO(mohamedawnallah): Process the divergence region. This includes
270-
// strategy/strategies for handling divergence region that may exist in
271-
// the target header stores while importing.
269+
// Process divergence headers region.
270+
// Process headers in the divergence region by validating the leading
271+
// store and syncing the lagging store.
272+
err = h.processDivergenceHeadersRegion(
273+
ctx, regions.divergence, result,
274+
)
275+
if err != nil {
276+
return nil, fmt.Errorf("headers import failed: divergence "+
277+
"headers processing failed: %w", err)
278+
}
272279

273280
// Process new headers region.
274281
// Add headers from the import source to the target stores, extending
@@ -618,6 +625,55 @@ func (h *headersImport) determineDivergenceSyncModes(blockTipHeight,
618625
}
619626
}
620627

628+
// processDivergenceHeadersRegion processes divergence headers by validating
629+
// the leading store and syncing the lagging store.
630+
func (h *headersImport) processDivergenceHeadersRegion(ctx context.Context,
631+
region headerRegion, result *ImportResult) error {
632+
633+
if !region.exists {
634+
return nil
635+
}
636+
637+
log.Infof("Processing %d divergence headers from heights %d to %d",
638+
region.end-region.start+1, region.start, region.end)
639+
640+
if err := h.validateLeadAndSyncLag(ctx, region); err != nil {
641+
return fmt.Errorf("failed to validate lead and sync lag "+
642+
"headers: %w", err)
643+
}
644+
645+
result.ProcessedCount += int(region.end - region.start + 1)
646+
result.AddedCount += int(region.end - region.start + 1)
647+
648+
return nil
649+
}
650+
651+
// validateLeadAndSyncLag resolves divergence between target stores by
652+
// validating the last header from the leading store against import source and
653+
// syncing the lagging target store with headers from the import source. This
654+
// approach ensures the leading store's highest header is consistent with the
655+
// import source before proceeding with synchronization.
656+
func (h *headersImport) validateLeadAndSyncLag(ctx context.Context,
657+
region headerRegion) error {
658+
659+
// Verify last header from the leading store against import source.
660+
if err := h.verifyHeadersAtTargetHeight(
661+
region.end, region.syncModes.verify,
662+
); err != nil {
663+
return fmt.Errorf("failed to verify headers at target "+
664+
"height: %w", err)
665+
}
666+
667+
// Sync the lagging store with headers from import source.
668+
if err := h.appendNewHeaders(
669+
ctx, region.start, region.end, region.syncModes.append,
670+
); err != nil {
671+
return fmt.Errorf("failed to sync target header store: %w", err)
672+
}
673+
674+
return nil
675+
}
676+
621677
// processNewHeadersRegion imports headers from the specified region into the
622678
// target stores. This method handles the case where headers exist in the import
623679
// source but not in the target stores.

0 commit comments

Comments
 (0)