Skip to content

Commit 3ab1740

Browse files
authored
Merge pull request #14390 from MinaProtocol/feature/ledger-hashes-in-checkpoint
First-pass ledger hashes in replayer checkpoint files
2 parents fd40b46 + 359c222 commit 3ab1740

File tree

1 file changed

+58
-37
lines changed

1 file changed

+58
-37
lines changed

src/app/replayer/replayer.ml

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ type input =
2929
{ target_epoch_ledgers_state_hash : State_hash.t option [@default None]
3030
; start_slot_since_genesis : int64 [@default 0L]
3131
; genesis_ledger : Runtime_config.Ledger.t
32+
; first_pass_ledger_hashes : Ledger_hash.t list [@default []]
33+
; last_snarked_ledger_hash : Ledger_hash.t option [@default None]
3234
}
3335
[@@deriving yojson]
3436

@@ -62,6 +64,42 @@ let create_ledger_as_list ledger =
6264
List.map accounts ~f:(fun acc ->
6365
Genesis_ledger_helper.Accounts.Single.of_account acc None )
6466

67+
module First_pass_ledger_hashes = struct
68+
(* ledger hashes after 1st pass, indexed by order of occurrence *)
69+
70+
module T = struct
71+
type t = Ledger_hash.Stable.Latest.t * int
72+
[@@deriving bin_io_unversioned, compare, sexp, hash]
73+
end
74+
75+
include T
76+
include Hashable.Make_binable (T)
77+
78+
let hash_set = Hash_set.create ()
79+
80+
let add =
81+
let count = ref 0 in
82+
fun ledger_hash ->
83+
Base.Hash_set.add hash_set (ledger_hash, !count) ;
84+
incr count
85+
86+
let find ledger_hash =
87+
Base.Hash_set.find hash_set ~f:(fun (hash, _n) ->
88+
Ledger_hash.equal hash ledger_hash )
89+
90+
(* once we find a snarked ledger hash corresponding to a ledger hash, don't need to store earlier ones *)
91+
let flush_older_than ndx =
92+
let elts = Base.Hash_set.to_list hash_set in
93+
List.iter elts ~f:(fun ((_hash, n) as elt) ->
94+
if n < ndx then Base.Hash_set.remove hash_set elt )
95+
96+
let get_last_snarked_hash, set_last_snarked_hash =
97+
let last_snarked_hash = ref Ledger_hash.empty_hash in
98+
let getter () = !last_snarked_hash in
99+
let setter hash = last_snarked_hash := hash in
100+
(getter, setter)
101+
end
102+
65103
let create_output ~target_epoch_ledgers_state_hash ~target_fork_state_hash
66104
~ledger ~staking_epoch_ledger ~staking_seed ~next_epoch_ledger ~next_seed
67105
(input_genesis_ledger : Runtime_config.Ledger.t) =
@@ -106,9 +144,19 @@ let create_replayer_checkpoint ~ledger ~start_slot_since_genesis :
106144
; add_genesis_winner = Some true
107145
}
108146
in
147+
let first_pass_ledger_hashes =
148+
let elts = Base.Hash_set.to_list First_pass_ledger_hashes.hash_set in
149+
List.sort elts ~compare:(fun (_h1, n1) (_h2, n2) -> Int.compare n1 n2)
150+
|> List.map ~f:(fun (h, _n) -> h)
151+
in
152+
let last_snarked_ledger_hash =
153+
Some (First_pass_ledger_hashes.get_last_snarked_hash ())
154+
in
109155
{ target_epoch_ledgers_state_hash = None
110156
; start_slot_since_genesis
111157
; genesis_ledger
158+
; first_pass_ledger_hashes
159+
; last_snarked_ledger_hash
112160
}
113161

114162
(* map from global slots (since genesis) to state hash, ledger hash, snarked ledger hash triples *)
@@ -118,42 +166,6 @@ let global_slot_hashes_tbl :
118166

119167
let get_slot_hashes slot = Hashtbl.find global_slot_hashes_tbl slot
120168

121-
module First_pass_ledger_hashes = struct
122-
(* ledger hashes after 1st pass, indexed by order of occurrence *)
123-
124-
module T = struct
125-
type t = Ledger_hash.Stable.Latest.t * int
126-
[@@deriving bin_io_unversioned, compare, sexp, hash]
127-
end
128-
129-
include T
130-
include Hashable.Make_binable (T)
131-
132-
let hash_set = Hash_set.create ()
133-
134-
let add =
135-
let count = ref 0 in
136-
fun ledger_hash ->
137-
Base.Hash_set.add hash_set (ledger_hash, !count) ;
138-
incr count
139-
140-
let find ledger_hash =
141-
Base.Hash_set.find hash_set ~f:(fun (hash, _n) ->
142-
Ledger_hash.equal hash ledger_hash )
143-
144-
(* once we find a snarked ledger hash corresponding to a ledger hash, don't need to store earlier ones *)
145-
let flush_older_than ndx =
146-
let elts = Base.Hash_set.to_list hash_set in
147-
List.iter elts ~f:(fun ((_hash, n) as elt) ->
148-
if n < ndx then Base.Hash_set.remove hash_set elt )
149-
150-
let get_last_snarked_hash, set_last_snarked_hash =
151-
let last_snarked_hash = ref Ledger_hash.empty_hash in
152-
let getter () = !last_snarked_hash in
153-
let setter hash = last_snarked_hash := hash in
154-
(getter, setter)
155-
end
156-
157169
let process_block_infos_of_state_hash ~logger pool ~state_hash ~start_slot ~f =
158170
match%bind
159171
Caqti_async.Pool.use
@@ -674,6 +686,13 @@ let main ~input_file ~output_file_opt ~archive_uri ~continue_on_error
674686
max_slot ;
675687
try_slot ~logger pool max_slot
676688
in
689+
if not @@ List.is_empty input.first_pass_ledger_hashes then (
690+
[%log info] "Populating set of first-pass ledger hashes" ;
691+
List.iter input.first_pass_ledger_hashes ~f:First_pass_ledger_hashes.add
692+
) ;
693+
Option.iter input.last_snarked_ledger_hash ~f:(fun h ->
694+
[%log info] "Setting last snarked ledger hash" ;
695+
First_pass_ledger_hashes.set_last_snarked_hash h ) ;
677696
[%log info]
678697
"Loading block information using target state hash and start slot" ;
679698
let%bind block_ids, oldest_block_id =
@@ -1263,7 +1282,9 @@ let main ~input_file ~output_file_opt ~archive_uri ~continue_on_error
12631282
"Current snarked ledger hash not among first-pass \
12641283
ledger hashes, but we haven't yet found one. The \
12651284
transaction that created this ledger hash might have \
1266-
been in a replayer run that created a checkpoint file" ;
1285+
been in an older replayer run that created a \
1286+
checkpoint file without saved first-pass ledger \
1287+
hashes" ;
12671288
First_pass_ledger_hashes.set_last_snarked_hash
12681289
snarked_hash )
12691290
else

0 commit comments

Comments
 (0)