Skip to content

Commit 312c563

Browse files
committed
fix: prevent race condition during store initialization in WriteToStoreAndBroadcast
1 parent 1b424f5 commit 312c563

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

pkg/sync/sync_service.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,13 @@ func (syncService *SyncService[H]) WriteToStoreAndBroadcast(ctx context.Context,
137137
}
138138

139139
storeInitialized := false
140-
if !syncService.storeInitialized.Load() {
140+
if syncService.storeInitialized.CompareAndSwap(false, true) {
141141
var err error
142142
storeInitialized, err = syncService.initStore(ctx, headerOrData)
143143
if err != nil {
144+
syncService.storeInitialized.Store(false)
144145
return fmt.Errorf("failed to initialize the store: %w", err)
145146
}
146-
syncService.storeInitialized.Store(true)
147147
}
148148

149149
firstStart := false
@@ -338,10 +338,15 @@ func (syncService *SyncService[H]) initFromP2PWithRetry(ctx context.Context, pee
338338
return false, fmt.Errorf("failed to fetch height %d from peers: %w", heightToQuery, err)
339339
}
340340

341-
if _, err := syncService.initStore(ctx, trusted); err != nil {
342-
return false, fmt.Errorf("failed to initialize the store: %w", err)
341+
// Use CompareAndSwap to atomically check and set initialization flag
342+
// This prevents race condition where concurrent calls could both initialize the store
343+
if syncService.storeInitialized.CompareAndSwap(false, true) {
344+
if _, err := syncService.initStore(ctx, trusted); err != nil {
345+
// Revert the flag on error so initialization can be retried
346+
syncService.storeInitialized.Store(false)
347+
return false, fmt.Errorf("failed to initialize the store: %w", err)
348+
}
343349
}
344-
syncService.storeInitialized.Store(true)
345350
if err := syncService.startSyncer(ctx); err != nil {
346351
return false, err
347352
}

0 commit comments

Comments
 (0)