Skip to content

Commit b973ce9

Browse files
authored
Merge pull request #18028 from MinaProtocol/cjjdespres/set-auto-hard-fork-genesis-correctly
Set hard fork config slot and timestamp properly
2 parents 94d4386 + 3a5ed3a commit b973ce9

File tree

4 files changed

+105
-22
lines changed

4 files changed

+105
-22
lines changed

src/lib/mina_graphql/mina_graphql.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2614,11 +2614,11 @@ module Queries = struct
26142614
in
26152615
let%bind { source_ledgers
26162616
; global_slot_since_genesis
2617+
; genesis_state_timestamp = _
26172618
; state_hash
26182619
; staking_epoch_seed
26192620
; next_epoch_seed
26202621
; blockchain_length
2621-
; block_timestamp = _
26222622
} =
26232623
Mina_lib.Hardfork_config.prepare_inputs ~breadcrumb_spec mina
26242624
in

src/lib/mina_lib/mina_lib.ml

Lines changed: 97 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,24 @@ let get_node_state t =
453453
; uptime_of_node
454454
}
455455

456+
(** Compute the hard fork genesis slot from the runtime config, if all the stop
457+
slots and the genesis slot delta have been set. Note that this is the hard
458+
fork genesis slot expressed as a
459+
[Mina_numbers.Global_slot_since_hard_fork.t] of the current chain/hard
460+
fork. *)
461+
let scheduled_hard_fork_genesis_slot t :
462+
Mina_numbers.Global_slot_since_hard_fork.t option =
463+
let open Option.Let_syntax in
464+
let runtime_config = t.config.precomputed_values.runtime_config in
465+
let%bind slot_chain_end_since_hard_fork =
466+
Runtime_config.slot_chain_end runtime_config
467+
in
468+
let%map hard_fork_genesis_slot_delta =
469+
Runtime_config.hard_fork_genesis_slot_delta runtime_config
470+
in
471+
Mina_numbers.Global_slot_since_hard_fork.add slot_chain_end_since_hard_fork
472+
hard_fork_genesis_slot_delta
473+
456474
(* This is a hack put in place to deal with nodes getting stuck
457475
in Offline states, that is, not receiving blocks for an extended period,
458476
or stuck in Bootstrap for too long
@@ -2834,24 +2852,97 @@ module Hardfork_config = struct
28342852
type inputs =
28352853
{ source_ledgers : genesis_source_ledgers
28362854
; global_slot_since_genesis : Mina_numbers.Global_slot_since_genesis.t
2855+
; genesis_state_timestamp : string
28372856
; state_hash : State_hash.t
28382857
; staking_epoch_seed : Epoch_seed.t
28392858
; next_epoch_seed : Epoch_seed.t
28402859
; blockchain_length : Mina_numbers.Length.t
2841-
; block_timestamp : Block_time.t
28422860
}
28432861

2862+
(** The genesis state timestamp string is the timestamp of the start of the
2863+
[global_slot] of the hard fork, relative to the current chain *)
2864+
let genesis_timestamp_str ~consensus_constants global_slot =
2865+
Consensus.Data.Consensus_time.(
2866+
start_time ~constants:consensus_constants
2867+
(of_global_slot ~constants:consensus_constants global_slot))
2868+
|> Block_time.to_time_exn
2869+
|> Time.to_string_iso8601_basic ~zone:Time.Zone.utc
2870+
2871+
(** Compute the hard fork slot. This will be derived from the stop slots and
2872+
hard fork genesis slot delta in the runtime config, if those have been set
2873+
and the [breadcrum_spec] was [`Stop_slot]. Otherwise, it will be the
2874+
global slot since genesis of the hard fork block. *)
2875+
let hard_fork_global_slot ~breadcrumb_spec ~block mina :
2876+
Mina_numbers.Global_slot_since_hard_fork.t =
2877+
let block_global_slot =
2878+
Mina_block.consensus_state block
2879+
|> Consensus.Data.Consensus_state.curr_global_slot
2880+
in
2881+
let configured_slot =
2882+
match breadcrumb_spec with
2883+
| `Stop_slot ->
2884+
scheduled_hard_fork_genesis_slot mina
2885+
| `State_hash _state_hash_base58 ->
2886+
None
2887+
| `Block_height _block_height ->
2888+
None
2889+
in
2890+
Option.value ~default:block_global_slot configured_slot
2891+
2892+
(** We schedule the hard fork genesis to occur at a particular
2893+
[Mina_numbers.Global_slot_since_hard_fork.t], but need a
2894+
[Mina_numbers.Global_slot_since_genesis.t] for the hard fork config. This
2895+
method does this conversion by taking the hard fork block's consensus data
2896+
applying the same slot update as [Consensus.Data.Consensus_state.update]
2897+
to the hard fork block's global slots (since hard fork and since genesis),
2898+
then returning the resulting global slot since genesis.
2899+
2900+
This method requires that the desired hard fork genesis slot occur after
2901+
the hard fork block's slot. This property is guaranteed by
2902+
[hard_fork_global_slot] (which determines the scheduled genesis slot) and
2903+
[breadcrumb] (which retrieves the hard fork block). *)
2904+
let move_hard_fork_consensus_to_scheduled_genesis ~hard_fork_consensus_data
2905+
next_genesis_global_slot =
2906+
let block_global_slot =
2907+
Consensus.Data.Consensus_state.curr_global_slot hard_fork_consensus_data
2908+
in
2909+
let block_global_slot_since_genesis =
2910+
Consensus.Data.Consensus_state.global_slot_since_genesis
2911+
hard_fork_consensus_data
2912+
in
2913+
(* We pretend that the consensus moved forward from the hard fork block's
2914+
slot to the scheduled genesis slot, and get that slot difference *)
2915+
let global_slot_span =
2916+
Mina_numbers.Global_slot_since_hard_fork.diff next_genesis_global_slot
2917+
block_global_slot
2918+
|> Option.value_exn ~here:[%here]
2919+
~message:
2920+
"Invariant: hard fork genesis cannot be scheduled before the hard \
2921+
fork block"
2922+
in
2923+
(* Now apply that difference to the hard fork block's slot since genesis *)
2924+
Mina_numbers.Global_slot_since_genesis.add block_global_slot_since_genesis
2925+
global_slot_span
2926+
28442927
let prepare_inputs ~breadcrumb_spec mina =
28452928
let open Deferred.Result.Let_syntax in
28462929
let%bind breadcrumb = breadcrumb ~breadcrumb_spec mina in
28472930
let block = Transition_frontier.Breadcrumb.block breadcrumb in
28482931
let blockchain_length = Mina_block.blockchain_length block in
2932+
let global_slot_since_hard_fork =
2933+
hard_fork_global_slot ~breadcrumb_spec ~block mina
2934+
in
28492935
let global_slot_since_genesis =
2850-
Mina_block.consensus_state block
2851-
|> Consensus.Data.Consensus_state.global_slot_since_genesis
2936+
move_hard_fork_consensus_to_scheduled_genesis
2937+
~hard_fork_consensus_data:(Mina_block.consensus_state block)
2938+
global_slot_since_hard_fork
2939+
in
2940+
let genesis_state_timestamp =
2941+
genesis_timestamp_str
2942+
~consensus_constants:mina.config.precomputed_values.consensus_constants
2943+
global_slot_since_hard_fork
28522944
in
28532945
let state_hash = Transition_frontier.Breadcrumb.state_hash breadcrumb in
2854-
let block_timestamp = block |> Mina_block.timestamp in
28552946
let protocol_state =
28562947
Transition_frontier.Breadcrumb.protocol_state breadcrumb
28572948
in
@@ -2867,11 +2958,11 @@ module Hardfork_config = struct
28672958
let%map source_ledgers = source_ledgers ~breadcrumb mina in
28682959
{ source_ledgers
28692960
; global_slot_since_genesis
2961+
; genesis_state_timestamp
28702962
; state_hash
28712963
; staking_epoch_seed
28722964
; next_epoch_seed
28732965
; blockchain_length
2874-
; block_timestamp
28752966
}
28762967

28772968
(** Copy the roots of the [source_ledgers] and gather the stable ledger
@@ -3046,20 +3137,15 @@ module Hardfork_config = struct
30463137
~state_hash ~blockchain_length ~staking_epoch_seed ~next_epoch_seed
30473138
genesis_config )
30483139

3049-
let genesis_timestamp_str ~hardfork_genesis_timestamp_offset block_timestamp =
3050-
block_timestamp |> Block_time.to_time_exn
3051-
|> Fn.flip Time.add hardfork_genesis_timestamp_offset
3052-
|> Time.to_string_iso8601_basic ~zone:Time.Zone.utc
3053-
30543140
let generate_hardfork_configs ~logger
30553141
~inputs:
30563142
{ source_ledgers
30573143
; global_slot_since_genesis
3144+
; genesis_state_timestamp
30583145
; state_hash
30593146
; staking_epoch_seed
30603147
; next_epoch_seed
30613148
; blockchain_length
3062-
; block_timestamp
30633149
} ~build_dir directory_name =
30643150
let open Deferred.Or_error.Let_syntax in
30653151
let migrate_and_apply (root, diff) =
@@ -3099,12 +3185,6 @@ module Hardfork_config = struct
30993185
, genesis_next_epoch_ledger_migrated ) =
31003186
migrate_and_apply genesis_next_epoch_ledger_data
31013187
in
3102-
(* TODO: the correct timestamp is actually the timestamp of the slot_tx_end plus the hardfork genesis offset *)
3103-
let genesis_state_timestamp =
3104-
genesis_timestamp_str
3105-
~hardfork_genesis_timestamp_offset:(Time.Span.of_int_sec 0)
3106-
block_timestamp
3107-
in
31083188
[%log debug] "Writing hard fork config directories" ;
31093189
let%bind () =
31103190
write_stable_config_directory ~logger ~genesis_state_timestamp

src/lib/mina_lib/mina_lib.mli

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,6 @@ val best_chain_block_by_height :
278278
val best_chain_block_by_state_hash :
279279
t -> State_hash.t -> Transition_frontier.Breadcrumb.t Or_error.t
280280

281-
val best_chain_block_before_stop_slot :
282-
t -> Transition_frontier.Breadcrumb.t Deferred.Or_error.t
283-
284281
module Hardfork_config : sig
285282
type mina_lib = t
286283

@@ -325,11 +322,11 @@ module Hardfork_config : sig
325322
type inputs =
326323
{ source_ledgers : genesis_source_ledgers
327324
; global_slot_since_genesis : Mina_numbers.Global_slot_since_genesis.t
325+
; genesis_state_timestamp : string
328326
; state_hash : State_hash.t
329327
; staking_epoch_seed : Epoch_seed.t
330328
; next_epoch_seed : Epoch_seed.t
331329
; blockchain_length : Mina_numbers.Length.t
332-
; block_timestamp : Block_time.t
333330
}
334331

335332
val prepare_inputs :

src/lib/runtime_config/runtime_config.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,12 @@ let slot_tx_end, slot_chain_end =
16861686
in
16871687
(f (fun d -> d.slot_tx_end), f (fun d -> d.slot_chain_end))
16881688

1689+
let hard_fork_genesis_slot_delta t =
1690+
let open Option.Let_syntax in
1691+
let%bind daemon = t.daemon in
1692+
let%map delta = daemon.hard_fork_genesis_slot_delta in
1693+
Mina_numbers.Global_slot_span.of_int delta
1694+
16891695
(** This method creates a runtime daemon config for a hard fork, containing the
16901696
data that can't necessarily be computed in advance of the hard fork. This
16911697
ends up being data that's computed based on the last block produced before

0 commit comments

Comments
 (0)