Process-worker generation — September 14, 2026
Release 190b518c278240212ec66224d96af42a18d0009e integrates the process-worker
and smaller ARM JIT permission-range optimization previously measured only in
randomx-scaling-20260911. It retains the WireGuard cleanup and publication
recovery fixes from 659fc73. It restarted production at 2026-09-14 23:16:22 UTC (16:16 PDT), with
24 reserved CPUs and 8 GiB. Fresh nonce-bound Nitro/TLS evidence verifies the
new release and Mullvad egress. The first full-work puzzle is warming.
Implementation
A freshly executed helper initializes one RandomX dataset/cache and then forks 24 workers, each pinned to one enclave CPU. Fork happens before the helper starts threads, never inside the multithreaded serving process. Read-only dataset pages are shared. Each worker owns its VM and memory map, avoiding the kernel memory-permission contention measured with threads.
The helper clears inherited environment and file descriptors. Only the public dataset key and private segment seeds cross internal anonymous pipes. The signing key and epoch key remain in the serving process. Fixed-size events carry progress and final outputs, with bounds, work counts and completeness checked. Workers die with their supervisor; a failed worker terminates generation promptly. All helper processes finish before publication. These pipes remain inside Nitro.
ARM full-memory JIT permission changes cover the main code region. Light/cache JIT expands the range when generating superscalar code. W^X checks and complete allocation wiping remain enabled. The RandomX algorithm, puzzle format and work count are unchanged: 96 groups × 4,843,750 = 465,000,000 hashes. Faster generation does not change serial recovery work or rebase a published puzzle's lifetime.
Verification
- Deterministic process generation with one and three workers produces the same signed puzzle and key as threaded generation; serial recovery matches.
- A killed worker fails its supervisor promptly; helper failure is rejected.
- Seven end-to-end tests pass, covering commands, pastes, recovery, rollover and publication-failure cases. One optional external HTTPS test is skipped.
- Full/light native JIT versus interpreter, memory wiping and injected permission failure checks pass.
- Both independent ARM builds reproduced the Docker image and PCR0/1/2.
Run 34907704604
passed. The report signature verified with exact CI revision
66e69c6c1d58c3be2c7ff7f06c356591ae72d4f9, rejecting self-hosted runners. - A full-mode process test completed 960,000 hashes on the parent’s eight available cores; production throughput is sampled separately.
Release inputs, EIF build information, measurements, validation, signed report, signature bundle, fresh Nitro evidence, launch, progress samples, parent process status.
Live production throughput
From elapsed 50 to 130 seconds, the deployed generator advanced from 240,000 to 1,440,000 hashes: 15,000 hashes/second over 80 seconds. This is about 2.2× the previous sustained production rate of roughly 6,900 hashes/second. At this rate, 465M hashes take about 8.6 hours, excluding startup. The remaining work at that observation projects to about 8.6 hours. The estimate can change; progress counters are published in batches. These are parent-reported operational counters, not signed timing measurements.
The benchmark prototype measured 15,064 hashes/second; the deployed implementation now demonstrates comparable throughput on the actual production workload.
Operational continuity
The parent process and its socket-leak fix were preserved. Existing append-only archives, pastes, historical solver jobs and checkpoints remain in place. A new follower pins this release, and a one-shot acceptance service waits to check POST, paste access, S3 replication and live solving once the full puzzle is ready. The boot service pins the new EIF. Only the in-progress, unpublished generation was restarted, as requested.
Current PCR0:
c7c8fcfdc8b40212095f0733ebd9348f80f5c8d5fab06f475531f9336edafc6b1576d202763d3a360a7c356aab7ba713
A real tunnel reconnect at 23:19:26 UTC retained the same enclave and continued generation; the parent process remained PID 210881.