celestiaorg / celestiaorg/nmt

NamespacedMerkleTree.Root has a data race during concurrent cache initialization

Open
#338 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
122
Forks
53
Avg merge
1d 15h
Merged PRs (30d)
5

Description

### Reproduction

On current `main` (`e2177ee`):

```sh
go test -race -run '^Test_Root_RaceCondition$'
```

The existing test starts 200 goroutines that call `Root()` on the same tree. The race detector reports concurrent access to `rawRoot` in `nmt.go`:

- write at line 532 vs. read at line 522
- write at line 532 vs. read at line 535

The test fails with `race detected during execution of test`.

### Expected

Concurrent `Root()` calls used by the existing regression test complete without a data race and return the same root.

### Actual

Lazy cache initialization reads and writes `rawRoot` concurrently. Normal CI does not expose this because the test suite is run without the race detector.

### Impact

Concurrent callers can trigger unsynchronized access to the cached root. Besides failing race-enabled builds, this leaves behavior dependent on a data race under legitimate concurrent read-style use.

### Acceptance criteria

- `go test -race -run '^Test_Root_RaceCondition$'` passes.
- Existing root calculation and cache semantics remain intact.
- The concurrent regression coverage is retained or strengthened.
- The supported goroutine-safety contract is documented or clarified, in coordination with #39.

This report is narrower than #39: it records a concrete, reproducible race in the existing concurrent `Root()` test. It intentionally does not prescribe a locking or cache implementation.

Contributor guide

Open the contributing guide

Research direction

Start with nmt.go and the existing Test_Root_RaceCondition test, then inspect the rawRoot accesses around lines 522, 532, and 535. Run go test -race -run '^Test_Root_RaceCondition$' while preserving the existing root and cache behavior. Done means the race-enabled test passes, concurrent calls return the same root, and the goroutine-safety contract is documented or clarified with #39.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.