Skip to content

Commit 3822824

Browse files
MariusVanDerWijdenjagdeep sidhu
authored andcommitted
core/state/snapshot: fix race condition (ethereum#24685)
Fixes three race conditions found through fuzzing by David Theodore
1 parent ce1b562 commit 3822824

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

core/state/snapshot/difflayer.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ func (dl *diffLayer) Root() common.Hash {
258258

259259
// Parent returns the subsequent layer of a diff layer.
260260
func (dl *diffLayer) Parent() snapshot {
261+
dl.lock.RLock()
262+
defer dl.lock.RUnlock()
263+
261264
return dl.parent
262265
}
263266

eth/protocols/snap/sync.go

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,8 @@ type Syncer struct {
422422
storageSynced uint64 // Number of storage slots downloaded
423423
storageBytes common.StorageSize // Number of storage trie bytes persisted to disk
424424

425+
extProgress *SyncProgress // progress that can be exposed to external caller.
426+
425427
// Request tracking during healing phase
426428
trienodeHealIdlers map[string]struct{} // Peers that aren't serving trie node requests
427429
bytecodeHealIdlers map[string]struct{} // Peers that aren't serving bytecode requests
@@ -477,6 +479,8 @@ func NewSyncer(db ethdb.KeyValueStore) *Syncer {
477479
trienodeHealReqs: make(map[uint64]*trienodeHealRequest),
478480
bytecodeHealReqs: make(map[uint64]*bytecodeHealRequest),
479481
stateWriter: db.NewBatch(),
482+
483+
extProgress: new(SyncProgress),
480484
}
481485
}
482486

@@ -633,6 +637,21 @@ func (s *Syncer) Sync(root common.Hash, cancel chan struct{}) error {
633637
s.assignTrienodeHealTasks(trienodeHealResps, trienodeHealReqFails, cancel)
634638
s.assignBytecodeHealTasks(bytecodeHealResps, bytecodeHealReqFails, cancel)
635639
}
640+
// Update sync progress
641+
s.lock.Lock()
642+
s.extProgress = &SyncProgress{
643+
AccountSynced: s.accountSynced,
644+
AccountBytes: s.accountBytes,
645+
BytecodeSynced: s.bytecodeSynced,
646+
BytecodeBytes: s.bytecodeBytes,
647+
StorageSynced: s.storageSynced,
648+
StorageBytes: s.storageBytes,
649+
TrienodeHealSynced: s.trienodeHealSynced,
650+
TrienodeHealBytes: s.trienodeHealBytes,
651+
BytecodeHealSynced: s.bytecodeHealSynced,
652+
BytecodeHealBytes: s.bytecodeHealBytes,
653+
}
654+
s.lock.Unlock()
636655
// Wait for something to happen
637656
select {
638657
case <-s.update:
@@ -705,6 +724,9 @@ func (s *Syncer) loadSyncStatus() {
705724
}
706725
}
707726
}
727+
s.lock.Lock()
728+
defer s.lock.Unlock()
729+
708730
s.snapped = len(s.tasks) == 0
709731

710732
s.accountSynced = progress.AccountSynced
@@ -802,25 +824,12 @@ func (s *Syncer) saveSyncStatus() {
802824
func (s *Syncer) Progress() (*SyncProgress, *SyncPending) {
803825
s.lock.Lock()
804826
defer s.lock.Unlock()
805-
806-
progress := &SyncProgress{
807-
AccountSynced: s.accountSynced,
808-
AccountBytes: s.accountBytes,
809-
BytecodeSynced: s.bytecodeSynced,
810-
BytecodeBytes: s.bytecodeBytes,
811-
StorageSynced: s.storageSynced,
812-
StorageBytes: s.storageBytes,
813-
TrienodeHealSynced: s.trienodeHealSynced,
814-
TrienodeHealBytes: s.trienodeHealBytes,
815-
BytecodeHealSynced: s.bytecodeHealSynced,
816-
BytecodeHealBytes: s.bytecodeHealBytes,
817-
}
818827
pending := new(SyncPending)
819828
if s.healer != nil {
820829
pending.TrienodeHeal = uint64(len(s.healer.trieTasks))
821830
pending.BytecodeHeal = uint64(len(s.healer.codeTasks))
822831
}
823-
return progress, pending
832+
return s.extProgress, pending
824833
}
825834

826835
// cleanAccountTasks removes account range retrieval tasks that have already been

0 commit comments

Comments
 (0)