https://github.com/syvb/yosoku-core
https://github.com/syvb/yosoku-core
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/syvb/yosoku-core
- Owner: syvb
- License: mit
- Created: 2024-04-24T01:14:34.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2024-09-02T17:23:29.000Z (almost 2 years ago)
- Last Synced: 2025-03-03T20:13:50.524Z (over 1 year ago)
- Language: Rust
- Size: 19.5 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Yosoku
*Yosoku* is an append-only financial ledger, intended for use in financial applications such as prediction markets. Currently this is more of an idea than an actual implementation; the code in this repo is very minimal.
## How it works
All Yosoku data is stored in an append-only ledger, which is a list of transaction. `Ledger` is a trait, so there can be multiple different implementations of a ledger (e.g. `MemoryLedger`, `PostgresLedger`).
### What's in a ledger
A ledger is a list of transactions. A transaction has a list of postings and some metadata (monotonic creation time, creator, and arbitrary metadata). A posting increases/decreases a specified account by a specified amount. The postings of a transaction always sum to zero.
#### Example
```
Ledger
Transaction
# Create user 1 with 100¤ initial balance
Creator: SYSTEM_ACCOUNT
Status: Finalized at Jan 1 2024 00:00
Data: AccountCreation(Account(1), User)
Postings:
SYSTEM_ACCOUNT: -100¤
Account(1): +100¤
Transaction
# Create market
Creator: Account(1)
Status: Finalized at Jan 1 2024 00:03
Data: AccountCreation(Account(2), Contract("Will Twilight Sparkle win my Best Pony award?", ...))
Postings:
# initial subsidy
Account(1): -20¤
Account(2): +20¤
Transaction
# Bet 5¤ on YES
Creator: Account(1)
Status: Finalized at Jan 1 2024 00:06
Data: Bet(Account(2), Outcome::YES)
Postings:
Account(1): -6¤
# Pay 5¤ to contract
Account(2): +5¤
# Pay fee to system
SYSTEM_ACCOUNT: +1¤
# ... 115¤ of other bets ...
Transaction
# Resolve market
Creator: Account(1)
Status: Finalized at Jan 2 2024 00:06
Data: Resolve(Account(2), Outcome::YES)
Postings:
# Reduce market balance to zero
Account(2): -120¤
# Send payouts using market balance
Account(1): +10¤
Account(3): +30¤
Account(4): +80¤
```
### Ledger implementations
`MemoryLedger` is the simplest ledger - it just[^ml-time] stores a list of transactions. Most queries on a `MemoryLedger` is slow - for example, `MemoryLedger::account_balance` has to look at every transaction in the ledger to find out which ones affect the provided account. `PostgresLedger` (coming soon!) is much more efficent, by using various indexes and caches to make commonly used queries faster. However, it always produces the same results as a memory ledger.
Since all ledger implementations implement the same `Ledger` interface, user code doesn't need to care what ledger implementation is being used. You can use a `MemoryLedger` for local testing, a `SqliteLedger` in dev, and a `PostgresLedger` in production - they are indistinguishable from the perspective of user code.
[^ml-time]: It also stores a time number (incremented on every transaction), so that transaction times are deterministic.