-
Notifications
You must be signed in to change notification settings - Fork 385
/
Copy pathstorage.sql
151 lines (133 loc) · 6.3 KB
/
storage.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# MySQL / MariaDB version of the tree schema
-- ---------------------------------------------
-- Tree stuff here
-- ---------------------------------------------
-- Tree parameters should not be changed after creation. Doing so can
-- render the data in the tree unusable or inconsistent.
CREATE TABLE IF NOT EXISTS Trees(
TreeId INTEGER NOT NULL,
KeyId VARBINARY(255) NOT NULL,
TreeType ENUM('LOG', 'MAP') NOT NULL,
LeafHasherType ENUM('SHA256') NOT NULL,
TreeHasherType ENUM('SHA256') NOT NULL,
AllowsDuplicateLeaves BOOLEAN NOT NULL DEFAULT 0,
PRIMARY KEY(TreeId)
);
-- This table contains tree parameters that can be changed at runtime such as for
-- administrative purposes.
CREATE TABLE IF NOT EXISTS TreeControl(
TreeId INTEGER NOT NULL,
ReadOnlyRequests BOOLEAN,
SigningEnabled BOOLEAN,
SequencingEnabled BOOLEAN,
SequenceIntervalSeconds INTEGER,
SignIntervalSeconds INTEGER,
PRIMARY KEY(TreeId),
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId)
);
CREATE TABLE IF NOT EXISTS Subtree(
TreeId INTEGER NOT NULL,
SubtreeId VARBINARY(255) NOT NULL,
Nodes VARBINARY(32768) NOT NULL,
SubtreeRevision INTEGER NOT NULL, -- negated because DESC indexes aren't supported :/
PRIMARY KEY(TreeId, SubtreeId, SubtreeRevision),
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
);
-- The TreeRevisionIdx is used to enforce that there is only one STH at any
-- tree revision
CREATE TABLE IF NOT EXISTS TreeHead(
TreeId INTEGER NOT NULL,
TreeHeadTimestamp BIGINT,
TreeSize BIGINT,
RootHash VARBINARY(255) NOT NULL,
RootSignature VARBINARY(255) NOT NULL,
TreeRevision BIGINT,
PRIMARY KEY(TreeId, TreeHeadTimestamp),
UNIQUE INDEX TreeRevisionIdx(TreeId, TreeRevision),
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
);
-- ---------------------------------------------
-- Log specific stuff here
-- ---------------------------------------------
-- Creating index at same time as table allows some storage engines to better
-- optimize physical storage layout. Most engines allow multiple nulls in a
-- unique index but some may not.
-- A leaf that has not been sequenced has a row in this table. If duplicate leaves
-- are allowed they will all reference this row.
CREATE TABLE IF NOT EXISTS LeafData(
TreeId INTEGER NOT NULL,
-- This is a personality specific has of some subset of the leaf data.
-- It's only purpose is to allow Trillian to identify duplicate entries in
-- the context of the personality.
LeafIdentityHash VARBINARY(255) NOT NULL,
-- This is the data stored in the leaf for example in CT it contains a DER encoded
-- X.509 certificate but is application dependent
LeafValue BLOB NOT NULL,
-- This is extra data that the application can associate with the leaf should it wish to.
-- This data is not included in signing and hashing.
ExtraData BLOB,
PRIMARY KEY(TreeId, LeafIdentityHash),
INDEX LeafHashIdx(LeafIdentityHash),
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
);
-- When a leaf is sequenced a row is added to this table. If logs allow duplicates then
-- multiple rows will exist with different sequence numbers. The signed timestamp
-- will be communicated via the unsequenced table as this might need to be unique, depending
-- on the log parameters and we can't insert into this table until we have the sequence number
-- which is not available at the time we queue the entry. We need both hashes because the
-- LeafData table is keyed by the raw data hash.
CREATE TABLE IF NOT EXISTS SequencedLeafData(
TreeId INTEGER NOT NULL,
SequenceNumber BIGINT UNSIGNED NOT NULL,
-- This is a personality specific has of some subset of the leaf data.
-- It's only purpose is to allow Trillian to identify duplicate entries in
-- the context of the personality.
LeafIdentityHash VARBINARY(255) NOT NULL,
-- This is a MerkleLeafHash as defined by the treehasher that the log uses. For example for
-- CT this hash will include the leaf prefix byte as well as the leaf data.
MerkleLeafHash VARBINARY(255) NOT NULL,
PRIMARY KEY(TreeId, SequenceNumber),
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE,
FOREIGN KEY(TreeId, LeafIdentityHash) REFERENCES LeafData(TreeId, LeafIdentityHash) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS Unsequenced(
TreeId INTEGER NOT NULL,
-- This is a personality specific has of some subset of the leaf data.
-- It's only purpose is to allow Trillian to identify duplicate entries in
-- the context of the personality.
LeafIdentityHash VARBINARY(255) NOT NULL,
-- This is a MerkleLeafHash as defined by the treehasher that the log uses. For example for
-- CT this hash will include the leaf prefix byte as well as the leaf data.
MerkleLeafHash VARBINARY(255) NOT NULL,
-- SHA256("queueId"|TreeId|leafValueHash)
-- We want this to be unique per entry per log, but queryable by FEs so that
-- we can try to stomp dupe submissions.
MessageId BINARY(32) NOT NULL,
Payload BLOB NOT NULL,
QueueTimestampNanos BIGINT NOT NULL,
PRIMARY KEY (TreeId, LeafIdentityHash, MessageId)
);
-- ---------------------------------------------
-- Map specific stuff here
-- ---------------------------------------------
CREATE TABLE IF NOT EXISTS MapLeaf(
TreeId INTEGER NOT NULL,
KeyHash VARBINARY(255) NOT NULL,
-- MapRevision is stored negated to invert ordering in the primary key index
-- st. more recent revisions come first.
MapRevision BIGINT NOT NULL,
LeafValue BLOB NOT NULL,
PRIMARY KEY(TreeId, KeyHash, MapRevision),
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS MapHead(
TreeId INTEGER NOT NULL,
MapHeadTimestamp BIGINT,
RootHash VARBINARY(255) NOT NULL,
MapRevision BIGINT,
RootSignature VARBINARY(255) NOT NULL,
MapperData BLOB,
PRIMARY KEY(TreeId, MapHeadTimestamp),
UNIQUE INDEX TreeRevisionIdx(TreeId, MapRevision),
FOREIGN KEY(TreeId) REFERENCES Trees(TreeId) ON DELETE CASCADE
);