Skip to content

Commit 3b0baac

Browse files
committed
Create faster populate from genesis API
Instead of having a populate_root method to populate an existing, empty root ledger from genesis, the genesis ledger now has a create_root method. This method assumes the responsibility for creating the root ledger itself. The create_root method can thus checkpoint the genesis ledger directly when the genesis ledger is backed by a database.
1 parent 2c70f34 commit 3b0baac

File tree

9 files changed

+81
-55
lines changed

9 files changed

+81
-55
lines changed

src/lib/consensus/proof_of_stake.ml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,14 +2666,9 @@ module Make_str (A : Wire_types.Concrete) = struct
26662666
| Ledger_snapshot.Ledger_root ledger ->
26672667
Ok ledger
26682668
| Ledger_snapshot.Genesis_epoch_ledger packed ->
2669-
let fresh_root_ledger =
2670-
Mina_ledger.Ledger.Root.create ~logger
2671-
~config:snapshot_config
2672-
~depth:Context.constraint_constants.ledger_depth
2673-
()
2674-
in
2675-
Genesis_ledger.Packed.populate_root packed
2676-
fresh_root_ledger )
2669+
Genesis_ledger.Packed.create_root packed
2670+
~config:snapshot_config
2671+
~depth:Context.constraint_constants.ledger_depth () )
26772672
in
26782673
match snapshot_id with
26792674
| Staking_epoch_snapshot ->

src/lib/genesis_ledger/genesis_ledger.ml

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,19 @@ module Balances (Balances : Intf.Named_balances_intf) = struct
6666
end
6767

6868
module Utils = struct
69-
let populate_root_with_backing_root genesis_mask ~src ~dest =
70-
let open Or_error.Let_syntax in
69+
(* Create a new [Ledger.Root.t] ledger with the components of a root
70+
backing_ledger for a genesis ledger. These components are the underlying
71+
root ledger and the stored mask on top of that root that is presented to
72+
users of the genesis root. The mask is passed in to this function so we can
73+
assert that there are no uncommitted changes to it, so we can simply
74+
checkpoint the root instead of performing a much slower account transfer. *)
75+
let create_root_from_backing_root genesis_mask root ~config ~depth () =
7176
assert (
7277
Ledger_hash.equal
7378
(Ledger.merkle_root genesis_mask)
74-
(Ledger.Root.merkle_root src) ) ;
75-
let%map _root =
76-
Ledger_transfer_any.transfer_accounts
77-
~src:(Ledger.Root.as_unmasked src)
78-
~dest:(Ledger.Root.as_unmasked dest)
79-
in
80-
dest
79+
(Ledger.Root.merkle_root root) ) ;
80+
assert (Ledger.Root.depth root = depth) ;
81+
Ledger.Root.create_checkpoint ~config root () |> Or_error.return
8182

8283
let keypair_of_account_record_exn (private_key, account) =
8384
let open Account in
@@ -163,11 +164,12 @@ module Make (Inputs : Intf.Ledger_input_intf) : Intf.S = struct
163164

164165
let t = Lazy.map ~f:snd backing_ledger
165166

166-
let populate_root root =
167+
let create_root ~config ~depth () =
167168
let backing_ledger, mask = Lazy.force backing_ledger in
168169
match backing_ledger with
169170
| `Ephemeral ledger ->
170171
let open Or_error.Let_syntax in
172+
let root = Ledger.Root.create ~logger ~config ~depth () in
171173
(* We are transferring to an unmasked view of the root, so this is
172174
used solely for the transfer side effect *)
173175
let%map _dest =
@@ -176,7 +178,7 @@ module Make (Inputs : Intf.Ledger_input_intf) : Intf.S = struct
176178
in
177179
root
178180
| `Root ledger ->
179-
populate_root_with_backing_root mask ~src:ledger ~dest:root
181+
create_root_from_backing_root mask ledger ~config ~depth ()
180182

181183
include Utils
182184

@@ -214,7 +216,7 @@ module Packed = struct
214216

215217
let t ((module L) : t) = L.t
216218

217-
let populate_root ((module L) : t) ledger = L.populate_root ledger
219+
let create_root ((module L) : t) = L.create_root
218220

219221
let depth ((module L) : t) = L.depth
220222

@@ -258,9 +260,9 @@ end) : Intf.S = struct
258260

259261
include Utils
260262

261-
let populate_root dest =
263+
let create_root ~config ~depth () =
262264
let genesis_root, mask = Lazy.force backing_ledger in
263-
populate_root_with_backing_root mask ~src:genesis_root ~dest
265+
create_root_from_backing_root mask genesis_root ~config ~depth ()
264266

265267
let find_account_record_exn ~f =
266268
find_account_record_exn ~f (Lazy.force accounts)

src/lib/genesis_ledger/intf.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,12 @@ end
7474
module type S = sig
7575
val t : Mina_ledger.Ledger.t Lazy.t
7676

77-
(** Populate a root ledger with the content of the genesis ledger *)
78-
val populate_root :
79-
Mina_ledger.Ledger.Root.t -> Mina_ledger.Ledger.Root.t Or_error.t
77+
(** Create a new root ledger that is equal in state to the genesis ledger *)
78+
val create_root :
79+
config:Mina_ledger.Ledger.Root.Config.t
80+
-> depth:int
81+
-> unit
82+
-> Mina_ledger.Ledger.Root.t Or_error.t
8083

8184
val depth : int
8285

src/lib/genesis_proof/genesis_proof.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ module T = struct
115115
let genesis_ledger { genesis_ledger; _ } =
116116
Genesis_ledger.Packed.t genesis_ledger
117117

118-
let populate_root { genesis_ledger; _ } =
119-
Genesis_ledger.Packed.populate_root genesis_ledger
118+
let create_root { genesis_ledger; _ } =
119+
Genesis_ledger.Packed.create_root genesis_ledger
120120

121121
let genesis_epoch_data { genesis_epoch_data; _ } = genesis_epoch_data
122122

src/lib/transition_frontier/full_frontier/full_frontier.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,8 @@ module For_tests = struct
10251025
~directory:(Filename.temp_file "snarked_ledger" "")
10261026
~ledger_depth
10271027
in
1028-
Persistent_root.reset_to_genesis_exn ~precomputed_values persistent_root ;
1028+
Async.Thread_safe.block_on_async_exn (fun () ->
1029+
Persistent_root.reset_to_genesis_exn persistent_root ~precomputed_values ) ;
10291030
let persistent_root_instance =
10301031
Persistent_root.create_instance_exn persistent_root
10311032
in

src/lib/transition_frontier/persistent_root/persistent_root.ml

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,15 +309,27 @@ let with_instance_exn t ~f =
309309
let x = f instance in
310310
Instance.close instance ; x
311311

312-
let reset_to_genesis_exn t ~precomputed_values =
312+
(** Clear the factory directory and recreate the snarked ledger instance for
313+
this factory with [create_root] and [setup] *)
314+
let reset_factory_root_exn t ~create_root ~setup =
315+
let open Async.Deferred.Let_syntax in
313316
assert (Option.is_none t.instance) ;
314-
Mina_stdlib_unix.File_system.rmrf t.directory ;
315-
with_instance_exn t ~f:(fun instance ->
316-
ignore
317-
( Precomputed_values.populate_root precomputed_values
318-
(Instance.snarked_ledger instance)
319-
|> Or_error.map ~f:Ledger.Root.as_unmasked
320-
: Ledger.Any_ledger.witness Or_error.t ) ;
317+
let%map () =
318+
Mina_stdlib_unix.File_system.create_dir ~clear_if_exists:true t.directory
319+
in
320+
let root =
321+
create_root
322+
~config:(Instance.Config.snarked_ledger t)
323+
~depth:t.ledger_depth ()
324+
|> Or_error.ok_exn
325+
in
326+
Ledger.Root.close root ;
327+
with_instance_exn t ~f:setup
328+
329+
let reset_to_genesis_exn t ~precomputed_values =
330+
reset_factory_root_exn t
331+
~create_root:(Precomputed_values.create_root precomputed_values)
332+
~setup:(fun instance ->
321333
Instance.set_root_identifier instance
322334
(genesis_root_identifier
323335
~genesis_state_hash:

src/lib/transition_frontier/persistent_root/persistent_root.mli

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,11 @@ val load_from_disk_exn :
105105

106106
val with_instance_exn : t -> f:(Instance_type.t -> 'a) -> 'a
107107

108-
val reset_to_genesis_exn : t -> precomputed_values:Genesis_proof.t -> unit
108+
val reset_factory_root_exn :
109+
t
110+
-> create_root:(config:Root.Config.t -> depth:int -> unit -> Root.t Or_error.t)
111+
-> setup:(Instance_type.t -> 'a)
112+
-> 'a Async.Deferred.t
113+
114+
val reset_to_genesis_exn :
115+
t -> precomputed_values:Genesis_proof.t -> unit Async.Deferred.t

src/lib/transition_frontier/transition_frontier.ml

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,9 @@ let rec load_with_max_length :
283283
(State_hash.With_state_hashes.state_hash
284284
precomputed_values.protocol_state_with_hashes )
285285
in
286-
Persistent_root.reset_to_genesis_exn persistent_root ~precomputed_values ;
286+
let%bind () =
287+
Persistent_root.reset_to_genesis_exn persistent_root ~precomputed_values
288+
in
287289
let genesis_ledger_hash =
288290
Precomputed_values.genesis_ledger precomputed_values
289291
|> Lazy.force |> Ledger.merkle_root |> Frozen_ledger_hash.of_ledger_hash
@@ -684,8 +686,8 @@ module For_tests = struct
684686

685687
let gen ?(logger = Logger.null ()) ~verifier ?trust_system
686688
?consensus_local_state ~precomputed_values
687-
?(populate_root_and_accounts =
688-
( Precomputed_values.populate_root precomputed_values
689+
?(create_root_and_accounts =
690+
( Precomputed_values.create_root precomputed_values
689691
, Lazy.force (Precomputed_values.accounts precomputed_values) ))
690692
?(gen_root_breadcrumb =
691693
gen_genesis_breadcrumb_with_protocol_states ~logger ~verifier
@@ -724,7 +726,7 @@ module For_tests = struct
724726
precomputed_values.protocol_state_with_hashes )
725727
~epoch_ledger_backing_type:Stable_db )
726728
in
727-
let populate_root, root_ledger_accounts = populate_root_and_accounts in
729+
let create_root, root_ledger_accounts = create_root_and_accounts in
728730
(* TODO: ensure that rose_tree cannot be longer than k *)
729731
let%bind root, branches, protocol_states =
730732
let%bind root, protocol_states = gen_root_breadcrumb in
@@ -755,12 +757,12 @@ module For_tests = struct
755757
~genesis_state_hash:
756758
(State_hash.With_state_hashes.state_hash
757759
precomputed_values.protocol_state_with_hashes ) ) ;
758-
Persistent_root.with_instance_exn persistent_root ~f:(fun instance ->
759-
let transition = Root_data.Limited.transition root_data in
760-
Persistent_root.Instance.set_root_state_hash instance
761-
(Mina_block.Validated.state_hash transition) ;
762-
ignore
763-
@@ populate_root (Persistent_root.Instance.snarked_ledger instance) ) ;
760+
Async.Thread_safe.block_on_async_exn (fun () ->
761+
Persistent_root.reset_factory_root_exn persistent_root ~create_root
762+
~setup:(fun instance ->
763+
let transition = Root_data.Limited.transition root_data in
764+
Persistent_root.Instance.set_root_state_hash instance
765+
(Mina_block.Validated.state_hash transition) ) ) ;
764766
let frontier_result =
765767
Async.Thread_safe.block_on_async_exn (fun () ->
766768
load_with_max_length ~max_length ~retry_with_fresh_db:false
@@ -797,21 +799,21 @@ module For_tests = struct
797799

798800
let gen_with_branch ?logger ~verifier ?trust_system ?consensus_local_state
799801
~precomputed_values
800-
?(populate_root_and_accounts =
801-
( Precomputed_values.populate_root precomputed_values
802+
?(create_root_and_accounts =
803+
( Precomputed_values.create_root precomputed_values
802804
, Lazy.force (Precomputed_values.accounts precomputed_values) ))
803805
?gen_root_breadcrumb ?(get_branch_root = root) ~max_length ~frontier_size
804806
~branch_size () =
805807
let open Quickcheck.Generator.Let_syntax in
806808
let%bind frontier =
807809
gen ?logger ~verifier ?trust_system ?consensus_local_state
808-
~precomputed_values ?gen_root_breadcrumb ~populate_root_and_accounts
810+
~precomputed_values ?gen_root_breadcrumb ~create_root_and_accounts
809811
~max_length ~size:frontier_size ()
810812
in
811813
let%map make_branch =
812814
Breadcrumb.For_tests.gen_seq ?logger ~precomputed_values ~verifier
813815
?trust_system
814-
~accounts_with_secret_keys:(snd populate_root_and_accounts)
816+
~accounts_with_secret_keys:(snd create_root_and_accounts)
815817
branch_size
816818
in
817819
let branch =

src/lib/transition_frontier/transition_frontier.mli

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,10 @@ module For_tests : sig
152152
-> ?trust_system:Trust_system.t
153153
-> ?consensus_local_state:Consensus.Data.Local_state.t
154154
-> precomputed_values:Precomputed_values.t
155-
-> ?populate_root_and_accounts:
156-
( Mina_ledger.Ledger.Root.t
155+
-> ?create_root_and_accounts:
156+
( config:Mina_ledger.Ledger.Root.Config.t
157+
-> depth:int
158+
-> unit
157159
-> Mina_ledger.Ledger.Root.t Core_kernel.Or_error.t )
158160
* (Private_key.t option * Account.t) list
159161
-> ?gen_root_breadcrumb:
@@ -173,8 +175,10 @@ module For_tests : sig
173175
-> ?trust_system:Trust_system.t
174176
-> ?consensus_local_state:Consensus.Data.Local_state.t
175177
-> precomputed_values:Precomputed_values.t
176-
-> ?populate_root_and_accounts:
177-
( Mina_ledger.Ledger.Root.t
178+
-> ?create_root_and_accounts:
179+
( config:Mina_ledger.Ledger.Root.Config.t
180+
-> depth:int
181+
-> unit
178182
-> Mina_ledger.Ledger.Root.t Core_kernel.Or_error.t )
179183
* (Private_key.t option * Account.t) list
180184
-> ?gen_root_breadcrumb:

0 commit comments

Comments
 (0)