Arcfield is a production-grade, highly durable game economy service built with FastAPI and PostgreSQL. It enforces exactly-once transaction execution using global idempotency scoping, pessimistic locking concurrency control, and append-only ledgers to prevent issues such as double-spending, balance overflows, and partial state creation during crashes.
- Atomic Transactions: Every mutating operation (wallet updates, ledger updates, inventory grants, claimed rewards, and idempotency status updates) is committed together in a single PostgreSQL transaction block.
- Exactly-Once Semantics: Clients provide a unique
Idempotency-Key(UUIDv4) header. The service fingerprints requests using SHA-256 and replays the original response (including status code and response body) upon duplicate requests. Reuses of the same key with different payloads are rejected with400 Bad Request. - Pessimistic Concurrency Control: Relies on
SELECT ... FOR UPDATErow-level exclusive locks in PostgreSQL. Concurrent requests for a single player are serialized, preventing double-spending or duplicate reward claims. - Audit Trail: An append-only ledger logs every balance modification, guaranteeing that the final wallet balance always matches the sum of the ledger entries.
- Python 3.12+
- Docker & Docker Compose
Launch the PostgreSQL database container:
docker compose up -d dbThe database will start on port 5433 with user/password/db set to arcfield.
Install dependencies and run the server locally:
pip install -e .
python -m uvicorn src.main:app --port 8080 --reloadAlternatively, run the entire stack (app + db) via Docker Compose:
docker compose up -dThe application will listen on http://localhost:8080.
To run the complete automated test suite (including health checks, credit, purchase, reward claim, concurrency race, and subprocess kill -9 durability tests):
python -m pytestBelow are standard API usage examples using curl. All mutating endpoints require an Idempotency-Key header.
curl -X GET http://localhost:8080/healthcurl -X GET http://localhost:8080/v1/wallets/player_01Credits a player's wallet with a specific positive integer amount.
curl -X POST http://localhost:8080/v1/wallets/player_01/credit \
-H "Content-Type: application/json" \
-H "Idempotency-Key: a4fa29d3-57b1-4d11-b0e9-ffb203c9d64f" \
-d '{"amount": 1000}'Debits the player's wallet and grants an inventory item.
curl -X POST http://localhost:8080/v1/wallets/player_01/purchase \
-H "Content-Type: application/json" \
-H "Idempotency-Key: b77e8fd0-6819-482a-a92c-0de5d688cf7f" \
-d '{"price": 150, "item_id": "iron_shield_02"}'Claims a reward exactly once per player.
curl -X POST http://localhost:8080/v1/rewards/epic_quest_reward_01/claim \
-H "Content-Type: application/json" \
-H "Idempotency-Key: c9d8e7f6-1234-5678-90ab-cdef12345678" \
-d '{"player_id": "player_01"}'