|
| 1 | +CREATE TABLE IF NOT EXISTS multiverse_roots ( |
| 2 | + id BIGINT PRIMARY KEY, |
| 3 | + |
| 4 | + -- For the namespace root, we set the foreign key constraint evaluation to |
| 5 | + -- be deferred until after the database transaction ends. Otherwise, if the |
| 6 | + -- root of the SMT is deleted temporarily before inserting a new root, then |
| 7 | + -- this constraint is violated as there's no longer a root that this |
| 8 | + -- universe tree can point to. |
| 9 | + namespace_root VARCHAR UNIQUE NOT NULL REFERENCES mssmt_roots(namespace) DEFERRABLE INITIALLY DEFERRED, |
| 10 | + |
| 11 | + -- This field is an enum representing the proof type stored in the given |
| 12 | + -- universe. |
| 13 | + proof_type TEXT NOT NULL CHECK(proof_type IN ('issuance', 'transfer')) |
| 14 | +); |
| 15 | + |
| 16 | +CREATE TABLE IF NOT EXISTS multiverse_leaves ( |
| 17 | + id BIGINT PRIMARY KEY, |
| 18 | + |
| 19 | + multiverse_root_id BIGINT NOT NULL REFERENCES multiverse_roots(id), |
| 20 | + |
| 21 | + asset_id BLOB CHECK(length(asset_id) = 32), |
| 22 | + |
| 23 | + -- We use the 32 byte schnorr key here as this is what's used to derive the |
| 24 | + -- top-level Taproot Asset commitment key. |
| 25 | + group_key BLOB CHECK(LENGTH(group_key) = 32), |
| 26 | + |
| 27 | + leaf_node_key BLOB NOT NULL, |
| 28 | + |
| 29 | + leaf_node_namespace VARCHAR NOT NULL, |
| 30 | + |
| 31 | + -- Both the asset ID and group key cannot be null at the same time. |
| 32 | + CHECK ( |
| 33 | + (asset_id IS NOT NULL AND group_key IS NULL) OR |
| 34 | + (asset_id IS NULL AND group_key IS NOT NULL) |
| 35 | + ) |
| 36 | +); |
| 37 | + |
| 38 | +CREATE UNIQUE INDEX multiverse_leaves_unique ON multiverse_leaves ( |
| 39 | + leaf_node_key, leaf_node_namespace |
| 40 | +); |
| 41 | + |
| 42 | +-- If there already is a multiverse root entry in the mssmt_roots for the |
| 43 | +-- issuance or transfer multiverses, add them to the multiverse_roots table as |
| 44 | +-- well. Both statements are no-ops if the root doesn't exist yet. |
| 45 | +INSERT INTO multiverse_roots (namespace_root, proof_type) |
| 46 | +SELECT 'multiverse-issuance', 'issuance' |
| 47 | +WHERE EXISTS ( |
| 48 | + SELECT 1 FROM mssmt_roots WHERE namespace = 'multiverse-issuance' |
| 49 | +); |
| 50 | + |
| 51 | +INSERT INTO multiverse_roots (namespace_root, proof_type) |
| 52 | +SELECT 'multiverse-transfer', 'transfer' |
| 53 | +WHERE EXISTS ( |
| 54 | + SELECT 1 FROM mssmt_roots WHERE namespace = 'multiverse-transfer' |
| 55 | +); |
| 56 | + |
| 57 | +-- And now we create the multiverse_leaves entries for the multiverse roots. |
| 58 | +-- This is a no-op if the multiverse root doesn't exist yet. |
| 59 | +INSERT INTO multiverse_leaves ( |
| 60 | + multiverse_root_id, asset_id, group_key, leaf_node_key, leaf_node_namespace |
| 61 | +) SELECT |
| 62 | + (SELECT id from multiverse_roots mr where mr.namespace_root = 'multiverse-issuance'), |
| 63 | + CASE WHEN ur.group_key IS NULL THEN ur.asset_id ELSE NULL END, |
| 64 | + ur.group_key, |
| 65 | + -- UNHEX() only exists in SQLite and it doesn't take a second argument |
| 66 | + -- (the 'hex' part). But it also doesn't complain about it, so we can |
| 67 | + -- leave it in for the Postgres version which is replaced in-memory to |
| 68 | + -- DECODE() which needs the 'hex' argument. |
| 69 | + UNHEX(REPLACE(ur.namespace_root, 'issuance-', ''), 'hex'), |
| 70 | + ur.namespace_root |
| 71 | + FROM universe_roots ur |
| 72 | + WHERE ur.namespace_root LIKE 'issuance-%'; |
| 73 | + |
| 74 | +INSERT INTO multiverse_leaves ( |
| 75 | + multiverse_root_id, asset_id, group_key, leaf_node_key, leaf_node_namespace |
| 76 | +) SELECT |
| 77 | + (SELECT id from multiverse_roots mr where mr.namespace_root = 'multiverse-transfer'), |
| 78 | + CASE WHEN ur.group_key IS NULL THEN ur.asset_id ELSE NULL END, |
| 79 | + ur.group_key, |
| 80 | + -- UNHEX() only exists in SQLite and it doesn't take a second argument |
| 81 | + -- (the 'hex' part). But it also doesn't complain about it, so we can |
| 82 | + -- leave it in for the Postgres version which is replaced in-memory to |
| 83 | + -- DECODE() which needs the 'hex' argument. |
| 84 | + UNHEX(REPLACE(ur.namespace_root, 'transfer-', ''), 'hex'), |
| 85 | + ur.namespace_root |
| 86 | +FROM universe_roots ur |
| 87 | +WHERE ur.namespace_root LIKE 'transfer-%'; |
0 commit comments