Last active
December 12, 2018 13:03
-
-
Save vizanto/841353e80868c736a01e61b29b9e53c8 to your computer and use it in GitHub Desktop.
This file contains 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
(def multi-transfer-invariant | |
'[$balance-sums | |
[:find [(sum ?balance-before) :as sum-before | |
(sum ?balance-after) :as sum-after | |
(sum ?balance-change) :as sum-of-change] | |
:with ?affected-entity | |
:in $before $after $txn | |
:where | |
;; Unify data from databases and transactions with affected-entity | |
[$after ?affected-entity :account/balance ?balance-after] | |
[$txn ?affected-entity :account/balance ?balance-change] | |
[(get-else $before ?affected-entity :account/balance 0) ?balance-before] | |
;; 1. Zero-Sum | |
[(+ ?balance-change ?balance-before) ?computed-balance-after] | |
[(= ?balance-after ?computed-balance-after)] | |
;; 2. Positivity | |
[(>= ?balance-after 0)] | |
;; 3. Sender spending | |
[$txn _ :transaction/signed-by ?sender] | |
(or | |
;; sender balance should only decrease | |
(and [(= ?sender ?affected-entity)] | |
[(> ?balance-before ?balance-after)]) | |
;; recipient balances should only increase | |
(and [(not= ?sender ?affected-entity)] | |
[(< ?balance-before ?balance-after)]))] | |
$balance-check | |
[:find ?matches . | |
;-- this statement: | |
:within $balance-sums | |
;-- gets rewritten as: | |
:in [?sum-before ?sum-after ?sum-of-change] | |
;-- | |
:where [(= ?sum-before ?sum-after)] | |
[(= ?sum-change 0) ?matches]]]) | |
;;; Schema | |
{:db/ident :datopia.ednt/balance | |
:db/cardinality :db.cardinality/one | |
:db/valueType :db.type/bigdec | |
:db/invariant multi-transfer-invariant} | |
;;; Balance transfer Usage | |
(d/q multi-transfer-invariant | |
;; current state | |
@conn | |
;; apply transaction to current state | |
(dc/db-with @conn transfer-transaction) | |
;; empty database with only transaction applied | |
(dc/db-with (dc/empty-db schema) transfer-transaction) | |
transfer-transaction) |
This file contains 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
(def vote-results-query | |
'[$votes | |
[:find ?issue, ?proposal-name, (count ?vote) :as vote-count | |
:in $ ?issue | |
:where | |
[?ballot :ballot/issue ?issue] | |
;; Bind the proposal | |
[?proposal :proposal/name ?proposal-name] | |
;; Count only votes for this Ballot | |
[?vote :voter/ballot ?ballot] | |
;; Bind the votes for this proposal | |
[?vote :voter/vote-on-proposal ?proposal]] | |
$most-voted | |
[:find (max ?vote-count) :as winning-vote-count . | |
;-- this statement: | |
:within $votes | |
;-- gets rewritten as: | |
:in [[?issue ?proposal-name ?vote-count]]] | |
;-- | |
$winners | |
[:find ?proposal-name ?vote-count | |
;-- this statement: | |
:within $votes $most-voted | |
;-- gets rewritten as: | |
:in [[?issue ?proposal-name ?vote-count]] ?winning-vote-count | |
;-- | |
:where [(= ?winning-vote-count ?vote-count)]]]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment