A specialised ledger database for ordered transfers, reservations and recoverable storage.
This payment ledger architecture keeps the ledger engine apart from the application around it. The engine applies debits and credits. Applications see a model of accounts and the transfers between them. The application around it keeps customer profiles, supplies authorization and groups requests into batches. Every transfer runs through a replicated state machine, which fixes its order and its effect on balances.
The challenge
Losing a response does not tell the caller whether its transfer ran. A resend must not create a second transfer. An old insufficient-funds request must not quietly succeed just because the money arrived later. That decision has to hold across replicas, and damaged local storage needs a way back to a good state.
What we built
A transfer names a debit account, a credit account and an amount, and the two accounts must differ while belonging to the same ledger. Fixed operations create, look up and query these records. A pending transfer first reserves funds.
A later record can post all or part of a reservation or void it, and it keeps a link back to the original instruction. A set timeout can expire the reservation. Linked transfers can form an atomic group that shares one outcome.
Load the batch before changing balances
The primary replica checks and journals a batch, then replicates the batch to the other replicas. Before it runs, the engine loads the accounts and transfers it will need. The operations then run in order, with no pause for disk or network access partway through a balance update. Balances are stored as unsigned integers. Every change runs through an overflow check before it is applied. A transfer record cannot be changed after it is created.
Keep the request's identity
Callers generate and keep a transfer identifier before they submit the request to the engine. Matching details under that identifier return the existing record, while other details flag a mismatch. A failed attempt can keep its identifier marked as failed, which is what stops an old insufficient-funds request from succeeding later. Session numbers and checksums catch in-flight repeats. Stored replies then let the caller recover cleanly after a lost response.
Repair from matching replicated state
Viewstamped Replication uses a hash-chained journal, checkpoints and checksummed blocks. Because every replica builds the same deterministic physical state, a damaged block can be rebuilt from any peer that holds a matching copy. Reservation expiry is a consensus operation, which means the replicas agree on when a hold ends.
Project success
Applications can post transfers, reserve funds and follow the records that resolve those reservations. Retry responses are defined, and damaged storage has a peer-repair path. Customer management and public access stay outside the engine, while the application around it submits its work in batches.
Technology stack
Implementation
Zig
Replication
Viewstamped Replication
Storage
Hash-chained journal, checksummed blocks, LSM structures
Client protocol
Batched binary requests
Integration options
C, Go, Java, .NET, Node.js, Python, Ruby and Rust clients
Other engagements
Recognize the pattern?
If one of these looks like your situation, the discovery call is where we find out how close.