@@ -2833,6 +2833,7 @@ module Hardfork_config = struct
28332833 ; staking_epoch_seed : Epoch_seed .t
28342834 ; next_epoch_seed : Epoch_seed .t
28352835 ; blockchain_length : Mina_numbers.Length .t
2836+ ; block_timestamp : Block_time .t
28362837 }
28372838
28382839 let prepare_inputs ~breadcrumb_spec mina =
@@ -2845,6 +2846,7 @@ module Hardfork_config = struct
28452846 |> Consensus.Data.Consensus_state. global_slot_since_genesis
28462847 in
28472848 let state_hash = Transition_frontier.Breadcrumb. state_hash breadcrumb in
2849+ let block_timestamp = block |> Mina_block. timestamp in
28482850 let protocol_state =
28492851 Transition_frontier.Breadcrumb. protocol_state breadcrumb
28502852 in
@@ -2864,7 +2866,256 @@ module Hardfork_config = struct
28642866 ; staking_epoch_seed
28652867 ; next_epoch_seed
28662868 ; blockchain_length
2869+ ; block_timestamp
28672870 }
2871+
2872+ (* * Copy the roots of the [source_ledgers] and gather the stable ledger
2873+ diffs from the [source_ledgers] to their roots *)
2874+ let copy_genesis_roots_and_diffs ~source_ledgers parent_directory =
2875+ Core.Unix. mkdir_p parent_directory ;
2876+ let genesis_ledger_data =
2877+ let directory_name = parent_directory ^/ " genesis_ledger" in
2878+ let root =
2879+ Ledger.Root. create_checkpoint_with_directory
2880+ source_ledgers.root_snarked_ledger ~directory_name
2881+ in
2882+ let diff = Ledger. all_accounts_on_masks source_ledgers.staged_ledger in
2883+ (root, diff)
2884+ in
2885+ let genesis_staking_ledger_data =
2886+ let directory_name = parent_directory ^/ " staking_ledger" in
2887+ match source_ledgers.staking_ledger with
2888+ | `Genesis _l ->
2889+ failwith " TODO!"
2890+ | `Root l ->
2891+ let root =
2892+ Ledger.Root. create_checkpoint_with_directory l ~directory_name
2893+ in
2894+ let diff = Ledger.Location.Map. empty in
2895+ (root, diff)
2896+ in
2897+ let genesis_next_epoch_ledger_data =
2898+ let directory_name = parent_directory ^/ " next_epoch_ledger" in
2899+ match source_ledgers.next_epoch_ledger with
2900+ | `Genesis _l ->
2901+ failwith " TODO!"
2902+ | `Root l ->
2903+ let root =
2904+ Ledger.Root. create_checkpoint_with_directory l ~directory_name
2905+ in
2906+ let diff = Ledger.Location.Map. empty in
2907+ (root, diff)
2908+ | `Uncommitted l ->
2909+ let root =
2910+ Ledger.Root. create_checkpoint_with_directory
2911+ source_ledgers.root_snarked_ledger ~directory_name
2912+ in
2913+ let diff = Ledger. all_accounts_on_masks l in
2914+ (root, diff)
2915+ in
2916+ ( genesis_ledger_data
2917+ , genesis_staking_ledger_data
2918+ , genesis_next_epoch_ledger_data )
2919+
2920+ (* * Generate the tar file and runtime ledger config for the given root
2921+ database, and close and delete the database *)
2922+ let generate_tar_and_config ~get_directory ~get_root_hash ~close_root ~logger
2923+ ~target_dir ~ledger_name_prefix root =
2924+ let open Deferred.Or_error.Let_syntax in
2925+ let root_hash = get_root_hash root in
2926+ let ledger_dirname = get_directory root |> Option. value_exn in
2927+ let % bind tar_path =
2928+ Genesis_ledger_helper.Ledger. generate_tar ~logger ~target_dir
2929+ ~ledger_name_prefix ~root_hash ~ledger_dirname ()
2930+ in
2931+ let % map s3_data_hash =
2932+ Genesis_ledger_helper. sha3_hash tar_path
2933+ |> Deferred. map ~f: Or_error. return
2934+ in
2935+ let config =
2936+ Runtime_config. ledger_of_hashes
2937+ ~root_hash: (Mina_base.Ledger_hash. to_base58_check root_hash)
2938+ ~s3_data_hash ()
2939+ in
2940+ close_root root ;
2941+ Mina_stdlib_unix.File_system. rmrf ledger_dirname ;
2942+ config
2943+
2944+ let generate_tars_and_configs ~get_directory ~get_root_hash ~close_root
2945+ ~logger ~target_dir genesis_ledger genesis_staking_ledger
2946+ genesis_next_epoch_ledger =
2947+ let open Deferred.Or_error.Let_syntax in
2948+ Core.Unix. mkdir_p target_dir ;
2949+ let % bind genesis_ledger_config =
2950+ generate_tar_and_config ~get_directory ~get_root_hash ~close_root ~logger
2951+ ~target_dir ~ledger_name_prefix: " genesis_ledger" genesis_ledger
2952+ in
2953+ let % bind genesis_staking_ledger_config =
2954+ generate_tar_and_config ~get_directory ~get_root_hash ~close_root ~logger
2955+ ~target_dir ~ledger_name_prefix: " epoch_ledger" genesis_staking_ledger
2956+ in
2957+ let % map genesis_next_epoch_ledger_config =
2958+ generate_tar_and_config ~get_directory ~get_root_hash ~close_root ~logger
2959+ ~target_dir ~ledger_name_prefix: " epoch_ledger" genesis_next_epoch_ledger
2960+ in
2961+ ( genesis_ledger_config
2962+ , genesis_staking_ledger_config
2963+ , genesis_next_epoch_ledger_config )
2964+
2965+ let make_full_config ~genesis_state_timestamp ~global_slot_since_genesis
2966+ ~state_hash ~blockchain_length ~staking_epoch_seed ~next_epoch_seed
2967+ ( genesis_ledger_config
2968+ , genesis_staking_ledger_config
2969+ , genesis_next_epoch_ledger_config ) =
2970+ Runtime_config. make_automatic_fork_config ~genesis_state_timestamp
2971+ ~genesis_ledger_config ~global_slot_since_genesis ~state_hash
2972+ ~blockchain_length ~staking_ledger_config: genesis_staking_ledger_config
2973+ ~staking_epoch_seed: (Epoch_seed. to_base58_check staking_epoch_seed)
2974+ ~next_epoch_ledger_config: (Some genesis_next_epoch_ledger_config)
2975+ ~next_epoch_seed: (Epoch_seed. to_base58_check next_epoch_seed)
2976+
2977+ let write_config_file ~filename daemon_config =
2978+ Async.Writer. save filename
2979+ ~contents: (Yojson.Safe. to_string (Runtime_config. to_yojson daemon_config))
2980+ |> Deferred. map ~f: Or_error. return
2981+
2982+ let write_stable_config_directory ~logger ~genesis_state_timestamp
2983+ ~global_slot_since_genesis ~state_hash ~staking_epoch_seed
2984+ ~next_epoch_seed ~blockchain_length ~config_dir genesis_ledger
2985+ genesis_staking_ledger genesis_next_epoch_ledger =
2986+ let open Deferred.Or_error.Let_syntax in
2987+ [% log debug]
2988+ " Generating database files and daemon.json for stable hard fork config" ;
2989+ Core.Unix. mkdir_p config_dir ;
2990+ let genesis_dir = config_dir ^/ " genesis" in
2991+ let % bind genesis_config =
2992+ generate_tars_and_configs ~get_directory: Ledger.Db. get_directory
2993+ ~get_root_hash: Ledger.Db. merkle_root ~close_root: Ledger.Db. close ~logger
2994+ ~target_dir: genesis_dir genesis_ledger genesis_staking_ledger
2995+ genesis_next_epoch_ledger
2996+ in
2997+ write_config_file
2998+ ~filename: (config_dir ^/ " daemon.json" )
2999+ (make_full_config ~genesis_state_timestamp ~global_slot_since_genesis
3000+ ~state_hash ~blockchain_length ~staking_epoch_seed ~next_epoch_seed
3001+ genesis_config )
3002+
3003+ let write_migrated_config_directory ~logger ~genesis_state_timestamp
3004+ ~global_slot_since_genesis ~state_hash ~staking_epoch_seed
3005+ ~next_epoch_seed ~blockchain_length ~config_dir genesis_ledger
3006+ genesis_staking_ledger genesis_next_epoch_ledger =
3007+ let open Deferred.Or_error.Let_syntax in
3008+ [% log debug]
3009+ " Generating database files and daemon.json for migrated hard fork config" ;
3010+ Core.Unix. mkdir_p config_dir ;
3011+ let genesis_dir = config_dir ^/ " genesis" in
3012+ let % bind genesis_config =
3013+ generate_tars_and_configs ~get_directory: Ledger.Hardfork_db. get_directory
3014+ ~get_root_hash: Ledger.Hardfork_db. merkle_root
3015+ ~close_root: Ledger.Hardfork_db. close ~logger ~target_dir: genesis_dir
3016+ genesis_ledger genesis_staking_ledger genesis_next_epoch_ledger
3017+ in
3018+ write_config_file
3019+ ~filename: (config_dir ^/ " daemon.json" )
3020+ (make_full_config ~genesis_state_timestamp ~global_slot_since_genesis
3021+ ~state_hash ~blockchain_length ~staking_epoch_seed ~next_epoch_seed
3022+ genesis_config )
3023+
3024+ let genesis_timestamp_str ~hardfork_genesis_timestamp_offset block_timestamp =
3025+ block_timestamp |> Block_time. to_time_exn
3026+ |> Fn. flip Time. add hardfork_genesis_timestamp_offset
3027+ |> Time. to_string_iso8601_basic ~zone: Time.Zone. utc
3028+
3029+ let generate_hardfork_configs ~logger
3030+ ~inputs :
3031+ { source_ledgers
3032+ ; global_slot_since_genesis
3033+ ; state_hash
3034+ ; staking_epoch_seed
3035+ ; next_epoch_seed
3036+ ; blockchain_length
3037+ ; block_timestamp
3038+ } ~build_dir directory_name =
3039+ let open Deferred.Or_error.Let_syntax in
3040+ let migrate_and_apply (root , diff ) =
3041+ let % map.Deferred root = Ledger.Root. make_converting root in
3042+ Ledger.Any_ledger.M. set_batch
3043+ (Ledger.Root. as_unmasked root)
3044+ (Map. to_alist diff) ;
3045+ let stable_db, migrated_db_opt =
3046+ Ledger.Root. unsafely_decompose_root root
3047+ in
3048+ let migrated_db =
3049+ migrated_db_opt
3050+ |> Option. value_exn
3051+ ~message: " Invariant: root was already made converting"
3052+ in
3053+ (stable_db, migrated_db)
3054+ in
3055+ [% log debug] " Copying hard fork genesis ledger inputs" ;
3056+ let ( genesis_ledger_data
3057+ , genesis_staking_ledger_data
3058+ , genesis_next_epoch_ledger_data ) =
3059+ copy_genesis_roots_and_diffs ~source_ledgers build_dir
3060+ in
3061+ let % bind.Deferred genesis_ledger_legacy, genesis_ledger_migrated =
3062+ migrate_and_apply genesis_ledger_data
3063+ in
3064+ let % bind.Deferred ( genesis_staking_ledger_legacy
3065+ , genesis_staking_ledger_migrated ) =
3066+ migrate_and_apply genesis_staking_ledger_data
3067+ in
3068+ let % bind.Deferred ( genesis_next_epoch_ledger_legacy
3069+ , genesis_next_epoch_ledger_migrated ) =
3070+ migrate_and_apply genesis_next_epoch_ledger_data
3071+ in
3072+ (* TODO: the correct timestamp is actually the timestamp of the slot_tx_end plus the hardfork genesis offset *)
3073+ let genesis_state_timestamp =
3074+ genesis_timestamp_str
3075+ ~hardfork_genesis_timestamp_offset: (Time.Span. of_int_sec 0 )
3076+ block_timestamp
3077+ in
3078+ [% log debug] " Writing hard fork config directories" ;
3079+ let % bind () =
3080+ write_stable_config_directory ~logger ~genesis_state_timestamp
3081+ ~global_slot_since_genesis ~state_hash ~staking_epoch_seed
3082+ ~next_epoch_seed ~blockchain_length
3083+ ~config_dir: (directory_name ^/ " fork_validation" ^/ " legacy" )
3084+ genesis_ledger_legacy genesis_staking_ledger_legacy
3085+ genesis_next_epoch_ledger_legacy
3086+ in
3087+ let % bind () =
3088+ write_migrated_config_directory ~logger ~genesis_state_timestamp
3089+ ~global_slot_since_genesis ~state_hash ~staking_epoch_seed
3090+ ~next_epoch_seed ~blockchain_length ~config_dir: directory_name
3091+ genesis_ledger_migrated genesis_staking_ledger_migrated
3092+ genesis_next_epoch_ledger_migrated
3093+ in
3094+ return ()
3095+
3096+ let dump_reference_config ~breadcrumb_spec ~directory_name mina =
3097+ let open Deferred.Or_error.Let_syntax in
3098+ let logger = mina.config.logger in
3099+ Deferred.Or_error. try_with_join ~here: [% here]
3100+ @@ fun () ->
3101+ let % bind.Deferred dir_exists =
3102+ Mina_stdlib_unix.File_system. dir_exists directory_name
3103+ in
3104+ let % bind () =
3105+ if dir_exists then
3106+ Deferred.Or_error. error_string
3107+ " Requested config directory already exists"
3108+ else return ()
3109+ in
3110+ [% log debug] " Creating reference hard fork config in $directory_name"
3111+ ~metadata: [ (" directory_name" , `String directory_name) ] ;
3112+ let % bind.Deferred () =
3113+ Mina_stdlib_unix.File_system. create_dir directory_name
3114+ in
3115+ let % bind inputs = prepare_inputs ~breadcrumb_spec mina in
3116+ Mina_stdlib_unix.File_system. with_temp_dir (directory_name ^/ " _build" )
3117+ ~f: (fun build_dir ->
3118+ generate_hardfork_configs ~logger ~inputs ~build_dir directory_name )
28683119end
28693120
28703121let zkapp_cmd_limit t = t.config.zkapp_cmd_limit
0 commit comments