mithril_aggregator/database/
migration.rs

1//! Migration module
2//!
3use mithril_persistence::database::SqlMigration;
4
5/// Get all the migrations required by this version of the software.
6/// There shall be one migration per database version. There could be several
7/// statements per migration.
8pub fn get_migrations() -> Vec<SqlMigration> {
9    vec![
10        SqlMigration::new_squashed(
11            29,
12            "2445.0",
13            r#"
14create table if not exists signed_entity_type (
15    signed_entity_type_id       integer     not null,
16    name                        text        not null,
17    primary key (signed_entity_type_id)
18);
19insert into signed_entity_type (signed_entity_type_id, name)
20    values  (0, 'Mithril Stake Distribution'),
21            (1, 'Cardano Stake Distribution'),
22            (2, 'Full Cardano Immutable Files'),
23            (3, 'Cardano Transactions');
24
25create table if not exists signer (
26    signer_id                   text        not null,
27    pool_ticker                 text,
28    created_at                  text        not null,
29    updated_at                  text        not null,
30    last_registered_at          text        null,
31    primary key (signer_id)
32);
33
34create table if not exists epoch_setting (
35    epoch_setting_id                    integer     not null,
36    protocol_parameters                 json        not null,
37    cardano_transactions_signing_config json        not null,
38    primary key (epoch_setting_id)
39);
40
41create table if not exists signer_registration (
42    signer_id                   text        not null,
43    epoch_setting_id            integer     not null,
44    verification_key            text        not null,
45    verification_key_signature  text,
46    operational_certificate     text,
47    kes_period                  integer,
48    stake                       integer,
49    created_at                  text        not null,
50    primary key (epoch_setting_id, signer_id)
51    foreign key (epoch_setting_id) references epoch_setting(epoch_setting_id)
52    foreign key (signer_id) references signer(signer_id)
53);
54create index signer_registration_epoch_setting_id_index on signer_registration(epoch_setting_id);
55create index signer_registration_signer_id_index on signer_registration(signer_id);
56
57create table if not exists open_message (
58    open_message_id         text    not null,
59    epoch_setting_id        int     not null,
60    beacon                  json    not null,
61    signed_entity_type_id   int     not null,
62    created_at              text    not null,
63    protocol_message        json    not null,
64    is_certified            bool    not null default false,
65    is_expired              bool    not null default false,
66    expires_at              text    null,
67    primary key (open_message_id),
68    foreign key (epoch_setting_id)     references epoch_setting (epoch_setting_id),
69    foreign key (signed_entity_type_id) references signed_entity_type (signed_entity_type_id)
70);
71create unique index open_message_unique_index on open_message(signed_entity_type_id, beacon);
72create index open_message_epoch_setting_id_index on open_message(epoch_setting_id);
73create index open_message_signed_entity_type_id_index on open_message(signed_entity_type_id);
74
75create table if not exists single_signature (
76    open_message_id                 text        not null,
77    signer_id                       text        not null,
78    registration_epoch_setting_id   integer     not null,
79    lottery_indexes                 json        not null,
80    signature                       text        not null,
81    created_at                      text        not null,
82    primary key (open_message_id, signer_id, registration_epoch_setting_id)
83    foreign key (open_message_id) references open_message(open_message_id) on delete cascade
84    foreign key (signer_id, registration_epoch_setting_id) references signer_registration(signer_id, epoch_setting_id)
85);
86create index single_signature_open_message_id_index on single_signature(open_message_id);
87create index single_signature_signer_id_index on single_signature(signer_id);
88create index single_signature_registration_epoch_setting_id_index on single_signature(registration_epoch_setting_id);
89
90create table if not exists buffered_single_signature (
91    signed_entity_type_id           integer     not null,
92    party_id                        text        not null,
93    lottery_indexes                 json        not null,
94    signature                       text        not null,
95    created_at                      text        not null,
96    primary key (signed_entity_type_id, party_id)
97);
98create index buffered_single_signature_signed_entity_type_id on buffered_single_signature(signed_entity_type_id);
99create index buffered_single_signature_party_id_index on buffered_single_signature(party_id);
100
101create table if not exists certificate (
102    certificate_id              text     not null,
103    parent_certificate_id       text,
104    message                     text     not null,
105    signature                   text     not null,
106    aggregate_verification_key  text     not null,
107    epoch                       integer  not null,
108    network                     text     not null,
109    signed_entity_type_id       integer  not null,
110    signed_entity_beacon        json     not null,
111    protocol_version            text     not null,
112    protocol_parameters         json     not null,
113    protocol_message            json     not null,
114    signers                     json     not null,
115    initiated_at                text     not null,
116    sealed_at                   text     not null,
117    primary key (certificate_id),
118    foreign key (parent_certificate_id) references certificate(certificate_id)
119    foreign key (signed_entity_type_id) references signed_entity_type(signed_entity_type_id)
120);
121create index epoch_index on certificate(epoch);
122create index certificate_parent_certificate_id_index on certificate(parent_certificate_id);
123
124create table if not exists signed_entity (
125    signed_entity_id            text        not null,
126    signed_entity_type_id       integer     not null,
127    certificate_id              text        not null,
128    beacon                      json        not null,
129    created_at                  text        not null,
130    artifact                    json        not null,
131    primary key (signed_entity_id)
132    foreign key (signed_entity_type_id) references signed_entity_type(signed_entity_type_id)
133    foreign key (certificate_id) references certificate(certificate_id)
134);
135create index signed_entity_signed_entity_type_id_index on signed_entity(signed_entity_type_id);
136create index signed_entity_certificate_id_index on signed_entity(certificate_id);
137create unique index signed_entity_unique_index on signed_entity(signed_entity_type_id, beacon);
138
139create table if not exists pending_certificate (
140    key_hash                    text     primary key,
141    key                         json     not null,
142    value                       json     not null
143);
144
145create table if not exists stake_pool (
146    stake_pool_id text      not null,
147    epoch         integer   not null,
148    stake         integer   not null,
149    created_at    text      not null,
150    primary key (epoch, stake_pool_id)
151);
152        "#,
153        ),
154        // Migration 30
155        // Alter `signed_entity` table to add `network` in `artifact` JSON field (for snapshot only).
156        SqlMigration::new(
157            30,
158            r#"
159update signed_entity
160    set artifact = json_insert(
161        json_insert(
162            artifact,
163            '$.network', 
164            json_extract(beacon, '$.network'))
165    ) 
166where signed_entity.signed_entity_type_id = 2;
167        "#,
168        ),
169        // Migration 31
170        // Remove `network` from cardano immutable files full beacons in `open_message`,
171        // `signed_entity`, and `certificate` tables
172        SqlMigration::new(
173            31,
174            r#"
175update open_message
176    set beacon = json_remove(beacon, '$.network')
177    where open_message.signed_entity_type_id = 2;
178
179update signed_entity
180    set beacon = json_remove(beacon, '$.network'),
181        artifact = json_remove(artifact, '$.beacon.network')
182    where signed_entity.signed_entity_type_id = 2;
183
184update certificate
185    set signed_entity_beacon = json_remove(signed_entity_beacon, '$.network')
186    where certificate.signed_entity_type_id = 2;
187        "#,
188        ),
189        // Migration 32
190        // Add the `signed_entity_type` record for 'CardanoDatabase'
191        SqlMigration::new(
192            32,
193            r#"
194insert into signed_entity_type (signed_entity_type_id, name) 
195    values  (4, 'Cardano Database');
196        "#,
197        ),
198        // Migration 33
199        // Add the `certificate_pending` table and migration data from the previous
200        // `certificate_pending` JSON format.
201        SqlMigration::new(
202            33,
203            r#"
204create table new_pending_certificate (
205    epoch                           integer     not null,
206    pending_certificate             text        not null,
207    created_at                      text        not null,
208    primary key (epoch)
209);
210create table if not exists pending_certificate (key_hash text primary key, key json not null, value json not null);
211insert into new_pending_certificate (epoch, pending_certificate, created_at) 
212    select 
213        json_extract(pending_certificate.value, '$.epoch') as epoch,
214        pending_certificate.value, 
215        strftime('%Y-%m-%dT%H:%M:%fZ', current_timestamp)
216    from pending_certificate;
217
218drop table pending_certificate;
219alter table new_pending_certificate rename to pending_certificate;
220        "#,
221        ),
222        // Migration 34
223        // Add the `immutable_file_digest` table.
224        SqlMigration::new(
225            34,
226            r#"
227create table immutable_file_digest (
228    immutable_file_name     text    not null,
229    digest                  text    not null,
230    primary key (immutable_file_name)
231);
232        "#,
233        ),
234        // Migration 35
235        // Remove `pending_certificate` table.
236        SqlMigration::new(
237            35,
238            r#"
239drop table pending_certificate;
240        "#,
241        ),
242    ]
243}