@@ -172,14 +172,14 @@ struct
172172 | Converting_db db ->
173173 Converting_ledger. merkle_root db
174174
175- let create ~logger ~config ~depth () =
175+ let create ~logger ~config ~depth ?( assert_synced = false ) () =
176176 match config with
177177 | Config. Stable_db_config directory_name ->
178178 Stable_db (Stable_db. create ~directory_name ~depth () )
179179 | Converting_db_config config ->
180180 Converting_db
181181 (Converting_ledger. create ~config: (In_directories config) ~logger
182- ~depth () )
182+ ~depth ~assert_synced () )
183183
184184 let create_temporary ~logger ~backing_type ~depth () =
185185 match backing_type with
@@ -215,6 +215,64 @@ struct
215215 ; backing_2 = Config. backing_of_config config
216216 } )
217217
218+ let create_checkpoint_with_directory t ~directory_name =
219+ let backing_type =
220+ match t with
221+ | Stable_db _db ->
222+ Config. Stable_db
223+ | Converting_db _db ->
224+ Config. Converting_db
225+ in
226+ let config = Config. with_directory ~backing_type ~directory_name in
227+ create_checkpoint t ~config ()
228+
229+ (* * Migrate the accounts in the ledger database [stable_db] and store them in
230+ [empty_hardfork_db]. The accounts are set in the target database in chunks
231+ so the daemon is still responsive during this operation; the daemon would
232+ otherwise stop everything as it hashed every account in the list. *)
233+ let chunked_migration ?(chunk_size = 1 lsl 6 ) stable_locations_and_accounts
234+ empty_migrated_db =
235+ let open Async.Deferred.Let_syntax in
236+ let ledger_depth = Migrated_db. depth empty_migrated_db in
237+ let addrs_and_accounts =
238+ List. mapi stable_locations_and_accounts ~f: (fun i acct ->
239+ ( Migrated_db.Addr. of_int_exn ~ledger_depth i
240+ , Account.Hardfork. of_stable acct ) )
241+ in
242+ let rec set_chunks accounts =
243+ let % bind () = Async_unix.Scheduler. yield () in
244+ let chunk, accounts' = List. split_n accounts chunk_size in
245+ if List. is_empty chunk then return empty_migrated_db
246+ else (
247+ Migrated_db. set_batch_accounts empty_migrated_db chunk ;
248+ set_chunks accounts' )
249+ in
250+ set_chunks addrs_and_accounts
251+
252+ let make_converting t =
253+ let open Async.Deferred.Let_syntax in
254+ match t with
255+ | Converting_db _db ->
256+ return t
257+ | Stable_db db ->
258+ let directory_name =
259+ Stable_db. get_directory db
260+ |> Option. value_exn
261+ ~message: " Invariant: database must be in a directory"
262+ in
263+ let converting_config =
264+ Converting_ledger.Config. with_primary ~directory_name
265+ in
266+ let migrated_db =
267+ Migrated_db. create
268+ ~directory_name: converting_config.converting_directory
269+ ~depth: (Stable_db. depth db) ()
270+ in
271+ let % map migrated_db =
272+ chunked_migration (Stable_db. to_list_sequential db) migrated_db
273+ in
274+ Converting_db (Converting_ledger. of_ledgers db migrated_db)
275+
218276 let as_unmasked t =
219277 match t with
220278 | Stable_db db ->
@@ -270,4 +328,12 @@ struct
270328 Stable_db. get_all_accounts_rooted_at_exn db
271329 | Converting_db db ->
272330 Converting_ledger. get_all_accounts_rooted_at_exn db
331+
332+ let unsafely_decompose_root t =
333+ match t with
334+ | Stable_db db ->
335+ (db, None )
336+ | Converting_db db ->
337+ ( Converting_ledger. primary_ledger db
338+ , Some (Converting_ledger. converting_ledger db) )
273339end
0 commit comments