@@ -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
0 commit comments