mirror of
https://github.com/luxfi/precompile.git
synced 2026-09-24 00:26:21 +00:00
WIP main was an orphaned old base; remote main is the canonical refactor (p3q/+starkfri/ split, slot 0x012205=P3Q, newer dep pins) and already contains the P3Q work. The only genuinely-new, non-superseded WIP artifact is this still-relevant data-race analysis (remote fhe/*.go still has no mutex). dex/engine_embedded.go intentionally dropped: remote refactor removed the embedded AMM in favor of the inert default and added inert_no_embedded_test.go asserting it is gone. Full WIP preserved on branch wip/local + tag backup/pre-reconcile-main.
3.3 KiB
3.3 KiB
FHE + Attestation Mutex Fix Plan
Status: Analysis complete (agent a0677f0c, 2026-04-10). Implementation blocked by usage limit.
Threat Model
- Assets: Consensus determinism across validator nodes
- Adversary: Concurrent EVM transaction execution within a block
- Attack: Unprotected map writes → data races → non-determinism → chain split
Findings
REAL bugs requiring fix
-
FHE —
/Users/z/work/lux/precompile/fhe/contract.gociphertextStore— no lockciphertextTypes— no lock- Pattern: every operation reads & writes → heavy R+W
- Fix:
sync.RWMutex(reads are more frequent)getCiphertextcalled 2× per binary op → RLockstoreCiphertextcalled 1× → Lock
-
attestation —
/Users/z/work/lux/precompile/attestation/globalVerifier— fromluxfi/ailibrary, no visible internal lockingnvtrustVerifier— same, no guard- Library Verifier has internal mutable state (device registrations, job completions)
- Fix: Wrap calls in package-level
sync.RWMutex, OR upstream the fix toluxfi/ai
Already protected (no fix needed)
| Package | Lock | Notes |
|---|---|---|
| zk/stark.go | starkVerifiersMu |
OK |
| zk/pedersen.go | sync.RWMutex on pointCache + globalPedersen |
OK |
| zk/poseidon.go | cacheMu |
OK |
| zk/verifier.go | internal mu |
OK |
| frost | liftXCacheMu |
OK |
| quantum | qv.mu |
OK |
| dex | per-struct mu; HookSignatures read-only after init |
OK |
| bridge | gateway.go + signer.go have internal mu |
OK |
| graph | OracleQueries + AMMQueries + PredefinedQueries are read-only literals | OK |
| ai | privacyMultipliers read-only; baseRewardPerMinute only .Set() reads |
OK |
| threshold | only error sentinels (immutable) | OK |
Implementation
// fhe/contract.go additions:
var (
ciphertextStoreMu sync.RWMutex
ciphertextStore = make(map[string]*tfhe.Ciphertext)
ciphertextTypes = make(map[string]int)
)
func storeCiphertext(key string, ct *tfhe.Ciphertext, fheType int) {
ciphertextStoreMu.Lock()
defer ciphertextStoreMu.Unlock()
ciphertextStore[key] = ct
ciphertextTypes[key] = fheType
}
func getCiphertext(key string) (*tfhe.Ciphertext, int, bool) {
ciphertextStoreMu.RLock()
defer ciphertextStoreMu.RUnlock()
ct, ok := ciphertextStore[key]
if !ok {
return nil, 0, false
}
return ct, ciphertextTypes[key], true
}
Test (must add)
// fhe/concurrency_test.go
func TestFHE_ConcurrentAccess(t *testing.T) {
const N = 100
var wg sync.WaitGroup
wg.Add(N)
for i := 0; i < N; i++ {
go func(i int) {
defer wg.Done()
// perform FHE op that reads+writes maps
_, _ = runFheOp(/* ... */)
}(i)
}
wg.Wait()
}
Run with: go test -race -run TestFHE_ConcurrentAccess
Out-of-scope packages
Per analysis, all other packages already have proper synchronization. Do NOT add mutexes where not needed — that's just noise.
Commits expected
fhe: add sync.RWMutex to ciphertextStore and ciphertextTypes (prevents consensus split)attestation: protect globalVerifier + nvtrustVerifier with sync.RWMutexprecompile: add concurrency tests for fhe + attestation