-
-
Notifications
You must be signed in to change notification settings - Fork 63
Bug: Concurrency Race Condition causes silent data loss in Raid XP #404
Copy link
Copy link
Open
Labels
Gssoc 26Part of GirlScript Summer of Code 2026Part of GirlScript Summer of Code 2026backendBackend/API relatedBackend/API relatedgood first issueGood for newcomersGood for newcomersgssoc:approvedApproved GSSoC contributionApproved GSSoC contributionlevel:intermediateIntermediate difficulty levelIntermediate difficulty leveltype:bugSomething isn't working as expectedSomething isn't working as expected
Metadata
Metadata
Assignees
Labels
Gssoc 26Part of GirlScript Summer of Code 2026Part of GirlScript Summer of Code 2026backendBackend/API relatedBackend/API relatedgood first issueGood for newcomersGood for newcomersgssoc:approvedApproved GSSoC contributionApproved GSSoC contributionlevel:intermediateIntermediate difficulty levelIntermediate difficulty leveltype:bugSomething isn't working as expectedSomething isn't working as expected
Description
In src/app/api/raid/execute/route.ts, the defender and attacker's
aid_xp are updated using values computed in application memory based on reads that occurred at the very beginning of the request:
typescript await Promise.all([ admin.from("developers").update({ raid_xp: (attacker.raid_xp ?? 0) + XP_WIN_ATTACKER }).eq("id", attacker.id), admin.from("developers").update({ raid_xp: (defender.raid_xp ?? 0) + XP_WIN_DEFENDER }).eq("id", defender.id), ]);Because the atomic execute_raid RPC executes in between the initial read and this update, any concurrent XP changes to the defender (e.g. they defended another raid concurrently, or completed a daily mission granting XP) will be completely overwritten by this stale update, resulting in silent data loss for users.
Recommendation
Update the
aid_xp natively inside the execute_raid RPC function in Supabase where row-level locks prevent concurrent data races, rather than doing it in the Node environment.