Skip to content

Commit 8640694

Browse files
committed
archive-hardfork-toolbox: only check on migration record to ensure migration succeeded, integrity is maintained by the migration SQL
1 parent 40192d2 commit 8640694

File tree

3 files changed

+58
-133
lines changed

3 files changed

+58
-133
lines changed

src/app/archive_hardfork_toolbox/archive_hardfork_toolbox.ml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,18 @@ let verify_upgrade_command =
6666
Async.Command.async
6767
~summary:"Verify upgrade from pre-fork to post-fork schema"
6868
(let%map_open.Command { value = postgres_uri; _ } = Uri.Archive.postgres
69-
and version =
70-
Command.Param.flag "--version"
69+
and expected_protocol_version =
70+
Command.Param.flag "--protocol-version"
7171
Command.Param.(required string)
72-
~doc:"String Version to upgrade to (e.g. 3.2.0 etc)"
72+
~doc:"String Protocol Version to upgrade to (e.g. 3.2.0 etc)"
73+
and expected_migration_version =
74+
Command.Param.flag "--migration-version"
75+
Command.Param.(required string)
76+
~doc:"String Migration Version that generates current schema"
7377
in
74-
run_check_and_exit (verify_upgrade ~postgres_uri ~version) )
78+
run_check_and_exit
79+
(verify_upgrade ~postgres_uri ~expected_protocol_version
80+
~expected_migration_version ) )
7581

7682
let validate_fork_command =
7783
Async.Command.async ~summary:"Validate fork block and its ancestors"

src/app/archive_hardfork_toolbox/logic.ml

Lines changed: 40 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -133,89 +133,52 @@ let no_commands_after ~postgres_uri ~fork_state_hash ~fork_slot () =
133133
in
134134
Deferred.return [ check_result ]
135135

136-
let verify_upgrade ~postgres_uri ~version () =
136+
let verify_upgrade ~postgres_uri ~expected_protocol_version
137+
~expected_migration_version () =
137138
let open Deferred.Let_syntax in
138-
let results = ref [] in
139139
let%bind pool = connect postgres_uri in
140140
let query_db = Mina_caqti.query pool in
141-
let%bind res =
142-
query_db ~f:(Sql.SchemaVerification.fetch_schema_row ~version)
143-
in
144-
let%bind missing_cols_zkapp_states =
145-
query_db
146-
~f:(Sql.SchemaVerification.fetch_missing_cols ~table:"zkapp_states")
147-
in
148-
let%bind missing_cols_zkapp_states_nullable =
149-
query_db
150-
~f:
151-
(Sql.SchemaVerification.fetch_missing_cols
152-
~table:"zkapp_states_nullable" )
153-
in
154-
155-
let%bind () =
156-
match res with
157-
| None ->
158-
results :=
141+
let%map res = query_db ~f:Sql.fetch_latest_migration_history in
142+
match res with
143+
| Some (status, protocol_version, migration_version) -> (
144+
let results = Queue.create () in
145+
if String.(status <> "applied") then
146+
Queue.enqueue results
159147
{ id = "4.S"
160-
; name = "Schema migration status"
148+
; name = "Schema migration"
149+
; result = Failure (sprintf "Latest migration has status %s" status)
150+
} ;
151+
if String.(protocol_version <> expected_protocol_version) then
152+
Queue.enqueue results
153+
{ id = "4.S"
154+
; name = "Schema migration"
161155
; result =
162156
Failure
163-
(sprintf "No schema migration found for version %s" version)
164-
}
165-
:: !results ;
166-
Deferred.return ()
167-
| Some status ->
168-
let expected = "applied" in
169-
let result =
170-
if String.equal status expected then Success
171-
else
172-
Failure
173-
(sprintf
174-
"Expected schema migration with version %s to be \"%s\" \
175-
however got status %s"
176-
version expected status )
177-
in
178-
results :=
179-
{ id = "4.S"; name = "Schema migration status"; result } :: !results ;
180-
Deferred.return ()
181-
in
182-
183-
let%bind () =
184-
let result =
185-
if Int.( = ) missing_cols_zkapp_states 0 then Success
186-
else
187-
Failure
188-
(sprintf
189-
"Missing columns for zkapp_states detected during upgrade \
190-
verification: %d"
191-
missing_cols_zkapp_states )
192-
in
193-
results :=
194-
{ id = "5.M"; name = "Missing columns check [zkapp_states]"; result }
195-
:: !results ;
196-
Deferred.return ()
197-
in
198-
199-
let%bind () =
200-
let result =
201-
if Int.( = ) missing_cols_zkapp_states_nullable 0 then Success
202-
else
203-
Failure
204-
(sprintf
205-
"Missing columns for zkapp_states_nullable detected during \
206-
upgrade verification: %d"
207-
missing_cols_zkapp_states_nullable )
208-
in
209-
results :=
210-
{ id = "6.M"
211-
; name = "Missing columns check [zkapp_states_nullable]"
212-
; result
213-
}
214-
:: !results ;
215-
Deferred.return ()
216-
in
217-
218-
Deferred.return !results
157+
(sprintf
158+
"Latest protool version mismatch: actual %s vs expected %s"
159+
protocol_version expected_protocol_version )
160+
} ;
161+
if String.(migration_version <> expected_migration_version) then
162+
Queue.enqueue results
163+
{ id = "4.S"
164+
; name = "Schema migration"
165+
; result =
166+
Failure
167+
(sprintf
168+
"Latest migration version mismatch: actual %s vs expected %s"
169+
migration_version expected_protocol_version )
170+
} ;
171+
match Queue.to_list results with
172+
| [] ->
173+
[ { id = "4.S"; name = "Schema migration"; result = Success } ]
174+
| _ :: _ as results ->
175+
results )
176+
| None ->
177+
[ { id = "4.S"
178+
; name = "Schema migration"
179+
; result = Failure "Can't find latest migration record"
180+
}
181+
]
219182

220183
let validate_fork ~postgres_uri ~fork_state_hash ~fork_slot () =
221184
let open Deferred.Let_syntax in

src/app/archive_hardfork_toolbox/sql.ml

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -120,59 +120,15 @@ let last_fork_block_query =
120120
let last_fork_block (module Conn : CONNECTION) =
121121
Conn.find last_fork_block_query ()
122122
123-
module SchemaVerification = struct
124-
module Types = struct
125-
type schema_row =
126-
{ status : string option
127-
; description : string option
128-
; applied_at : string
129-
; validated_at : string option
130-
}
131-
132-
type result =
133-
{ missing_cols : int
134-
; total_fks : int
135-
; valid_fks : int
136-
; expected_cols_min : int
137-
; expected_cols_max : int
138-
; expected_fk_count : int
139-
; schema : schema_row option
140-
; ok_cols : bool
141-
; ok_fk_present : bool
142-
; ok_fk_validated : bool
143-
; ok_schema_status : bool
144-
; ok : bool
145-
}
146-
end
147-
148-
module Queries = struct
149-
(* 1) How many of element8..element31 are missing in table ? *)
150-
let missing_cols_req =
151-
Caqti_type.(string ->! int)
152-
@@ {|
153-
SELECT count(*) FROM generate_series(8,31) g(n)
154-
LEFT JOIN information_schema.columns c
155-
ON c.table_schema='public'
156-
AND c.table_name=?
157-
AND c.column_name='element'||g.n
158-
WHERE c.column_name IS NULL
159-
|}
160-
161-
(* 2) Row from public.schema_version for a given version.
162-
We stringify timestamps for driver simplicity. *)
163-
let schema_row_req =
164-
Caqti_type.(string ->? string)
165-
@@ {|
123+
let fetch_latest_migration_history_query =
124+
Caqti_type.(unit ->? t3 string string string)
125+
{|
166126
SELECT
167-
status
127+
status, protocol_version, migration_version
168128
FROM migration_history
169-
WHERE protocol_version = ?
129+
ORDER BY commit_start_at DESC
130+
LIMIT 1;
170131
|}
171-
end
172-
173-
let fetch_missing_cols (module Conn : CONNECTION) ~table =
174-
Conn.find Queries.missing_cols_req table
175132
176-
let fetch_schema_row (module Conn : CONNECTION) ~version =
177-
Conn.find_opt Queries.schema_row_req version
178-
end
133+
let fetch_latest_migration_history (module Conn : CONNECTION) =
134+
Conn.find_opt fetch_latest_migration_history_query ()

0 commit comments

Comments
 (0)