Storage model
The gateway persists application state in SQLite. Storage::new configures
WAL journal mode, synchronous=NORMAL, a five-connection pool, and a five-
second busy timeout. Embedded migrations run on startup and are forward-only.
Core records
| Record / table | Role |
|---|---|
attestations |
Canonical hash, timestamp, network, sequence, job status, lease and retry fields |
signatures |
Individual Ed25519 witness signatures keyed by hash and witness ID |
aggregated_signatures |
One BLS aggregate per hash |
aggregated_signers |
Ordered signer IDs for a BLS aggregate |
sequences |
Per-network next sequence allocator |
batches |
Batch ID, network, period, count, and Merkle root |
batch_attestations |
Batch membership and Merkle index |
signed_tree_heads |
RFC 9162 tree size, root, timestamp, batch, and signed envelope |
log_state |
Cached current log root and size for STH computation |
cross_anchors |
Peer network and serialized peer signed attestation for a batch |
external_anchor_proofs |
Provider, timestamp, provider JSON, and optional anchored bytes |
The schema also retains compatibility migration logic for legacy BLS rows. New BLS data uses the dedicated aggregate tables.
Job state
pending ---> confirmed
| ^
v |
retryable ------+
|
+-----------> failed
hash is the canonical primary key. network_id and sequence are also
unique as a tuple. Reservation allocates the sequence and inserts the job in a
single transaction. Claiming adds an expiring lease; completion is allowed
only for the current live lease and matching tuple.
The gateway reads signature rows in the same SQLite snapshot as the job state and exposes signatures only for confirmed jobs. The durable job fields include attempt count, next attempt time, bounded last error, lease token, lease expiry, and completion time.
Batch and log state
batch_attestations.merkle_index records the position of each attestation hash
inside its batch. The batch root is built with the RFC 9162 domain-separated
Merkle algorithm. signed_tree_heads stores the global log commitment after a
batch closes. log_state is a cache used for efficient current-root
calculation; the persisted batch and membership records remain the source for
reconstructing the log.
Local-disk requirement
gateway process
|
+--> gateway.db
+--> gateway.db-wal
+--> gateway.db-shm
|
v
reliable local disk
Keep the database and its WAL/SHM files on reliable persistent local storage. Do not put this SQLite database on a network filesystem. A restart can recover ordinary in-progress jobs and confirmed records, but SQLite does not protect against host loss, disk failure, operator compromise, or a malicious rewrite of the database.
Use a persistent directory rather than /tmp, restrict its permissions, and
back up the database and deployment configuration. Test restoration. A backup
is not an independent proof of gateway honesty; signed attestations, retained
proofs, STH consistency checks, and an auditor serve that purpose.
Migration posture
Migrations are compiled into the gateway and applied in order at startup. They are forward-only. Operators should take a verified backup and test an upgrade against a copy. Downgrading requires a compatible pre-upgrade backup and the older binary; migrations are not automatically reversed.