Last active
April 3, 2018 10:49
-
-
Save dahlia/25daed6f8545f4d3a3219eae04379049 to your computer and use it in GitHub Desktop.
Experiments on integrity of ledgers using constraints
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BEGIN; | |
CREATE TABLE transaction ( | |
id uuid PRIMARY KEY, | |
time timestamptz NOT NULL DEFAULT (now()), | |
ledger_id uuid NOT NULL, | |
prev_id uuid, | |
prev_time timestamptz, | |
prev_balance decimal NOT NULL, | |
genesis bool, -- It cannot be false, but only true or NULL. | |
amount decimal NOT NULL, | |
balance decimal NOT NULL, | |
-- A unique index to guarantee every transaction has only one child at most. | |
UNIQUE (prev_id), | |
-- A unique index to be referenced by (ledger_id, prev_id, prev_time, | |
-- balance). | |
UNIQUE (ledger_id, id, time, balance), | |
-- Guarantee that a transaction is chained from a previous transaction. | |
FOREIGN KEY (ledger_id, prev_id, prev_time, prev_balance) | |
REFERENCES transaction (ledger_id, id, time, balance), | |
-- Gurantee a transaction cannot be a child of a future transaction. | |
CHECK (prev_time < time), | |
-- Guarantee a transaction delta amount cannot be zero unless it's genesis. | |
CHECK (amount != 0 OR genesis IS NOT NULL AND amount = 0), | |
-- Guarantee integrity between balance and its and its previous' balance. | |
CHECK (balance = amount + coalesce(prev_balance, 0)), | |
-- Guarantee genesis must not be false, but either only true or NULL. | |
CHECK (genesis IS NULL OR genesis), | |
-- Guarantee there is only one genesis transaction for each ledger. | |
UNIQUE (ledger_id, genesis) | |
); | |
CREATE INDEX ON transaction (time); | |
-- Get the current balance of a ledger: | |
SELECT balance | |
FROM transaction | |
WHERE ledger_id = '00000000-0000-0000-0000-000000000000' | |
ORDER BY time DESC | |
LIMIT 1; | |
ROLLBACK; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment