---
title: "Demo 3: The Auditor's Demo (Bank Ledger)"
---

# Demo 3: The Auditor's Demo (Bank Ledger)

A financial integrity stress test. 20 concurrent workers perform random bank
transfers while the primary database is killed and restarted 5 times. At the
end, a single query proves that not a single cent was lost.

## What invariant is tested?

Every transfer is a paired DEBIT + CREDIT inside a single transaction.
The total balance across all 100 accounts must always equal exactly
**$1,000,000.00** -- the original seed amount. If any transaction is
partially applied, double-applied, or lost during failover, this number
will be wrong.

## How to run

```bash
# 1. Start the cluster
docker compose up -d --build
docker compose exec pg-primary psql -U app -d bankdb -f /dev/stdin < schema.sql

# 2. Run workers and chaos in parallel
./workers.sh 20 120 &
./chaos.sh 5
wait

# 3. Audit
./audit.sh
```

## Expected results

```
Total balance:  $1000000.00
Transfers done: <thousands>
Balance range:  $XXX.XX ... $XXXXX.XX
Negative accts: 0

RESULT: PASS

The money quote:
SUM(balance) = $1000000.00
Zero cents lost across all failovers.
```

HeliosProxy's Transaction Replay records every statement in the active transaction,
along with a digest of the responses the client was shown. When the primary dies
mid-transaction (`tr_mode = "transaction"`), the proxy detects the failure, waits for
the new primary, and replays the exact sequence of statements there -- the client sees
a pause, not a dropped connection, and the DEBIT+CREDIT pair stays atomic. Each
replayed response is re-digested and compared: if the new primary would have returned
anything other than what the client already saw, the replay is rolled back and the
statement returns `40001` rather than continuing on different rows. A transaction
opened at `SERIALIZABLE` or `REPEATABLE READ` is never replayed at all. If the primary
dies while a
COMMIT is outstanding, that COMMIT is never retried: the client receives
SQLSTATE `08007` and the transfer must be verified before it is re-issued. That
is what keeps the ledger free of double-applied transfers.

## Configuration

- **Workers:** 20 concurrent (configurable: `./workers.sh 50 180`)
- **Chaos cycles:** 5 kills (configurable: `./chaos.sh 10`)
- **Transfer amount:** random $1-$500 per transfer
- **Pool mode:** transaction
- **Sync replication:** enabled (synchronous_standby_names = '*')

## Cleanup

```bash
docker compose down -v
```
