diff --git a/script/research/vm-db-types/export-table.py b/script/research/vm-db-types/export-table.py new file mode 100644 index 000000000..97ffc0de5 --- /dev/null +++ b/script/research/vm-db-types/export-table.py @@ -0,0 +1,141 @@ +from tabulate import tabulate + +headers = [ + "row_index", "first_name", "last_name", "..." +] + +table = [ + ["46", "john", "doe", "..."], + ["...", "", "", ""] +] + +print(tabulate(table, headers, tablefmt="github")) +print() + +# Foos + +headers = [ + "foo_index", "foo_name" +] + +table = [ + [1, "john doe"], + [2, "alison bob"], + ["...", ""], +] + +print(tabulate(table, headers, tablefmt="github")) +print() + +# Foo-Bars + +headers = [ + "foo_index", "bar_index" +] + +table = [ + [1, 73], + [1, 74], + ["...", ""], +] + +print(tabulate(table, headers, tablefmt="github")) +print() + +# Bars + +headers = [ + "bar_index", "bar_x" +] + +table = [ + [73, 110], + [74, 4], + ["...", ""], +] + +print(tabulate(table, headers, tablefmt="github")) +print() + +##### DAO State + +headers = [ + "dao_tree_index", "proposal_tree_index" +] +table = [ + [301, 406] +] +print(tabulate(table, headers, tablefmt="github")) +print() + +# DAO bullas + +headers = [ + "dao_bulla" +] +table = [ + ["0xabea9132b05a70803a4e85094fd0e1800777fbef"], + ["0x7c4de4aa5068376033aef8e3df766aff3080e045"] +] +print(tabulate(table, headers, tablefmt="github")) +print() + +# DAO roots + +headers = [ + "dao_roots" +] +table = [ + ["0xd6dfd811e06267b25472753c4e57c0b28652bfb8"], + ["0x5f78fbab81f9892bbe379d88c8a224774411b0a9"] +] +print(tabulate(table, headers, tablefmt="github")) +print() + +# proposal roots + +headers = [ + "proposal_roots" +] +table = [ + ["0x1430118732f564ec474c4998d94521661143df23"], + ["0x87611ca3403a3878dfef0da2a786e209abfc1eff"] +] +print(tabulate(table, headers, tablefmt="github")) +print() + +# proposal votes + +headers = [ + "proposal_votes_index", "yes_votes_commit", "all_votes_commit" +] +table = [ + [72, "xxx", "yyy"] +] +print(tabulate(table, headers, tablefmt="github")) +print() + +# vote nullifiers + +headers = [ + "proposal_votes_index", "nullifier" +] +table = [ + [72, "aaa"], + [72, "bbb"], + [72, "ccc"], +] +print(tabulate(table, headers, tablefmt="github")) +print() + +# Base -> ProposalVotes index (proposal_votes) + +headers = [ + "base", "proposal_votes_index" +] +table = [ + ["0xa20bfb25ab13a77cc9b50aec28a0b826cee20f88892d087ec1cbc1cbda635d6e", 72], +] +print(tabulate(table, headers, tablefmt="github")) +print() + diff --git a/script/research/vm-db-types/vm-db-types.md b/script/research/vm-db-types/vm-db-types.md new file mode 100644 index 000000000..d820dddfa --- /dev/null +++ b/script/research/vm-db-types/vm-db-types.md @@ -0,0 +1,167 @@ +# Tables vs Key-Value + +Every SQL style DB can be transformed to a key-value database. + +Imagine you have a table with 2 indexes like so: + +| row_index | first_name | last_name | ... | +|-------------|--------------|-------------|-------| +| 46 | john | doe | ... | +| ... | | | | + +This can be represented by two key-value databases. + +```python +objects = { + 46: (...), + ... +} + +indexes = { + "john": ("first_name", 46), + "doe": ("last_name", 46) +} +``` + +This simple trick means we can translate any table layout easily +to a key-value format. + +Indeed both key-value databases above can actually be combined together +but then that means the keys for object would allow string types. Having +just integer indexes that are sequential allows for fast optimization of +object lookups. + +Also object types can be combined inside the same kv-db since the value +field of the db is just bytes that are deserialized. + +# Example 1 + +```rust +struct State { + foos: Vec +} + +struct Foo { + name: String, + bars: Vec +} + +struct Bar { + x: u32 +} + +... + +let state = State { + foos: vec![ + Foo { + name: "john doe", + bars: vec![ + Bar { x: 110 }, + Bar { x: 4 }, + ] + }, + Foo { + name: "alison bob", + bars: vec![ + ] + }, + ] +}; +``` + +Table containing Foo objects: + +| foo_index | foo_name | +|-------------|------------| +| 1 | john doe | +| 2 | alison bob | +| ... | | + +This table links Bar objects to Foo: + +| foo_index | bar_index | +|-------------|-------------| +| 1 | 73 | +| 1 | 74 | +| ... | | + +Table containing Bar objects: + +| bar_index | bar_x | +|-------------|---------| +| 73 | 110 | +| 74 | 4 | +| ... | | + +# Example 2: DAO State + +```rust +pub struct ProposalVotes { + // TODO: might be more logical to have 'yes_votes_commit' and 'no_votes_commit' + /// Weighted vote commit + pub yes_votes_commit: pallas::Point, + /// All value staked in the vote + pub all_votes_commit: pallas::Point, + /// Vote nullifiers + pub vote_nulls: Vec, +} + +/// This DAO state is for all DAOs on the network. There should only be a single instance. +pub struct State { + dao_bullas: Vec, + pub dao_tree: MerkleTree, + pub dao_roots: Vec, + + //proposal_bullas: Vec, + pub proposal_tree: MerkleTree, + pub proposal_roots: Vec, + pub proposal_votes: HashMap, +} +``` + +The important thing to note is that we are not restricted to using simple key-value databases. + +We can also combine them with optimized databases such as merkle-tree dbs. + +The main DAO state is represented by a table with a single row. + +| dao_tree_index | proposal_tree_index | +|------------------|-----------------------| +| 301 | 406 | + +301 and 406 here refer to instances of separate merkle tree dbs. + +| dao_bulla | +|--------------------------------------------| +| 0xabea9132b05a70803a4e85094fd0e1800777fbef | +| 0x7c4de4aa5068376033aef8e3df766aff3080e045 | + +| dao_roots | +|--------------------------------------------| +| 0xd6dfd811e06267b25472753c4e57c0b28652bfb8 | +| 0x5f78fbab81f9892bbe379d88c8a224774411b0a9 | + +| proposal_roots | +|--------------------------------------------| +| 0x1430118732f564ec474c4998d94521661143df23 | +| 0x87611ca3403a3878dfef0da2a786e209abfc1eff | + +These tables keeping track of the roots, could even be part of the merkle databases themselves. + +| proposal_votes_index | yes_votes_commit | all_votes_commit | +|------------------------|--------------------|--------------------| +| 72 | xxx | yyy | + +| proposal_votes_index | nullifier | +|------------------------|-------------| +| 72 | aaa | +| 72 | bbb | +| 72 | ccc | + +And lastly we create the Base -> ProposalVotes index. + +| base | proposal_votes_index | +|--------------------------------------------------------------------|------------------------| +| 0xa20bfb25ab13a77cc9b50aec28a0b826cee20f88892d087ec1cbc1cbda635d6e | 72 | +