Please see this project's accompanying blog post on my website.
Inspiration
Reserva is an open source central bank digital currency. Its design decisions were inspired by several recent works on the topic, but the most important was Technical possibilities for a U.S. Central Bank Digital Currency, a paper published by the US Federal government on the technical subtleties they are grappling with in their early stages of exploring CBDCs.
I found SingleStore to be an excellent database for this use case for three reasons:
- It's ability to mix rowstore with columnstore tables allows you to run analytics directly on your live data without advanced data engineering.
- Its ability to store JSON and other flexible data types is also important, as it would enable banks to store KYC data and anything else required by potential legislation.
- Its first class support for sharding, combined with a clever data model, allows you to make a funds transfer a single-node transaction. This means that write performance can theoretically scale linearly with hardware resource!
What it does
This API is designed to complement the M1 money supply, and will be used by "pre-vetted" end users - most likely commercial banks, and possibly payment providers. There are routes to create banks (which is similar to a "users" table), accounts, and transfers, as well a few routes to update and get relevant information on those objects.
How I built it
I built this application using the Go programming language with no web framework. The Reserva server was designed to be stateless, so it could be containerized and scaled horizontally in popular orchestration services like Kubernetes or ECS.
The API uses the Middleware pattern to do authentication, authorization, and panic (error) handling.
There is also an addBank program and loadTest program packaged in the repository - these allow you to add a bank to a freshly migrated database, and load test your Reserva setup, respectively. These are also Go programs that take command line flags for relevant inputs, and use somewhat similar development patterns to the main API program.
All of these programs are copied and installed into a container running on top of the official Go Docker image, and deployed alongside SingleStore and a key value cache in a docker compose file. So, simply running docker-compose up should start the project!
Challenges I ran into
Building an API from scratch is always a challenging endeavor - especially if you want it to be high performance and secure.
The main creative challenge was simplifying the data model and storing enough in the key-value cache so that a funds transfer would be a single node transaction. A key component of making a sharded database schema go fast is the art of splitting work effectively - it took a lot of thought to settle on such a simple data model.
Accomplishments that I'm proud of
Running 2,400 transfers per second on a SingleStore "Cluster In A Box" docker container, with no specialized knowledge of the DB, along with several other resource intensive services, was very gratifying.
What I learned
There are a lot of "sanity checks" that go into making a funds transfer (or a CBDC in general) that aren't immediately apparent. Obviously, you should check that a source account exists, and that there are enough funds in it to make the transfer.
However, the paper from the US government does a great job pointing out subtle questions like "who should be able to make requests to the API?" or "should there be a central authority who can create or reverse transactions?". These are philosophical questions first and foremost, but have real consequences on technical work down the line.
What's next for Reserva
Right now, account balances are stored in the key value cache. This means that if the cache goes down, all account balances will need to be re-computed by iterating over previous transactions and money supply changes.
This logic will be very similar to a database write ahead logging (WAL) recovery system, which I have actually had to implement in the past for a school project. This would be the next big milestone (along with adding a few key API routes) that would need to be completed before Reserva is anywhere near "production ready".
Log in or sign up for Devpost to join the conversation.