Commit c15f433
commitment: fix warmuper arena data race in HashSort (erigontech#21432)
## Problem
`HashSort` streams each batch's hashed/plain keys into a reused
`byteArena` bump buffer and hands every key to the async warmuper as a
sub-slice for MDBX prefetch. At each 10k batch boundary it reset that
single arena while warmup workers were still reading earlier keys — the
next batch's `arenaAlloc` overwrote bytes a worker was mid-read on. Data
race.
Latent on main: `HexToCompact` tolerates the garbage (at worst a wasted
prefetch). On nibblesv2 (erigontech#21146) `EncodeKeyV2` validates nibbles and
panics on the corrupted byte: `panic: nibbles v2: nibble at index 68 is
0xff`, mainnet ~blk 24.83M, mid commitment.
## Fix
Replace the single arena with a 2-slot ring (`arenaRingSize`) keyed by a
generation counter. Each warmed key is tagged with the current `gen`;
the warmuper keeps a per-slot in-flight count (`outstanding[gen %
ringSize]`). Before a batch boundary reuses a slot, the producer calls
`WaitBufferFree(slot)`, which blocks until that slot's
previous-generation warm items have drained — so no worker still
references the bytes about to be overwritten. Workers decrement on
completion and broadcast on drain-to-zero; a waker goroutine releases
any waiter on ctx cancellation.
Zero-copy, no per-key allocation: the arena is pre-sized once per batch
(`arenaEnsureCap`), and an over-capacity key falls back to an
independent allocation rather than reallocating the buffer (which would
invalidate live sub-slices). Wired at both `HashSort` batch boundaries
for `ModeDirect` and `ModeUpdate`; the `nil`-warmuper path is unchanged.
## Tests
- `TestHashSort_WarmupArenaNoRace` — `-race` repro; DATA RACE in
`HexToCompact` on the old single-arena wiring, green after. Covers
`ModeDirect` and `ModeUpdate`.
- `WaitBufferFree` behaviour: blocks until a straggler drains, fast-path
when the slot is already empty, unblocks on ctx cancel.
- Slot-reuse invariant `curArena == gen % arenaRingSize` survives a
cancel landing inside a boundary wait; `arenaAlloc` returns
non-overlapping sub-slices and falls back cleanly on over-capacity.
`make lint` clean, `make erigon integration` builds, commitment package
green under `-race`.
---------
Co-authored-by: Alex Sharov <AskAlexSharov@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>1 parent 19115fe commit c15f433
3 files changed
Lines changed: 534 additions & 29 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1457 | 1457 | | |
1458 | 1458 | | |
1459 | 1459 | | |
1460 | | - | |
| 1460 | + | |
| 1461 | + | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
1461 | 1465 | | |
1462 | 1466 | | |
| 1467 | + | |
| 1468 | + | |
| 1469 | + | |
1463 | 1470 | | |
1464 | 1471 | | |
1465 | 1472 | | |
1466 | 1473 | | |
1467 | 1474 | | |
1468 | 1475 | | |
1469 | 1476 | | |
1470 | | - | |
| 1477 | + | |
| 1478 | + | |
1471 | 1479 | | |
1472 | | - | |
| 1480 | + | |
1473 | 1481 | | |
1474 | 1482 | | |
1475 | 1483 | | |
1476 | 1484 | | |
1477 | 1485 | | |
1478 | 1486 | | |
1479 | 1487 | | |
1480 | | - | |
1481 | | - | |
1482 | | - | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
1483 | 1492 | | |
1484 | 1493 | | |
1485 | | - | |
1486 | | - | |
| 1494 | + | |
1487 | 1495 | | |
1488 | | - | |
1489 | | - | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
1490 | 1500 | | |
1491 | 1501 | | |
1492 | 1502 | | |
| |||
1811 | 1821 | | |
1812 | 1822 | | |
1813 | 1823 | | |
1814 | | - | |
1815 | | - | |
1816 | | - | |
1817 | | - | |
| 1824 | + | |
| 1825 | + | |
| 1826 | + | |
| 1827 | + | |
| 1828 | + | |
| 1829 | + | |
1818 | 1830 | | |
1819 | | - | |
| 1831 | + | |
1820 | 1832 | | |
1821 | 1833 | | |
1822 | 1834 | | |
| |||
1838 | 1850 | | |
1839 | 1851 | | |
1840 | 1852 | | |
1841 | | - | |
| 1853 | + | |
1842 | 1854 | | |
1843 | 1855 | | |
1844 | 1856 | | |
| |||
1854 | 1866 | | |
1855 | 1867 | | |
1856 | 1868 | | |
| 1869 | + | |
| 1870 | + | |
| 1871 | + | |
1857 | 1872 | | |
1858 | | - | |
| 1873 | + | |
| 1874 | + | |
| 1875 | + | |
1859 | 1876 | | |
1860 | | - | |
1861 | | - | |
| 1877 | + | |
| 1878 | + | |
| 1879 | + | |
1862 | 1880 | | |
1863 | 1881 | | |
1864 | 1882 | | |
| |||
1882 | 1900 | | |
1883 | 1901 | | |
1884 | 1902 | | |
| 1903 | + | |
| 1904 | + | |
| 1905 | + | |
| 1906 | + | |
| 1907 | + | |
1885 | 1908 | | |
1886 | | - | |
| 1909 | + | |
1887 | 1910 | | |
1888 | 1911 | | |
1889 | 1912 | | |
| |||
1906 | 1929 | | |
1907 | 1930 | | |
1908 | 1931 | | |
1909 | | - | |
| 1932 | + | |
1910 | 1933 | | |
1911 | 1934 | | |
1912 | 1935 | | |
| |||
1923 | 1946 | | |
1924 | 1947 | | |
1925 | 1948 | | |
| 1949 | + | |
| 1950 | + | |
| 1951 | + | |
1926 | 1952 | | |
1927 | | - | |
| 1953 | + | |
| 1954 | + | |
| 1955 | + | |
| 1956 | + | |
1928 | 1957 | | |
1929 | | - | |
1930 | | - | |
| 1958 | + | |
| 1959 | + | |
| 1960 | + | |
1931 | 1961 | | |
1932 | 1962 | | |
1933 | 1963 | | |
| |||
1971 | 2001 | | |
1972 | 2002 | | |
1973 | 2003 | | |
1974 | | - | |
| 2004 | + | |
| 2005 | + | |
| 2006 | + | |
| 2007 | + | |
| 2008 | + | |
1975 | 2009 | | |
1976 | 2010 | | |
1977 | 2011 | | |
| |||
0 commit comments