Commit f568d6f
[SharovBot] fix(stagedsync): add mutex to Progress.LogCommitments to fix DATA RACE (#19501)
**[SharovBot]**
## Problem
The `All tests (with -race)` CI job has been failing on `main` since
#19486 merged. The race detector reports:
```
WARNING: DATA RACE
Read at 0x...: (*Progress).LogCommitments() exec3_metrics.go:741
Previous write at 0x...: (*Progress).LogCommitments() exec3_metrics.go:742
WARNING: DATA RACE
Read at 0x...: updateExecDomainMetrics() exec3_metrics.go:267
Previous write at 0x...: updateExecDomainMetrics() exec3_metrics.go:291
```
Both races are concurrent calls to `Progress.LogCommitments()` from:
- **Goroutine A** (`func1.2`): the commit-logger goroutine spawned
inside `parallelExecutor.exec` — triggered when the `commitProgress`
channel closes (`!ok` case at `exec3_parallel.go:350`)
- **Goroutine B** (outer `exec()`): at `exec3_parallel.go:470`, after
`pe.wait()` returns, for the final summary log call
## Root Cause
The `<-LogCommitmentsDone` synchronisation at `exec3_parallel.go:408`
only runs on the **normal commit-completion path**. If `func1` exits
early via `ctx.Done()` (at line 443), it never reaches line 408 —
leaving the commit-logger goroutine (`func1.2`) still running.
`pe.wait()` returns (tracking `execLoopGroup`, which `func1` is part
of), the outer `exec()` proceeds to its `LogCommitments` call — and both
goroutines simultaneously mutate `p.prevCommitTime`,
`p.prevDomainMetrics`, etc.
**Why did #19486 expose this?** It made BAL validation optional, so more
Amsterdam-fork blocks complete successfully instead of aborting.
`TestExecutionSpecBlockchainDevnet` runs short-lived test contexts; with
more successful commits the race window is hit consistently.
## Fix
Add `sync.Mutex` to `Progress` and lock it for the duration of
`LogCommitments()`. All `p.prev*` field reads and writes happen inside
this one function, so a single lock site covers both reported races.
```go
type Progress struct {
mu sync.Mutex // protects prev* fields from concurrent LogCommitments calls
// ...
}
func (p *Progress) LogCommitments(...) {
p.mu.Lock()
defer p.mu.Unlock()
// ...
}
```
## Verification
`go build ./execution/stagedsync/...` passes. The fix unblocks `All
tests (with -race)` on `main`.
Co-authored-by: SharovBot <sharovbot@erigon.ci>1 parent 14154ba commit f568d6f
1 file changed
+8
-0
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
455 | 455 | | |
456 | 456 | | |
457 | 457 | | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
458 | 463 | | |
459 | 464 | | |
460 | 465 | | |
| |||
725 | 730 | | |
726 | 731 | | |
727 | 732 | | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
728 | 736 | | |
729 | 737 | | |
730 | 738 | | |
| |||
0 commit comments