The simulator model
What Crucible Simulator is, in one picture:
Simulator
├── Environment configuration + state store + RNG + ledger
├── Accounts synthetic identities (Alice, Bob, Carol, Issuer, Auditor)
├── Tokens native test asset and configured confidential tokens
├── State commitments, nullifiers, transitions, snapshots
├── Flows register -> deposit -> merge -> transfer -> withdraw
├── Transactions every operation produces one (Success/Rejected/Failed)
└── Events value-free observable output
A developer drives it the way the spec’s MVP does:
Create environment → Create token → Create accounts → Register accounts
→ Deposit assets → Generate state → Execute confidential operation
→ Update state → Inspect result → Assert expected state
The two promises that make the model usable:
- Determinism — the same configuration, initial state, operation sequence, and seed produce the same resulting state, events, commitments, and transaction outcomes, bit for bit, on any machine.
- Inspectability — every operation leaves an auditable trail
(transaction record, event, explicit
State0 → Transition → State1) and the private simulation state behind the balances is reachable through the labeledinspect_private_*testing APIs.
What the simulator is NOT
It is a testing environment, not a production system:
- it does not prove anything — proofs enter through the
ProofProviderboundary (seedocs/integration.md); - it does not hold real identities or assets — accounts are synthetic and deterministic;
- it does not invent cryptography — commitments and Merkle structures
model the shapes flows need, with domain-separated SHA-256 for
determinism rather than adversarial strength (see
docs/security.md).
Operation outcomes
Since every operation is recorded, a scenario can assert on all three outcome classes:
| Status | Meaning |
|---|---|
Success | Applied and committed: version bumped, transition recorded |
Rejected | Failed validation/authorization/state/proof before any mutation; nothing changed, operation_rejected event emitted |
Failed | Started inside the transaction scope and rolled back; nothing changed, operation_rejected event emitted |
Rejected and failed operations never bump the version and never move the state root — atomicity is absolute — but they leave a structured, deterministic-ID transaction and event behind, so conformance suites can assert on the rejection record, not just on the error return.